System DamageUnitOverTime

Matrix

New Member
Reaction score
5
This system allows u not only to damage units over time but also to create special effects and to make the damage non stackable! These are the features of the system

So Pros:
1) System uses structs and not cache
2) System allows u to create speciall effects
3) System allows u to make it non-stackable

Cons:
1) System uses JassNewgenPack
2) System requires CSData+CSSafety

JASS:
//**********************************************************
//*                                                        *
//*         D A M A G E  T A R G E T  O V E R  T I M E     *
//*                       Actual Code                      *
//*                        v1.01                           *
//*                                                        *
//*                      By: Matrix                        *
//*                                                        *
//**********************************************************
library DamageTargetOverTime uses CSSafety
private struct data
unit c
unit u
timer t
real dmg
boolean attack
boolean ranged
damagetype DamageType
attacktype AttackType
weapontype WeaponType
real runned
real duration
real howoften
integer Buff
string Effect
string where
string stack
effect e
static method create takes unit c, unit u, real dmg, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real duration, real howoften, string stack,integer Buff, string Effect, string where returns data
    local data dat = data.allocate()
    local data d = GetCSData(u)
    if stack!=null and stack==d.stack then
       call data.destroy(d)
    endif
    set dat.t = NewTimer()
    set dat.u = u
    set dat.c = c
    set dat.dmg = dmg
    set dat.attack=attack
    set dat.ranged=ranged
    set dat.AttackType=AttackType
    set dat.DamageType=DamageType
    set dat.WeaponType=WeaponType
    set dat.duration = duration
    set dat.howoften=howoften
    set dat.Buff=Buff
    set dat.Effect=Effect
    set dat.where=where
    set dat.stack=stack
    set dat.runned=0
    if (Effect!=null or Effect!="") and (where!=null or where!="") then
       set dat.e=AddSpecialEffectTarget(Effect,u,where)
    endif
    call SetCSData(dat.t,dat)
    call SetCSData(u,dat)
    return dat
endmethod
method onDestroy takes nothing returns nothing
call DestroyEffect(.e)
call ReleaseTimer(.t)
endmethod
endstruct
private function Child takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local data dat = GetCSData(t)
    set dat.runned=dat.runned+dat.howoften
    if dat.runned>=dat.duration or GetUnitState(dat.u,UNIT_STATE_LIFE)<=.405 or (dat.Buff!=0 and GetUnitAbilityLevel(dat.u,dat.Buff)==0) then
       call data.destroy(dat)
    else
       call DestroyEffect(dat.e)
       set dat.e=AddSpecialEffectTarget(dat.Effect,dat.u,dat.where)
       call UnitDamageTarget(dat.c, dat.u, dat.dmg, dat.attack, dat.ranged, dat.AttackType, dat.DamageType, dat.WeaponType)
    endif
    set t = null
endfunction
function SetAttackType takes unit target, attacktype AttackType returns nothing
local data dat = GetCSData(target)
set dat.AttackType=AttackType
endfunction
function SetDamageType takes unit target, damagetype DamageType returns nothing
local data dat = GetCSData(target)
set dat.DamageType=DamageType
endfunction
function SetDamage takes unit target, real amount returns nothing
   local data dat = GetCSData(target)
   set dat.dmg=amount
endfunction
function SetDuration takes unit target, real duration returns nothing
   local data dat = GetCSData(target)
   set dat.duration=duration
endfunction
function SetEffect takes unit target, string Effect, string where returns nothing
   local data dat = GetCSData(target)
   set dat.Effect = Effect
   set dat.where = where
endfunction
function DamageOverBuffEx takes unit whichUnit, unit target, real amount, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real howoften,integer Buff,string stack, string Effect, string where returns nothing
call TimerStart(data.create(whichUnit, target,amount,attack,ranged, AttackType, DamageType,WeaponType, 9999999, howoften,stack, Buff,Effect, where).t, howoften, true, function Child)
endfunction
function DamageOverBuff takes unit whichUnit, unit target, real amount, attacktype AttackType, damagetype DamageType, integer Buff, real howoften returns nothing
call TimerStart(data.create(whichUnit, target,amount,true,false, AttackType, DamageType, null, 99999999, howoften,null,Buff,"","").t, howoften, true, function Child)
endfunction
function DamageOverTimeEx takes unit whichUnit, unit target, real amount, boolean attack, boolean ranged, attacktype AttackType, damagetype DamageType, weapontype WeaponType, real duration, real howoften,string stack, string Effect, string where returns nothing
call TimerStart(data.create(whichUnit, target,amount,attack,ranged, AttackType, DamageType,WeaponType, duration, howoften,stack,0, Effect, where).t, howoften, true, function Child)
endfunction
function DamageOverTime takes unit whichUnit, unit target, real amount, attacktype AttackType, damagetype DamageType, real duration, real howoften returns nothing
call TimerStart(data.create(whichUnit, target,amount,true,false, AttackType, DamageType, null, duration, howoften,null,0,"","").t, howoften, true, function Child)
endfunction
endlibrary
Download DamageUnitOverTime
 
