- Joined
- Oct 14, 2008
- Messages
- 340
Alright so here's the deal, I have no idea whats wrong with my code here, gone over it tons of times.. so I'll once again harness the helpful power of the hive. Basically "trueshot" is a passive ability that adds +1 agility for X amount of time on every successful attack. The current code works fine for one unit, but when another hero steps in.. all hell breaks loose.. Really not sure whats wrong with my code.. Can anyone help? Maybe tell me how inefficient it might be too 
JASS:
library Trueshot initializer init
private struct agibonus
unit u
static agibonus array ab
static integer index = 0
method onDestroy takes nothing returns nothing
set .u = null
endmethod
static method timerExpire takes nothing returns nothing
local agibonus a = agibonus.ab[0]
local integer i = 1
call SetHeroAgi(a.u, GetHeroAgi(a.u, false)-1, true)
call a.destroy()
call DestroyTimer(GetExpiredTimer())
loop
exitwhen i > agibonus.index
set agibonus.ab[i-1] = agibonus.ab[i]
set i = i+1
endloop
set agibonus.index = agibonus.index-1
endmethod
static method create takes unit u, integer slvl returns agibonus
local agibonus a = agibonus.allocate()
local timer tim = CreateTimer()
local real time = 3.5+(0.5*slvl)
set a.u = u
call SetHeroAgi(u, GetHeroAgi(u, false)+1, true)
set agibonus.ab[agibonus.index] = a
set agibonus.index = agibonus.index+1
call TimerStart(tim, time, false, function agibonus.timerExpire)
return a
endmethod
endstruct
private struct data
unit attacker
unit attacked
integer slvl
trigger dmgtrigger
triggeraction act
timer tim
static data array dat
static integer index = 0
method onDestroy takes nothing returns nothing
call TriggerRemoveAction(.dmgtrigger, .act)
call DestroyTrigger(.dmgtrigger)
set .attacker = null
set .attacked = null
endmethod
static method timerExpire takes nothing returns nothing
local timer tim = GetExpiredTimer()
local data d
local integer i = 0
local integer q = 0
local integer z = 0
local boolean b = false
loop
exitwhen i > data.index
exitwhen b == true
set d = data.dat[i]
if d.tim == tim then
set b = true
call DestroyTimer(tim)
call d.destroy()
loop
set q = data.index
set z = i+1
set data.dat[z-1] = data.dat[z]
set z = z+1
exitwhen z > q
endloop
set data.index = data.index-1
endif
set i = i+1
endloop
endmethod
static method dmgTriggerActions takes nothing returns nothing
local unit src = GetEventDamageSource()
local unit u = GetTriggerUnit()
local integer i = 0
local integer q = 0
local integer z = 0
local boolean b = false
local data d
loop
exitwhen i > data.index
exitwhen b == true
set d = data.dat[i]
if d.attacker == src and d.attacked == u then
set b = true
call agibonus.create(d.attacker, d.slvl)
call PauseTimer(d.tim)
call DestroyTimer(d.tim)
call d.destroy()
loop
set q = data.index
set z = i+1
set data.dat[z-1] = data.dat[z]
set z = z+1
exitwhen z > q
endloop
set data.index = data.index-1
endif
set i = i + 1
endloop
set src = null
set u = null
endmethod
static method create takes unit attacker, unit attacked returns data
local data d = data.allocate()
set d.attacker = attacker
set d.attacked = attacked
set d.slvl = GetUnitAbilityLevel(d.attacker, 'A00K')
set d.dmgtrigger = CreateTrigger()
set d.tim = CreateTimer()
call TriggerRegisterUnitEvent(d.dmgtrigger, d.attacked, EVENT_UNIT_DAMAGED)
set d.act = TriggerAddAction(d.dmgtrigger, function data.dmgTriggerActions)
call TimerStart(d.tim, 1.0, false, function data.timerExpire)
set data.dat[data.index] = d
set data.index = data.index+1
return d
endmethod
endstruct
private function Eval takes nothing returns boolean
if GetUnitAbilityLevel(GetAttacker(), 'A00K') > 0 then
call data.create(GetAttacker(), GetTriggerUnit())
endif
return false
endfunction
private function init takes nothing returns nothing
local trigger trg = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddCondition(trg, Condition(function Eval))
endfunction
endlibrary