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

[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:
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.)
 
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.
 
@xD.Schurke: Both of ours do the exact same thing, except mine can take attack and damage type arguments =p.
EDIT: @Slaydon .....no.
 
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:
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.
Back
Top