System DPS - Damage Per Second

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Damage Per Second System v2.5

A system that allows you to damage a unit every second for a specific duration. Has a normal and an extended function. If the target does not recieve the assigned buff in 5 seconds, DPS that was called is canceled. This will not screw in any way the instant appliement of a buff (such as frost nova). The system checks every .1 seconds if the target has that buff. If it does then everything works normally. I think 5 seconds is fair enough for some spells to travel and apply the buff (such as Acid Bomb). Thanks to Cohadar for this tip. If you want to stop the damaging then just remove the buff from the target. DPS stops if the target has the buff dispelled, too.

Test map includes Frost Nova and Acid Bomb test.
Requires: JASS NewGen, ABCT v1.2

Code:
JASS:

//==============================================================================
//        Damage Per Second System by cr4xzZz v2.5
//==============================================================================
//
//  PURPOSE:
//      - Creating dps spells or other same stuff the easy way
//      - Save you time from repeating the same timer/loop method over and over
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  HOW TO USE:
//      call DPS_Start(which damager, which target, damage (NOT dps!), duration, buff raw code, show effect or not (true or false) )
//      call DPS_StartEx(which damager, which target, damage (NOT dps!), duration, buff raw code, attack type, damage type, string effect, attachment point, show effect or not (true or false) ) 
//
//          * As you can see you can use a normal function and an extended function. 
//            The extended function has more arguments to add. If you are still confused 
//            how to use it I'll explain a bit more with the functions' arguments.
//
//      whichUnit - the unit which will damage something
//      whichTarg - the target that is going to be damaged
//      whichDmg - the full damage dealt for the specific period (NOT the damage per second)
//          * damage per second is calculated by the system
//      whichDur - the duration of the damaging
//      whichBuff - the buff that the target has to have it so it can be damaged
//          * if the target does not have that buff the damaging will stop
//      whichAttackType - the attack type used for damaging
//      whichDamageType - the damage type used for damaging
//      whichFx - the special effect string
//      whichPoint - where the effect will be attached (head, chest, etc.)
//      whichBool - should an effect be shown? MUST be true or false
//          * if the boolean flag is true then the special effect WILL appear
//          * if the boolean flag is false then the special effect WON'T appear
//
//      - If you want to stop the buff damaging then remove the 
//        buff you assigned with the Buff functions from the target unit
//      - If the target does not recieve the buff in 5 seconds from 
//        calling Buff/BuffEx then the function is cancelled
//      
//      The non-extended function uses some arguments from the system's configuration menu.
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  HOW IT WORKS:
//      When you start one of the functions a periodic timer 
//      will run for 5 seconds, checking each .1 seconds if 
//      the target has the specific buff you chose. This is 
//      used because some spells have a missile to travel
//      before the buff actually appears. 5 seconds should be enough 
//      for a missile to travel and hit a unit.Remember that this
//      system works only for a single unit. If the unit recieves the buff
//      instantly or in the 5 seconds the DPS starts. These 5 seconds 
//      can be increased/decreased but it's recommended to
//      keep them this way.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  PROS:
//      - Easy to use
//      - A lot customizeable (has extended functions)
//      - Won't mess up with other systems
//      - Stackable damage (not like slow poison)
// 
//  CONS:
//      - A bit difficult to use
//      - Requires another system to work
//      - Stackable damage (not like slow poison)
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  HOW TO USE:
//      - Copy the ABCT system if you don't have them
//      - Create a trigger named DPS
//      - Convert it to custom text and replace the text with this one
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  CREDITS TO:
//      - Cohadar for ABCT and some help
//      - 0zaru and ~GaLs~ for some help
//
//==============================================================================


library DPS uses ABCT

globals
    private constant real INTERVAL = 1.
    private constant real CHECK_PERIOD = 0.1
    private constant attacktype ATTACK = ATTACK_TYPE_MAGIC
    private constant damagetype DAMAGE = DAMAGE_TYPE_MAGIC
    private constant string EFFECT = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
    private constant string POINT = "chest"