Why are you using a string for stacking? Why not use a boolean? The stacking option is pretty restricting too since it's all or nothing (i.e. separate spells can conflict if the stack option is true). IMO, a buff/ability-check would be much more effective, e.g.
JASS:
//Take a buffer skill argument (this is taken from a DoT system I made for myself)
public function Start takes unit caster, unit target, real dps, real dmgint, real duration, string sfx, string attachpt, integer bskillid, integer bid, attacktype at, damagetype dt, weapontype wt returns nothing

//And the stack check
        if GetUnitAbilityLevel (data<i>.target, bskillid) &gt; 0 and data<i>.target == target then
            set data<i>.caster = caster
            set data<i>.target = target
            set data<i>.dps = dps
            set data<i>.dmgint = dmgint
            set data<i>.curdur = 0
            set data<i>.maxdur = duration
            set newinstance = false
            set skiploop = true
        endif

</i></i></i></i></i></i></i></i>


That will allow separate spells to stack with each other as intended, but the same spell will not stack, and it allows for the use of a buff :)

JASS:
attacktype AttackType

H2I(AttackType)

ConvertAttackType(dat.AttackType)


Please, explain why you are doing all that? Why not just store the attacktype as a struct member of type attacktype rather than using stuff that you don't even need
 
because in CSData something was that its not good to store attactype and damagetypes if I understand right?

string is because if u dont want to stack the damge from the spell frostnova u write 'frostnova" and whe u dont want to stack damge from burningspear u write "burningSpear" but if u just write true or false it will not stack with all spells which isn't good
 
because in CSData something was that its not good to store attactype and damagetypes if I understand right?

Store it as a struct member -.-' You aren't actually attaching data to the attacktype, damagetype or weapontype, you are only attaching to timer and unit (and that won't change)

string is because if u dont want to stack the damge from the spell frostnova u write 'frostnova" and whe u dont want to stack damge from burningspear u write "burningSpear" but if u just write true or false it will not stack with all spells which isn't good

Ah, never thought of it that way, nice idea :p
 
Store it as a struct member -.-' You aren't actually attaching data to the attacktype, damagetype or weapontype, you are only attaching to timer and unit (and that won't change)

will be fixed. (in few days)

thx for reply =)
 
> 2) System requires CSData+CSSafety
That's not a Con.
> 1) System uses JassNewgenPack
that's not a Con either.

It would be better if you use a buff check, because with buffs you can stop the dps with an ability (like Dispell and such) and thus make it balanced for melee games. But if you use a buff check you need to think of how to use it with abilities with projectiles (such as Acid Bomb), because they give a buff after some time. :rolleyes:

JASS:
call PauseTimer(.t)
call ReleaseTimer(.t)

Isn't it paused with ReleaseTimer? Why do you pause it 2 times?

Plus, some people may want to change values during the effect. Why not include methods like SetDamage, SetAttackType, SetEffect?

And please indent your code. It's horrible in this way.. :/
 
JASS:
private function Child takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local data dat = GetCSData(t)
    set dat.runned=dat.runned+dat.howoften
    if dat.runned&gt;=dat.duration or GetWidgetLife(dat.u)&lt;=.405 then
       call data.destroy(dat)
    else
       call DestroyEffect(dat.e)
       set dat.e=AddSpecialEffectTarget(dat.Effect,dat.u,dat.where)
       call UnitDamageTarget(dat.c, dat.u, dat.dmg, dat.attack, dat.ranged, ConvertAttackType(dat.AttackType), ConvertDamageType(dat.DamageType), ConvertWeaponType(dat.WeaponType))
       call SetCSData(t,dat)
    endif
endfunction


Why are you re-attaching data to the timer? I see no reason to do it, the data isn't going anywhere.

And you didn't null t
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    News portal has been retired. Main page of site goes to Headline News forum now
  • The Helper The Helper:
    I am working on getting access to the old news portal under a different URL for those that would rather use that for news before we get a different news view.
  • Ghan Ghan:
    Easily done
    +1
  • The Helper The Helper:
    https://www.thehelper.net/pages/news/ is a link to the old news portal - i will integrate it into the interface somewhere when i figure it out
  • Ghan Ghan:
    Need to try something
  • Ghan Ghan:
    Hopefully this won't cause problems.
  • Ghan Ghan:
    Hmm
  • Ghan Ghan:
    I have converted the Headline News forum to an Article type forum. It will now show the top 20 threads with more detail of each thread.
  • Ghan Ghan:
    See how we like that.
  • The Helper The Helper:
    I do not see a way to go past the 1st page of posts on the forum though
  • The Helper The Helper:
    It is OK though for the main page to open up on the forum in the view it was before. As long as the portal has its own URL so it can be viewed that way I do want to try it as a regular forum view for a while
  • Ghan Ghan:
    Yeah I'm not sure what the deal is with the pagination.
  • Ghan Ghan:
    It SHOULD be there so I think it might just be an artifact of having an older style.
  • Ghan Ghan:
    I switched it to a "Standard" article forum. This will show the thread list like normal, but the threads themselves will have the first post set up above the rest of the "comments"
  • The Helper The Helper:
    I don't really get that article forum but I think it is because I have never really seen it used on a multi post thread
  • Ghan Ghan:
    RpNation makes more use of it right now as an example: https://www.rpnation.com/news/
  • The Helper The Helper:
  • The Helper The Helper:
    What do you think Tom?
  • tom_mai78101 tom_mai78101:
    I will have to get used to this.
  • tom_mai78101 tom_mai78101:
    The latest news feed looks good

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top