Всем привет знаю что это "говнокод" но всё же я в jass неопытен и поэтому прошу помощи так как сам уже устал биться. Вообщем сделал карту, добавил ботов и нижеприведённый код заставляет ботов кастовать заклинания на вражеских героев, примерно в 50% случаев игра вылетает без всяких ошибок и прочего, судя по логу из war3dbg.log ошибка в ниже приведённой функции.
Собственно вот часть лога:
000AFEAB	UNIT_TYPE_HERO
000AFEAC	IsUnitType
000AFEAD	g
000AFEAE	FirstOfGroup
000AFEAF	 	u
000AFEB0	  	AI
000AFEB1		GetOwningPlayer
000AFEB2		IsUnitEnemy
000AFEB3		AI
000AFEB4		IsUnitAliveBJ
000AFEB5		whichUnit
000AFEB6		IsUnitDeadBJ
000AFEB7		whichUnit
000AFEB8		UNIT_STATE_LIFE
000AFEB9		GetUnitState
000AFEBA	u
000AFEBB	AI
000AFEBC	GetOwningPlayer
000AFEBD	IsUnitVisible
000AFEBE	u
000AFEBF		GetUnitX
000AFEC0	u
000AFEC1	GetUnitY
000AFEC2	AI
000AFEC3	u
000AFEC4	IssueTargetOrder
А вот сама функция:
function filtgAI takes nothing returns boolean
return GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 and IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)==false and GetUnitAbilityLevel(GetFilterUnit(),'Aloc')==0 and IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO)==true
endfunction

function NewAI2_system takes real distance returns nothing
local group g=CreateGroup()
local unit u=null
local unit AI=null
local real x = 0.
local real y = 0.
local real x2 = 0.
local real y2 = 0.
local integer A = 1
local integer B = 12

loop
 exitwhen A>B
  if  GetUnitState(udg_hero[A], UNIT_STATE_LIFE) > 0 and GetPlayerController(GetOwningPlayer(udg_hero[A]))==MAP_CONTROL_COMPUTER then
  set AI = udg_hero[A]
  set x = GetUnitX(AI)
  set y = GetUnitY(AI)
  call GroupEnumUnitsInRange(g,x,y,distance,Condition(function filtgAI))
  set u=FirstOfGroup(g)
  
    loop
     exitwhen u==null
      if IsUnitEnemy(u,GetOwningPlayer(AI)) == true and GetUnitState(AI, UNIT_STATE_LIFE) > 0 and IsUnitVisible(u,GetOwningPlayer(AI)) then
        set x2 = GetUnitX(u)
        set y2 = GetUnitY(u)
        call IssueTargetOrder(AI,"thunderbolt",u)
        call IssueTargetOrder(AI,"creepthunderbolt",u)
        call IssueTargetOrder(AI,"banish",u)
        call IssueTargetOrder(AI,"frostnova",u)
        call IssueTargetOrder(AI,"sleep", u)
        call IssueTargetOrder(AI,"shadowstrike",u)
        call IssueTargetOrder(AI,"chainlightning",u)
        call IssueTargetOrder(AI,"drunkenhaze",u)
        call IssueTargetOrder(AI,"acidbomb",u)
        call IssueTargetOrder(AI,"soulburn",u)
        call IssueTargetOrder(AI,"hex",u)
        call IssueTargetOrder(AI,"manaburn",u)
        call IssueTargetOrder(AI,"slow",u)
        call IssueTargetOrder(AI,"cripple",u)
        call IssueTargetOrder(AI,"forkedlighting",u)
        call IssueTargetOrder(AI,"antimagicshell",u)
        call IssueTargetOrder(AI,"entanglingroots",u)
        call IssueTargetOrder(AI,"purge",u)
        call IssueTargetOrder(AI,"ensnare",u)
        // --------C указанием точки--------
        call IssuePointOrder(AI,"flamestrike",x2,y2)
        call IssuePointOrder(AI,"inferno",x2,y2)
        call IssuePointOrder(AI,"shockwave",x2,y2)
        call IssuePointOrder(AI,"clusterrockets",x2,y2)
        call IssuePointOrder(AI,"impale",x2,y2)
        call IssuePointOrder(AI,"rainoffire",x2,y2)
        call IssuePointOrder(AI,"blink",x2,y2)
        call IssuePointOrder(AI,"silence",x2,y2)
        call IssuePointOrder(AI,"breathoffire",x2,y2)
        call IssuePointOrder(AI,"stasistrap",x2,y2)
        call IssuePointOrder(AI,"blizzard",x2,y2)
        // --------Без цели--------
        call IssueImmediateOrder(AI,"waterelemental" )
        call IssueImmediateOrder(AI,"windwalk" )
        call IssueImmediateOrder(AI,"thunderclap" )
        call IssueImmediateOrder(AI,"creepthunderclap" )
        call IssueImmediateOrder(AI,"spiritwolf" )
        call IssueImmediateOrder(AI,"Locustswarm" )
        call IssueImmediateOrder(AI,"Summongrizzly" )
        call IssueImmediateOrder(AI,"stomp" )
        call IssueImmediateOrder(AI,"Serpentward" )
        call IssueImmediateOrder(AI,"metamorphosis" )
        call IssueImmediateOrder(AI,"whirlwind" )
        call IssueImmediateOrder(AI,"fanofknives" )
        call IssueImmediateOrder(AI,"immolation" )
        call IssueImmediateOrder(AI,"berserk" )
        call IssueImmediateOrder(AI,"roar" )
        call IssueImmediateOrder(AI,"manashield" )
        call IssueImmediateOrder(AI,"robogoblin" )
        call IssueImmediateOrder(AI,"battleroar" )
        call RemoveLocation(Location(x2,y2))
        set x2 = 0.
        set y2 = 0.
      call GroupRemoveUnit(g,u)
      set u=FirstOfGroup(g)
      else
      call GroupRemoveUnit(g,u)
      set u=FirstOfGroup(g)
      endif
    endloop
    
   endif
   set A = A +1
 endloop
