• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

GUI Damage over Time [GDoT]

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
This is a GUI version of Damage over Time system.
I don't know if there's already bunch of DoT system, I made this system just to see how good I'm in trigger editor and ofcourse for sharing.


  • GDoT Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set GDoT_DebugMode = False
      • -------- you can change this, just make sure below 0.10 --------
      • Set GDoT_INTERVAL = 0.05

  • GDoT
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • GDoTRegister_Caster Not equal to No unit
              • GDoTRegister_Target Not equal to No unit
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • GDoT_UseWrapper Equal to True
            • Then - Actions
              • Custom script: call ExecuteFunc("GDoTRegister")
            • Else - Actions
              • Custom script: call ExecuteFunc("GDoTRegisterEx")
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • GDoT_DebugMode Equal to True
            • Then - Actions
              • Game - Display to (All players) the text: GUI DoT: Error! App...
            • Else - Actions
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTOnIterate takes nothing returns nothing
      • Set GDoT_Current = GDoT_MaxIndex
      • -------- --------
      • Custom script: loop
      • Custom script: exitwhen udg_GDoT_Current == 0
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_Active[GDoT_Current] Equal to True
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • GDoT_HitAmount[GDoT_Current] Greater than 0
                  • (GDoT_Target[GDoT_Current] is alive) Equal to True
            • Then - Actions
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • GDoT_Freq[GDoT_Current] Greater than or equal to GDoT_DmgFrequency[GDoT_Current]
                • Then - Actions
                  • Unit - Cause GDoT_Caster[GDoT_Current] to damage GDoT_Target[GDoT_Current], dealing GDoT_DpS[GDoT_Current] damage of attack type GDoT_AttackType[GDoT_Current] and damage type GDoT_DamageType[GDoT_Current]
                  • -------- --------
                  • -------- on damage event --------
                  • Set GDoTEvent_Caster = GDoT_Caster[GDoT_Current]
                  • Set GDoTEvent_Target = GDoT_Target[GDoT_Current]
                  • Set GDoTEvent_DpS = GDoT_DpS[GDoT_Current]
                  • Set GDoTEvent_OnDamage = 1.00
                  • Set GDoTEvent_OnDamage = 0.00
                  • -------- --------
                  • Set GDoT_HitAmount[GDoT_Current] = (GDoT_HitAmount[GDoT_Current] - 1)
                  • Set GDoT_Freq[GDoT_Current] = 0.00
                • Else - Actions
                  • Set GDoT_Freq[GDoT_Current] = (GDoT_Freq[GDoT_Current] + GDoT_INTERVAL)
              • -------- --------
            • Else - Actions
              • Set GDoTEvent_Caster = GDoT_Caster[GDoT_Current]
              • Set GDoTEvent_Target = GDoT_Target[GDoT_Current]
              • Set GDoTEvent_DpS = GDoT_DpS[GDoT_Current]
              • Set GDoTEvent_EndDoT = 1.00
              • Set GDoTEvent_EndDoT = 0.00
              • -------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • GDoT_Current Equal to GDoT_MaxIndex
                • Then - Actions
                  • Set GDoT_MaxIndex = (GDoT_MaxIndex - 1)
                • Else - Actions
                  • Set GDoT_Recycle[GDoT_Current] = GDoT_Recycle[0]
                  • Set GDoT_Recycle[0] = GDoT_Current
              • -------- --------
              • Special Effect - Destroy GDoT_DmgFx[GDoT_Current]
              • Set GDoT_Caster[GDoT_Current] = No unit
              • Set GDoT_Target[GDoT_Current] = No unit
              • Set GDoT_Freq[GDoT_Current] = 1.00
              • Set GDoT_DmgFrequency[GDoT_Current] = 1.00
              • Set GDoT_HitAmount[GDoT_Current] = 0
              • Set GDoT_DpS[GDoT_Current] = 0.00
              • Set GDoT_AttackType[GDoT_Current] = Spells
              • Set GDoT_DamageType[GDoT_Current] = Normal
              • Set GDoT_Active[GDoT_Current] = False
              • -------- --------
        • Else - Actions
      • Set GDoT_Current = (GDoT_Current - 1)
      • -------- --------
      • Custom script: endloop
      • -------- --------
      • -------- pause/stop the timer when there's nothing on the list --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_MaxIndex Equal to 0
        • Then - Actions
          • Countdown Timer - Pause GDoT_Iterator
        • Else - Actions
      • -------- --------
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTRegisterEx takes nothing returns nothing
      • -------- increase the instance by 1 or recycle --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_Recycle[0] Equal to 0
        • Then - Actions
          • Set GDoT_MaxIndex = (GDoT_MaxIndex + 1)
          • Set GDoT_Int = GDoT_MaxIndex
        • Else - Actions
          • Set GDoT_Int = GDoT_Recycle[0]
          • Set GDoT_Recycle[0] = GDoT_Recycle[GDoT_Int]
      • Set GDoT_Active[GDoT_Int] = True
      • -------- --------
      • -------- store everything we need... --------
      • Set GDoT_Caster[GDoT_Int] = GDoTRegister_Caster
      • Set GDoT_Target[GDoT_Int] = GDoTRegister_Target
      • -------- --------
      • Special Effect - Create a special effect attached to the GDoTRegister_FxAttachPoint of GDoTRegister_Target using GDoTRegister_DmgEffect
      • Set GDoT_DmgFx[GDoT_Int] = (Last created special effect)
      • -------- --------
      • Set GDoT_Freq[GDoT_Int] = GDoTRegister_DmgFrequency
      • Set GDoT_DmgFrequency[GDoT_Int] = GDoTRegister_DmgFrequency
      • -------- I use counter insteads duration for accurate damage. --------
      • Set GDoT_HitAmount[GDoT_Int] = (Integer((GDoTRegister_Duration / GDoTRegister_DmgFrequency)))
      • -------- --------
      • Set GDoT_DpS[GDoT_Int] = (GDoTRegister_TotalDamage / (Real(GDoT_HitAmount[GDoT_Int])))
      • Set GDoT_AttackType[GDoT_Int] = GDoTRegister_AttackType
      • Set GDoT_DamageType[GDoT_Int] = GDoTRegister_DamageType
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_MaxIndex Equal to 1
        • Then - Actions
          • Custom script: call TimerStart(udg_GDoT_Iterator, udg_GDoT_INTERVAL, true, function GDoTOnIterate)
        • Else - Actions
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTRegister takes nothing returns nothing
      • -------- wrapper --------
      • -------- you can config these --------
      • Set GDoTRegister_FxAttachPoint = origin
      • Set GDoTRegister_DmgFrequency = 1.00
      • Set GDoTRegister_AttackType = Spells
      • Set GDoTRegister_DamageType = Normal
      • Set GDoT_UseWrapper = False
      • Custom script: call GDoTRegisterEx()

