Добавлен EviLInside
Совсем недавно пробую что то писать на vjass. Решил сделать способность Maledict из доты, столкнулся с проблемой запоминания и передачи информации о нанесённом уроне для каждого юнита (конкретно в этой абилке не пойму как выкрутиться) , скидываю код [Я его только начал , тут даже таймеры не выключены ещё и ничего не обнулено и т.п] что бы показать что конкретно не могу и не понимаю.
library Maledict requires DamageInterface, RegisterPlayerUnitEvent
/* ------------------------------ CONFIGURABLES ----------------------------- */
globals
endglobals
/* --------------------------------- System --------------------------------- */
private struct Maledict
static thistype array n
timer timer
timer timer2
unit Lcaster
group Lgroup
group Lgroup2
real dps
real maledmg
//*****************************************************
static method onDamage takes nothing returns nothing
local thistype this = GetUnitUserData(BlzGetEventDamageTarget())
local unit Ldamaged = BlzGetEventDamageTarget()
if UnitHasBuffBJ(Ldamaged, 'B015') == true and GetEventDamage() > 0 then
set maledmg = maledmg + (( GetEventDamage() / 100.00 ) * 16 )
else
endif
endmethod
private static method onPeriod2 takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit Picked = null
local integer i = CountUnitsInGroup(Lgroup2)
local group Lgroup3 = CreateGroup()
call GroupAddGroup( Lgroup2, Lgroup3 )
loop
set Picked = FirstOfGroup(Lgroup3)
exitwhen i == 0
call UnitDamageTargetBJ( Lcaster, Picked, maledmg, ATTACK_TYPE_HERO, DAMAGE_TYPE_UNIVERSAL )
call GroupRemoveUnit(Lgroup3,Picked)
set i = i-1
endloop
endmethod
private static method onPeriod takes nothing returns nothing
local thistype this = GetTimerData(GetExpiredTimer())
local unit Picked = null
local integer i = CountUnitsInGroup(Lgroup2)
local group Lgroup3 = CreateGroup()
call GroupAddGroup( Lgroup2, Lgroup3 )
loop
set Picked = FirstOfGroup(Lgroup3)
exitwhen i == 0
call UnitDamageTargetBJ( Lcaster, Picked, dps, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC )
call GroupRemoveUnit(Lgroup3,Picked)
set i = i-1
endloop
endmethod
static method onCast takes nothing returns nothing
local thistype this = thistype.allocate()
local unit source =GetSpellAbilityUnit()
local unit Picked = null
set timer = NewTimerEx(this)
set timer2 = NewTimer()
set Lcaster = source
set Lgroup = CreateGroup()
set Lgroup2 = CreateGroup()
call SetTimerData(timer2,this)
set maledmg = 0
set dps = 100
call GroupEnumUnitsInRange(Lgroup,GetLocationX(GetSpellTargetLoc()),GetLocationY(GetSpellTargetLoc()),225,null)
call CreateNUnitsAtLoc( 1, 'h003', GetOwningPlayer(Lcaster), GetUnitLoc(Lcaster), bj_UNIT_FACING )
set Ldummy =GetLastCreatedUnit()
call UnitAddAbilityBJ( 'A03F', Ldummy )
loop
set Picked = FirstOfGroup(Lgroup)
exitwhen Picked == null
if Lcaster != Picked and IsUnitType(Picked, UNIT_TYPE_STRUCTURE) == false and IsUnitDeadBJ(Picked) == false and BlzIsUnitInvulnerable(Picked) == false and IsPlayerEnemy(GetOwningPlayer(Picked), GetOwningPlayer(Lcaster)) == true then
call IssueTargetOrderBJ( Ldummy, "slow", Picked )
call GroupAddUnitSimple(Picked,Lgroup2)
call SetUnitUserData(Picked,this)
call GroupRemoveUnit(Lgroup,Picked)
else
call GroupRemoveUnit(Lgroup,Picked)
endif
endloop
call TimerStart(timer, 0.99, true, function thistype.onPeriod)
call TimerStart(timer2, 4, true, function thistype.onPeriod2)
set source = null
endmethod
static method onInit takes nothing returns nothing
call RegisterSpellEffectEvent('A03E', function thistype.onCast)
call RegisterAttackDamageEvent(function thistype.onDamage)
call RegisterSpellDamageEvent(function thistype.onDamage)
endmethod
endstruct
endlibrary
Получается в функции OnDamage я ДОЛЖЕН запоминать 16% от дамага для каждого отдельного юнита из группы на которую наложен дебаф. и в OnPeriod2 наносить эти 16% (если они есть) тоже каждому отдельно. А по факту в OnPeriod2 у меня наносится всем в группе кто с дебафом урон каждому, в размере 16% от полученного ВСЕМИ из группы. В общем в надежде жду любые подсказки или объяснение что я делаю не так, и что структура моего начального кода настолько неправильная что можно вызвать сатану.и как сделать лучше.
Принятый ответ
Там все гораздо проще, на каждого юнита аттачится экземпляр структуры где хранится цель, заклинатель, кол-во урона в сек, и сколько хп у тебя было, по нему высчитывается урон каждые 4 секунды. Тебе ни 10 таймеров ни группы не нужны.
function WC5 takes nothing returns boolean
local trigger t = GetTriggeringTrigger( )
local integer S5I = GetHandleId( t )
local unit P7I = ( LoadUnitHandle( HashData, ( S5I ), ( 2 ) ) )
local unit P8I = ( LoadUnitHandle( HashData, ( S5I ), ( 17 ) ) )
local integer SUI = GetUnitAbilityLevel( P7I, 'A0NO' )
local integer NPI = GetTriggerEvalCount( t )
local real WD5 = ( LoadReal( HashData, ( S5I ), ( 392 ) ) )
local real H84 = 0
if GetTriggerEventId( ) == EVENT_WIDGET_DEATH then
call DestroyEffect( ( LoadEffectHandle( HashData, ( S5I ), ( 32 ) ) ) )
call FlushChildHashtable( HashData, ( S5I ) )
call S0I( t )
else
if NPI == 4 or NPI == 8 or NPI == 12 then
call DestroyEffect( ( LoadEffectHandle( HashData, ( S5I ), ( 32 ) ) ) )
if NPI == 12 then
call FlushChildHashtable( HashData, ( S5I ) )
call S0I( t )
elseif NPI == 4 or NPI == 8 then
call SaveEffectHandle( HashData, ( S5I ), ( 32 ), ( AddSpecialEffectTarget( "effects\\NetherInferno.mdx", P8I, "origin" ) ) )
endif
set H84 = ( 0.08 + SUI * 0.08 ) * QDI( WD5 - GetUnitState( P8I, UNIT_STATE_LIFE ), 0 )
if H84 > 0 then
call UYI( "+" + I2S( R2I( H84 ) ), 2, P8I, 0.023, 68, 0, 187, 216 )
endif
endif
call DamageTarget( P7I, P8I, 1, 5 * SUI + H84 )
endif
set t = null
set P7I = null
set P8I = null
return false
endfunction
function WE5 takes nothing returns nothing
local trigger t = CreateTrigger( )
local integer S5I = GetHandleId( t )
local unit P7I = GetTriggerUnit( )
local unit P8I = GetEnumUnit( )
call DestroyEffect( AddSpecialEffectTarget( "effects\\NetherInferno.mdx", P8I, "origin" ) )
call TriggerRegisterTimerEvent( t, 1, true )
call TriggerRegisterDeathEvent( t, P8I )
call TriggerAddCondition( t, Condition( function WC5 ) )
call SaveUnitHandle( HashData, ( S5I ), ( 17 ), ( P8I ) )
call SaveUnitHandle( HashData, ( S5I ), ( 2 ), ( P7I ) )
call SaveReal( HashData, ( S5I ), ( 392 ), ( ( GetUnitState( P8I, UNIT_STATE_LIFE ) ) * 1.0 ) )
call SaveEffectHandle( HashData, ( S5I ), ( 32 ), ( AddSpecialEffectTarget( "effects\\NetherInferno.mdx", P8I, "origin" ) ) )
set t = null
set P7I = null
set P8I = null
endfunction
function WF5 takes nothing returns nothing
local unit P7I = GetTriggerUnit( )
local location l = GetSpellTargetLoc( )
local real x = GetLocationX( l )
local real y = GetLocationY( l )
local group g = NTI( )
local integer SUI = GetUnitAbilityLevel( P7I, 'A0NO' )
call GroupEnumUnitsInRange( g, x, y, 180 + 25, Condition( function D01 ) )
call ForGroup( g, function WE5 )
call NSI( g )
call RemoveLocation( l )
set l = null
set g = null
endfunction
function WG5 takes nothing returns boolean
if GetSpellAbilityId( ) == 'A0NO' then
call WF5( )
endif
return false
endfunction
function NI1 takes nothing returns nothing
local trigger t = CreateTrigger( )
call UMI( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Condition( function WG5 ) )
set t = null
endfunction
Как видишь все очень примитивно.Точно так же делаешь структуру с данными кто, где, когда. Нет смысла пытатся хранить сразу группу.
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
XGM Bot
4 года назад
0
Похожие вопросы:
- Нужна помощь с vJass
ответ
Clamp:
- vjass Нужна помощь
ответ
nvc123:
- Помогите найти десинх в карте
ответ
quq_CCCP:
- Помогите определиться / Создание нормальной карты на GUI
ответ
Araders:
Поиск по всем ресурсам на сайте
2
quq_CCCP
4 года назад
2
Там все гораздо проще, на каждого юнита аттачится экземпляр структуры где хранится цель, заклинатель, кол-во урона в сек, и сколько хп у тебя было, по нему высчитывается урон каждые 4 секунды. Тебе ни 10 таймеров ни группы не нужны.
Как видишь все очень примитивно.Точно так же делаешь структуру с данными кто, где, когда. Нет смысла пытатся хранить сразу группу.
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.