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
 

Flare

Stops copies me!
Reaction score
662
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
 

Matrix

New Member
Reaction score
5
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
 

Flare

Stops copies me!
Reaction score
662
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
 

Matrix

New Member
Reaction score
5
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 =)
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> 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.. :/
 

Flare

Stops copies me!
Reaction score
662
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.

      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