| 09-26-2004, 03:34 PM | #1 |
I have a function that deals damage over time, but I need it to return immediately. This isn't the exact function, but it'll get the concept across: Code:
function DOT takes unit whichUnit, real damagePerSecond, real duration returns boolean
local integer counter
set counter = 0
loop
set counter = counter + 1
call UnitDamageTargetBJ(whichUnit, whichUnit, damagePerSecond, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DISEASE)
exitwhen counter >= duration
call PolledWait(1)
endloop
return true
endfunctionThis works fine except the following code can't execute until <duration> seconds have passed and the function finally returns. I assume that I'll need to create a trigger with an event that executes every second, but I'm not sure as to how I could then retain the values of the parameters. In the real application of this, the trigger needs to be damaging dozens of units and preferably not simultaneously. For instance, if the function is called 20 seconds into the game to start damaging unitA, and then called 20.4 seconds into the game to damage unitB -- I don't want them both receiving damage at 21 or 22 seconds into the game. UnitA should be at 21.0 and unitB at 21.4 (But I won't throw a fit is this isn't possible). |
| 09-26-2004, 06:39 PM | #2 |
what you need to do is have the DOT function create a new trigger every time it's called. it then needs to store the parameters on the new trigger using gamecache and the return bug. make sure the triggers destroy themselves when done. |
| 09-27-2004, 01:01 PM | #3 |
You could try this DoT I use, might want to adapt it a little if you already use return bug exploiters or handle vars of some description. Just use Code:
function AddGenericDott takes unit caster, unit target, real duration, real period, real dpp, effect sfx returns timer Code:
// **** Return Bug Exploiters **** //
function H2I takes handle value returns integer
return value
return 0
endfunction
function I2U takes integer value returns unit
return value
return null
endfunction
function I2W takes integer value returns widget
return value
return null
endfunction
function I2Timer takes integer value returns timer
return value
return null
endfunction
function I2Effect takes integer value returns effect
return value
return null
endfunction
// **** Game Cache Handle Vars **** //
function VCache takes nothing returns gamecache
return InitGameCache("VCache.c")
endfunction
function SetHandleInt takes handle subject, string name, integer value returns nothing
call StoreInteger(VCache(), I2S(H2I(subject)), name, value)
endfunction
function GetHandleInt takes handle subject, string name returns integer
return GetStoredInteger(VCache(), I2S(H2I(subject)), name)
endfunction
function SetHandleReal takes handle subject, string name, real value returns nothing
call StoreReal(VCache(), I2S(H2I(subject)), name, value)
endfunction
function GetHandleReal takes handle subject, string name returns real
return GetStoredReal(VCache(), I2S(H2I(subject)), name)
endfunction
function SetHandleString takes handle subject, string name, string data returns nothing
call StoreString(VCache(), I2S(H2I(subject)), name, data)
endfunction
function GetHandleString takes handle subject, string name returns string
return GetStoredString(VCache(), I2S(H2I(subject)), name)
endfunction
function DoesHandleVarExist takes handle subject, string name returns boolean
return HaveStoredInteger(VCache(), I2S(H2I(subject)), name)
endfunction
function FlushHandle takes handle subject returns nothing
call FlushStoredMission(VCache(), I2S(H2I(subject)))
endfunction
// **** Dott functions ****
function Dott_duration_timer_expires takes nothing returns nothing
local timer t = GetExpiredTimer()
local timer period_timer = I2Timer(GetHandleInt(t,"periodtimer"))
local effect sfx = I2Effect(GetHandleInt(t,"sfx"))
call FlushHandle(t)
call FlushHandle(period_timer)
call DestroyTimer(t)
call DestroyTimer(period_timer)
call DestroyEffect(sfx)
set sfx = null
set t = null
set period_timer = null
endfunction
function Dott_period_timer_expires takes nothing returns nothing
local timer t = GetExpiredTimer()
local unit caster = I2U(GetHandleInt(t,"caster"))
local widget target = I2W(GetHandleInt(t,"target"))
local real damage = GetHandleReal(t,"damage")
call UnitDamageTarget(caster, target, damage, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, WEAPON_TYPE_WHOKNOWS)
//In case of death, get the duration timer to immediatly expire
if (GetWidgetLife(target)<=0) then
call TimerStart(I2Timer(GetHandleInt(t,"durationtimer")),0.00,false, function Dott_duration_timer_expires)
endif
set t = null
set caster = null
set target = null
endfunction
function AddGenericDott takes unit caster, widget target, real duration, real period, real dpp, effect sfx returns timer
local timer period_timer = CreateTimer()
local timer duration_timer = CreateTimer()
//Attach important data to the timer
call SetHandleInt(period_timer,"caster",H2I(caster))
call SetHandleInt(period_timer,"target",H2I(target))
call SetHandleReal(period_timer,"damage", dpp)
call SetHandleInt(duration_timer,"sfx",H2I(sfx))
//Reference the timers to each other
call SetHandleInt(duration_timer,"periodtimer",H2I(period_timer))
call SetHandleInt(period_timer,"durationtimer",H2I(duration_timer))
//Start the timers
call TimerStart(period_timer, period, true, function Dott_period_timer_expires)
call TimerStart(duration_timer, duration, false, function Dott_duration_timer_expires)
return period_timer
endfunction
Btw the abbreviation dott possibly means "damage over time target" |
| 09-27-2004, 03:54 PM | #4 | |
Quote:
Thanks a bunch ^_^ I think it stands for Damage Over Time Timer though -- heh. |
