Name | Type | is_array | initial_value |
CdA_caster | unit | No | |
CdA_damage | real | No | |
CdA_group | group | No |
library HeroSimpleStateMachine
//**************************************************************************************************************************
// HeroSimpleStateMachine - Version 0.0.2 - By allknowledge aka iam20842
//**************************************************************************************************************************
//**************************************************************************************************************************
// Add custom temporarily state to an Hero.
//**************************************************************************************************************************
//**************************************************************************************************************************
// How the magic happend?
// 1. Save the state hash in statesTable using CreateState (Find the function explaination in: HSSM Globals Trigger)
// 1. Create an global variable for the state using integer STATE_YOURCUSTOMSTATE = yourvalue in HSSM Globals Trigger
// 2. Define a way to see the default value of the heroesTable for an Hero (Find a example in: HSSM SaveHeroTable Trigger)
// 3. Create your custom spell
// 3. Add your custom spell id like a global variable like this SPELL_STATE_YOURCUSTOMSTATE in HSSM Globals Trigger
// 3.1 Use UnitAddState for add an state
// 3.2 Use UnitRemoveState for remove an state
// 3.3 Use UnitHasState if you want add an state only if hero already have another state, like sleep to awake
// 3.4 Use UnitHasStateLeft if you want get the remaining time of an state
// 3.5 Use UnitHasStateMsg for get a debug message of the state
// 4. Combine your spells with the power of Hero Simple States Machine to add damage,
// times, or any bonus, checking if a unit have your custom state . see HSSM Example
//**************************************************************************************************************************
//**************************************************************************************************************************
// Conclusion:
//
// 1. Cast a state_spell over the unit to set custom state
// 2. If the unit already have the spell and you set stack mode OFF, this will happend
// 2.1 If new duration of the state is biggest that the current, the new will set
// 2.2 If new duration is less that the current state, nothing will apply
// 3. If the unit already have the spell and you set stack mode ON, this will happend
// 3.1 If new duration of the state is biggest that the current, the new will set
// 2.2 If new duration is less that the current state, both duration will sum and create new timer for the result duration
// The stack mode is "pseudostack" because even you set stack mode ON only the state with less duration that the current
// will sum, no biggers.
//**************************************************************************************************************************
globals
hashtable heroesTable = InitHashtable()
hashtable statesTable = InitHashtable()
hashtable timersTable = InitHashtable()
integer STATE_STUN = 0
integer STATE_POISON = 1
integer STATE_PARALYSIS = 2
integer STATE_SLEEP = 3
integer STATE_BROKEN = 4
integer STATE_ROOTED = 5
integer STATE_SLOWED = 6
integer STATE_DRAINED = 7
integer STATE_CAPTURE = 8
integer STATE_FROZEN = 9
integer STATE_HEALED = 10
integer SPELL_STATE_STUN = 'A000'
integer SPELL_STATE_STUNX30 = 'A008'
integer SPELL_STATE_PARALYSIS = 'A001'
integer SPELL_STATE_SLEEP = 'A002'
integer SPELL_STATE_BROKEN = 'A003'
integer SPELL_STATE_CLEAR = 'A006'
integer SPELL_STATE_CHECK = 'A005'
integer SPELL_STATE_STORMBOLT = 'A007'
integer MAX_STATES
endglobals
//**************************************************************************************************************************
// Explaining the HASHTABLES
//**************************************************************************************************************************
//**************************************************************************************************************************
// statesTable: save every custom state
//**************************************************************************************************************************
// Takes:
//
// Parent: Integer -> state index
// Child: 0 -> Integer -> index
// 1 -> String -> name
// 2 -> String -> description
// 3 -> Boolean -> Stack mode
// Value: the correspondig
//**************************************************************************************************************************
//**************************************************************************************************************************
// heroesTable: save the every state of the hero and their values, default: 0
//**************************************************************************************************************************
// Takes:
// Parent: Integer -> unit index
// Child: Integer -> state index
//**************************************************************************************************************************
//**************************************************************************************************************************
// timersTable: save the timer of the state (duration) for every unit+state
//**************************************************************************************************************************
// Takes:
//
// Parent: Integer -> timer index
// Child: 1 -> Retrieve -> Integer -> unit index
// 2 -> Retrieve -> Integer -> state index
//
// Parent: Integer -> unit index
// Child: Integer -> stateIndex -> Retrieve -> Timer -> currentTimer
//**************************************************************************************************************************
// Explaining the functions
//**************************************************************************************************************************
//**************************************************************************************************************************
// TimerHandler: Create a timer that manage the duration of state, when it expire the state get zero
//**************************************************************************************************************************
function TimerHandler takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer tid = GetHandleId(t)
local integer uid = LoadInteger(timersTable, GetHandleId(t), 1)
local integer sid = LoadInteger(timersTable, GetHandleId(t), 2)
local string sn = LoadStr(statesTable, sid, 1)
// CLEAR tid child data.
call FlushChildHashtable(timersTable, tid)
call SaveInteger(heroesTable, uid, sid, 0)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
// DEBUG msg
call BJDebugMsg("State: " + sn + " |cffff0000Expired|r")
endfunction
//**************************************************************************************************************************
// CreateState: Create a new state.
//**************************************************************************************************************************
// Takes:
// integer i -> index
// string n -> name
// string d -> description
//**************************************************************************************************************************
function CreateState takes integer i, string n, string d, boolean s returns nothing
call SaveInteger(statesTable, i, 0, i)
call SaveStr(statesTable, i, 1, n)
call SaveStr(statesTable, i, 2, d)
call SaveBoolean(statesTable, i, 3, s)
endfunction
//**************************************************************************************************************************
// UnitHasState: Get true or false from check does hero have state?
//**************************************************************************************************************************
// Takes:
// unit u -> target unit
// integer sid -> state index
//**************************************************************************************************************************
function UnitHasState takes unit u, integer s returns boolean
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local integer us = LoadInteger(heroesTable, uid, sid)
local boolean flag = false
if (us == 1) then
set flag = true
else
set flag = false
endif
set u = null
return flag
endfunction
//**************************************************************************************************************************
// UnitHasStateLeft: Get the remaining time of the State from hero.
//**************************************************************************************************************************
// Takes:
// unit u -> target unit
// integer sid -> state index
// Retrieves:
// real -> remaining time
//**************************************************************************************************************************
function UnitHasStateLeft takes unit u, integer s returns real
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local integer us = LoadInteger(heroesTable, uid, sid)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local real tl = TimerGetRemaining(t)
return tl
endfunction
//**************************************************************************************************************************
// UnitHasStateMsg: Return a message with the current value of the hero state
//**************************************************************************************************************************
// Takes:
// unit u -> target unit
// integer sid -> state index
// Retrieve:
// Custom message
//**************************************************************************************************************************
function UnitHasStateMsg takes unit u, integer s returns nothing
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local integer us = LoadInteger(heroesTable, uid, sid)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local real tl = TimerGetRemaining(t)
call ClearTextMessages()
if (us == 1) then
call BJDebugMsg("State: " + sn + " |cff00ff00ON|r" + " left: " + "|cffffff00" + R2S(tl) + "|r seconds" )
else
call BJDebugMsg("State: " + sn + " |cffff0000OFF|r")
endif
set u = null
endfunction
//**************************************************************************************************************************
// UnitRemoveState: Set OF an state of a Hero
//**************************************************************************************************************************
// Takes:
// unit u -> target unit
// integer sid -> state index
//**************************************************************************************************************************
function UnitRemoveState takes unit u, integer s returns nothing
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local integer uid = GetHandleId(u)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local integer tid = GetHandleId(t)
call ClearTextMessages()
// Debug Message
call BJDebugMsg("State: " + sn + " |cffff0000OFF|r")
// SET hero + state => 0
call SaveInteger(heroesTable, uid, sid, 0)
// CLEAR tid child data.
call FlushChildHashtable(timersTable, tid)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
set u = null
endfunction
//**************************************************************************************************************************
// UnitAddState: Set ON an state of a Hero
//**************************************************************************************************************************
// Takes:
// unit u -> target unit
// integer sid -> state index
// real d -> duration of the state
//**************************************************************************************************************************
function UnitAddState takes unit u, integer s, real d returns nothing
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local boolean sm = LoadBoolean(statesTable, s, 3)
local timer t = CreateTimer()
local integer tid = GetHandleId(t)
local real ntl
local timer nt
call ClearTextMessages()
// Check if unit have a timer (state)
// You can check the STACK value for the timer.
// Stack -> 0 : will sum the remaining actual time (if exist) to the new duration of the state
// Stack -> 1 : will set the current state remaining time to the biggest value. This mean that
// if unit have 8 sec left of state X and you apply 5 sec of state Y,
// the time left is gonna be 8 sec
if(UnitHasState(u, sid) == true) then
// Debug Message
call BJDebugMsg("The unit HAVE the state, checking remaining times")
// if the current time (ctl) is less than the new (d), the new timer will apply
call BJDebugMsg("Remaining time: " + R2S(UnitHasStateLeft(u, sid)))
if ( d > UnitHasStateLeft(u, sid) ) then
call BJDebugMsg("The new timer(d) is bigger than old timer(ctl), effect will apply")
call BJDebugMsg("call UnitRemoveState()")
// Removing previous state
call UnitRemoveState(u, sid)
call BJDebugMsg("--------------------")
// SET hero + state => 1
call SaveInteger(heroesTable, uid, sid, 1)
// SAVE for hero + state => Timer
call SaveTimerHandle(timersTable, uid, sid, t)
// SAVE for timer + 1 => unit index
call SaveInteger(timersTable, tid, 1, uid)
// SAVE for timer + 2 => state index
call SaveInteger(timersTable, tid, 2, sid)
// START the timer
call TimerStart(t, d, false, function TimerHandler)
// Debug Message
call BJDebugMsg("State: " + sn + " |cff00ff00ON|r" + " for: " + "|cffffff00" + R2S(d) + "|r seconds" )
else
call BJDebugMsg("The new timer is lowest than the actual")
call BJDebugMsg("Checking stack mode")
// Stack Mode.
// If ON, will add the timer
// If OFF, will do nothing
if (sm == true) then
call BJDebugMsg("Stack ON: sum the times")
set ntl = d + UnitHasStateLeft(u, sid)
call BJDebugMsg("call UnitRemoveState()")
// Removing previous state
call UnitRemoveState(u, sid)
call BJDebugMsg("--------------------")
// SAVE for hero + state => Timer
call SaveTimerHandle(timersTable, uid, sid, t)
// SAVE for timer + 1 => unit index
call SaveInteger(timersTable, tid, 1, uid)
// SAVE for timer + 2 => state index
call SaveInteger(timersTable, tid, 2, sid)
// START the timer
call TimerStart(t, d, false, function TimerHandler)
// Debug Message
call BJDebugMsg("Update State: " + sn + " |cff00ff00ON|r" + " for: " + "|cffffff00" + R2S(ntl) + "|r seconds" )
else
call BJDebugMsg("Stack OFF nothing more to do")
set u = null
set t = null
return
endif
endif
else
// Debug Message
call BJDebugMsg("The unit DONT have the state, effects will apply")
// SET hero + state => 1
call SaveInteger(heroesTable, uid, sid, 1)
// SAVE for hero + state => Timer
call SaveTimerHandle(timersTable, uid, sid, t)
// SAVE for timer + 1 => unit index
call SaveInteger(timersTable, tid, 1, uid)
// SAVE for timer + 2 => state index
call SaveInteger(timersTable, tid, 2, sid)
// START the timer
call TimerStart(t, d, false, function TimerHandler)
// Debug Message
call BJDebugMsg("State: " + sn + " |cff00ff00ON|r" + " for: " + "|cffffff00" + R2S(d) + "|r seconds" )
endif
set u = null
set t = null
endfunction
endlibrary
//**************************************************************************************************************************
// END
//**************************************************************************************************************************
library HeroSimpleStateMachine
globals
hashtable heroesTable = InitHashtable()
hashtable statesTable = InitHashtable()
hashtable timersTable = InitHashtable()
integer STATE_STUN = 0
integer STATE_POISON = 1
integer STATE_PARALYSIS = 2
integer STATE_SLEEP = 3
integer STATE_BROKEN = 4
integer STATE_ROOTED = 5
integer STATE_SLOWED = 6
integer STATE_DRAINED = 7
integer STATE_CAPTURE = 8
integer STATE_FROZEN = 9
integer STATE_HEALED = 10
integer SPELL_STATE_STUN = 'A000'
integer SPELL_STATE_STUNX30 = 'A008'
integer SPELL_STATE_PARALYSIS = 'A001'
integer SPELL_STATE_SLEEP = 'A002'
integer SPELL_STATE_BROKEN = 'A003'
integer SPELL_STATE_CLEAR = 'A006'
integer SPELL_STATE_CHECK = 'A005'
integer SPELL_STATE_STORMBOLT = 'A007'
integer MAX_STATES
endglobals
function TimerHandler takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer tid = GetHandleId(t)
local integer uid = LoadInteger(timersTable, GetHandleId(t), 1)
local integer sid = LoadInteger(timersTable, GetHandleId(t), 2)
local string sn = LoadStr(statesTable, sid, 1)
call FlushChildHashtable(timersTable, tid)
call SaveInteger(heroesTable, uid, sid, 0)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
endfunction
function CreateState takes integer i, string n, string d, boolean s returns nothing
call SaveInteger(statesTable, i, 0, i)
call SaveStr(statesTable, i, 1, n)
call SaveStr(statesTable, i, 2, d)
call SaveBoolean(statesTable, i, 3, s)
endfunction
function UnitHasState takes unit u, integer s returns boolean
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local integer us = LoadInteger(heroesTable, uid, sid)
local boolean flag = false
if (us == 1) then
set flag = true
else
set flag = false
endif
set u = null
return flag
endfunction
function UnitHasStateLeft takes unit u, integer s returns real
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local integer us = LoadInteger(heroesTable, uid, sid)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local real tl = TimerGetRemaining(t)
return tl
endfunction
function UnitHasStateMsg takes unit u, integer s returns nothing
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local integer us = LoadInteger(heroesTable, uid, sid)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local real tl = TimerGetRemaining(t)
call ClearTextMessages()
if (us == 1) then
call BJDebugMsg("State: " + sn + " |cff00ff00ON|r" + " left: " + "|cffffff00" + R2S(tl) + "|r seconds" )
else
call BJDebugMsg("State: " + sn + " |cffff0000OFF|r")
endif
set u = null
endfunction
function UnitRemoveState takes unit u, integer s returns nothing
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local integer uid = GetHandleId(u)
local timer t = LoadTimerHandle(timersTable, uid, sid)
local integer tid = GetHandleId(t)
call SaveInteger(heroesTable, uid, sid, 0)
call FlushChildHashtable(timersTable, tid)
call PauseTimer(t)
call DestroyTimer(t)
set t = null
set u = null
endfunction
function UnitAddState takes unit u, integer s, real d returns nothing
local integer uid = GetHandleId(u)
local integer sid = LoadInteger(statesTable, s, 0)
local string sn = LoadStr(statesTable, s, 1)
local boolean sm = LoadBoolean(statesTable, s, 3)
local timer t = CreateTimer()
local integer tid = GetHandleId(t)
local real ntl
local timer nt
if(UnitHasState(u, sid) == true) then
if (d > UnitHasStateLeft(u, sid) ) then
call UnitRemoveState(u, sid)
call SaveInteger(heroesTable, uid, sid, 1)
call SaveTimerHandle(timersTable, uid, sid, t)
call SaveInteger(timersTable, tid, 1, uid)
call SaveInteger(timersTable, tid, 2, sid)
call TimerStart(t, d, false, function TimerHandler)
else
if (sm == true) then
set ntl = d + UnitHasStateLeft(u, sid)
call UnitRemoveState(u, sid)
call SaveTimerHandle(timersTable, uid, sid, t)
call SaveInteger(timersTable, tid, 1, uid)
call SaveInteger(timersTable, tid, 2, sid)
call TimerStart(t, d, false, function TimerHandler)
else
set u = null
set t = null
return
endif
endif
else
call SaveInteger(heroesTable, uid, sid, 1)
call SaveTimerHandle(timersTable, uid, sid, t)
call SaveInteger(timersTable, tid, 1, uid)
call SaveInteger(timersTable, tid, 2, sid)
call TimerStart(t, d, false, function TimerHandler)
endif
set u = null
set t = null
endfunction
endlibrary
function CreateStates takes nothing returns nothing
call CreateState(0, "stun", "you get stunned", true)
call CreateState(1, "poison", "you get poisoned", false)
call CreateState(2, "paralysis", "you get paralyzed", false)
call CreateState(3, "sleep", "you get sleep", false)
call CreateState(4, "broken", "you get broken", false)
call CreateState(5, "rooted", "you get rooted", false)
call CreateState(6, "slowed", "you get slowed", false)
call CreateState(7, "drained", "you get drained", false)
call CreateState(8, "capture", "you get capture", false)
call CreateState(9, "frozen", "you get frozen", false)
call CreateState(10, "healed", "you get healed", false)
// Remember set the MAX_STATES
set MAX_STATES = 11
endfunction
//===========================================================================
function InitTrig_HSSM_CreateStates takes nothing returns nothing
local trigger tg = CreateTrigger( )
call TriggerRegisterTimerEventSingle( tg, 0.00 )
call TriggerAddAction( tg, function CreateStates)
endfunction
function HSSM_SaveHeroTable_Actions takes nothing returns nothing
local unit su = GetSoldUnit()
local integer uid = GetHandleId(su)
local integer i = 0
call ClearTextMessages()
// Set the default states zero
loop
call SaveInteger(heroesTable, uid, i, 0)
set i = i + 1
exitwhen i == MAX_STATES
endloop
set su = null
call BJDebugMsg("You hero is ready for get custom state!")
call BJDebugMsg("Use Q and select what state you want apply")
call BJDebugMsg("Use W to get the current state of the target unit")
call BJDebugMsg("Use E to get all the states cleared for the target unit")
call BJDebugMsg("Use R without and with STUN state to see the magic")
call BJDebugMsg("Use STUN x30 and later STUN for try stack system")
endfunction
//===========================================================================
function InitTrig_HSSM_SaveHeroTable takes nothing returns nothing
local trigger tg = CreateTrigger()
call TriggerRegisterUnitEvent( tg, gg_unit_ntav_0000, EVENT_UNIT_SELL )
call TriggerAddAction( tg, function HSSM_SaveHeroTable_Actions )
endfunction
function HSSM_Cast_Dummy_Spell_Actions takes nothing returns nothing
local unit tu = GetSpellTargetUnit()
local integer s = GetSpellAbilityId()
local integer i = 0
// STUN DEMO
if (GetSpellAbilityId() == SPELL_STATE_STUN) then
call UnitAddState(tu, 0, 10.0)
endif
// STUN X30 DEMO
if (GetSpellAbilityId() == SPELL_STATE_STUNX30) then
call UnitAddState(tu, 0, 30.0)
endif
// PARALYSIS DEMO
if (GetSpellAbilityId() == SPELL_STATE_PARALYSIS) then
call UnitAddState(tu, 2, 7.0)
endif
// SLEEP DEMO
if (GetSpellAbilityId() == SPELL_STATE_SLEEP) then
call UnitAddState(tu, 3, 20.0)
endif
// BROKEN DEMO
if (GetSpellAbilityId() == SPELL_STATE_BROKEN) then
call UnitAddState(tu, 5, 4.0)
endif
// CLEAR DEMO
if (GetSpellAbilityId() == SPELL_STATE_CLEAR) then
call ClearTextMessages()
loop
call UnitRemoveState(tu, i)
set i = i + 1
exitwhen i == MAX_STATES
endloop
call BJDebugMsg("All states Cleared")
endif
// CHECK DEMO
if (GetSpellAbilityId() == SPELL_STATE_CHECK) then
call BJDebugMsg("Current States")
call ClearTextMessages()
loop
call UnitHasStateMsg(tu, i)
set i = i + 1
exitwhen i == MAX_STATES
endloop
endif
set tu = null
endfunction
function InitTrig_HSSM_Cast_Dummy_Spell takes nothing returns nothing
local trigger tg = CreateTrigger()
local integer i = 0
call TriggerAddAction(tg, function HSSM_Cast_Dummy_Spell_Actions)
loop
call TriggerRegisterPlayerUnitEvent(tg, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYERS
endloop
endfunction
function HSSM_Example_Actions takes nothing returns nothing
local unit tu = GetSpellTargetUnit()
local unit c = GetSpellAbilityUnit()
local integer s = GetSpellAbilityId()
local real b = 250.0
// StormBolt Demo
if (GetSpellAbilityId() == SPELL_STATE_STORMBOLT) then
if (UnitHasState(tu , STATE_STUN)) then
// Pure Damage
if(GetUnitState(tu, UNIT_STATE_LIFE) <= b) then
call UnitDamageTarget( c, tu, 1000000000.00, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_ROCK_HEAVY_BASH)
else
call UnitDamageTarget( c, tu, b, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_ROCK_HEAVY_BASH)
endif
call UnitRemoveState(tu, STATE_STUN)
call BJDebugMsg("+250 pure damage bonus!")
else
call BJDebugMsg("Unit dont have STUN, bonus will not apply")
endif
endif
set tu = null
set c = null
endfunction
function InitTrig_HSSM_Example takes nothing returns nothing
local trigger tg = CreateTrigger()
local integer i = 0
call TriggerAddAction(tg, function HSSM_Example_Actions)
loop
call TriggerRegisterPlayerUnitEvent(tg, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYERS
endloop
endfunction