endglobals

private struct Config
    unit cast
    unit targ
    real dps
    integer ticks
    string effe
    string point
    attacktype attack
    damagetype damage
    integer buffz
    boolean check
    integer temp = 0

    static method create takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint, boolean whichBool returns Config
        local Config store = Config.allocate()
        set store.cast = whichUnit
        set store.targ = whichTarg
        set store.dps = ((whichDmg / whichDur) * INTERVAL)
        set store.effe = whichFx
        set store.point = whichPoint
        set store.attack = whichAttackType
        set store.damage = whichDamageType
        set store.buffz = whichBuff
        set store.check = whichBool
        set store.ticks = R2I(whichDur)
        return store
    endmethod
endstruct

private function DPZ takes nothing returns boolean
    local Config store = ABCT_GetData()
    if GetWidgetLife(store.targ) >= 0.405 and GetUnitAbilityLevel(store.targ, store.buffz) > 0 and store.ticks > 0 then
        call UnitDamageTarget(store.cast, store.targ, store.dps, true, true, store.attack, store.damage, null)
        if store.check == true then 
            call DestroyEffect(AddSpecialEffectTarget(store.effe, store.targ, store.point))
        endif
    else
        call store.destroy()
        //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps stops")
        return true
    endif
    set store.ticks = store.ticks - 1
    return false
endfunction

private function Check takes nothing returns boolean
    local Config store = ABCT_GetData()
    if GetUnitAbilityLevel(store.targ, store.buffz) > 0 then
        call ABCT_Start(function DPZ, store, INTERVAL)
        //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps starts")
        return true
    endif
    set store.temp = store.temp + 1
    if store.temp > 50 then //10 checks in a second (0.1 period) for 4 seconds
        call store.destroy()
        //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps cancelled")
        return true
    endif
    return false
endfunction

public function StartEx takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint, boolean whichBool returns nothing
    local Config store = Config.create(whichUnit, whichTarg, whichDmg, whichDur, whichBuff, whichAttackType, whichDamageType, whichFx, whichPoint, whichBool)
    call ABCT_Start(function Check, store, CHECK_PERIOD)
endfunction

public function Start takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, boolean whichBool returns nothing
    local Config store = Config.create(whichUnit, whichTarg, whichDmg, whichDur, whichBuff, ATTACK, DAMAGE, EFFECT, POINT, whichBool)
    call ABCT_Start(function Check, store, CHECK_PERIOD)
endfunction

endlibrary
//==============================================================================
//        End of Damage Per Second System
//==============================================================================


Previous Version:
JASS:

