- Joined
- Jul 26, 2008
- Messages
- 1,009
Alright I've been making a series of skills that detect damage and either reduce or deflect it. I'm curious if I'm doing it right (The spells work, but do they leak and can they be fixed up/made better?)
Thank you for the help
Thank you for the help
JASS:
scope Cover initializer InitTrig_Cover
globals
//"Abilities\\Spells\\Items\\StaffOfSanctuary\\Staff_Sanctuary_Target.mdl"
private constant integer SPELLID = 'Cove'
private constant integer BUFFID = 'BCov'
private unit array CASTER
private trigger array EVENT
private effect array CoverFX
endglobals
private struct Data
unit c
unit t
static method Timer takes nothing returns nothing
local timer tim = GetExpiredTimer()
local Data D = Data(GetTimerData(tim))
call DestroyEffect(CoverFX[GetUnitId(D.t)])
call ReleaseTimer(tim)
call DestroyTrigger(EVENT[GetUnitId(D.t)])
set EVENT[GetUnitId(D.t)] = null
set D.c = null
set CoverFX[GetUnitId(D.t)] = null
set D.t = null
call D.destroy()
endmethod
static method Conditions takes nothing returns boolean
local unit caster = CASTER[GetUnitId(GetTriggerUnit())]
local integer lvl = GetUnitAbilityLevel(caster, SPELLID)
local real dist = SquareRoot((GetUnitX(caster)-GetUnitX(GetTriggerUnit())) * (GetUnitX(caster)-GetUnitX(GetTriggerUnit())) + (GetUnitY(caster)-GetUnitY(GetTriggerUnit())) * (GetUnitY(caster)-GetUnitY(GetTriggerUnit())))
if GetUnitAbilityLevel(GetTriggerUnit(), BUFFID) > 0 then
if GetRandomInt(1,3) == 3 then
call DestroyEffect(AddSpecialEffectTarget(GetAbilityEffectById(SPELLID,EFFECT_TYPE_MISSILE,1), GetTriggerUnit(), "origin"))
endif
call SetWidgetLife(GetTriggerUnit(), GetWidgetLife(GetTriggerUnit()) + GetEventDamage())
call SetWidgetLife(caster, GetWidgetLife(caster) - GetEventDamage()*(1.1-0.05*lvl))
if GetWidgetLife(caster)/GetUnitState(caster, UNIT_STATE_MAX_LIFE) < 0.25 or dist > 400+50*lvl then
call UnitRemoveAbility(GetTriggerUnit(), BUFFID)
call DestroyEffect(CoverFX[GetUnitId(GetTriggerUnit())])
call DestroyTrigger(EVENT[GetUnitId(GetTriggerUnit())])
set EVENT[GetUnitId(GetTriggerUnit())] = null
set CoverFX[GetUnitId(GetTriggerUnit())] = null
endif
else
call UnitRemoveAbility(GetTriggerUnit(), BUFFID)
call DestroyEffect(CoverFX[GetUnitId(GetTriggerUnit())])
call DestroyTrigger(EVENT[GetUnitId(GetTriggerUnit())])
set EVENT[GetUnitId(GetTriggerUnit())] = null
set CoverFX[GetUnitId(GetTriggerUnit())] = null
endif
set caster = null
return false
endmethod
static method create takes unit caster, unit target, integer lvl returns Data
local Data D = Data.allocate()
local timer tim = NewTimer()
set D.c = caster
set D.t = target
set CASTER[GetUnitId(target)] = D.c
if EVENT[GetUnitId(D.t)] == null then
set EVENT[GetUnitId(D.t)] = CreateTrigger()
call TriggerRegisterUnitEvent(EVENT[GetUnitId(D.t)], D.t, EVENT_UNIT_DAMAGED)
call TriggerAddCondition(EVENT[GetUnitId(D.t)], function Data.Conditions)
endif
if CoverFX[GetUnitId(D.t)] == null then
set CoverFX[GetUnitId(D.t)] = AddSpecialEffectTarget(GetAbilityEffectById(SPELLID,EFFECT_TYPE_MISSILE,0), D.t, "origin")
endif
call SetTimerData(tim,D)
call TimerStart(tim, 10+5*lvl, false, function Data.Timer)
return D
endmethod
endstruct
private function Conditions takes nothing returns boolean
if GetSpellAbilityId() == SPELLID then
call Data.create(GetTriggerUnit(), GetSpellTargetUnit(), GetUnitAbilityLevel(GetTriggerUnit(), SPELLID))
endif
return false
endfunction
//===========================================================================
public function InitTrig_Cover takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, function Conditions )
call XE_PreloadAbility(SPELLID)
set t = null
endfunction
endscope