XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Zahanc

offline
Опыт: 23,017
Активность:
Применение заклинание на 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
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
Кстати, как сделать так, чтобы если было несколько юнитов обладающих заклинанием, то они не > использовали его одновременно на одной цели? Предложите свой вариант.
if GetRandomInt(1,10) <= 3 then
обычно я так это делал)
Hatsume_Hate добавил:
IsUnitAlly( f, GetOwningPlayer(r) ) == true лучше писать просто IsUnitAlly( f, GetOwningPlayer(r) )
Hatsume_Hate добавил:
союзники у тебя это войска под твоим владением или другие дружелюбные игроки?
Старый 10.05.2012, 02:11
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
союзники у тебя это войска под твоим владением или другие дружелюбные игроки?
Дружелюбные игроки включая собственные войска.
Старый 10.05.2012, 02:13
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
Hatsume_Hate:
союзники у тебя это войска под твоим владением или другие дружелюбные игроки?
Дружелюбные игроки включая собственные войска.
мг. Насколько я знаю Ally берет лишь союзные войска но не собственные
Старый 10.05.2012, 02:15
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
мг. Насколько я знаю Ally берет лишь союзные войска но не собственные
Юнит спокойно кастует на войска у которых с ним общий владелец.
bladget добавил:
Hatsume_Hate:
if GetRandomInt(1,10) <= 3 then
а чем здесь поможет случайное число?
Старый 10.05.2012, 02:28
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget:
Hatsume_Hate:
мг. Насколько я знаю Ally берет лишь союзные войска но не собственные
Юнит спокойно кастует на войска у которых с ним общий владелец.
bladget добавил:
Hatsume_Hate:
if GetRandomInt(1,10) <= 3 then
а чем здесь поможет случайное число?
смотри
2 юнита, выбрали одну и туже цель.
и тут ВНЕЗАПНО рандом, первому рандом благословил 2 и он кастанул койл, второму выпало 5 и он не кастанул койл
Старый 10.05.2012, 02:30
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
и тут ВНЕЗАПНО рандом, первому рандом благословил 2 и он кастанул койл, второму выпало 5 и он не кастанул койл
Немного по-корейски. Я думал при касте привязывать юниту логическую переменную через хеш (или вешать баф) и от неё плясать.
А идеи касательно главной проблемы есть?
Старый 10.05.2012, 02:32
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
if IsUnitAlly( f, GetOwningPlayer(r) ) and IsUnitIdType(GetUnitTypeId(f), UNIT_TYPE_UNDEAD) and GetUnitStatePercent(f, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE ) <= 50.0 and not IsUnitType(f,UNIT_TYPE_DEAD) then
                //call DisplayTextToForce( GetPlayersAll(), GetUnitName(r) + I2S(GetHandleId(r)) + " койлит " + GetUnitName(f) + I2S(GetHandleId(f)) )
                call IssueTargetOrder( r, "deathcoil", f )
            elseif IsUnitEnemy( f, GetOwningPlayer(r) ) and GetUnitState( f, UNIT_STATE_LIFE ) <= 250.0 and GetUnitState( f, UNIT_STATE_LIFE ) > 50.0 then
                    //call DisplayTextToForce( GetPlayersAll(), GetUnitName(r) + I2S(GetHandleId(r)) + " койлит " + GetUnitName(f) + I2S(GetHandleId(f)) )
           	 call IssueTargetOrder( r, "deathcoil", f )
endif
хз даже
Старый 10.05.2012, 02:57
Zahanc

offline
Опыт: 23,017
Активность:
Мне так кажется что цикл сбивает каст каким-то образом (т. е. цель с каждым "оборотом" цикла меняется, поэтому каст происходит на последнего юнита, который удовлетворил условия) и нужно паузить цикл пока каст не будет выполнен, либо пока все условия не вернут false.
Но я могу ошибатся.
Старый 10.05.2012, 02:58
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
ну раз так попробуй добавить рандом как я писал, если цикл прерывает каст то рандом даст скастануть на цель койл в 30% случаев (или сколько ты там выберешь)
Старый 10.05.2012, 03:08
Zahanc

offline
Опыт: 23,017
Активность:
Можно, но я сначала по-другому попробую. Я сделаю 2 разных цикла, на врагов и на союзников. Ведь второй цикл не запуститься, пока первый не закончиться, верно?
Старый 10.05.2012, 03:14
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget, насчет этого я даже хз. попробуй сначала просто союзники, потом просто враги. Если разница заметна, то дело в цикле
Старый 10.05.2012, 03:18
Zahanc

offline
Опыт: 23,017
Активность:
Блин, сначала сделал 2 отдельных цикла - начались ОЧЕНЬ ощутимые лаги. Потом вернул как было, но без else - вернулась и проблема.
Старый 10.05.2012, 03:25
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
bladget, попробуй рандом
Старый 10.05.2012, 03:32
Zahanc

offline
Опыт: 23,017
Активность:
Так, главную проблему решил путём очищения группы после приказа кастовать спелл (код обновил). Буду думать над второй.
И ещё, как можно проверить перезарядился ли спелл, без особого изврата?
Старый 10.05.2012, 03:45
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
а зачем проверять перезарядку? юнит то всеравно не сможет кастовать абилку, так зачем головная боль?
Старый 10.05.2012, 03:48
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
а зачем проверять перезарядку? юнит то всеравно не сможет кастовать абилку, так зачем головная боль?
Когда я тестил мне было неудобно, но главное это не нагружать память обработкой группы. Поэтому, кстати, я и вставил проверку на ману.
Старый 10.05.2012, 03:53
Hate
конь вакуумный
offline
Опыт: 43,033
Активность:
вешай на юнита логическую false, стартуй таймер на длительность кд, и не иди дальше пока логическая не будет тру, по истечению таймера сохраняй ее как тру и се. либо извращения с UnitUserData если оно нигде не используется
Старый 10.05.2012, 04:05
Zahanc

offline
Опыт: 23,017
Активность:
Hatsume_Hate:
вешай на юнита логическую false, стартуй таймер на длительность кд, и не иди дальше пока логическая не будет тру, по истечению таймера сохраняй ее как тру и се. либо извращения с UnitUserData если оно нигде не используется
Эх, а я надеялся на какую-нибудь встроенную функцию, ну да ландно.
Кстати, код теперь работает точно так как мне нужно, первый пост обновил. Тема исчерпана. Спасибо Hatsume_Hate.
Старый 10.05.2012, 17:12
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 16:19.