//==============================================================================
//        Damage Per Second System by cr4xzZz v2.4
//==============================================================================
//
//  PURPOSE:
//      - Creating dps spells or other same stuff the easy way
//      - Save you time from repeating the same timer/loop method over and over
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  HOW TO USE:
//      call DPS_Start(which damager, which target, damage (NOT dps!), duration, show effect or not (true or false) )
//      call DPS_StartEx(which damager, which target, damage (NOT dps!), duration, attack type, damage type, string effect, attachment point, show effect or not (true or false) ) 
//      call DPS_Buff(which damager, which target, damage (NOT dps!), duration, buff raw code, show effect or not (true or false) )
//      call DPS_BuffEx(which damager, which target, damage (NOT dps!), duration, buff raw code, attack type, damage type, string effect, attachment point, show effect or not (true or false) )
//
//          * As you can see you can use a normal function and an extended function. The extended function 
//            has more arguments to add. If you are still confused how to use it I'll explain a bit more with
//            the functions' arguments.
//          * Every time the unit is damaged you can choose if you want a effect to be shown or not
//
//      whichUnit - the unit which will damage something
//      whichTarg - the target that is going to be damaged
//      whichDmg - the full damage dealt for the specific period (NOT the damage per second)
//          * damage per second is calculated by the system
//      whichDur - the duration of the damaging
//      whichBuff - the buff that the target has to have it so it can be damaged
//          * if the target does not have that buff the damaging will stop (only for DPS_Buff and DPS_BuffEx functions)
//      whichAttackType - the attack type used for damaging
//      whichDamageType - the damage type used for damaging
//      whichFx - the special effect string
//      whichPoint - where the effect will be attached (head, chest, etc.)
//      whichBool - should an effect be shown? MUST be true or false
//          * if the boolean flag is true then the special effect WILL appear
//          * if the boolean flag is false then the special effect WON'T appear
//
//      If you want to stop the buff damaging then remove the buff you assigned with the Buff functions from the target unit
//      If you want to stop the normal Start/StartEx function then use:
//      call DPS_Stop(whichTarg)     /unit argument/
//          - This stops all DPS_Start and DPS_StartEx functions used on that unit
//
//      If you want to increase the duration of the damaging then use:
//      call DPS_IncreaseDur(whichDur)     /integer argument/
//          - This works only for DPS_Start and DPS_StartEx !!
//      
//      The non-extended functions uses some arguments from the system's configuration menu.
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  PROS:
//      - Easy to use
//      - A lot customizeable (has extended functions)
//      - Won't mess up with other systems
//      - Stackable damage (not like slow poison)
// 
//  CONS:
//      - A bit difficult to use
//      - Requires another system to work
//      - Stackable damage (not like slow poison)
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  HOW TO USE:
//      - Copy the ABCT and PUI systems if you don't have them
//      - Create a trigger named DPS
//      - Convert it to custom text and replace the text with this one
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//  CREDITS TO:
//      - Cohadar for ABCT, PUI and some help
//      - 0zaru and ~GaLs~ for some help
//
//==============================================================================


library DPS uses ABCT, PUI

globals
    private constant real INTERVAL = 1.
    private constant attacktype ATTACK = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGE = DAMAGE_TYPE_MAGIC
    private constant string EFFECT = "Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl"
    private constant string POINT = "chest"
    private integer array PUI_TICKS 
endglobals

private struct Config
    unit cast
    unit targ
    real dps
    integer ticks
    string effe
    string point
    attacktype attack
    damagetype damage
    integer buffz
    boolean check

    static method create takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint, boolean whichBool returns Config
        local Config store = Config.allocate()
        set store.cast = whichUnit
        set store.targ = whichTarg
        set store.dps = ((whichDmg / whichDur) * INTERVAL)
        set store.effe = whichFx
        set store.point = whichPoint
        set store.attack = whichAttackType
        set store.damage = whichDamageType
        set store.buffz = whichBuff
        set store.check = whichBool
        set store.ticks = R2I(whichDur)
        return store
    endmethod
endstruct

private function CheckDPS takes nothing returns boolean
    local Config store = ABCT_GetData()
    if GetWidgetLife(store.targ) >= 0.405 and GetUnitAbilityLevel(store.targ, store.buffz) > 0 and store.ticks > 0 then
        call UnitDamageTarget(store.cast, store.targ, store.dps, true, true, store.attack, store.damage, null)
        if store.check == true then
            call DestroyEffect(AddSpecialEffectTarget(store.effe, store.targ, store.point))
        endif
    else
        call store.destroy()
        //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps stops")
        return true
    endif
    set store.ticks = store.ticks - 1
    return false
endfunction

private function NormalDPS takes nothing returns boolean
    local Config store = ABCT_GetData()
    local integer pui = GetUnitIndex(store.targ)
    if GetWidgetLife(store.targ) >= 0.405 and PUI_TICKS[pui] > 0 then
        call UnitDamageTarget(store.cast, store.targ, store.dps, true, true, store.attack, store.damage, null)
        if store.check == true then
            call DestroyEffect(AddSpecialEffectTarget(store.effe, store.targ, store.point))
        endif
    else
        call store.destroy()
        //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps stops")
        return true
    endif
    set PUI_TICKS[pui] = PUI_TICKS[pui] - 1
    return false
