Эта функция или call TriggerSleepAction( ) у меня соверщенно не работает. Просто хотелось бы понять почему. Сам триггер довольно простой: при кастовании вражеским юнитам в радиусе 150 наносится ежесекундно 1 ед урона в течении 5 секунд. Однако до call TriggerSleepAction( ) все идет нормально, даже если удалить его, то цикл пройдется 5 раз. Как это исправить?
Code
function PoisionCond takes nothing returns boolean local unit filter=GetFilterUnit() local unit spell=GetSpellAbilityUnit() local real LifeFilter=GetUnitState(filter, UNIT_STATE_LIFE) local player P=GetOwningPlayer(spell) if ((LifeFilter> 0) and ( IsUnitEnemy(filter,P) == true ) ) then return true else return false endif set filter=null set spell=null endfunction
function Trig_Poison_Func003A takes nothing returns nothing local integer i=1 local unit u=GetEnumUnit() loop call UnitDamageTarget( udg_Player, u, 1, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS ) exitwhen (i==5) set i=i+1 call TriggerSleepAction( 3.00 ) endloop set u=null endfunction
function Trig_Poison_Actions takes nothing returns nothing local integer id=GetSpellAbilityId() local unit u=GetSpellAbilityUnit() local location l=GetUnitLoc(u) if ( id == 'A005' ) then call ForGroup( GetUnitsInRangeOfLocMatching(150.00, l, Condition(function PoisionCond)), function Trig_Poison_Func003A ) endif set u=null call RemoveLocation(l) set l=null endfunction
//=========================================================================== function InitTrig_Poison takes nothing returns nothing set gg_trg_Poison = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Poison, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddAction( gg_trg_Poison, function Trig_Poison_Actions ) endfunction
Сообщение отредактировал sumert - Воскресенье, 09 Октября 2011, 13:34:25
Во-первых, видимо конверт из гуи в жасс рулит. Но это не самое страшное. Далее- лучше делать так: loop exitwhen т.е. объявлять условие выхода сразу после луп. Далее кондишн. Тут страшно. Ты, видимо проверяешь, жив ли юнит или нет. Твоя проверка- кака, надо делать так. Можно сразу без переменных, т.е. (IsUnitType(GetFilterUnit()) == UNIT_TYPE_DEAD) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == true пишу по памяти, но принцип думаю ясен
Добавлено (09 Октябрь 2011, 14:24:59) --------------------------------------------- return (IsUnitType(GetFilterUnit()) == UNIT_TYPE_DEAD) == false and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit ())) == true
Добавлено (09 Октябрь 2011, 14:26:02) --------------------------------------------- И вообще, юзай таймер- в твоем случае это проще простого
Добавлено (09 Октябрь 2011, 14:27:38) --------------------------------------------- И не юзай спеллабилитиюнит, юзай триггерюнит
Ty3uK, хватит умничать. Ты ничтожно помог мне с моим вопросом. Буду знать, что из тебя никакой помощник. Спелл я сделал на скорую руку, да это и не важно. Перечитай первые 4 строчки.
Ty3uK, сам-то нуб еще какой. Я писал спелл на скорую руку. Между прочим, у меня много там утечек, а ты их не заметил. По нормальному, там над инициализацию триггера переписать и функцию группы видоизменить. Кстати, GetFilterUnit(), GetTriggerUnit() и GetOwnerPlayer() вызывают утечки, не? Впрочем, не важно: я спрашиваю, с какого перепугу wait не работает, даже при трех секундах? Я не понимаю, зачем писать таймеры для такого типичного спелла? Это все равно, что для того, чтобы вычислить сумму цифр, писать целый калькулятор.
Добавлено (10 Октябрь 2011, 08:25:05) --------------------------------------------- Так вот переписал на таймеры.
Code
function Trig_Timer_Exprice takes nothing returns nothing local timer t = GetExpiredTimer() local integer id = GetHandleId(t) call UnitDamageTarget( udg_Player, LoadUnitHandle(udg_Hash, id, 1), 1, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS ) call FlushChildHashtable(udg_Hash, id) call DestroyTimer(t) set t = null endfunction
function Trig_Poison_Func003A takes nothing returns nothing local integer i=1 local unit u=GetEnumUnit() local timer t=CreateTimer() local integer id = GetHandleId(t) loop call SaveAgentHandle(udg_Hash, id, 1, u) call TimerStart(t, i, false, function Trig_Timer_Exprice) exitwhen i>=5 set i=i+1 endloop set u=null set t=null endfunction
Сообщение отредактировал sumert - Понедельник, 10 Октября 2011, 08:28:06
Ммм... Таймер нужен для того, чтобы сделать все хорошо- вейты это говно. Юниты и игрок, которых ты выписал- не утечны. В событие никаких утечек нет. Я, может быть, и нуб, но по крайней мере не юзаю вейты, а тем более в цикле. Мой тебе совет- почитай про таймеры- они помогут тебе решить эту "проблему". А также почитай про утечки. Что и куда утекает, потому как ты этого, видимо, не знаешь. И юзать таймер для такого пустякового спелла- не верх кретинизма- нормальные люди, которые пишут на жассе так и делают. Плюс еще можно было фильтр и форгрупп засунуть в одну функцию. Засовывать ид спелла в переменную не обязательно, если ты не хочешь юзать формулы с его участием, юзать локу- ужасно глупо, надо юзать координаты и так далее. Вообщем, повторю еще раз- юзай таймер и все будет хорошо. А насчет того, что делал на скорую руку- не верю. Пооткрывать все бж, засунуть в локалки пустяковые ссылки, да это выглядело так: написал на гуи, перевел в жасс и целенаправленно минут пять раскрывал бж и делал прочее. Почему конверт из гуи? Да потому, что только гуи дает такие дурацкие названия функциям. Плюс юзает форгрупп. Короче, зря отмазывался... Код говно, характер у тебя тоже. Тебе помогают- ты быка включаешь. Давай, удачи, и напоследок еще раз- периодический таймер, офк.
Добавлено (10 Октябрь 2011, 08:36:59) --------------------------------------------- Ммм... Зачем таймер в лупе? Не понимаю. Периодический таймер запустил и все. Иначе обычный таймер у тебя в лупе перезапустит себя несколько раз
Добавлено (10 Октябрь 2011, 08:39:00) ---------------------------------------------
Quote
Кстати, GetFilterUnit(), GetTriggerUnit() и GetOwnerPlayer() вызывают утечки, не?
Вроде она вызывает другую утечную функцию, поэтому надо циклом всех игроков проверять.
Quote (Ty3uK)
Плюс еще можно было фильтр и форгрупп засунуть в одну функцию.
В курсе, просто лень пока это делать. Я уж думал, не заметил.
Quote (Ty3uK)
юзать локу- ужасно глупо, надо юзать координаты
Разница, если я все равно в локальную переменную и обнуляю её потом?
Quote (Ty3uK)
очему конверт из гуи? Да потому, что только гуи дает такие дурацкие названия функциям.
Не припомню, чтобы я отрицал это.
Quote (Ty3uK)
Тебе помогают- ты быка включаешь.
Ты помог там, где я не просил вовсе. Я же не спрашивал: как оптимизировать код или в таком духе. Кстати, ты не заметил в таймере одну ошибку, впрочем, черт с ней. Периодический таймер. Ты предлагаешь запустить таймер и в фнкции Trig_Timer_Exprice запустить оставшиеся 4 раза?
Добавлено (10 Октябрь 2011, 09:28:48) ---------------------------------------------
Code
function Trig_Spell_Filter takes nothing returns boolean local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local unit target = GetFilterUnit() if IsUnitEnemy(target, GetOwningPlayer(caster)) and IsUnitType(target, UNIT_TYPE_DEAD) == false then call UnitDamageTarget(caster, target, 50., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endif set t = null set caster = null set target = null return false endfunction
function Trig_Spell_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local integer i = LoadInteger(udg_hash, hid, 1) local group g = CreateGroup() local filterfunc f = Filter(function Trig_Spell_Filter) if i != 5 then set i = i + 1 call GroupEnumUnitsInRange(g, GetWidgetX(caster), GetWidgetY(caster), 500., f) call SaveInteger(udg_hash, hid, 1, i) else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable(udg_hash, hid) endif call DestroyGroup(g) call DestroyFilter(f) set t = null set g = null set f = null set caster = null endfunction
function Trig_Spell_Actions takes nothing returns nothing local timer t = CreateTimer() local integer hid = GetHandleId(t) local unit caster =GetTriggerUnit() call SaveUnitHandle(udg_hash, hid, 0, caster) call SaveInteger(udg_hash, hid, 1, 0) call TimerStart(t, 1., true, function Trig_Spell_Timer) set t = null set caster = null endfunction
Гм, очень странно. Я еще добавил функции вывода текста. Самое интересное, что все тексты в любых местах показывает. Но вот урона все равно никакого. И тексты бесконечное число раз показываются.
function Trig_Spell_Filter takes nothing returns boolean local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local unit target = GetFilterUnit() if IsUnitEnemy(target, GetOwningPlayer(caster)) and IsUnitType(target, UNIT_TYPE_DEAD) == false then call UnitDamageTarget(caster, target, 50., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) call BJDebugMsg("Тип: " + GetUnitName(target) + " | Нанесено: 50 урона!") endif set t = null set caster = null set target = null return false endfunction
function Trig_Spell_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local integer i = LoadInteger(udg_hash, hid, 1) local group g = CreateGroup() local filterfunc f = Filter(function Trig_Spell_Filter) if i != 5 then set i = i + 1 call GroupEnumUnitsInRange(g, GetWidgetX(caster), GetWidgetY(caster), 500., f) call SaveInteger(udg_hash, hid, 1, i) else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable(udg_hash, hid) endif call DestroyGroup(g) call DestroyFilter(f) set t = null set g = null set f = null set caster = null endfunction
function Trig_Spell_Actions takes nothing returns nothing local timer t = CreateTimer() local integer hid = GetHandleId(t) local unit caster =GetTriggerUnit() call SaveUnitHandle(udg_hash, hid, 0, caster) call SaveInteger(udg_hash, hid, 1, 0) call TimerStart(t, 1., true, function Trig_Spell_Timer) set t = null set caster = null endfunction
//=========================================================================== function InitTrig_Spell takes nothing returns nothing set gg_trg_Spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) ) call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions ) endfunction
function Trig_Spell_Filter takes nothing returns boolean local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local unit target = GetFilterUnit() if IsUnitEnemy(target, GetOwningPlayer(caster)) and IsUnitType(target, UNIT_TYPE_DEAD) == false then call UnitDamageTarget(caster, target, 50., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS) endif set t = null set caster = null set target = null return false endfunction
function Trig_Spell_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_hash, hid, 0) local integer i = LoadInteger(udg_hash, hid, 1) local group g = CreateGroup() local filterfunc f = Filter(function Trig_Spell_Filter) if i != 5 then set i = i + 1 call GroupEnumUnitsInRange(g, GetWidgetX(caster), GetWidgetY(caster), 500., f) call SaveInteger(udg_hash, hid, 1, i) call BJDebugMsg(I2S(i) + " секунда") else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable(udg_hash, hid) endif call DestroyGroup(g) call DestroyFilter(f) set t = null set g = null set f = null set caster = null endfunction
function Trig_Spell_Actions takes nothing returns nothing local timer t = CreateTimer() local integer hid = GetHandleId(t) local unit caster =GetTriggerUnit() call SaveUnitHandle(udg_hash, hid, 0, caster) call SaveInteger(udg_hash, hid, 1, 0) call TimerStart(t, 1., true, function Trig_Spell_Timer) set t = null set caster = null endfunction
//=========================================================================== function InitTrig_Spell takes nothing returns nothing set gg_trg_Spell = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT ) call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) ) call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions ) endfunction
function Trig_Spell_Timer takes nothing returns nothing local timer t = GetExpiredTimer() local integer hid = GetHandleId(t) local unit caster = LoadUnitHandle(udg_Hash, hid, 0) local integer i = LoadInteger(udg_Hash, hid, 1) local group g = CreateGroup() local filterfunc f = Filter(function Trig_Spell_Filter) if i != 5 then set i = i + 1
call GroupEnumUnitsInRange(g, GetWidgetX(caster), GetWidgetY(caster), 150, f) call SaveInteger(udg_Hash, hid, 1, i) else call PauseTimer(t) call DestroyTimer(t) call FlushChildHashtable(udg_Hash, hid) endif call DestroyGroup(g) call DestroyFilter(f) set t = null set g = null set f = null set caster = null endfunction
Так вот i постоянно равно 1.
Добавлено (10 Октябрь 2011, 10:10:57) --------------------------------------------- А этот глюк может связан с тем, что у меня есть еще одна функция, использующая хеш?
Code
function removeunittimed takes nothing returns nothing local timer t = GetExpiredTimer() local unit u = LoadUnitHandle(udg_Hash, GetHandleId(t), 1) call RemoveUnit(u) call FlushChildHashtable(udg_Hash, GetHandleId(t)) call DestroyTimer(t) set t = null set u = null endfunction
function RemUT takes unit u, real time returns nothing local timer t = CreateTimer() call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u) call TimerStart(t, time, false, function removeunittimed) set t = null endfunction
function Trig_RemoveUnit_Actions takes nothing returns nothing local unit u set u=GetTriggerUnit() call RemUT(u, 60) set u=null endfunction
//=========================================================================== function InitTrig_RemoveUnit takes nothing returns nothing set gg_trg_RemoveUnit = CreateTrigger( ) call TriggerRegisterAnyUnitEventBJ( gg_trg_RemoveUnit, EVENT_PLAYER_UNIT_DEATH ) call TriggerAddAction( gg_trg_RemoveUnit, function Trig_RemoveUnit_Actions ) endfunction
Хотя, нет, погоди. Это не совсем то, что мне надо было. Урон наносится каждую секунду вокруг кастующего. А мне надо было, чтобы юниты словно отравились. То бишь один раз кастанул и юнитам, попавшим в зону действия, наносися урон. Думаю, я сам уже это исправлю)))