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

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

Ответ
 
felix_ff

offline
Опыт: 757
Активность:
Проверка по группе
Доброго времени суток уважаемые. Столкнулся вот с такой проблемой.
Делал один спелл через кеш. собсна концепция спелла в том что герой приводит спелл в действие и пока он действует он поглощает в себя полученный урон. а по истечении действия спелла выбрасывает его на всех вражеских юнитов стоящих рядом.

Итак. теперь расскажу о методе. Я не стал заморачиваться и пошел самым простым путем. при касте спелл я создаю локальный тригер с событие что тригеринг юнит получает урон ну далее там я выполняю некие действия. и таймер который отсчитыват время действия спелла.
по истечение таймера я дисеблю тригер, получаю с него данные урона (переменная реала) записанные по тригеру и далее довольно хитрым циклом по группе дамажу врагов.

Так как при использовании таймера я не могу просто указать группу врагов определенного юнита я выполняю два цикла (первый ремувит из группы всех союзников юнита) второй уже дамажит врагов оставшихся в группе.

собственно вот код всего спелла
Код:
function Trig_Rage_of_Daminion_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A019'
endfunction

function Rage_of_Daminion_Cond takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)==false and not F_UnitDead(GetFilterUnit())
endfunction

function Rage_of_Daminion__Act_Timer takes nothing returns nothing
local timer t = GetExpiredTimer()
local trigger T = I2T(GetStoredInteger(udg_Cache, I2S(H2I(t)), "t"))
local unit a = I2U(GetStoredInteger(udg_Cache, I2S(H2I(t)), "a"))
local unit b = null
local real r = GetStoredReal(udg_Cache, I2S(H2I(T)), "r")
local location l = GetUnitLoc(a)
local group g = CreateGroup()
local integer i = 0
call PauseTimer(t)
call DisableTrigger(T)
call FlushStoredMission(udg_Cache, I2S(H2I(t)))
call FlushStoredMission(udg_Cache, I2S(H2I(T)))
call DestroyTimer(t)
call DestroyTrigger(T)
set g = GetUnitsInRangeOfLocMatching(600, l, Condition(function Rage_of_Daminion_Cond))
set i = CountUnitsInGroup(g)
if i > 0 then
loop
set b = FirstOfGroup(g)
if F_Ally(a, b) or b==a then
call GroupRemoveUnit(g, b)
endif
set i = i - 1
exitwhen i == 0
endloop
loop
set b = FirstOfGroup(g)
exitwhen F_GroupEmpty(g)
call UnitDamageTargetBJ(a,b,r, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL)
call DestroyEffect(AddSpecialEffectTarget("HolyAwakening.mdx", b, "chest"))
call GroupRemoveUnit(g, b)
endloop
endif
call DestroyGroup(g)
call RemoveLocation(l)
set T = null
set t = null
set g = null
set l = null
set a = null
set b = null
set i = 0
set r = 0.00
endfunction

function Rage_of_Daminion_Act takes nothing returns nothing
local unit a = GetTriggerUnit()
local integer i = GetUnitAbilityLevel(a, 'A019')
local real r = GetEventDamage()
local real rx = GetStoredReal(udg_Cache, I2S(H2I(GetTriggeringTrigger())),"r")
if rx <= 0.00 then
set rx = 1.00
call StoreReal(udg_Cache, I2S(H2I(GetTriggeringTrigger())), "r", rx)
endif
set rx = rx + r/(6-I2R(i))
call StoreReal(udg_Cache, I2S(H2I(GetTriggeringTrigger())), "r", rx)
call DestroyEffect(AddSpecialEffectTarget("units\\orc\\SpiritWyvern\\SpiritWyvern.mdl", a, "chets"))
endfunction

function Trig_Rage_of_Daminion_Actions takes nothing returns nothing
local unit a = GetTriggerUnit()
local integer i = GetUnitAbilityLevel(a, 'A019')
local trigger T = CreateTrigger()
local timer t = CreateTimer()
call TriggerRegisterUnitEvent(T, a, EVENT_UNIT_DAMAGED)
call TriggerAddAction(T, function Rage_of_Daminion_Act)
call StoreInteger(udg_Cache, I2S(H2I(t)), "t", H2I(T))
call StoreInteger(udg_Cache, I2S(H2I(t)), "a", H2I(a))
call TimerStart(t, ( 8 +4 * Pow( i,1) ) / 2, false, function Rage_of_Daminion__Act_Timer)
set T = null
set t = null
set a = null
set i = 0
endfunction



//===========================================================================
function InitTrig_Rage_of_Daminion takes nothing returns nothing
    set gg_trg_Rage_of_Daminion = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rage_of_Daminion, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Rage_of_Daminion, Condition( function Trig_Rage_of_Daminion_Conditions ) )
    call TriggerAddAction( gg_trg_Rage_of_Daminion, function Trig_Rage_of_Daminion_Actions )
endfunction


Теперь о проблемме... дело в том что иногда почему то урон наносится и союзникам и герою. Чего быть не должно. я уже все перепроверил.. даже функцию создал что бы посмотреть что происходит.. но так особо и не обнаружил откуда исходит этот баг. есть предпольжение что союзнический юнит иногда не удаляется из группы при первом цикле.

Ну вообщем главный вопрос что делать? :mama: как избежать что в группе оставались союзнические войска?

и еще что бы не возникло вопросов что некоторых функций в коде не хватает то они элементарны(я просто их для упрощения жизни себе нарисовал) воть
Код:
function F_Ally takes unit u, unit v, returns boolean
return IsUnitAlly(u, GetOwningPlayer(v))
endfunction

function F_UnitDead takes unit u returns boolean
if GetUnitState(u, UNIT_STATE_LIFE) >= 0.00 then
return false
else
return true
endif
endfunction

function F_GroupEmpty takes group g returns boolean
return FirstOfGroup(g) == null
endfunction
Старый 27.06.2006, 16:25
Van Damm
wait... what?
offline
Опыт: 22,268
Активность:
можешь сделать так - фильтр группы такой:
Код:
function Rage_of_Daminion_Cond takes nothing returns boolean
   return (not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE)) and (GetWidgetLife(GetFilterUnit()) >0) and (not IsUnitAlly(GetFilterUnit(),I2P(GetStoredInteger(udg_Cache,"temp","p"))))
endfunction

а вместо 2х циклов работы с группами выйдет один, но перед ним надо написать
Код:
local player p = GetOwningPlayer(a)
...
   call StoreInteger(udg_Cache,"temp","p",H2I(p))
   //и потом цикл с дамагом

кстати, вместо твоей функции ГрупЭмпти можно просто в цикле писать
Код:
set u = FirstOfGroup(gr)
   exitwhen (u == null)

это лучше, чем куча функций

PS: кстати, помойму пишется Dominion =)
Старый 28.06.2006, 02:09
felix_ff

offline
Опыт: 757
Активность:
thx наверное так и сделаю :)
Старый 28.06.2006, 12:45
NETRAT

offline
Опыт: 83,712
Активность:
Вот твои дополнительные функции я в функции не выделяю, ибо они все однострочные, вторую фукцию лучше уж так записать
Код:
function F_UnitDead takes unit u returns boolean
   return (GetUnitState(u, UNIT_STATE_LIFE) < 0.00)
endfunction
Старый 28.06.2006, 19:30
Ответ

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

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

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

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



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