library FireSystem initializer Init
globals
private constant integer STACK_DURATION = 10
private constant integer FIRE_DMG = 'A000'
Fire array fire
endglobals
private struct DD
static group gr = CreateGroup()
static trigger trg = null
static code func
static method add takes unit u returns nothing
if not IsUnitInGroup(u, .gr) then
call GroupAddUnit(.gr, u)
call TriggerRegisterUnitEvent(.trg, u, EVENT_UNIT_DAMAGED)
endif
endmethod
static method refresh takes nothing returns nothing
if .trg != null then
call DestroyTrigger(.trg)
endif
set .trg = CreateTrigger()
call TriggerAddCondition(.trg, Condition(.func))
call GroupClear(.gr)
call BJDebugMsg("refreshed")
endmethod
endstruct
struct Fire
unit flame = null
unit target = null
real stack_dmg = 0
integer stack_time = 0
static integer count = 0
static group active = CreateGroup()
static trigger trgPeriodic = CreateTrigger()
method stack takes real damage returns nothing
set .stack_dmg = .stack_dmg + damage
set stack_time = STACK_DURATION
endmethod
static method create takes nothing returns Fire
local thistype f = .allocate()
return f
endmethod
method reset takes nothing returns nothing // Temporary Solution
call GroupRemoveUnit(.active, .target)
set .target = null
set .count = .count - 1
set .stack_dmg = 0
set .stack_time = 0
call .deallocate()
endmethod
static method forLoop takes nothing returns nothing
local unit u = GetEnumUnit()
local integer i = GetUnitUserData(u)
set fire[i].stack_time = fire[i].stack_time - 1
call BJDebugMsg(I2S(fire[i].stack_time) + " " + R2S(fire[i].stack_dmg))
if fire[i].stack_time == 0 then
call fire[i].reset()
if .count == 0 then
call DisableTrigger(.trgPeriodic)
call DD.refresh()
endif
endif
set u = null
endmethod
static method periodic takes nothing returns boolean
call ForGroup(.active, function Fire.forLoop)
return false
endmethod
static method onInit takes nothing returns nothing
call TriggerRegisterTimerEvent(trgPeriodic, 1.0, true)
call TriggerAddCondition(trgPeriodic, Condition(function Fire.periodic))
call DisableTrigger(trgPeriodic)
endmethod
endstruct
private function OnDamage takes nothing returns boolean
local unit target = GetTriggerUnit()
local unit source = GetEventDamageSource()
local real damage = GetEventDamage()
local integer i = GetUnitUserData(target)
if fire[i].flame == null then
call fire[i].stack(damage)
endif
return false
endfunction
private function OnAttackFilter takes unit attacked, unit attacker returns boolean
return IsUnitType(attacked, UNIT_TYPE_STRUCTURE) and GetUnitAbilityLevel(attacker, FIRE_DMG) > 0
endfunction
private function OnAttack takes nothing returns boolean
local unit attacked = GetTriggerUnit()
local unit attacker = GetAttacker()
local integer i = GetUnitUserData(attacked)
if OnAttackFilter(attacked, attacker) then
if fire[i] == null then
set fire[i] = Fire.create()
call BJDebugMsg("null")
endif
if fire[i].flame == null and fire[i].target == null then
if Fire.count == 0 then
call EnableTrigger(Fire.trgPeriodic)
endif
call DD.add(attacked)
set Fire.count = Fire.count + 1
call GroupAddUnit(Fire.active, attacked)
set fire[i].target = attacked
endif
endif
return false
endfunction
private function Init takes nothing returns nothing
local trigger t1 = CreateTrigger()
local integer i = 0
loop
call TriggerRegisterPlayerUnitEvent(t1, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(t1, Condition(function OnAttack))
set DD.func = function OnDamage
call DD.refresh()
endfunction
endlibrary