Zahanc
offline
Опыт:
22,977Активность: |
Применение заклинание на FirstOfGroup через цикл
Пытаюсь "научить" юнита применять заклинание "Лик смерти" в зависимости от конкретных условий. Код:
» код
((код jass
function Trig_Revenants_Coil_Conditions takes nothing returns boolean
return GetUnitAbilityLevel( GetEnteringUnit(), 'Arcl' ) > 0 and IsUnitInGroup(GetEnteringUnit(), GetUnitsOfPlayerMatching(Player(8), null)) == true endfunction function Coiled takes nothing returns nothing
local timer t = GetExpiredTimer() local integer id = GetHandleId(t) local unit u = LoadUnitHandle( udg_hash, id, StringHash("Coiled") ) call UnitRemoveAbility( u, 'A00E' ) call FlushChildHashtable( udg_hash, id ) call DestroyTimer(t) set t = null set u = null endfunction function Revenants_Coil_Filter takes nothing returns boolean
return GetUnitState( GetFilterUnit(), UNIT_STATE_LIFE ) > 0.0 and GetUnitAbilityLevel( GetFilterUnit(), 'A00E' ) <= 0 and GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE ) < GetUnitState(GetFilterUnit(), UNIT_STATE_MAX_LIFE ) endfunction function Check_For_Revenants_Coil takes nothing returns nothing
local timer t = GetExpiredTimer() local timer c local integer id = GetHandleId(t) local integer cid local group g = LoadGroupHandle( udg_hash, id, StringHash("UnitWithRevenantCoilSpellGroup") ) local unit r = LoadUnitHandle( udg_hash, id, StringHash("UnitWithRevenantCoilSpell") ) local unit f local real x = GetUnitX(r) local real y = GetUnitY(r) if GetUnitState( r, UNIT_STATE_LIFE ) <= 0.0 then call DestroyGroup(g) call FlushChildHashtable( udg_hash, id ) call DestroyTimer(t) endif call GroupEnumUnitsInRange( g, x, y, 800.00, function Revenants_Coil_Filter ) if GetUnitState( r, UNIT_STATE_MANA ) >= 75.0 then loop set f = FirstOfGroup(g) exitwhen f == null if IsUnitAlly( f, GetOwningPlayer(r) ) == true and IsUnitIdType(GetUnitTypeId(f), UNIT_TYPE_UNDEAD) == true and GetUnitStatePercent(f, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE ) < 50.0 then call DisplayTextToForce( GetPlayersAll(), GetUnitName(r) + I2S(GetHandleId(r)) + " койлит " + GetUnitName(f) + I2S(GetHandleId(f)) ) call IssueTargetOrder( r, "deathcoil", f ) call UnitAddAbility( f, 'A00E' ) set c = CreateTimer() set cid = GetHandleId(c) call SaveUnitHandle( udg_hash, cid, StringHash("Coiled"), f ) call TimerStart( c, 1.0, false, function Coiled ) call GroupClear(g) else if IsUnitEnemy( f, GetOwningPlayer(r) ) == true and GetUnitState( f, UNIT_STATE_LIFE ) <= 250.0 and GetUnitState( f, UNIT_STATE_LIFE ) > 50.0 and IsUnitIdType(GetUnitTypeId(f), UNIT_TYPE_UNDEAD) == false then call DisplayTextToForce( GetPlayersAll(), GetUnitName(r) + I2S(GetHandleId(r)) + " койлит " + GetUnitName(f) + I2S(GetHandleId(f)) ) call IssueTargetOrder( r, "deathcoil", f ) call UnitAddAbility( f, 'A00E' ) set c = CreateTimer() set cid = GetHandleId(c) call SaveUnitHandle( udg_hash, cid, StringHash("Coiled"), f ) call TimerStart( c, 1.0, false, function Coiled ) call GroupClear(g) endif endif call GroupRemoveUnit( g, f ) endloop endif set t = null set r = null set f = null set g = null set c = null endfunction function Trig_Revenants_Coil_Actions takes nothing returns nothing
local timer t = CreateTimer() local integer id = GetHandleId(t) local unit u = GetEnteringUnit() local group g = CreateGroup() call SaveUnitHandle( udg_hash, id, StringHash("UnitWithRevenantCoilSpell"), u ) call SaveGroupHandle( udg_hash, id, StringHash("UnitWithRevenantCoilSpellGroup"), g ) call TimerStart( t, 3.0, true, function Check_For_Revenants_Coil ) set t = null set u = null set g = null endfunction ===========================================================================
function InitTrig_Revenants_Coil takes nothing returns nothing set gg_trg_Revenants_Coil = CreateTrigger( ) call TriggerRegisterEnterRectSimple( gg_trg_Revenants_Coil, GetPlayableMapRect() ) call TriggerAddCondition( gg_trg_Revenants_Coil, Condition( function Trig_Revenants_Coil_Conditions ) ) call TriggerAddAction( gg_trg_Revenants_Coil, function Trig_Revenants_Coil_Actions ) endfunction )) Проблема в следующем: по идее приоритетными целями для юнита должны являться союзники, т. к. соответствующие условие стоит выше. Но во время игры очевидно, что пока рядом есть враги, которые "проходят" условие, юнит будет использовать заклинание на них. Почему так и как это исправить?
Кстати, как сделать так, чтобы если было несколько юнитов обладающих заклинанием, то они не использовали его одновременно на одной цели? Предложите свой вариант. [+] замечание от ScorpioT1000: используй теги форматирования
Отредактировано bladget, 10.05.2012 в 17:12. |
10.05.2012, 01:58 | #1
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
if GetRandomInt(1,10) <= 3 then
обычно я так это делал)
Hatsume_Hate добавил:
IsUnitAlly( f, GetOwningPlayer(r) ) == true лучше писать просто IsUnitAlly( f, GetOwningPlayer(r) ) Hatsume_Hate добавил: союзники у тебя это войска под твоим владением или другие дружелюбные игроки? |
10.05.2012, 02:11 | #2
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Hatsume_Hate:
Дружелюбные игроки включая собственные войска. |
10.05.2012, 02:13 | #3
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
bladget:
мг. Насколько я знаю Ally берет лишь союзные войска но не собственные |
10.05.2012, 02:15 | #4
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Hatsume_Hate:
Юнит спокойно кастует на войска у которых с ним общий владелец.
а чем здесь поможет случайное число? |
10.05.2012, 02:28 | #5
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
bladget:
смотри
2 юнита, выбрали одну и туже цель. и тут ВНЕЗАПНО рандом, первому рандом благословил 2 и он кастанул койл, второму выпало 5 и он не кастанул койл |
10.05.2012, 02:30 | #6
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Hatsume_Hate:
Немного по-корейски. Я думал при касте привязывать юниту логическую переменную через хеш (или вешать баф) и от неё плясать.
А идеи касательно главной проблемы есть? |
10.05.2012, 02:32 | #7
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
хз даже |
10.05.2012, 02:57 | #8
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Мне так кажется что цикл сбивает каст каким-то образом (т. е. цель с каждым "оборотом" цикла меняется, поэтому каст происходит на последнего юнита, который удовлетворил условия) и нужно паузить цикл пока каст не будет выполнен, либо пока все условия не вернут false.
Но я могу ошибатся. |
10.05.2012, 02:58 | #9
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
ну раз так попробуй добавить рандом как я писал, если цикл прерывает каст то рандом даст скастануть на цель койл в 30% случаев (или сколько ты там выберешь) |
10.05.2012, 03:08 | #10
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Можно, но я сначала по-другому попробую. Я сделаю 2 разных цикла, на врагов и на союзников. Ведь второй цикл не запуститься, пока первый не закончиться, верно? |
10.05.2012, 03:14 | #11
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
bladget, насчет этого я даже хз. попробуй сначала просто союзники, потом просто враги. Если разница заметна, то дело в цикле |
10.05.2012, 03:18 | #12
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Блин, сначала сделал 2 отдельных цикла - начались ОЧЕНЬ ощутимые лаги. Потом вернул как было, но без else - вернулась и проблема. |
10.05.2012, 03:25 | #13
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
bladget, попробуй рандом |
10.05.2012, 03:32 | #14
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Так, главную проблему решил путём очищения группы после приказа кастовать спелл (код обновил). Буду думать над второй.
И ещё, как можно проверить перезарядился ли спелл, без особого изврата? |
10.05.2012, 03:45 | #15
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
а зачем проверять перезарядку? юнит то всеравно не сможет кастовать абилку, так зачем головная боль? |
10.05.2012, 03:48 | #16
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Hatsume_Hate:
Когда я тестил мне было неудобно, но главное это не нагружать память обработкой группы. Поэтому, кстати, я и вставил проверку на ману. |
10.05.2012, 03:53 | #17
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Hate
конь вакуумный
offline
Опыт:
43,117Активность: |
вешай на юнита логическую false, стартуй таймер на длительность кд, и не иди дальше пока логическая не будет тру, по истечению таймера сохраняй ее как тру и се. либо извращения с UnitUserData если оно нигде не используется |
10.05.2012, 04:05 | #18
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|
Zahanc
offline
Опыт:
22,977Активность: |
Hatsume_Hate:
Эх, а я надеялся на какую-нибудь встроенную функцию, ну да ландно.
Кстати, код теперь работает точно так как мне нужно, первый пост обновил. Тема исчерпана. Спасибо Hatsume_Hate. |
10.05.2012, 17:12 | #19
+0/−0
Профиль |
Приват |
Поиск |
Цитата |
IP: Записан
|