HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

I need a Damage-Over-Time function that doesn't require waiting

09-26-2004, 03:34 PM#1
RaeVanMorlock
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
endfunction

This 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
curi
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
Grater
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
The uh, period is the time between damage, and dpp is damage per period, total damage being dpp * duration/period. It also takes a special effect, which will be destroyed at the end of the duration or when the target dies, like you attach the sfx to the target or caster (choosing attachment point and stuff too) then pass it to the function, or you can just pass null if you don't want a custom sfx.

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
RaeVanMorlock
Quote:
Originally Posted by Grater
Btw the abbreviation dott possibly means "damage over time target"


Thanks a bunch ^_^ I think it stands for Damage Over Time Timer though -- heh.