How to use? Here some Demo
  • Demo Type Wrapper
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Thunder Clap
    • Actions
      • Set dontCopy_Unit[1] = (Triggering unit)
      • Set dontCopy_tempLoc[1] = (Position of dontCopy_Unit[1])
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 512.00 of dontCopy_tempLoc[1] matching ((Matching unit) Not equal to dontCopy_Unit[1])) and do (Actions)
        • Loop - Actions
          • Set GDoTRegister_Caster = dontCopy_Unit[1]
          • Set GDoTRegister_Target = (Picked unit)
          • Set GDoTRegister_DmgEffect = Abilities\Spells\Human\Banish\BanishTarget.mdl
          • Set GDoTRegister_TotalDamage = 500.00
          • Set GDoTRegister_Duration = 2.00
          • Set GDoT_UseWrapper = True
          • Trigger - Run GDoT <gen> (ignoring conditions)

  • Demo Type Advanced
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Thunder Clap
    • Actions
      • Set dontCopy_Unit[1] = (Triggering unit)
      • Set dontCopy_tempLoc[1] = (Position of dontCopy_Unit[1])
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 512.00 of dontCopy_tempLoc[1] matching ((Matching unit) Not equal to dontCopy_Unit[1])) and do (Actions)
        • Loop - Actions
          • Set GDoTRegister_Caster = dontCopy_Unit[1]
          • Set GDoTRegister_Target = (Picked unit)
          • Set GDoTRegister_DmgEffect = Environment\LargeBuildingFire\LargeBuildingFire1.mdl
          • Set GDoTRegister_TotalDamage = 500.00
          • Set GDoTRegister_Duration = 5.00
          • -------- advanced --------
          • Set GDoTRegister_FxAttachPoint = origin
          • Set GDoTRegister_DmgFrequency = 0.25
          • Set GDoTRegister_AttackType = Spells
          • Set GDoTRegister_DamageType = Fire
          • Trigger - Run GDoT <gen> (ignoring conditions)
          • Unit - Add Slow Aura to (Picked unit)
As you can see, there is two demo over there. The first one the way with wrapper and the second is with a little advanced options.
Contents

GUI Damage over Timer [GDoT] (Map)

