System DOT - Damage Over Time

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Damage Over Time System v1.1

This is supposed to be a remake of my DPS system because it was not good enough. So I bring you this fresh new system that allows you to damage a unit for a specific duration every specific second(s) if it has a specific buff. It has a variety of Set and Get functions that allow you to control the system almost completely. I hope this one is better than the last one...

Requires:
- JASS NewGen Editor
- ABCT v2.0 (or higher)
- PUI v4.2 (or higher)

Implementation Instructions:
JASS:

//==============================================================================
//        Damage Over Time System [v 1.1] by cr4xzZz
//==============================================================================

' PURPOSE:

 - Creating damage over time spells the easy way
 - Save time on damage over time spells
 
 ' HOW IT WORKS:
 
  - When you call the start function ( DOT_Start() ) 
    a periodic timer will run every 0.1 seconds for 
    5 seconds, checking each period if the target
    has the assigned buff you chose. If in that time
    the target is applied the buff then DOT starts
    with all the values you used. If the target does 
    not recieve that buff on time (5 secs) then the
    function is cancelled. These values can be
    changed to satisfy your needs (look for a 
    comment in the globals in the DOT trigger). 
  - After the normal damaging starts the system
    checks if the target has the assigned buff 
    each time before it damages it. If the target
    does not have that buff then the damaging
    stops. The system stops if the buff is dispelled,
    too (obviously). 
  - The system attaches all values to array globals
    thanks to PUI. That way they can easily be used
    for Set and Get functions.
    
' HOW TO USE:

 - call DOT_Start( DAMAGER, TARGET, PERIOD, DURATION, BUFF, DAMAGE, ATTACK TYPE, DAMAGE TYPE, MELEE?, RANGED?, EFFECT, ATTACHMENT POINT)
    * DAMAGER - unit; The unit that is going to damage something
    * TARGET - unit; The target unit that is going to be damaged
    * PERIOD - real; Period per damaging 
    * DURATION - real; Maximum duration of the damaging
    * BUFF - integer; The buff that is required for the damaging to work
        // raw code !
        //! IF THE TARGET DOES NOT HAVE THAT
        //! BUFF THEN THE DAMAGING STOPS
    * DAMAGE - real; The damage dealt per each period
        //! NOTE THAT THIS IS NOT THE MAX DAMAGE
    * ATTACK TYPE - attacktype; The attack type of the damaging
    * DAMAGE TYPE - damagetype; The damage type of the damaging
    * MELEE? - boolean; If it is a melee type damage 
    * RANGED? - boolean; If it i s a ranged type damage
        // these two booleans must be true or false
    * EFFECT - string; Special effect string
    * ATTACHMENT POINT - string; The attachment point of the special effect
    
' OTHER FUNCTIONS:

//! Note that these functions work only on the TARGET
//! and NOT on the DAMAGER ! This means that the
//! unit argument should be a TARGET that has DOT 
//! on it.

 - call DOT_SetDamage(unit TARGET, real AMOUNT)
 - call DOT_SetDuration(unit TARGET, integer AMOUNT)
 - call DOT_SetAttackType(unit TARGET, attacktype ATTACK TYPE)
 - call DOT_SetDamageType(unit TARGET, damagetype DAMAGE TYPE)
    // this must be true or false
 - call DOT_SetMelee(unit TARGET, boolean MELEE?)
    // this must be true or false
 - call DOT_SetRange(unit TARGET, boolean RANGED?)
 - call DOT_SetEffect(unit TARGET, string EFFECT)
 - call DOT_SetAttachmentPoint(unit TARGET, string ATTACHMENT POINT)

 
 - call DOT_GetDamage(unit TARGET) -> real AMOUNT
 - call DOT_GetDuration(unit TARGET) -> integer AMOUNT
 - call DOT_GetAttackType(unit TARGET) -> attacktype ATTACK TYPE
 - call DOT_GetDamageType(unit TARGET) -> damagetype DAMAGE TYPE
 - call DOT_GetMelee(unit TARGET) -> boolean MELEE?
 - call DOT_GetRange(unit TARGET) -> boolean RANGED?
 - call DOT_GetEffect(unit TARGET) -> string EFFECT
 - call DOT_GetAttachmentPoint(unit TARGET) -> string ATTACHMENT POINT
 
 - call DOT_Stop(unit TARGET) // stop all assigned DOT functions
 - call DOT_AddDuration(unit TARGET, integer AMOUNT) // add more duration to the damaging
 
 ' PROS:
    - Easy to use 
    - A lot customizeable
    - Can be fully controlled
' CONS:
    - None? (cannot think of any...)
    
' HOW TO IMPLEMENT: 
    - Copy the ABCT and PUI systems if you
      do not have them
    - Copy the DOT trigger in your map
    
' CREDITS TO:
    - Cohadar for ABCT v2.0 and PUI v4.2
    