endfunction

public function Stop takes unit whichTarg returns nothing
    local integer pui = GetUnitIndex(whichTarg)
    if PUI_TICKS[pui] <= 0 then
        call BJDebugMsg("|cffffcc00[DPS]Error|r - Cannot stop DPS for unit that has no DPS_Start/DPS_StartEx")
        return
    else
        set PUI_TICKS[pui] = 0
    endif
endfunction

public function IncreaseDur takes unit whichTarg, real whichDur returns nothing
    local integer pui = GetUnitIndex(whichTarg)
    local integer inc = R2I(whichDur)
    if PUI_TICKS[pui] <= 0 then
        call BJDebugMsg("|cffffcc00[DPS]Error|r - Cannot increase duration for a unit with no DPS_Start/DPS_StartEx")
        return
    else
        set PUI_TICKS[pui] = PUI_TICKS[pui] + inc
    endif
endfunction

public function BuffEx takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint, boolean whichBool returns nothing
    local Config store = Config.create(whichUnit, whichTarg, whichDmg, whichDur, whichBuff, whichAttackType, whichDamageType, whichFx, whichPoint, whichBool)
    call ABCT_Start(function CheckDPS, store, INTERVAL) 
    //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps starts")
endfunction

public function Buff takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, integer whichBuff, boolean whichBool returns nothing
    call DPS_BuffEx(whichUnit, whichTarg, whichDmg, whichDur, whichBuff, ATTACK, DAMAGE, EFFECT, POINT, whichBool)
endfunction

public function StartEx takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint, boolean whichBool returns nothing       
    local Config store = Config.create(whichUnit, whichTarg, whichDmg, whichDur, 0, whichAttackType, whichDamageType, whichFx, whichPoint, whichBool)
    local integer pui = GetUnitIndex(store.targ)
    set PUI_TICKS[pui] = PUI_TICKS[pui] + R2I(whichDur / INTERVAL)
    call ABCT_Start(function NormalDPS, store, INTERVAL)
    //call BJDebugMsg("|cffffcc00[DPS]Message|r - Dps starts")
endfunction

public function Start takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, boolean whichBool returns nothing
    call DPS_StartEx(whichUnit, whichTarg, whichDmg, whichDur, ATTACK, DAMAGE, EFFECT, POINT, whichBool)
endfunction

endlibrary
//==============================================================================
//        End of Damage Per Second System
//==============================================================================

Changelog:
JASS:

v1.0 - First release
v1.1 - Shortened code and removed buff check. Added extended function
v1.2 - Added stop and increase duration functions which require a target (refer only on a target from dps)
v2.0 - Fixed increase and stop functions
v2.1 - Minor code fixes
v2.2 - Added buff check again
v2.3 - Simplified a little. Removed non-buff check function and left it with a buff check one
v2.4 - Added normal dps again (non-buff check) (omg..). Returned Stop and Increase Duration functions. Uses ABCT and PUI
v2.5 - Removed non-buff check (again.. omg wtf!). Uses only ABCT. Now, if the target does not recieve the assigned buff in 
         5 seconds, DPS is canceled. This is because some spells have a missile to travel before they apply a buff (thanks,
         Cohadar, for this tip).
 

Attachments

  • [System] DPS v2.5.w3x
    81.5 KB · Views: 223

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
How should we stop it when emergency happens? zz... I don't want to get tide up by the Duration and cant stop it manually.

In my oppinion, why are you making such easy system to so complicated?

Just create a unit group, then add x unit to the unit group when start function in called.
Then remove the x unit from then unit group when cancel function is called.

Then, the system should be ran by only 1 timer. Every one second pick every unit in that unit group and damage that unit.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Small fixes. Added How to use instructions in map.

