Name | Type | is_array | initial_value |
i | integer | No | |
l | location | No | |
r | real | Yes | |
t | timer | No | |
u | unit | Yes |
//TESH.scrollpos=0
//TESH.alwaysfold=0
//***************************************************************************
//*
//* DOOM FUSE vJASS
//* v1.0b
//* by JC Helas
//*
//* FAQ
//* Q.How to Import?
//* A1. Goto File>Preferences>General> Mark "Automatically create unknown variable while pasting trigger data".
//* A2. Copy all custom object that spell need into your map.
//* A3. Copy Doom Fuse category into your map.
//* A4. Then done, have fun.
//*
//* Q.Is it Configurable?
//* A.1 You can configure all detailed constant functions what ever you want.
//* A.2 You can even remodel the spell and change some values amount.
//*
//*
//* Report any Bugs
//* Contact:[email protected]
//*
//* Credits
//* Magtheridn96
//* C.C.T.O.
//* CTL
//* SpellEffectEvent
//*
//* Changelog
//* v1.0
//* Initial Release
//* v1.0a
//* Fix Waves
//* Fix SpellEffectEvent
//* Fix Filter
//* v1.0b
//* Add Vaccum Effect
//* Fix Lightning deindex
//* Fix Spell Effect Optional
//*
//*
//***************************************************************************
scope DoomFuse
globals
// CONFIGURE SPELL
//
// Ability ID of spell
private integer ABILITY_ID = 'A000'
// Ability ID that makes dummy flyable
private integer FLY_ABILITY_ID = 'Amrf'
// Unit Type ID of dummy
private integer DUMMY_ID = 'u000'
// Model of dummy that was place at center
private string BALL_MODEL = "Abilities\\Spells\\Undead\\AntiMagicShell\\AntiMagicShell.mdl"
// Attach location of ball model
private string BALL_MODEL_ATTACH = "origin"
// Model of turning dummy
// attach to dummy that will turn to ball dummy
private string POST_MODEL = "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl"
// Attach location of post model
private string POST_MODEL_ATTACH = "origin"
// Effect that stands as vacuumer
private string VACUUM_MODEL = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl"
// Lighting Type
//
// "CLPB":Chain Lightning - Primary
// "CLSB":Chain Lightning - Secondary
// "DRAB":Drain
// "DRAM":Drain Mana
// "AFOD":Finger of Death
// "FORK":Fork Lightning
// "HWPB":Healing Wave
// "CHIM":Lightning Attack
// "LEAS":Magic Leash
// "MBUR":Mana Burn
// "MFPB":Mana Flare
// "SPLK":Spirit Link
//
// This lightning was use at damaging the target
// and summon every interval damage.
private string LIGHTNING_TYPE = "SPLK"
// Lightning life time
private real LIGHTNING_DURATION = 0.125
// Lightning type of damaging effect
// Effect that will stand as thunders hits the ground.
private string LIGHTNING_MARKS = "Abilities\\Weapons\\CannonTowerMissile\\CannonTowerMissile.mdl"
// Loop Periodic PS: Changing this may cause bigger change
private real PERIODIC = 0.031250
// Owner of all dummies
private player DUMMY_OWNER = Player(PLAYER_NEUTRAL_PASSIVE)
// Height of the center dummy
private real CENTER_BALL_HEIGHT = 400.0
// Duration of center dummy's travling to its height limit
private real FLY_DURATION = 2.0
// Duration of post dummies traveling to its distance limit from center
private real POST_TRAVEL_DURATION = 2.0
// Amount of post line that will rotate
private integer POST_NUMBERS = 6
// Max distance of post to center
private real POST_DISTANCE = 400.0
// Speed turning of 360 deg.
private real ROTATE_SPEED = 2.0//seconds
// Attack Type of damaging
private attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL
// Damage Type of damaging
private damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
// Damage Per Interval
private real DAMAGE = 150.0
// Damage Base+(Amount Added each lvl)
private real DAMAGE_LVL = 25.0
// Damage Interval
private real DAMAGE_INTERVAL = 0.25
// Damage Range per interval
private real DAMAGE_RADIUS = 100.0
// Drop speed of all dummies at last wave
private real DROP_SPEED = 15.0
// Vacuum force speed
private real VACUUM_FORCE = 2.0
// Duration of damaging and post rotate
private real DURATION = 10.0
//END CONFIGURE
//***************************************************************************
// In this wave ball will raise,
// Upon reaching its height, ball will
// call forth of thunders that scars its
// designated area and causing damage
// as well as vacuuming enemy in area.
private constant integer WaveBall = 1
//***************************************************************************
// In this wave post are being summoned
private constant integer WaveCreatePost = 2
//***************************************************************************
// In this wave post are rotating
private constant integer WaveRotatePost = 3
//***************************************************************************
// In this wave every dummies are falling
// and deindex instance.
private constant integer WaveEnd = 4
endglobals
//***************************************************************************
native UnitAlive takes unit id returns boolean
//***************************************************************************
private constant function Damage takes integer lv returns real
return DAMAGE+(DAMAGE_LVL*lv)
endfunction
private constant function SinMax takes nothing returns real
return 90.0
endfunction
//***************************************************************************
private function SinSpeed takes real sm,real d returns real
return sm/(d/PERIODIC)
endfunction
//***************************************************************************
private function Filters takes unit u,unit t returns boolean
return UnitAlive(t) and not IsUnitType(u,UNIT_TYPE_MAGIC_IMMUNE) and not (GetUnitAbilityLevel(u,'Bvul') > 0) and not IsUnitAlly(u,GetOwningPlayer(t))
endfunction
//***************************************************************************
private struct LightningLifeTime
private static integer ix=0
private static integer array ic
private lightning l
private real r
implement CTL
local integer i=1
local real c
implement CTLExpire
loop
exitwhen i>ix
set this=ic[i]
if r>PERIODIC then
set r=r-PERIODIC
set c=Sin(((SinMax()/LIGHTNING_DURATION)*r)*bj_DEGTORAD)
call SetLightningColor(l,c,c,c,c)
else
call DestroyLightning(l)
set l=null
call destroy()
set ic[i]=ic[ix]
set ix=ix-1
set i=i-1
endif
set i=i+1
endloop
implement CTLEnd
static method SetTime takes lightning lh,real d returns nothing
local thistype this
set this=create()
set ix=ix+1
set ic[ix]=this
set l=lh
set r=d
endmethod
endstruct
private struct DoomFuse
private unit Caster
private unit Dummy
private real SpellX
private real SpellY
private real Sins
private real SinW2
private real HeightW3
private real Duration
private real AngleW23
private integer Waves
private integer Level
private boolean LeftRightW3
private effect Models
private static group GroupDamage=CreateGroup()
private static boolean LeftRight=false
private static integer ix=0
private static integer array ic
implement CTL
local integer i=1
local thistype dis
local real x
local real y
local real a
local unit u
local LightningLifeTime lfx
implement CTLExpire
loop
exitwhen i>ix
set this=ic[i]
if Waves==WaveBall then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),FLY_DURATION+POST_TRAVEL_DURATION)
call SetUnitFlyHeight(Dummy,Sin(Sins*bj_DEGTORAD)*CENTER_BALL_HEIGHT,0.0)
if Sins>=SinMax() then
call DestroyEffect(Models)
set Models=AddSpecialEffect(VACUUM_MODEL,GetUnitX(Dummy),GetUnitY(Dummy))
endif
else
set Sins=Sins+SinSpeed(SinMax(),DAMAGE_INTERVAL)
call GroupEnumUnitsInRange(GroupDamage,SpellX,SpellY,POST_DISTANCE,null)
loop
set u=FirstOfGroup(GroupDamage)
exitwhen u==null
if Filters(Caster,u) then
set x=GetUnitX(u)
set y=GetUnitY(u)
set a=Atan2(y-SpellY,x-SpellX)*bj_RADTODEG
call SetUnitX(u,x-VACUUM_FORCE*Cos(a*bj_DEGTORAD))
call SetUnitY(u,y-VACUUM_FORCE*Sin(a*bj_DEGTORAD))
endif
call GroupRemoveUnit(GroupDamage,u)
endloop
call GroupClear(GroupDamage)
if Sins>=(SinMax()*2) then
set a=GetRandomReal(0,359)
set x=SpellX+GetRandomReal(20.0,CENTER_BALL_HEIGHT)*Cos(a*bj_DEGTORAD)
set y=SpellY+GetRandomReal(20.0,CENTER_BALL_HEIGHT)*Sin(a*bj_DEGTORAD)
call DestroyEffect(AddSpecialEffect(LIGHTNING_MARKS,x,y))
call GroupEnumUnitsInRange(GroupDamage,x,y,DAMAGE_RADIUS,null)
loop
set u=FirstOfGroup(GroupDamage)
exitwhen u==null
if Filters(Caster,u) then
call UnitDamageTarget(Caster,u,Damage(Level),false,false,ATTACK_TYPE,DAMAGE_TYPE,null)
endif
call GroupRemoveUnit(GroupDamage,u)
endloop
call GroupClear(GroupDamage)
set Sins=SinMax()
call LightningLifeTime.SetTime(AddLightningEx(LIGHTNING_TYPE,true,SpellX,SpellY,CENTER_BALL_HEIGHT,x,y,0.0),LIGHTNING_DURATION)
endif
set Duration=Duration+PERIODIC
if Duration>=DURATION then
set Waves=WaveEnd
set Duration=0.0
endif
endif
elseif Waves==WaveCreatePost then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),POST_TRAVEL_DURATION)
set a=(POST_DISTANCE/SinMax())*Sins
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if SinW2>=SinMax()/POST_NUMBERS then
if LeftRight then
set LeftRight=false
else
set LeftRight=true
endif
set dis=create()
set ix=ix+1
set ic[ix]=dis
set dis.Waves=WaveRotatePost
set dis.Sins=0.0
set dis.Duration=0.0
set dis.HeightW3=POST_DISTANCE-a
set dis.Caster=Caster
set dis.SpellX=SpellX
set dis.SpellY=SpellY
set dis.AngleW23=AngleW23
set dis.LeftRightW3=LeftRight
set dis.Level=Level
set dis.Dummy=CreateUnit(DUMMY_OWNER,DUMMY_ID,x,y,0)
set dis.Models=AddSpecialEffectTarget(POST_MODEL,dis.Dummy,POST_MODEL_ATTACH)
call UnitAddAbility(dis.Dummy,FLY_ABILITY_ID)
call UnitRemoveAbility(dis.Dummy,FLY_ABILITY_ID)
set SinW2=0
endif
set SinW2=SinW2+SinSpeed(SinMax(),POST_TRAVEL_DURATION)
else
set Waves=WaveEnd
endif
elseif Waves==WaveRotatePost then
if Sins<SinMax() then
set Sins=Sins+SinSpeed(SinMax(),FLY_DURATION)
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
elseif LeftRightW3 then
set AngleW23=AngleW23+(360/(ROTATE_SPEED/PERIODIC))
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if AngleW23==360 then
set AngleW23=0
endif
set Duration=Duration+PERIODIC
else
set AngleW23=AngleW23-(360/(ROTATE_SPEED/PERIODIC))
set a=Sin(Sins*bj_DEGTORAD)*(POST_DISTANCE-HeightW3)
set x=SpellX+a*Cos(AngleW23*bj_DEGTORAD)
set y=SpellY+a*Sin(AngleW23*bj_DEGTORAD)
if AngleW23==0 then
set AngleW23=360
endif
set Duration=Duration+PERIODIC
endif
call SetUnitFlyHeight(Dummy,Sin(Sins*bj_DEGTORAD)*HeightW3,0.0)
call SetUnitX(Dummy,x)
call SetUnitY(Dummy,y)
if Duration>=DURATION then
set Waves=WaveEnd
set Duration=0.0
endif
elseif Waves==WaveEnd then
if Dummy!=null then
set a=GetUnitFlyHeight(Dummy)
if a>=DROP_SPEED then
call SetUnitFlyHeight(Dummy,a-DROP_SPEED,0.0)
elseif Caster!=null then
call DestroyEffect(Models)
set Duration=1.0
set Caster=null
elseif Duration>PERIODIC then
set Duration=Duration-PERIODIC
elseif Duration<=PERIODIC then
call RemoveUnit(Dummy)
set Dummy=null
set Models=null
endif
else
call destroy()
set ic[i]=ic[ix]
set ix=ix-1
set i=i-1
endif
endif
set i=i+1
endloop
implement CTLEnd
static method onCast takes nothing returns nothing
local integer i
local thistype this=create()
set ix=ix+1
set ic[ix]=this
set Waves=WaveBall
set Sins=0.0
set Duration=0.0
set Caster=GetTriggerUnit()
set SpellX=GetSpellTargetX()
set SpellY=GetSpellTargetY()
set Level=GetUnitAbilityLevel(Caster,ABILITY_ID)
set Dummy=CreateUnit(DUMMY_OWNER,DUMMY_ID,SpellX,SpellY,0)
set Models=AddSpecialEffectTarget(BALL_MODEL,Dummy,BALL_MODEL_ATTACH)
call UnitAddAbility(Dummy,FLY_ABILITY_ID)
call UnitRemoveAbility(Dummy,FLY_ABILITY_ID)
set i=1
loop
exitwhen i>POST_NUMBERS
set this=create()
set ix=ix+1
set ic[ix]=this
set Waves=WaveCreatePost
set Sins=0.0
set SinW2=SinMax()/POST_NUMBERS
set AngleW23=(360/POST_NUMBERS)*i
set Caster=GetTriggerUnit()
set SpellX=GetSpellTargetX()
set SpellY=GetSpellTargetY()
set i=i+1
endloop
endmethod
private static method onCheckAbi takes nothing returns boolean
return GetSpellAbilityId()==ABILITY_ID
endmethod
static method onInit takes nothing returns nothing
local integer index
static if LIBRARY_SpellEffectEvent then
call RegisterSpellEffectEvent(ABILITY_ID, function thistype.onCast)
else
set gg_trg_Doom_Fuse = CreateTrigger()
set index = 0
loop
call TriggerRegisterPlayerUnitEvent(gg_trg_Doom_Fuse, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(gg_trg_Doom_Fuse, Condition(function thistype.onCheckAbi))
call TriggerAddAction(gg_trg_Doom_Fuse, function thistype.onCast)
endif
endmethod
endstruct
endscope
//TESH.scrollpos=9
//TESH.alwaysfold=0
library CTL /* v1.2.0.3
*************************************************************************************
*
* CTL or Constant Timer Loop provides a loop for constant merged timers of timeout .03125
*
* Similar to T32 but pauses timer when no structs have instances and removes structs
* from timer trigger when those structs have no instances.
*
* This can also create new timers after destroying a previous timer and generates less
* code in the module. It also generates no triggers so long as the module is implemented
* at the top of the struct.
*
************************************************************************************
*
* module CTL
*
* Allows creation/destruction of timers in a struct. Provides instancing of those timers.
*
* - static method create takes nothing returns thistype
* - method destroy takes nothing returns nothing
*
* CTL (optional)
* local variables, code before running any timers
* CTLExpire (not optional)
* timer code
* CTLNull (optional)
* null any locals, runs after all timers
* CTLEnd (not optional)
*
* module CT32
*
* Converts struct into a timer group. Allows the timer group to be started and stopped.
* Instancing and looping through active timers is up to the user.
*
* - static method start takes nothing returns nothing
* - static method stop takes nothing returns nothing
*
* CT32 (not optional)
* timer code
* CT32End (not optional)
*
* struct TimerGroup32 extends array
*
* Allows for the creation of timer groups. Timer instancing and looping is entirely up
* to the user.
*
* - static method create takes code func returns thistype
* - method destroy takes nothing returns nothing
* - method start takes nothing returns nothing
* - method stop takes nothing returns nothing
*
************************************************************************************/
globals
private integer tgc = 0 //timer group count
private integer array tgr //timer group recycler
private integer ic=0 //instance count
private integer tc=0 //timer count
private integer array rf //root first
private integer array n //next
private integer array p //previous
private integer array th //timer head
private integer array ns //next stack
private trigger t=CreateTrigger()
private timer m=CreateTimer()
private triggercondition array ct
private conditionfunc array rc
private boolean array e32 //enabled
private integer array i32r //ct32 recycler
private integer i32cr = 0 //ct32 count recycler
private boolean array ir32 //is recycling
private boolean array id32 //is destroying
endglobals
private function E takes nothing returns nothing
local integer i=ns[0]
set ns[0]=0
loop
exitwhen 0==i
if (0==p[i]) then
if (0==n[i]) then
call TriggerRemoveCondition(t,ct[th[i]])
set ct[th[i]]=null
set tc=tc-1
set rf[th[i]]=0
else
set rf[th[i]]=n[i]
set p[n[i]]=0
endif
else
set p[n[i]]=p[i]
set n[p[i]]=n[i]
endif
set n[i]=n[0]
set n[0]=i
set i=ns[i]
endloop
loop
exitwhen 0 == i32cr
set i32cr = i32cr - 1
set i = i32r[i32cr]
if (not e32[i]) then
call TriggerRemoveCondition(t,ct[i])
set ct[i] = null
if (id32[i]) then
set tgr[i] = tgr[0]
set tgr[0] = i
set id32[i] = false
endif
set ir32[i] = false
endif
endloop
if (0==tc) then
call PauseTimer(m)
else
call TriggerEvaluate(t)
endif
endfunction
private function CT takes integer r returns integer
local integer i
local integer f
if (0==n[0]) then
set i=ic+1
set ic=i
else
set i=n[0]
set n[0]=n[i]
endif
set th[i]=r
set ns[i]=-1
set f=rf[r]
if (0==f) then
set n[i]=0
set p[i]=0
set rf[r]=i
set ct[r]=TriggerAddCondition(t,rc[r])
//set ct[r] = null
if (0==tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc=tc+1
else
set n[i]=f
set p[i]=0
set p[f]=i
set rf[r]=i
endif
return i
endfunction
private function DT takes integer t returns nothing
debug if (0>ns[t]) then
set ns[t]=ns[0]
set ns[0]=t
debug else
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,"TIMER LOOP ERROR: ATTEMPT TO DESTROY NULL TIMER")
debug endif
endfunction
private function A takes code c returns integer
local integer i = tgr[0]
if (0 == i) then
set i = tgc + 1
set tgc = i
else
set tgr[0] = tgr[i]
endif
set rc[i]=Condition(c)
return i
endfunction
private function A32 takes integer i returns nothing
if (not (e32[i] or id32[i])) then
if (ir32[i]) then
set ir32[i] = false
else
set ct[i] = TriggerAddCondition(t, rc[i])
endif
if (0 == tc) then
call TimerStart(m,.031250000,true,function E)
endif
set tc = tc + 1
set e32[i] = true
endif
endfunction
private function SR32 takes integer i returns nothing
if (e32[i]) then
if (not (ir32[i] or id32[i])) then
set i32r[i32cr] = i
set i32cr = i32cr + 1
set ir32[i] = true
endif
set e32[i] = false
set tc = tc - 1
endif
endfunction
private function DT32 takes integer i returns nothing
if (not id32[i]) then
if (not ir32[i]) then
set ir32[i] = true
set tc = tc - 1
set i32r[i32cr] = i
set i32cr = i32cr + 1
set e32[i] = false
endif
set id32[i] = true
endif
endfunction
private keyword r
private keyword e
module CTL
static integer rctl32
static method create takes nothing returns thistype
return CT(rctl32)
endmethod
method destroy takes nothing returns nothing
call DT(this)
endmethod
static method ectl32 takes nothing returns boolean
local thistype this=rf[rctl32]
endmodule
module CTLExpire
implement CTL
loop
exitwhen 0==this
endmodule
module CTLNull
set this=n[this]
endloop
endmodule
module CTLEnd
implement CTLNull
return false
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
module CT32
static integer rctl32
static method start takes nothing returns nothing
call A32(rctl32)
endmethod
static method stop takes nothing returns nothing
call SR32(rctl32)
endmethod
static method ectl32 takes nothing returns boolean
endmodule
module CT32End
return false
endmethod
private static method onInit takes nothing returns nothing
set rctl32 = A(function thistype.ectl32)
endmethod
endmodule
struct TimerGroup32 extends array
static method create takes code c returns thistype
return A(c)
endmethod
method destroy takes nothing returns nothing
call DT32(this)
endmethod
method start takes nothing returns nothing
call A32(this)
endmethod
method stop takes nothing returns nothing
call SR32(this)
endmethod
endstruct
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
/**************************************************************
*
* RegisterPlayerUnitEvent
* v5.1.0.1
* By Magtheridon96
*
* I would like to give a special thanks to Bribe, azlier
* and BBQ for improving this library. For modularity, it only
* supports player unit events.
*
* Functions passed to RegisterPlayerUnitEvent must either
* return a boolean (false) or nothing. (Which is a Pro)
*
* Warning:
* --------
*
* - Don't use TriggerSleepAction inside registered code.
* - Don't destroy a trigger unless you really know what you're doing.
*
* API:
* ----
*
* - function RegisterPlayerUnitEvent takes playerunitevent whichEvent, code whichFunction returns nothing
* - Registers code that will execute when an event fires.
* - function RegisterPlayerUnitEventForPlayer takes playerunitevent whichEvent, code whichFunction, player whichPlayer returns nothing
* - Registers code that will execute when an event fires for a certain player.
* - function GetPlayerUnitEventTrigger takes playerunitevent whichEvent returns trigger
* - Returns the trigger corresponding to ALL functions of a playerunitevent.
*
**************************************************************/
library RegisterPlayerUnitEvent // Special Thanks to Bribe and azlier
globals
private trigger array t
endglobals
function RegisterPlayerUnitEvent takes playerunitevent p, code c returns nothing
local integer i = GetHandleId(p)
local integer k = 15
if t[i] == null then
set t[i] = CreateTrigger()
loop
call TriggerRegisterPlayerUnitEvent(t[i], Player(k), p, null)
exitwhen k == 0
set k = k - 1
endloop
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function RegisterPlayerUnitEventForPlayer takes playerunitevent p, code c, player pl returns nothing
local integer i = 16 * GetHandleId(p) + GetPlayerId(pl)
if t[i] == null then
set t[i] = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t[i], pl, p, null)
endif
call TriggerAddCondition(t[i], Filter(c))
endfunction
function GetPlayerUnitEventTrigger takes playerunitevent p returns trigger
return t[GetHandleId(p)]
endfunction
endlibrary
//TESH.scrollpos=33
//TESH.alwaysfold=0
//============================================================================
// SpellEffectEvent
// - Version 1.1.0.0
//
// API
// ---
// RegisterSpellEffectEvent(integer abil, code onCast)
//
// Requires
// --------
// RegisterPlayerUnitEvent: hiveworkshop.com/forums/showthread.php?t=203338
//
// Optional
// --------
// Table: hiveworkshop.com/forums/showthread.php?t=188084
//
library SpellEffectEvent requires RegisterPlayerUnitEvent, optional Table
//============================================================================
private module M
static if LIBRARY_Table then
static Table tb
else
static hashtable ht = InitHashtable()
endif
static method onCast takes nothing returns nothing
static if LIBRARY_Table then
call TriggerEvaluate(.tb.trigger[GetSpellAbilityId()])
else
call TriggerEvaluate(LoadTriggerHandle(.ht, 0, GetSpellAbilityId()))
endif
endmethod
private static method onInit takes nothing returns nothing
static if LIBRARY_Table then
set .tb = Table.create()
endif
call RegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT, function thistype.onCast)
endmethod
endmodule
//============================================================================
private struct S extends array
implement M
endstruct
//============================================================================
function RegisterSpellEffectEvent takes integer abil, code onCast returns nothing
static if LIBRARY_Table then
if not S.tb.handle.has(abil) then
set S.tb.trigger[abil] = CreateTrigger()
endif
call TriggerAddCondition(S.tb.trigger[abil], Filter(onCast))
else
if not HaveSavedHandle(S.ht, 0, abil) then
call SaveTriggerHandle(S.ht, 0, abil, CreateTrigger())
endif
call TriggerAddCondition(LoadTriggerHandle(S.ht, 0, abil), Filter(onCast))
endif
endfunction
endlibrary