//************************************************************************************
//*
//*
//* LINKED LIST TABLE
//*
//* BY : ALMIA
//*
//*
//************************************************************************************
//*
//* Used to create linked list
//*
//************************************************************************************
//*
//*
//* CODE API
//*
//* constant function LLT_PrevArrayValueKey takes nothing returns integer
//* constant function LLT_NextArrayValueKey takes nothing returns integer
//* constant function LLT_RecycleArrayValueKey takes nothing returns integer
//* constant function LLT_ICChildKey takes nothing returns integer
//*
//* - system constants for settings
//* - Recommended not to be touched
//*
//* function LLT_GetNextKey takes integer index returns integer
//* function LLT_GetPrevKey takes integer index returns integer
//* function LLT_GetRCKey takes integer index returns integer
//*
//* - Value keys
//*
//* function GetNextIndexOfList takes integer list , integer index returns integer
//* function GetPrevIndexOfList takes integer list , integer index returns integer
//* function GetRecycleIndexOfList takes integer list, integer index returns integer
//* function GetInstanceCountOfList takes integer list returns integer
//*
//* - Getters of indexes
//* - Used for linked list's values
//*
//* function SetNextIndexOfList takes integer list , integer index , integer value returns nothing
//* function SetPrevIndexOfList takes integer list , integer index , integer value returns nothing
//* function SetRecycleIndexOfList takes integer list , integer index , integer value returns nothing
//* function SetInstanceIndexOfList takes integer list , integer value returns nothing
//*
//* - Setters for indexes
//* - Used for setting values of linked lists
//*
//* function CreateLinkedList takes nothing returns integer
//*
//* - Creates linked lists
//*
//* function ClearLinkedList takes integer list returns nothing
//*
//* - Clears linked lists cached values
//*
//* function DestroyLinkedList takes integer list returns nothing
//*
//* - Destroys linked list
//*
//* function GetNewIndexFromLinkedList takes integer list returns integer
//*
//* - Allocates a new instance for the linked list
//*
//* function RecycleIndexFromLinkedList takes integer list,integer index returns nothing
//*
//* - Recycles the instance
//* - Commonly used when a code's effect ends
//*
//* function GetNextIndexFromLinkedList takes integer index , integer list returns integer
//*
//* - Gets next index for the enumeration of index
//*
//* function GetFirstIndexFromLinkedList takes integer list returns integer
//*
//* - Gets first index for the enumeration of index
//*
//************************************************************************************
//*
//* ITERATION MODULE
//*
//* Module for iterating instance
//* Must be CnPed
//*
//* All words in between "$" should be replaced by
//* your own variable
//*
//* Legend:
//*
//* $LIST$ = Your List
//* $INDEX$ = Your Index
//* $CODE$ = Your code
//*
//*
//* set $INDEX$ = GetFirstIndexFromLinkedList($LIST$)
//*
//* loop
//* exitwhen $INDEX$ == 0
//*
//* $CODE$
//* ( NOTE : If the code's effect ends
//* please recycle index via calling:
//* call RecycleIndexFromLinkedList($LIST$, $INDEX$)
//* in a custom script)
//*
//* set $INDEX$ = GetNextIndexFromLinkedList($LIST$, $INDEX$)
//*
//* endloop
//*
//*
//* DESCRIPTION :
//*
//* This way,you can iterate indexed variables
//* unlike Indexed Arrays or Dynamic Indexing
//* You use custom scripts because GUI For Loop Integer
//* cannot handle this kind of iteration
//*
//************************************************************************************
//*
//* Variables :
//*
//* LLT_Table = hashtable
//* LLT_RC = integer array
//* LLT_IC = integer
//*
//************************************************************************************
//*
//* Credits :
//*
//* - Magtheridon96
//* - Maker
//*
//************************************************************************************
//***********************************************************
//*
//* SETTINGS
//*
//***********************************************************
//The following constants refer to minimum value of next
//prev and recycle.
constant function LLT_PrevArrayValueKey takes nothing returns integer
return 0
endfunction
constant function LLT_NextArrayValueKey takes nothing returns integer
return JASS_MAX_ARRAY_SIZE// 8192
endfunction
constant function LLT_RecycleArrayValueKey takes nothing returns integer
return 2* JASS_MAX_ARRAY_SIZE //16384
endfunction
constant function LLT_ICChildKey takes nothing returns integer
return -1
endfunction
//***********************************************************
//*
//* TOOLS
//*
//***********************************************************
function LLT_GetNextKey takes integer index returns integer
return LLT_NextArrayValueKey() + index
endfunction
function LLT_GetPrevKey takes integer index returns integer
return LLT_PrevArrayValueKey() + index
endfunction
function LLT_GetRCKey takes integer index returns integer
return LLT_RecycleArrayValueKey() + index
endfunction
//* SETS and GETS functions
//Get Values
function GetNextIndexOfList takes integer list , integer index returns integer
return LoadInteger(udg_LLT_Table, list, LLT_GetNextKey(index))
endfunction
function GetPrevIndexOfList takes integer list , integer index returns integer
return LoadInteger(udg_LLT_Table, list, LLT_GetPrevKey(index))
endfunction
function GetRecycleIndexOfList takes integer list , integer index returns integer
return LoadInteger(udg_LLT_Table, list, LLT_GetRCKey(index))
endfunction
function GetInstanceCountOfList takes integer list returns integer
return LoadInteger(udg_LLT_Table, list, LLT_ICChildKey())
endfunction
//Set Values
function SetNextIndexOfList takes integer list , integer index , integer value returns nothing
call SaveInteger(udg_LLT_Table, list, LLT_GetNextKey(index), value)
endfunction
function SetPrevIndexOfList takes integer list , integer index , integer value returns nothing
call SaveInteger(udg_LLT_Table, list, LLT_GetPrevKey(index), value)
endfunction
function SetRecycleIndexOfList takes integer list , integer index , integer value returns nothing
call SaveInteger(udg_LLT_Table, list, LLT_GetRCKey(index), value)
endfunction
function SetInstanceIndexOfList takes integer list , integer value returns nothing
call SaveInteger(udg_LLT_Table, list, LLT_ICChildKey(), value)
endfunction
//***********************************************************
//*
//* MAIN FUNCTIONS
//*
//***********************************************************
function CreateLinkedList takes nothing returns integer
local integer index = udg_LLT_RC[0]
//Initializing
if null == udg_LLT_Table then
set udg_LLT_Table = InitHashtable()
endif
if 0 == index then
set udg_LLT_IC = udg_LLT_IC + 1
return udg_LLT_IC
endif
set udg_LLT_RC[0] = udg_LLT_RC[index]
return index
endfunction
function ClearLinkedList takes integer list returns nothing
call FlushChildHashtable(udg_LLT_Table, list)
endfunction
function DestroyLinkedList takes integer list returns nothing
call ClearLinkedList(list)
set udg_LLT_RC[list] = udg_LLT_RC[0]
set udg_LLT_RC[0] = list
endfunction
function GetNewIndexFromLinkedList takes integer list returns integer
local integer this = GetRecycleIndexOfList(list, 0)
local integer ic
//Allocating Instance
if 0 == this then
set ic = GetInstanceCountOfList(list) + 1
call SetInstanceIndexOfList(list, ic)
set this = ic
else
call SetRecycleIndexOfList(list, 0, GetRecycleIndexOfList(list, this))
endif
// Adding the instance to list
call SetNextIndexOfList(list, this, 0)
call SetPrevIndexOfList(list, this, 0)
call SetNextIndexOfList(list, GetPrevIndexOfList(list, 0), this)
call SetPrevIndexOfList(list, 0, this)
return this
endfunction
function RecycleIndexFromLinkedList takes integer list,integer index returns nothing
//Recycling instance
call SetNextIndexOfList(list, GetPrevIndexOfList(list, index), GetNextIndexOfList(list, index))
call SetPrevIndexOfList(list, GetNextIndexOfList(list, index), GetPrevIndexOfList(list, index))
call SetRecycleIndexOfList(list, index, GetRecycleIndexOfList(list, 0))
call SetRecycleIndexOfList(list, 0, index)
endfunction
//***********************************************************
//*
//* EXTRA FUNCTIONS
//*
//***********************************************************
function GetNextIndexFromLinkedList takes integer list , integer index returns integer
return GetNextIndexOfList(list, index)
endfunction
function GetFirstIndexFromLinkedList takes integer list returns integer
return GetNextIndexOfList(list, 0)
endfunction
//************************************************************************************
//*
//*
//* 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
//************************************************************************************
Name | Type | is_array | initial_value |
LLT_IC | integer | No | |
LLT_RC | integer | Yes | |
LLT_Table | hashtable | No | |
SEI_Table | hashtable | No | |
SpellEffectEventIndex | integer | No | |
TC_Duration | real | Yes | |
TC_Index | integer | No | |
TC_Loc | location | No | |
TC_Time | real | Yes | |
TC_U | unit | Yes |