//************************************************************************************
//*
//*
//* SPELL EFFECT INDEXER
//*
//* BY : ALMIA
//*
//*
//************************************************************************************
//*
//* Indexes every instance created by a casted spell/ ability
//*
//************************************************************************************
//*
//* Requires:
//*
//* Linked List Table = http://www.hiveworkshop.com/forums/spells-569/linked-list-table-v1-2-a-230076/
//*
//************************************************************************************
//*
//* Code API
//*
//* constant function SpellDefaultTimeout takes nothing returns real
//* - System default timeout for looping spells
//*
//* function TriggerRegisterSpellEffect takes integer spell, trigger onEffect, trigger onLoop returns nothing
//*
//* - Registers the spell to the system
//* - Also, it registers the triggers being evaluated and looped
//* - Creates linked lists for every spell registered
//*
//* function RegisterSpellEffect takes integer spell, code onEffect ,code onLoop returns nothing
//* - Same goes to TriggerRegisterSpellEffect, though uses code
//*
//* function OnSpellEffect takes nothing returns boolean
//*
//* - System trigger condition
//* - Evaluates the triggers for every spell casted
//* - Creates new indexed instance for multi instancability
//*
//* function RecycleSpellIndex takes integer spell, integer index returns nothing
//*
//* - Recycles the spell's current index
//* - Used when the spell's effect ends in the loop
//*
//* function GetSpellNewIndex takes integer spell returns integer
//*
//* - Wrapper for SpellEffectEventIndex
//* - Created in case the SpellEffectEventIndex is overwritten
//*
//* function SpellGetFirst takes integer a returns integer
//*
//* - Gets the starting index of the spell's linked list
//*
//* function SpellGetNext takes integer a, integer index returns integer
//*
//* - Gets the next index of the given index from a spell's linked list
//*
//*
//************************************************************************************
//*
//* ITERATION MODULE
//*
//* All variables in between "$" will be replaced by your own variables
//* Must be CnPed
//*
//* Variables required:
//*
//* $SPELL$ = your Spell
//* $INDEX$ = Your Index variable
//*
//* =====================================================================
//*
//* set $INDEX$ = SpellGetFirst($SPELL$)
//*
//* loop
//*
//* exitwhen 0 == $INDEX$
//*
//* ( YOUR CODE HERE )
//*
//* ( IF YOUR SPELL'S EFFECT HAS ENDED )
//* ( MAKE SURE TO USE "call RecycleSpellIndex($SPELL$, $INDEX$)
//*
//* set $INDEX$ = SpellGetNext($SPELL$, $INDEX$)
//*
//* endloop
//*
//* =====================================================================
//*
//************************************************************************************
//*
//* NOTES:
//*
//* - Registers spells only in map initialization triggers.
//* - Do not register any events in your trigger which will have the spell's effect
//* - Do not register any events in your spell effect loop trigger
//* - Iteration module must be followed when iterating instances
//* - You can uses either GetSpellNewIndex or SpellEffectEventIndex to get
//* the spell being casted
//* - Use SpellEffectEventAbility to retrieve the casted spell
//*
//************************************************************************************
//*
//* Variables :
//*
//* SpellEffectEventIndex = Integer
//* SEI_Table = Hashtable
//*
//************************************************************************************
constant function SpellDefaultTimeout takes nothing returns real
return 0.031250000
endfunction
//************************************************************************************
function OnSpellEffect takes nothing returns boolean
// Locals
local integer spell = GetSpellAbilityId()
local integer count
local trigger t
if HaveSavedBoolean(udg_SEI_Table, spell, 0) then
set t = LoadTriggerHandle(udg_SEI_Table, spell, 1)
//Evaluating trigger with event-related variables
set udg_SpellEffectEventIndex = GetNewIndexFromLinkedList(LoadInteger(udg_SEI_Table, spell, 0))
//In case EventIndex is overwritten, save variable
call SaveInteger(udg_SEI_Table, spell, 4, udg_SpellEffectEventIndex)
//Start evaluating
if TriggerEvaluate(t) then
call TriggerExecute(t)
endif
set t = null
//Count instances
set count = LoadInteger(udg_SEI_Table, spell, 3) + 1
call SaveInteger(udg_SEI_Table, spell, 3, count)
//If instances counted is equal to 1
//then turn on the looping trigger
if 1 == count then
call EnableTrigger(LoadTriggerHandle(udg_SEI_Table, spell, 2))
endif
endif
return false
endfunction
//************************************************************************************
function InitSpellIndexer takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( t, Filter(function OnSpellEffect))
set udg_SEI_Table = InitHashtable()
set t = null
endfunction
//************************************************************************************
function TriggerRegisterSpellEffect takes integer spell, trigger onEffect, trigger onLoop returns nothing
if null == udg_SEI_Table then
call InitSpellIndexer()
endif
call SaveBoolean(udg_SEI_Table, spell, 0, true)
// Creating new linked list for the registered ability
call SaveInteger(udg_SEI_Table, spell, 0, CreateLinkedList())
// Saving trigger related to spell
call SaveTriggerHandle(udg_SEI_Table, spell, 1, onEffect)
call SaveTriggerHandle(udg_SEI_Table, spell, 2, onLoop)
// registering looping event
call TriggerRegisterTimerEvent(onLoop, SpellDefaultTimeout(), true)
endfunction
//************************************************************************************
function RegisterSpellEffect takes integer spell, code onEffect ,code onLoop returns nothing
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
call TriggerAddCondition(t, Condition(onEffect))
call TriggerAddCondition(t, Condition(onLoop))
call TriggerRegisterSpellEffect(spell, t, t2)
set t = null
set t2 = null
endfunction
//************************************************************************************
function RecycleSpellIndex takes integer spell, integer index returns nothing
// Recycling Instance
local integer count = LoadInteger(udg_SEI_Table, spell, 3) - 1
call RecycleIndexFromLinkedList(LoadInteger(udg_SEI_Table, spell, 0), index)
call SaveInteger(udg_SEI_Table, spell, 3, count)
// If number of instance counted is equal to 0
// Disable trigger
if 0 == count then
call DisableTrigger(LoadTriggerHandle(udg_SEI_Table, spell, 2))
endif
endfunction
//************************************************************************************
//*
//* EXTRA FUNCTIONS or UTILS
//*
//************************************************************************************
// SPELL EFFECT EVENT RELATED
function GetSpellNewIndex takes integer spell returns integer
return LoadInteger(udg_SEI_Table, spell, 4)
endfunction
// ITERATION RELATED
function SpellGetFirst takes integer a returns integer
return GetFirstIndexFromLinkedList(LoadInteger(udg_SEI_Table, a, 0))
endfunction
function SpellGetNext takes integer a, integer index returns integer
return GetNextIndexFromLinkedList(LoadInteger(udg_SEI_Table, a, 0), index)
endfunction
//************************************************************************************