I trying to update this system because I detected a problem with the GUI linked list,
here is the new trigger
  • GDoT
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • GDoTRegister_Caster Not equal to No unit
              • GDoTRegister_Target Not equal to No unit
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • And - All (Conditions) are true
                • Conditions
                  • GDoT_UseWrapper Equal to True
            • Then - Actions
              • Custom script: call ExecuteFunc("GDoTRegister")
            • Else - Actions
              • Custom script: call ExecuteFunc("GDoTRegisterEx")
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • GDoT_DebugMode Equal to True
            • Then - Actions
              • Game - Display to (All players) the text: GUI DoT: Error! App...
            • Else - Actions
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTOnIterate takes nothing returns nothing
      • Set GDoT_Current = GDoT_Next[0]
      • -------- --------
      • Custom script: loop
      • Custom script: exitwhen udg_GDoT_Current == 0
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • And - All (Conditions) are true
            • Conditions
              • GDoT_HitAmount[GDoT_Current] Greater than 0
              • (GDoT_Target[GDoT_Current] is alive) Equal to True
        • Then - Actions
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • GDoT_Freq[GDoT_Current] Greater than or equal to GDoT_DmgFrequency[GDoT_Current]
            • Then - Actions
              • Unit - Cause GDoT_Caster[GDoT_Current] to damage GDoT_Target[GDoT_Current], dealing GDoT_DpS[GDoT_Current] damage of attack type GDoT_AttackType[GDoT_Current] and damage type GDoT_DamageType[GDoT_Current]
              • -------- --------
              • -------- on damage event --------
              • Set GDoTEvent_OnDamage = 1.00
              • Set GDoTEvent_Caster = GDoT_Caster[GDoT_Current]
              • Set GDoTEvent_Target = GDoT_Target[GDoT_Current]
              • Set GDoTEvent_DpS = GDoT_DpS[GDoT_Current]
              • Set GDoTEvent_OnDamage = 0.00
              • -------- --------
              • Set GDoT_HitAmount[GDoT_Current] = (GDoT_HitAmount[GDoT_Current] - 1)
              • Set GDoT_Freq[GDoT_Current] = 0.00
            • Else - Actions
              • Set GDoT_Freq[GDoT_Current] = (GDoT_Freq[GDoT_Current] + GDoT_INTERVAL)
          • -------- --------
        • Else - Actions
          • Set GDoTEvent_EndDoT = 1.00
          • Set GDoTEvent_Caster = GDoT_Caster[GDoT_Current]
          • Set GDoTEvent_Target = GDoT_Target[GDoT_Current]
          • Set GDoTEvent_DpS = GDoT_DpS[GDoT_Current]
          • Set GDoTEvent_EndDoT = 0.00
          • -------- --------
          • Set GDoT_Prev[GDoT_Next[GDoT_Current]] = GDoT_Prev[GDoT_Current]
          • Set GDoT_Next[GDoT_Prev[GDoT_Current]] = GDoT_Next[GDoT_Current]
          • -------- --------
          • Special Effect - Destroy GDoT_DmgFx[GDoT_Current]
          • Set GDoT_Caster[GDoT_Current] = No unit
          • Set GDoT_Target[GDoT_Current] = No unit
          • Set GDoT_Freq[GDoT_Current] = 1.00
          • Set GDoT_DmgFrequency[GDoT_Current] = 1.00
          • Set GDoT_HitAmount[GDoT_Current] = 0
          • Set GDoT_DpS[GDoT_Current] = 0.00
          • Set GDoT_AttackType[GDoT_Current] = Spells
          • Set GDoT_DamageType[GDoT_Current] = Normal
          • -------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • GDoT_Current Equal to GDoT_Index
            • Then - Actions
              • Set GDoT_Index = (GDoT_Index - 1)
            • Else - Actions
      • Set GDoT_Current = GDoT_Next[GDoT_Current]
      • -------- --------
      • Custom script: endloop
      • -------- --------
      • -------- pause/stop the timer when there's nothing on the list --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_Index Equal to 0
        • Then - Actions
          • Countdown Timer - Pause GDoT_Iterator
        • Else - Actions
      • -------- --------
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTRegisterEx takes nothing returns nothing
      • -------- increase the instance by 1 --------
      • Set GDoT_Index = (GDoT_Index + 1)
      • -------- --------
      • -------- store everything we need... --------
      • Set GDoT_Caster[GDoT_Index] = GDoTRegister_Caster
      • Set GDoT_Target[GDoT_Index] = GDoTRegister_Target
      • -------- --------
      • Special Effect - Create a special effect attached to the GDoTRegister_FxAttachPoint of GDoTRegister_Target using GDoTRegister_DmgEffect
      • Set GDoT_DmgFx[GDoT_Index] = (Last created special effect)
      • -------- --------
      • Set GDoT_Freq[GDoT_Index] = GDoTRegister_DmgFrequency
      • Set GDoT_DmgFrequency[GDoT_Index] = GDoTRegister_DmgFrequency
      • -------- I use counter insteads duration for accurate damage. --------
      • Set GDoT_HitAmount[GDoT_Index] = (Integer((GDoTRegister_Duration / GDoTRegister_DmgFrequency)))
      • -------- --------
      • Set GDoT_DpS[GDoT_Index] = (GDoTRegister_TotalDamage / (Real(GDoT_HitAmount[GDoT_Index])))
      • Set GDoT_AttackType[GDoT_Index] = GDoTRegister_AttackType
      • Set GDoT_DamageType[GDoT_Index] = GDoTRegister_DamageType
      • -------- --------
      • -------- add the instance to the list --------
      • Set GDoT_Next[GDoT_Index] = 0
      • Set GDoT_Prev[GDoT_Index] = GDoT_Prev[0]
      • Set GDoT_Next[GDoT_Prev[0]] = GDoT_Index
      • Set GDoT_Prev[0] = GDoT_Index
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • GDoT_Index Equal to 1
        • Then - Actions
          • Custom script: call TimerStart(udg_GDoT_Iterator, udg_GDoT_INTERVAL, true, function GDoTOnIterate)
        • Else - Actions
      • Custom script: endfunction
      • -------- --------
      • Custom script: function GDoTRegister takes nothing returns nothing
      • -------- wrapper --------
      • -------- you can config these --------
      • Set GDoTRegister_FxAttachPoint = origin
      • Set GDoTRegister_DmgFrequency = 1.00
      • Set GDoTRegister_AttackType = Spells
      • Set GDoTRegister_DamageType = Normal
      • Set GDoT_UseWrapper = False
      • Custom script: call GDoTRegisterEx()