> How should we stop it when emergency happens?
Well... I don't know how to make that... :/

> Just create a unit group, then add x unit to the unit group when start function in called.

Yeah, but how am I going to check when each unit has to be damaged with a buff?
 

0zaru

Learning vJASS ;)
Reaction score
60
If you don't like that..
Well simple have a trigger that detect those emergencys, and destroy the struct..

Also the time interval should be a function argument, not a global..

The same i think with attack types and damage types. Also I suggest making a short-code function and a complete one(The short-code can use constant.. (Ex function (Extended) should be used when you want to modify things))

>Yeah, but how am I going to check when each unit has to be damaged with a buff?

That is quite unnecesary, because the user can use his own detection of the buff in his triggers.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> Also the time interval should be a function argument, not a global..
You mean a constant function?

> That is quite unnecesary, because the user can use his own detection of the buff in his triggers.
Probably... I'll start working on it right away

If I wanna make an extended function what other arguments should I add? I think it's long enough to put everything you want
 

0zaru

Learning vJASS ;)
Reaction score
60
>You mean a constant function?
No. I mean a function argument (takes integer a (For example..))

>This would be the extended, the another one should include constant inside (Like attack_types etc)
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
>>If you don't like that..
If I don't like it, I'd rather made my own system.

>>You mean a constant function?
I think he means the time interval should be independant? No idea.

But if he means constant function, then it is totally false. You are using vJass, not Jass. Why the hell you want to make a constant function for non-independant constant value?

>>I'll start working on it right away
On what?

>>If I wanna make an extended function what other arguments should I add?
Extended function?! Whats that? ==
Too much arguements will just make user confuse, just made some required arguements for it is fair enough.
Just like the current one.
 

0zaru

Learning vJASS ;)
Reaction score
60
>If I don't like it, I'd rather made my own system.
It was for cr4xzZz. Comenting about what you wrote.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Why the hell should I change the timer interval? It's a damage per second system, not a periodic damage system. ;)

> Extended function?! Whats that? ==
More arguments to the function.
Like native MoveLightning and native MoveLightningEx (I think Cohadar noted that somewhere).

Yesterday I made a new update but didn't have time to post it... Gonna check what I did and fix if something needs fixing. Still need a tip how to make the Stop function...

EDIT: New version
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
I bet you need PUI (Perfect Unit Indexing) to create a stop function in your condition.

-Create a integer array global, then set the struct to the integer variable arraying the unit id gotten by the PUI.

Then when stop function is called, destroy the struct indexed by the unit id.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Well... Never used PUI before. I hope I can get it to work :\
*calls Cohadar for help*
I'll start experimenting right away X_X

EDIT: Ok, read Cohadar's tutorial on PUI and I think nothing got into my brain... Still, I made the stop function but when I activate it in-game it gives me a list of errors:
ERROR: PUI - Index requested for null unit
ERROR: PUI - Index requested for null unit

//yes, repeats twice
Double free of type: dpssys__init
 

~GaLs~

† Ғσſ ŧħə ѕαĸε Φƒ ~Ğ䣚~ †
Reaction score
180
The error shows up when you call StartDps or StopDps?

It seems likely you are getting an index from a null unit.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> The error shows up when you call StartDps or StopDps?
StopDps.
> It seems likely you are getting an index from a null unit.
Mm, yes... The problem is that I don't know how to fix it :/ Maybe I don't set correctly the target's index?
JASS:
     static method Take takes unit targ returns init
        local integer pui = GetUnitIndex(targ)
        if .STUFF[pui] == null then
            set .STUFF[pui] = init.allocate()
        endif
        return .STUFF[pui]
    endmethod

I guess the problem should be here..
 

0zaru

