library Respawn initializer onInit requires TimerUtils, Table, UnitIndexer
globals
private constant player PLAYER = Player(PLAYER_NEUTRAL_AGGRESSIVE)
private constant real DURATION = 30 // default respawn time
private constant boolean SHOW_EFFECT = true
private constant string EFFECT = "effect.mdx"
private Table RespawnTime
private Table BlackList
endglobals
// custom respawn times
//! textmacro RESPAWN_DEFINE_TYPES
set RespawnTime['nmrl'] = 5
//! endtextmacro
private function UnitFilter takes nothing returns boolean
return true
endfunction
private struct info
real startX
real startY
real facing
endstruct
private struct data
timer timer
integer id
integer type
unit u
real x
real y
real f
real duration
boolean dead
method destroy takes nothing returns nothing
set this.u = null
set this.duration = 0
call ReleaseTimer(this.timer)
call this.deallocate()
endmethod
endstruct
private function onRevive takes nothing returns nothing
local data this = GetTimerData(GetExpiredTimer())
if (IsHeroUnitId(this.type)) then
call ReviveHero(this.u, this.x, this.y, SHOW_EFFECT)
else
call CreateUnit(PLAYER, this.type, this.x, this.y, info(GetUnitId(this.u)).facing)
call RemoveUnit(this.u)
call DestroyEffect(AddSpecialEffect(EFFECT, this.x, this.y))
endif
call this.destroy()
endfunction
private function onDeath takes nothing returns boolean
local unit u = GetTriggerUnit()
local integer i = GetUnitTypeId(u)
local integer h = GetHandleId(u)
local info n = GetUnitId(u)
local data this
if (BlackList[i] == 1 or BlackList[h] == 1) then
set u = null
return false
endif
set this = data.create()
set this.u = u
set this.timer = NewTimerEx(this)
set this.id = h
set this.type = i
set this.x = n.startX
set this.y = n.startY
set this.f = GetUnitFacing(this.u)
set this.dead = true
set i = RespawnTime[this.type]
if (i != 0) then
set this.duration = i
else
set this.duration = DURATION
endif
call TimerStart(this.timer, this.duration, false, function onRevive)
set u = null
return false
endfunction
function UnitEnableRevive takes unit id, boolean flag returns nothing
if (flag) then
set BlackList[GetHandleId(id)] = 0
else
set BlackList[GetHandleId(id)] = 1
endif
endfunction
function SetUnitReviveTime takes unit u, real duration returns nothing
local integer i = GetHandleId(u)
local data this = data(RespawnTime[i])
if (this.u != null) then
set this.duration = duration
if (this.dead) then
call TimerStart(this.timer, this.duration - TimerGetElapsed(this.timer), false, function onDeath)
endif
endif
endfunction
function SetUnitReviveTimeById takes integer id, real duration returns nothing
set RespawnTime[id] = R2I(duration)
endfunction
function UnitEnableReviveById takes integer id, boolean flag returns nothing
if (flag) then
set BlackList[id] = 0
else
set BlackList[id] = 1
endif
endfunction
private function onIndex takes nothing returns boolean
local unit u = GetIndexedUnit()
local info i = GetUnitId(u)
set i.startX = GetUnitX(u)
set i.startY = GetUnitY(u)
set i.facing = GetUnitFacing(u)
return false
endfunction
//===========================================================================
private function onInit takes nothing returns nothing
local trigger t = CreateTrigger()
call TriggerRegisterPlayerUnitEvent(t, PLAYER, EVENT_PLAYER_UNIT_DEATH, Filter(function UnitFilter))
call TriggerAddCondition(t, Filter(function onDeath))
set t = CreateTrigger()
call RegisterUnitIndexEvent(Filter(function onIndex), UnitIndexer.INDEX)
set RespawnTime=Table.create()
set BlackList=Table.create()
//! runtextmacro RESPAWN_DEFINE_TYPES()
endfunction
endlibrary