library LightningStack requires Table, TimerUtils
/*-----------------------------------------------------------------------------------------------------------------------------------------
*
* Lightning v1.0.0
* by Reventhous
*
* What's this? :-
* - a system that can do lightning work
* - a system that will recycle used lightning
*
* Requires :-
* -Table by Bribe
* |
* -TimerUtils by Vexorian, Bribe & Magtheridon96 [requires optional Table]
*-----------------------------------------------------------------------------------------------------------------------------------------
*
* API:
* ----
* | - function NewLightning takes string codeName, unit source returns Lightning
* | - return Lightning (lightning stack).
* |
* | - function ReleaseLightning takes Lightning lt returns nothing
* | - will destroy the Lightning (lightning stack)
* |
* | - function AddLightningTarget takes Lightning lt, unit target, boolean checkVisibility returns nothing
* | - will create/recycle lightning and lock it to target
* |
* | - function LockLightning takes Lightning lt, unit target, boolean lockFlag returns nothing
* | - Lock/Unlock lightning (the lightning will just froze and do nothing)
* |
* | - function ReleaseLightningTarget takes Lightning lt, unit target returns nothing
* | - will release target from lightning
*
*----------------------------------------------------------------------------------------------------------------------------------------
*/
globals
private constant real Periodic = 0.06 //make sure this number is > 0.05. No need high frequence timer
private constant integer MaxBolt = 256 // just to avoid big memory leak.
endglobals
// this is where the lightning data stored
private struct tooldata
unit t
lightning l
boolean lockFlag
boolean checkVisibility
integer instance
method destroy takes nothing returns nothing
if this.l != null then
call DestroyLightning(this.l)
endif
set this.lockFlag = false
set this.l = null
set this.t = null
set this.instance = 0
call this.deallocate()
endmethod
endstruct
// the is the main struct of this system
struct Lightning
Table get = 0
Table stack = 0
Table dat = 0
integer instance
integer used
string name
unit source
method destroy takes nothing returns nothing
// will destroy all of the lightning including the recycled
loop
exitwhen this.instance <= 0
call tooldata(this.stack.integer[this.instance]).destroy()
set this.instance = this.instance - 1
endloop
set this.source = null
call this.get.destroy()
call this.stack.destroy()
call this.dat.destroy()
call this.deallocate()
endmethod
static method onLock takes nothing returns nothing
local timer T = GetExpiredTimer()
local thistype bolt = GetTimerData(T)
local integer i = bolt.instance
loop
exitwhen i <= 0
if tooldata(i).lockFlag then
call MoveLightningEx(tooldata(i).l, tooldata(i).checkVisibility, GetUnitX(bolt.source), GetUnitY(bolt.source), GetUnitFlyHeight(bolt.source), GetUnitX(tooldata(i).t), GetUnitY(tooldata(i).t), GetUnitFlyHeight(tooldata(i).t))
endif
set i = i - 1
endloop
// will stop the timer when the stack is empty
if bolt.instance == 0 then
call ReleaseTimer(T)
endif
endmethod
// true = lock, false = unlock
method lock takes unit target, boolean flag returns nothing
set tooldata(this.get.integer[GetHandleId(target)]).lockFlag = flag
endmethod
method release takes unit target returns nothing
local thistype th
local tooldata dt
// will do nothing if use null data
if integer(this) <= 0 then
return
endif
if this.instance == this.dat.integer[GetHandleId(target)] then
set this.instance = this.instance - 1
endif
// finds the target
set dt = this.get.integer[GetHandleId(target)]
call dt.destroy()
endmethod
method add takes unit target, boolean checkVisibility returns nothing
local tooldata dt = tooldata.create()
local lightning bolt = AddLightningEx(this.name, checkVisibility, GetUnitX(this.source), GetUnitY(this.source), GetUnitFlyHeight(this.source), GetUnitX(target), GetUnitY(target), GetUnitFlyHeight(target))
if this.instance < MaxBolt then
// Store the data
set dt.t = target
set dt.l = bolt
set dt.checkVisibility = checkVisibility
set dt.lockFlag = true
set this.instance = this.instance + 1
set this.stack.integer[this.instance] = dt
set this.dat.integer[GetHandleId(target)] = this.instance
set this.get.integer[GetHandleId(target)] = dt
endif
// Create and start new timer on system start
if this.instance == 1 then
call TimerStart(NewTimerEx(this), Periodic, true, function thistype.onLock)
endif
endmethod
static method create takes string codeName, unit source returns thistype
local thistype this = thistype.allocate()
set this.name = codeName
set this.source = source
// For 'destroy' method
set stack = Table.create()
set get = Table.create()
set dat = Table.create()
return this
endmethod
endstruct
function LockLightning takes Lightning lt, unit target, boolean lockFlag returns nothing
call lt.lock(target, lockFlag)
endfunction
function ReleaseLightningTarget takes Lightning lt, unit target returns nothing
call lt.release(target)
endfunction
function AddLightningTarget takes Lightning lt, unit target, boolean checkVisibility returns nothing
call lt.add(target, checkVisibility)
endfunction
function ReleaseLightning takes Lightning lt returns nothing
call lt.destroy()
endfunction
function NewLightning takes string codeName, unit source returns Lightning
return Lightning.create(codeName, source)
endfunction
endlibrary