Learning vJASS ;)
Reaction score
60
I think that PUI was made so the struct doesn't needed to be destroyed, or maybe It musn't be destroyed.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
> I think that PUI was made so the struct doesn't needed to be destroyed, or maybe It musn't be destroyed.
Yeah, it is recycled from PUI. But wasn't sure if I have to remove onDestroy method... So, should I ?
 

Cohadar

master of fugue
Reaction score
209
How should we stop it when emergency happens? zz... I don't want to get tide up by the Duration and cant stop it manually.

In my oppinion, why are you making such easy system to so complicated?

Just create a unit group, then add x unit to the unit group when start function in called.
Then remove the x unit from then unit group when cancel function is called.

Then, the system should be ran by only 1 timer. Every one second pick every unit in that unit group and damage that unit.

Removing buff check was a bad move IMHO.
Buff checks are cool, use them more often.
Among other things they enable you to manually stop the dps and even to do so with default dispel abilities.

Unit groups + dps = I2H type errors.

This kind of systems contrary to the popular belief cannot be run on a single timer. (I already discussed this in the TT thread)

You should also avoid using PUI with structs when ever you can.
In this case particular you only need to attach ticks to unit.
So you need a global array for ticks:

JASS:
globals
    private integer array PUI_ticks
endglobals

(Remove the ticks from struct and use only global array one)

JASS:
private function Dps takes nothing returns nothing
    local timer tempTimer = GetExpiredTimer()
    local init info = GetTimerStructA(tempTimer)
    local integer pui = GetUnitIndex(info.cast)
    if PUI_ticks[pui] <= 0 then
        call info.destroy()
    else
        set PUI_ticks[pui] = PUI_ticks[pui] - 1
        call UnitDamageTarget(info.cast, info.targ, info.dps, true, false, ATTACK, DAMAGE, null)
        call DestroyEffect(AddSpecialEffectTarget(info.effe, info.targ, info.point))
    endif
    set tempTimer = null
endfunction


simple as that.

EDIT:
Q: Why it was necessary to attach ticks to unit?
A: because if for example you have poisoned one unit and the poison lasts 30 sec,
but after 15 sec you poison it again how long should the poison last?
Well the solution is to add the new tick value to the old ticks so the poison lasts 15+45 sec as it should

EDIT2:
In case someone did not get it how to manually stop the dps on a unit:
JASS:
    set PUI_ticks[GetUnitIndex(whichUnit)]=0
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
I had a dream last night that I'm gonna fix it... But that doesn't happen in real life >,< Yesterday I did what you said, Cohadar. Now I'm gonna fix some thingies and I'll post it here ..
Thanks a lot for your help <3<3

