• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Calculating Damage over Time with varying damage/duration

Status
Not open for further replies.

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
Hey guys, what's an efficient way for calculating damage over time?

In my map I have a Tower that applies a DoT effect on it's attacks. It has two DoT related stats that can be increased/decreased:
DoT_Damage
DoT_Duration

I have it working using the code below but I'm not a fan of this style since it creates extremely short timer intervals.
Here's the important parts of my code slightly modified for clarity (t = the enemy target):
Lua:
-- calculate interval and damage per interval
local duration = tow.dot_duration
local interval = duration / tow.dot_damage
local ticks = tow.dot_damage / duration
local dmg = interval*ticks
local elapsedTime = 0

local ThisTimer = CreateTimer()
TimerStart(ThisTimer, interval, true, function ()
    -- increment
    elapsedTime = elapsedTime + interval
    -- check duration
    if elapsedTime < duration and IsAlive(t) then
        -- damage
        DealDamage(u, t, dmg)
    else
        -- clean up
        DestroyTimer(ThisTimer)
    end
end)
I'm terrible at even the simplest of math so the answer is probably right in front of me, but any help would be appreciated.

Edit: So I'm now multiplying the interval and dmg by 5 which seems to do the trick. I don't think it will cause any problems but I'm not sure.
 
Last edited:
Level 1
Joined
Nov 8, 2020
Messages
9
You can specify the function() (fourth parameter of "Timerstart").
It gets called when the timer expires

Basically make a function that handles what to do, when the timer expires and destroys it.

I have some code for that, but not in Lua:
Code:
function HandlerfuncSpecial takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local effect e = LoadEffectHandleBJ(0, GetHandleIdBJ(t), udg_HashtableSpecialEffectTimer)
    call DestroyEffectBJ( e )
    call PauseTimer(t)
    call DestroyTimer(t)
    set t=null
endfunction

function SpecialEffectTimedDestruction_Actions takes effect e, real r returns nothing
    local timer t=CreateTimer()
    call TimerStart(t, r, false, function HandlerfuncSpecial)
    call SaveEffectHandleBJ(e, 0, GetHandleIdBJ(t), udg_HashtableSpecialEffectTimer )
endfunction
 
Level 23
Joined
Jun 26, 2020
Messages
1,838
I see in
Lua:
local interval = duration / tow.dot_damage
local ticks = tow.dot_damage / duration
local dmg = interval*ticks
interval and ticks are multiplicative inverses so dmg always will be 1.

Basically if you wanna the damage will be "every 1 second" so just do
Lua:
local dmg = tow.dot_damage / duration
But if the interval can vary so the amount of damage doesn't matter, it can be just 1 and you can just change the interval.

In this cases the damage or the interval values must be constant (or not depend of the rest of variables) if you wanna the total damage and the duration will have a certain value, if the two variables change so the value of the total damage will be a chaos.
 
Level 9
Joined
Mar 26, 2017
Messages
376
For these type of systems, I would prefer to base it on an ability like shadow strike if possible.

Otherwise I think for this particular system it would be best to make use of fixed intervals. Only modify damage and duration. Otherwise, it may either result in an unnecessary large amount of ticks per second, or a slow and unnatural looking DoT.
 

Uncle

Warcraft Moderator
Level 63
Joined
Aug 10, 2018
Messages
6,457
@John Schneddi
In Lua you can create the Callback Function inside of the Timer, which you'll see is what I'm doing in my code. Hashtables are a thing of the past (along with many other things), it's a huge improvement over vJass. Anyway, everything works fine, that's not the issue, all I was curious about was how to calculate the damage/interval efficiently.

@HerlySQR
Makes sense, so I'm sticking with what I have for now with constant damage. And I'm multiplying the dmg and interval by 5 now which increases the interval from ~0.04 seconds to ~0.20 seconds which is a much better outcome. Obviously these values will vary depending on the total damage/total duration but my map will only use small percentage changes so it should be fine.

@pr114
I'm planning on coding everything, missiles, buffs, abilities, etc. so I can have total control. But yeah, I'm actually fine with what I have now, the damage remains constant but the interval adjusts.

Thanks for the responses!
 
Last edited:
Status
Not open for further replies.
Top