call DestroyGroup(g)
set g=null
set u=null
set AI=null
set x = 0.
set y = 0.
set x2 = 0.
set y2 = 0.
set A = 0
set B = 0
endfunction
Извиняюсь если написал не в тот раздел. Прошу помощи в поиске ошибке и её устранения.

FenikS1991, убери стоимость в 15 маны.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
28
ты отдаёшь 1 и тому же юниту кучу приказов до того как он успел начать исполнять предыдущий
представь если бы тебе давали противоречащие друг другу приказы
то есть просто список того что ты должен сделать прямо сейчас
не думаю что у твоего юнита есть столько различных спелов
так что используй проверку на наличие спела а так же вейты между кастами
if(GetUnitAbilityLevel(AI,'A000')>0){ // A000 это равкод спела с приказом thunderbolt
	IssueTargetOrder(AI,"thunderbolt",u);
	TriggerSleepAction(0.4);
elseif(GetUnitAbilityLevel(AI,'A001')>0) // A001 это равкод спела с приказом creepthunderbolt
	IssueTargetOrder(AI,"creepthunderbolt",u);
	TriggerSleepAction(0.4);
elseif(GetUnitAbilityLevel(AI,'A002')>0) // A002 это равкод спела с приказом banish
	IssueTargetOrder(AI,"banish",u)
	TriggerSleepAction(0.4);
}
а вообще чтобы не писать простыню кода я бы сделал бд
в бд указаны спелы которые есть у юнита, затрачиваемое мп и строка приказа
2
а вообще чтобы не писать простыню кода я бы сделал бд
в бд указаны спелы которые есть у юнита, затрачиваемое мп и строка приказа
Спасибо за совет я знаю что бд отличная вещь но как юзать её в jass так и не понял...
Ошибку в карте нашёл отключив строки
call GroupRemoveUnit(g,u)
set u=FirstOfGroup(g)
в блоке else\endif. Но боты стали хуже кастовать способности, хотя теперь нет вылетов. Теперь понять бы как это дело исправить. А на будущее хотел бы попросить ещё примерчик использования бд для моего случая (для каста имеющихся способностей на героя врага), хотя-бы самый простой. Т.к этот "http://xgm.guru/p/wc3/wc3bd" пример выдаёт исключения при компиляции (говоря что есть не очищаемые переменные). а тут "http://xgm.guru/p/wc3/24007" всё ок, но как использовать не догнал.
Был бы очень благодарен.
28
FenikS1991, я хз кто и что тебе выдаёт но там всё нормально работает
скачай джнгп
FenikS1991, пример того как сделать бд есть в статье что я кинул
тебе осталось лишь немного подумать
так и быть опишу тебе бд
твоё бд должно содержать строки приказов спеллов, равкоды спеллов, мп необходимое для каста спеллов
хранить экземпляры структур лучше всего в хэше по равкоду героя
при необходимости кастануть спелл ты должен доставать экземпляр структуры из хэш таблицы по равкоду твоего героя
после чего циклом проверяем наличие спелла и достаточно ли мп для его каста
если да то кастуем спелл и завершаем выполнение функции

делать за тебя тут никто не будет
если ты не можешь сам по примеру из статьи сделать то что тебе надо то тебе стоит бросить это дело и заняться вязанием (носки там или шарфик)
2
FenikS1991, я хз кто и что тебе выдаёт но там всё нормально работает
скачай джнгп
Уже скачан и давно...
nvc123:
твоё бд должно содержать строки приказов спеллов, равкоды спеллов, мп необходимое для каста спеллов
хранить экземпляры структур лучше всего в хэше по равкоду героя
при необходимости кастануть спелл ты должен доставать экземпляр структуры из хэш таблицы по равкоду твоего героя
Это как раз понять и требовалось, спасибо.
nvc123:
делать за тебя тут никто не будет
И ненужно.
nvc123:
если ты не можешь сам по примеру из статьи сделать то что тебе надо то тебе стоит бросить это дело и заняться вязанием (носки там или шарфик)
Видимо ты в этом профи.
P.S Нет желанья помогать, лучше мимо прошагать.
29
Знаем что такое бинарный поиск? Берем изначальный код и комментируем в нем половину строк, вылеты прекратились - половину комментариев убираем, не прекратились - комментируем половину другой половины и так пока не найдем точную причину ошибки (при шансе 50% проверять очень легко). С этого нужно было и начать и затем создавать пост.
Не уверен, что проблема именно в группе, строки эти убирать нельзя, иначе цикл иногда будет выходить бесконечным, просто обрывая поток с подвисанием.
Начни с пустого цикла по группе юнитов без приказов, выводи имя юнита на экран. Поймешь где проблема.
И вот это:
call GroupRemoveUnit(g,u)
set u=FirstOfGroup(g)
Должно все-таки быть за пределами if'а.
28
Знаем что такое бинарный поиск?
ты предыдущие комменты читал?
если да то сам сможешь ответить на свой вопрос
29
Ты сам ставишь свой ответ лучшим или что? Ты вообще проверял своё решение?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.