• 🏆 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!

[JASS] DoT System

Status
Not open for further replies.
Level 10
Joined
Jan 21, 2007
Messages
576
Alright so I have been practicing my vJass for the last half week or so and have been trying to make spells for practice, on of them required a dot that was a bit more versatile then using Unholy Frenzy.

So I decided to make a DoT system, I am pretty overwhelmingly happy at how well this went. My ego is a bit bigger then it should be atm (even though this isn't anything to special for most coders).

Alright so anyways here is the code:
JASS:
library EasyDot initializer Init
/////////////////////////////////////////////////////////////////////////////////////
//                                   EasyDot                                       //
//                                   By: Gost                                      //
// A simple system allowing the user to apply a dot to a target with a single line //
//                         of code, or take one away.                              //
//                                                                                 //
//        Requirements: JNGP (If you plan on editing or using this that is.)       //
//                                   course.                                       //
//                                                                                 //
// The LowestInteral global is the minimum amount of time between two ticks of a   //
// DoT possible. This can be lowered down however low you want but there really is //
//                    normaly no need for an interval below .05                    //
//                                                                                 //
//                     To a DoT to a unit use this function                        //
// function CreateDot takes unit Caster, widget Target, real Dpi, real Interval,   //
//     real Dur, string SpecEfec, string AttachPoint, AttackType returns nothing   //
//                                                                                 //
//  Dpi is the damage per interval, interval is how long between each instance of  //      
//                  damage, and duration is how long the dot lasts                 //
//                                                                                 //
//                                  Version: 1.0                                   //
//                                                                                 //
//                                                                                 //
/////////////////////////////////////////////////////////////////////////////////////
//==============================================================================================================================
globals
    private Dot array DOTS
    private integer   total = 0
    //SETUP
    private real LowestInterval = .05
    //ENDSETUP
endglobals
//==============================================================================================================================
struct Dot
widget       Target
unit         Caster
real         Dpi
real         Interval
real         Dur
real         CurrentWait = 0
string       SpecEfec
string       AttachPoint
attacktype   AttackType
static timer Tim         = null

static method Loop takes nothing returns nothing
    local Dot dat
    local integer i = 0
    loop
        exitwhen i >= total
        set dat = DOTS[i]
        if GetWidgetLife(dat.Target) <= .405 or dat.Dur <= 0 then
            if dat.Dpi < 0 then
                call SetWidgetLife(dat.Target, GetWidgetLife(dat.Target) - dat.Dpi)
            else
                call UnitDamageTarget(dat.Caster, dat.Target, dat.Dpi, false, false, dat.AttackType, DAMAGE_TYPE_NORMAL, null)
            endif
            call DestroyEffect(AddSpecialEffectTarget(dat.SpecEfec, dat.Target, dat.AttachPoint))
            set dat.Target      = null
            set dat.Caster      = null
            set dat.Dpi         = 0
            set dat.Interval    = 0
            set dat.Dur         = 0
            set dat.CurrentWait = 0
            set dat.SpecEfec    = ""
            set dat.AttachPoint = ""
            set dat.AttackType  = null
            set total = total - 1
            set DOTS[i] = DOTS[total]
            set i = i - 1
        else
            if dat.CurrentWait >= dat.Interval then
                if dat.Dpi < 0 then
                    call SetWidgetLife(dat.Target, GetWidgetLife(dat.Target) - dat.Dpi)
                else
                    call UnitDamageTarget(dat.Caster, dat.Target, dat.Dpi, false, false, dat.AttackType, DAMAGE_TYPE_NORMAL, null)
                endif
                call DestroyEffect(AddSpecialEffectTarget(dat.SpecEfec, dat.Target, dat.AttachPoint))
                set dat.CurrentWait = 0
                set dat.Dur = dat.Dur - LowestInterval
                set dat.CurrentWait = dat.CurrentWait + LowestInterval
            else
               set dat.CurrentWait = dat.CurrentWait + LowestInterval
               set dat.Dur = dat.Dur - LowestInterval
            endif
        endif
            set i = i + 1
    endloop
            
            if total == 0 then
                call PauseTimer(dat.Tim)
            endif
endmethod

endstruct
//==============================================================================================================================
function CreateDot takes unit Caster, widget Target, real Dpi, real Interval, real Dur, string SpecEfec, string AttachPoint, attacktype AttackType returns nothing
        local Dot dat
        set dat             = Dot.create()
        set dat.Target      = Target
        set dat.Caster      = Caster
        set dat.Dpi         = Dpi
        set dat.Interval    = Interval
        set dat.Dur         = Dur
        set dat.SpecEfec    = SpecEfec
        set dat.AttachPoint = AttachPoint
        set DOTS[total]     = dat
        if total == 0 then
            call TimerStart(Dot.Tim, LowestInterval, true, function Dot.Loop)
        endif
        set total = total + 1
endfunction
//==============================================================================================================================
function RemoveDot takes unit u returns nothing
    local integer i = 0
    local Dot dat
    loop
        exitwhen i >= total
        if DOTS[i].Target == u then
            set dat = DOTS[i]
            set total = total - 1
            set DOTS[i] = DOTS[total]
            call dat.destroy()
        endif
        set i = i + 1
    endloop
endfunction
//==============================================================================================================================
private function Init takes nothing returns nothing
    set Dot.Tim = CreateTimer()
endfunction
//==============================================================================================================================
endlibrary
The main function takes up to 8 arguments which are explained within the code.

All critiques and suggestions on ways of improvements are encouraged,
 
Last edited:
Level 10
Joined
Jan 21, 2007
Messages
576
Yea I know there are other systems, but in my map I am coding everything myself. You learn quite a bit o_O, and thanks for pointing that out that could mess shit up pretty bad in longer.... spam happy maps.

EDIT: And my system is a bit different because instead of giving a total damage and duration, you give a Damage per interval, interval, and duration. Allowing more complex combinations of DoTs. (For example one spell that does 15 damage every second, and 50 damage every 5 seconds.)
 
Level 10
Joined
Jan 21, 2007
Messages
576
Yea I know there are other systems, but in my map I am coding everything myself. You learn quite a bit o_O, and thanks for pointing that out that could mess shit up pretty bad in longer.... spam happy maps.

EDIT: And my system is a bit different because instead of giving a total damage and duration, you give a Damage per interval, interval, and duration. Allowing more complex combinations of DoTs. (For example one spell that does 15 damage every second, and 50 damage every 5 seconds.)

EDIT2:
first: There are many other dot systems
second: in the if thing when the struct should be destroyed you forget to decrease the integer i
Actualy I looked agian and you had me confused, I don't need to decrease the integer i, that is just used for looping. The variable that holds the number of structs is "total" and that gets decreased.
 
Level 10
Joined
Jan 21, 2007
Messages
576
@xD.Schurke: Both of ours do the exact same thing, except mine can take attack and damage type arguments =p.
EDIT: @Slaydon .....no.
 
Level 10
Joined
Jan 21, 2007
Messages
576
Ah, thats cool. What line in your code actualy does the damaging / healing because I can't pick it out.

EDIT: Updated code, when you call the function if you put in -damage it heals the unit.
 
Last edited:
Level 10
Joined
Jan 21, 2007
Messages
576
Alright I was peaking at the jasshelper manual and I understand function interfaces, pretty cool. If you aren't using a damage action, how do you associate the damage with the caster. I know you could in this trigger, but if a unit died and you wanted to get the killing unit/player how would you do that with your system, especialy if that unit had more then 1 dot on it.
 
Status
Not open for further replies.
Top