EDIT: Made it. Stop function doesn't work >,< It refers only on target because I save PUI on targets. And maybe IncreaseDps doesn't work (haven't tested yet).
JASS:
library dpssys uses ABC, PUI

globals
    private constant real TIMER_INTERVAL = 1.
    private constant attacktype ATTACKT = ATTACK_TYPE_NORMAL
    private constant damagetype DAMAGET = DAMAGE_TYPE_MAGIC
    private constant string EFFECT = &quot;Abilities\\Spells\\Orc\\FeralSpirit\\feralspirittarget.mdl&quot;
    private constant string ATTACHMENT_POINT = &quot;chest&quot;
    private integer array PUI_TICKS
endglobals

private struct config
    unit cast
    unit targ
    real dps
    string effe
    string point
    attacktype attack
    damagetype damage
    timer time = CreateTimer()

    static method save takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint returns config
        local config store = config.allocate()
        set store.cast = whichUnit
        set store.targ = whichTarg
        set store.dps = ((whichDmg / whichDur) * TIMER_INTERVAL)
        set store.effe = whichFx
        set store.point = whichPoint
        set store.attack = whichAttackType
        set store.damage = whichDamageType
        call SetTimerStructA(store.time, store)
        return store
    endmethod
    
    method onDestroy takes nothing returns nothing
        call ClearTimerStructA(.time)
        call PauseTimer(.time)
        call DestroyTimer(.time)
    endmethod
endstruct

function StopDps takes unit whichUnit returns nothing
    local integer pui = GetUnitIndex(whichUnit)
    set PUI_TICKS[pui] = 0
endfunction

function IncreaseDps takes unit whichUnit, integer whichInteger returns nothing
    local integer pui = GetUnitIndex(whichUnit)
    local integer increase = whichInteger
    set PUI_TICKS[pui] = PUI_TICKS[pui] + increase
endfunction

private function Dps takes nothing returns nothing
    local timer tempTimer = GetExpiredTimer()
    local config store = GetTimerStructA(tempTimer)
    local integer pui = GetUnitIndex(store.targ)
    if PUI_TICKS[pui] &lt;= 0  then
        call store.destroy()
    else
        if PUI_TICKS[pui] &gt; 0 then
            set PUI_TICKS[pui] = PUI_TICKS[pui] - 1
        endif
        if GetUnitState(store.targ, UNIT_STATE_LIFE) &gt;= 0.405 then
            call UnitDamageTarget(store.cast, store.targ, store.dps, true, false, store.attack, store.damage, null)
            call DestroyEffect(AddSpecialEffectTarget(store.effe, store.targ, store.point))
        else 
            call store.destroy()
        endif
    endif
    set tempTimer = null
endfunction

function StartDpsEx takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur, attacktype whichAttackType, damagetype whichDamageType, string whichFx, string whichPoint returns nothing
    local config store = config.save(whichUnit, whichTarg, whichDmg, whichDur, whichAttackType, whichDamageType, whichFx, whichPoint)
     set PUI_TICKS[GetUnitIndex(store.targ)] = PUI_TICKS[GetUnitIndex(store.targ)] + R2I(whichDur)
    call TimerStart(store.time, TIMER_INTERVAL, true, function Dps)
endfunction

function StartDps takes unit whichUnit, unit whichTarg, real whichDmg, real whichDur returns nothing
    call StartDpsEx(whichUnit, whichTarg, whichDmg, whichDur, ATTACKT, DAMAGET, EFFECT, ATTACHMENT_POINT)
endfunction

endlibrary
 

Cohadar

master of fugue
Reaction score
209
First of all MAKE YOUR STRUCT NAMES START WITH UPPERCASE LETTER.
Why?
BECAUSE WHOLE PROGRAMMING WORLD DOES IT THAT WAY.
================================================

Seriously, starting your structs with lowercase would get you fired in any programming company within of 5 minutes of someone noticing you do it.

================================================
save ??? wtf is save? Use create keyword.
================================================

This can be improved: (terrible algorithm)
JASS:

    if PUI_TICKS[pui] &lt;= 0  then
        call store.destroy()
    else
        if PUI_TICKS[pui] &gt; 0 then
            set PUI_TICKS[pui] = PUI_TICKS[pui] - 1
        endif


JASS:

private function Dps takes nothing returns nothing
    local timer tempTimer = GetExpiredTimer()
    local config store = GetTimerStructA(tempTimer)
    local integer pui = GetUnitIndex(store.targ)

    set PUI_TICKS[pui] = PUI_TICKS[pui] - 1
    if PUI_TICKS[pui] &lt;= 0  then
        call store.destroy()
    else
        if GetUnitState(store.targ, UNIT_STATE_LIFE) &gt;= 0.405 then
            call UnitDamageTarget(store.cast, store.targ, store.dps, true, false, store.attack, store.damage, null)
            call DestroyEffect(AddSpecialEffectTarget(store.effe, store.targ, store.point))
        else 
            call store.destroy()
        endif
    endif
    set tempTimer = null
endfunction


Btw StopDps will work now.
 

cr4xzZz

Also known as azwraith_ftL.
Reaction score
51
Ok, ok, sorry, bash me no more! :/ *fixing*
EDIT: New version... Still not sure StopDps and IncreaseDps works >,<
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      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