' CHANGELOG:
    - v1.0: First release
    - v1.1: No changes at all. Just uses the newest version of ABCT (v 2.0)

Code:
JASS:

//==============================================================================
//        Damage Over Time System [v 1.1] by cr4xzZz
//==============================================================================


library DOT uses ABCT, PUI

globals
    private real array DPP
    private integer array DURATION
    private attacktype array ATTACK
    private damagetype array DAMAGE
    private string array EFFECT
    private string array POINT
    private boolean array MELEE
    private boolean array RANGE
// - Can be configured - 
    private constant real CHECK_PERIOD = 0.1 //period for buff checkup
    private constant real MAX_CHECK_TIME = 5. //max wait time for buff checkup
endglobals
// - DO NOT change anything below this line !!! -

private struct SysStruct
    unit damager
    unit target
    real period
    integer buffz
    integer temp
    timer clock = CreateTimer()
    
    static method create takes unit whichUnit, unit whichTarg, integer whichBuff, real whichPeriod returns SysStruct
        local SysStruct data = SysStruct.allocate()
        set data.damager = whichUnit
        set data.target = whichTarg
        set data.buffz = whichBuff
        set data.period = whichPeriod
        set data.temp = R2I(MAX_CHECK_TIME / CHECK_PERIOD)
        return data
    endmethod

    method onDestroy takes nothing returns nothing
        set DURATION[GetUnitIndex(.target)] = 0
        call PauseTimer(.clock)
        call DestroyTimer(.clock)
    endmethod
endstruct

// - - - - - SET FUNCTIONS - - - - -
public function SetDamage takes unit whichUnit, real whichDmg returns nothing
    set DPP[GetUnitIndex(whichUnit)] = whichDmg
endfunction

public function SetDuration takes unit whichUnit, integer whichInt returns nothing
    if whichInt > 0 then
        set DURATION[GetUnitIndex(whichUnit)] = whichInt
    else    
        //debug call BJDebugMsg("|cffffcc00[DOT] -|r Cannot use <= 0 in SetDuration(). Use Stop() instead")
    endif
endfunction

public function SetAttackType takes unit whichUnit, attacktype whichAttackType returns nothing
    set ATTACK[GetUnitIndex(whichUnit)] = whichAttackType 
endfunction

public function SetDamageType takes unit whichUnit, damagetype whichDamageType returns nothing
    set DAMAGE[GetUnitIndex(whichUnit)] = whichDamageType
endfunction

public function SetMelee takes unit whichUnit, boolean whichBool returns nothing
    set MELEE[GetUnitIndex(whichUnit)] = whichBool
endfunction

public function SetRanged takes unit whichUnit, boolean whichBool returns nothing
    set RANGE[GetUnitIndex(whichUnit)] = whichBool
endfunction

public function SetEffect takes unit whichUnit, string whichFx returns nothing
    set EFFECT[GetUnitIndex(whichUnit)] = whichFx
endfunction

public function SetAttachmentPoint takes unit whichUnit, string whichPoint returns nothing
    set POINT[GetUnitIndex(whichUnit)] = whichPoint
endfunction

// = = = = = = = = = = = = = = = = = = = = = = = = = =
// - - - - - GET FUNCTIONS - - - - -
public function GetDamage takes unit whichUnit returns real
    return DPP[GetUnitIndex(whichUnit)] 
endfunction

public function GetDuration takes unit whichUnit returns integer
    return DURATION[GetUnitIndex(whichUnit)]
endfunction

public function GetAttackType takes unit whichUnit returns attacktype
    return ATTACK[GetUnitIndex(whichUnit)]
endfunction

public function GetDamageType takes unit whichUnit returns damagetype
    return DAMAGE[GetUnitIndex(whichUnit)]
endfunction

public function GetMelee takes unit whichUnit returns boolean
    return MELEE[GetUnitIndex(whichUnit)]
endfunction

public function GetRange takes unit whichUnit returns boolean
    return RANGE[GetUnitIndex(whichUnit)]
endfunction

public function GetEffect takes unit whichUnit returns string
    return EFFECT[GetUnitIndex(whichUnit)]
endfunction

public function GetAttachmentPoint takes unit whichUnit returns string
    return POINT[GetUnitIndex(whichUnit)]
endfunction
// = = = = = = = = = = = = = = = = = = = = = = = = = =

public function Stop takes unit whichUnit returns nothing
    set DURATION[GetUnitIndex(whichUnit)] = 0
    //debug call BJDebugMsg("|cffffcc00[DOT] -|r DOT stops")
endfunction

public function AddDuration takes unit whichUnit, integer whichInt returns nothing
    set DURATION[GetUnitIndex(whichUnit)] = DURATION[GetUnitIndex(whichUnit)] + whichInt
endfunction