but still, I can't solve it. The GDoT_Index just keep increasing.
Can you help me

EDIT: Update: Solved!
can you check the code :)
 
Last edited:
Actually, this system is a mistake. There's already ton of system of this kind out there and they are even better.
If you guys have some idea that can make this system acceptable as approved system, I gladly to hear it. :)
And, about events in my system, can you guys tell me if I did something wrong.

@zv27: This is a system that can apply a DoT (Damage over Time) easily. You can see the demo I just provided in the description.
Also, except damaging units, you can also do something periodically by using the event. Like, creating a pulse of missile on every 0.25 s.
I haven't try this yet, but I think with the onDamage and EndDoT event, user can make a easy MUI spell.

@Chaosy: I don't know what to say about that easy method. From my imagination :) , that method will just wait and damage target (with just one hit) like a timed bomb. Can you tell me why use wait. From what I know, waits is forbidden.


EDIT: Updated!:
-fixed indexing problem
-fixed some minor problems
 
Last edited:
In jass it would be something like:

function DoT takes real dmg, unit target, real interval, integer numberOfTicks return nothing
//^ I am pretty sure those are considered local
local integer i = 0
loop
exitwhen i == numberofTicks
call TriggerSleepAction(interval)
deal dmg damage to target
set i = i + 1
endloop
endfunction

Waits can be up to 0.27 seconds inaccurate (at least that's what I read somewhere) which is why they are not used most of the time. But if it can cut down the code size to a third.. I'd say it's a decent trade.
 
Ahh, now I understand. But still, my thought says using waits is not acceptable and I don't think that method can replace this kind of system as long as the accuration is the important thing in order to create a smooth and clean spell .
If there is 20 spell with DoT, 20 waits will loop.:eek:

And like you said waits is 0.27s inaccurate. I can't imagine a spell that requires high damage frequency.
 
I think there are some cases where waits are acceptable. Though they are few.
Still, even without a wait I think you could cut down your code in half at least.

This would be the loop:

every 0.03 seconds
pick every unit in myGroup
set u = picked unit
set h = handle of u
set count = load from hashtable with keys h 0 + 0.03
save count in hashtable with keys h and 0
set interval = load from hashtable with keys h 1
if count is greater or equal to interval
save 0 in hashtavle with keys h and 0
deal damage to u
set completedTicks = load from hashtable with keys h 2 + 1
save completedTicks in hashtable with keys h 2
if completedTicks is greater than or equal to load fro mhashtable with keys h 3
remove u from group, dot is finished
endif
endif

there are some lazy coding in that but the concept would be the same. Just move some stuff around for minimal bonus speed
 
I will try and I'll add some sample spells that uses GDoT and its events, it will be the last update, I think (on second thought, I think its better to remove this system from Hive), and can I ask. Which is faster, Index or Hashtable? I'm confused:confused:
There is no way that the human brain registers the difference in speed between the above,
but if you ask me,
1-0 in favor of the index in the first half of the match hahaha.
Of course a little humor does not hurt.
Now seriously, both the fine.
And one more thing. damage type fire = damage type magic no difference(
refers to your demo code)
 
(on second thought, I think its better to remove this system from Hive)

Can you make that happen. :)

Btw, I'm going to upload a GUI version of Rapid Sound system. It is a conversion from vJass RapidSound by Quilnez.
[vJASS] - [Snippet] RapidSound
Is there any system out there that is similiar as my upcoming system? I googled and I saw nothing.
 
Back
Top