private function Damage takes nothing returns boolean
    local SysStruct data = ABCT_GetData()
    local integer pui = GetUnitIndex(data.target)
    if GetWidgetLife(data.target) >= 0.405 and GetUnitAbilityLevel(data.target, data.buffz) > 0 and DURATION[pui] > 0 then
        call UnitDamageTarget(data.damager, data.target, DPP[pui], MELEE[pui], RANGE[pui], ATTACK[pui], DAMAGE[pui], null)
        call DestroyEffect(AddSpecialEffectTarget(EFFECT[pui], data.target, POINT[pui]))
    else
        call data.destroy()
        //debug call BJDebugMsg("|cffffcc00[DOT] -|r DOT finishes")
        return true
    endif
    set DURATION[pui] = DURATION[pui] - 1
    return false
endfunction

private function Check takes nothing returns boolean
    local SysStruct data = ABCT_GetData()
    if GetUnitAbilityLevel(data.target, data.buffz) > 0 then
        call ABCT_Start(function Damage, data, data.period)
        //debug call BJDebugMsg("|cffffcc00[DOT] -|r DOT starts")
        return true
    endif
    set data.temp = data.temp - 1
    if data.temp <= 0 then 
        call data.destroy()
        //debug call BJDebugMsg("|cffffcc00[DOT] -|r DOT cancelled")
        return true
    endif
    return false
endfunction

public function Start takes unit whichUnit, unit whichTarg, real whichPeriod, real whichDur, integer whichBuff, real whichDmg, attacktype whichAttackType, damagetype whichDamageType, boolean isMelee, boolean isRange, string whichFx, string whichPoint returns nothing
    local SysStruct data = SysStruct.create(whichUnit, whichTarg, whichBuff, whichPeriod)
    local integer pui = GetUnitIndex(data.target)
    set DPP[pui] = whichDmg
    set DURATION[pui] = DURATION[pui] + R2I((1. / whichPeriod) * whichDur)
    set ATTACK[pui] = whichAttackType
    set DAMAGE[pui] = whichDamageType
    set MELEE[pui] = isMelee
    set RANGE[pui] = isRange
    set EFFECT[pui] = whichFx
    set POINT[pui] = whichPoint
    call ABCT_Start(function Check, data, CHECK_PERIOD)
endfunction

endlibrary


Test map includes Frost Nova and Acid Bomb spell test (for buffs).

Changelog:
JASS:

  v1 -    First release
  v1.1 - Absolutely no changes. The system just uses the newest version of ABCT.
 

Attachments

  • [System] DOT v1..w3x
    88.1 KB · Views: 206
  • [System] DOT v1.1.w3x
    86.7 KB · Views: 223

0zaru

Learning vJASS ;)
Reaction score
60
SetDuration shouldn't add more duration to the current duration. It should set the duration :p Maybe rename it to addDuration

Maybe add a debug in front of

call BJDebugMsg("|cffffcc00[DOT] -|r DOT finishes") and the rest of bjdebugmsg..

Seems very nice :d
 

GoGo-Boy

You can change this now in User CP
Reaction score
40
Oh I said I was looking for it when it has been out already ^_°. However, sounds really great!!
2 questions though.
First, the special effects, are that the effects that occur each time the damage happens or the ones that last as long as the buff resists? (I guess the periodic damage effect, since we can manipulate the buff to correspond anyway).

Second, you have this setblabla(unit target...) getblabla(unit target) in EVERY function you give us, isn't there a way to remove them and optimize the system, since it's the same unit anyway?
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> SetDuration shouldn't add more duration to the current duration. It should set the duration
Yah, u're right ... I wanted to keep the "set" and "get" theme :D I'll fix it later cuz now I'm not on my precious computer

> ^_°. However, sounds really great
Thank you. ^^


> First, the special effects, are that the effects that occur each time the damage happens or the ones that last as long as the buff resists?
Well, the effect appears every time the unit is damaged. I forgot to mention that in the first post... Will do in the next ver. ^^

> Second, you have this setblabla(unit target...) getblabla(unit target) in EVERY function you give us, isn't there a way to remove them and optimize the system, since it's the same unit anyway?
Urm, you can use it for every unit you want. If I find a more optimized way I'll make it, but as for now I think it's fine. :eek:

EDIT: Okay, fixed SetDuration() and added AddDuration() ^^

EDIT2:
> Maybe add a debug in front of
What's the purpose of that anyway? Doesn't normal BJDebugMsg work fine?
 

0zaru

Learning vJASS ;)
Reaction score
60
Yes but It's displayed even when you are playing on b.net...

debug keyword works like this:

When you are testing the map in debug mode (JassHelper > Enable DebugMode) the parser simple deletes the word debug leaving the function call normally. But if you are not in debug mode It simple deletes that line.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> It simple deletes that line.
Ow, I see...
Well, any other comments, anybody? ^^

EDIT:
New version. Absolutely no changes. Just uses the newest version of ABCT - v2.0.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top