System Custom Cooldown System

Laiev

Hey Listen!!
Reaction score
188
Custom Cooldown System​

Requirement

JASS:
library Cooldown /* v7.0.0.0
*************************************************************************************
*
*   Description
*   ¯¯¯¯¯¯¯¯¯¯¯
*        -    Cooldown is a full controllable custom cooldown system
*
*************************************************************************************
*
*   */uses/*
*   
*       */  AIDS  /*       thehelper.net/forums/showthread.php/130752-Advanced-Indexing-Data-Storage
*       */  Event /*       thehelper.net/forums/showthread.php/126846-Event
*       */  T32   /*       thehelper.net/forums/showthread.php/132538-Timer32
*       */  Table /*       thehelper.net/forums/showthread.php/162582-Table
*
************************************************************************************
*
*   Importing
*   ¯¯¯¯¯¯¯¯¯
*      Create a new trigger named Cooldown. Go to 'Edit > Convert to Custom Text',
*      and replace everything that's there with this script
*      Copy every ability in this map and change the icon, name and description
*
*   How to use
*   ¯¯¯ ¯¯ ¯¯¯
*      Cooldown[someUnit].$methods$
*        -    This will interact with some $method$ (read the docs below)
*        -    In Cooldown, everything is based on an unit reference
*        -    The reference of unit is treated as 'this'
*        -    This is why all method is non-static
*
*      Cooldown.$member$
*        -    This will interact with some static $member$
*        -    The static $members$ are just part of the events
*
*******************************************************************
*
*   struct Cooldown extends array
*
*       readonly static Event START
*            -    Fire event when some cooldown start
*       readonly static Event FINISH
*            -    Fire event when some cooldown finish
*       readonly static unit    Unit
*       readonly static integer AbilityId
*       readonly static real    Duration
*       readonly static integer Hotkey
*            -    Corresponds to the above events
*       method start takes integer abilId, integer hotkey, real duration returns nothing
*            -    Start the cooldown for some abilId corresponding to the hoktye for duration
*                   _______________       _______________
*                  |___|___|___|___|     |___|___|___|___|
*                  |___|_S_|_D_|___|  >  |___|_4_|_5_|___|
*                  |_Q_|_W_|_E_|_R_|     |_0_|_1_|_2_|_3_|
*
*       method duration takes integer hotkey returns real
*            -    Get the value of cooldown corresponding to the hotkey
*       method setDuration takes integer hotkey, real duration returns nothing
*            -    Set the value of cooldown corresponding to the hotkey
*       method abilityId takes integer hotkey returns integer
*            -    Get the id of ability in cooldown corresponding to the hotkey
*       method setAbilityId takes integer hotkey, integer abilId returns nothing
*            -    Set the id of ability in cooldown corresponding to the hotkey
*
************************************************************************************
*
*   Setting
*   ¯¯¯¯¯¯¯
*/

globals
    //-----------------------------------------------------------
    // Configure the value of execution, in other words, every X
    // second(s), the system will reduce the value of each cooldown
    private constant real    COUNT_COOLDOWN     = 1.0
    
    //-----------------------------------------------------------
    // Configure if the system should refresh the cooldown when
    // finish the cooldown of the system
    private constant boolean REFRESH_COOLDOWN   = true
    
            constant integer COOLDOWN_HOTKEY_Q  = 0
            constant integer COOLDOWN_HOTKEY_W  = 1
            constant integer COOLDOWN_HOTKEY_E  = 2
            constant integer COOLDOWN_HOTKEY_R  = 3
            
            constant integer COOLDOWN_HOTKEY_S  = 4
            constant integer COOLDOWN_HOTKEY_D  = 5
    
    //------------------------------------------------------------
    // Change this for your map rawcodes
    private constant integer COOLDOWN_ABILITY_Q = 'AC@Q'
    private constant integer COOLDOWN_ABILITY_W = 'AC@W'
    private constant integer COOLDOWN_ABILITY_E = 'AC@E'
    private constant integer COOLDOWN_ABILITY_R = 'AC@R'
    
    private constant integer COOLDOWN_ABILITY_S = 'AC@S'
    private constant integer COOLDOWN_ABILITY_D = 'AC@D'
endglobals
    
// The filter, if you want to use the system with units, just change here
private function System_Filter takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_HERO)
endfunction

/************************************************************************************/

struct Cooldown extends array
    private real            count
    
    private static integer array Cooldown_Ability[5]
    private static Table array T
    
    readonly static Event   START
    readonly static Event   FINISH
    readonly static unit    Unit
    readonly static integer AbilityId
    readonly static real    Duration
    readonly static integer Hotkey
    
    method start takes integer abilId, integer hotkey, real duration returns nothing
        set thistype.T[this].real[hotkey] = duration
        set thistype.T[this][hotkey] = abilId
        
        set thistype.Unit         = this.unit
        set thistype.AbilityId    = abilId
        set thistype.Duration     = duration
        set thistype.Hotkey       = hotkey
        call thistype.START.fire()
        
        call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit), abilId, false)
        call UnitAddAbility(this.unit, Cooldown_Ability[hotkey])
        call UnitMakeAbilityPermanent(this.unit, true, Cooldown_Ability[hotkey])
    endmethod
    
    method duration takes integer hotkey returns real
        return thistype.T[this].real[hotkey]
    endmethod
    
    method setDuration takes integer hotkey, real duration returns nothing
        set thistype.T[this].real[hotkey] = duration
    endmethod
    
    method abilityId takes integer hotkey returns integer
        return thistype.T[this][hotkey]
    endmethod
    
    method setAbilityId takes integer hotkey, integer abilId returns nothing
        set thistype.T[this][hotkey] = abilId
    endmethod
    
    private method periodic takes nothing returns nothing
        local integer i = 0
        local integer lvl = 0
        
        if COUNT_COOLDOWN <= this.count then
            loop
                exitwhen 6 == i
                if 0 &lt; GetUnitAbilityLevel(this.unit, Cooldown_Ability<i>) then
                    if 0 &gt;= this.duration(i) then
                        call UnitMakeAbilityPermanent(this.unit, false, Cooldown_Ability<i>)
                        call UnitRemoveAbility(this.unit, Cooldown_Ability<i>)
                        
                        static if REFRESH_COOLDOWN then
                            set lvl = GetUnitAbilityLevel(this.unit, this.abilityId(i))
                            call UnitRemoveAbility(this.unit, this.abilityId(i))
                            call UnitAddAbility(this.unit, this.abilityId(i))
                            call SetUnitAbilityLevel(this.unit, this.abilityId(i), lvl)
                        endif
                        
                        call SetPlayerAbilityAvailable(GetOwningPlayer(this.unit), this.abilityId(i), true)
                        
                        set thistype.Unit         = this.unit
                        set thistype.AbilityId    = this.abilityId(i)
                        set thistype.Duration     = this.duration(i)
                        set thistype.Hotkey       = i
                        call thistype.FINISH.fire()
                        
                        call this.setDuration(i, 0.0)
                        call this.setAbilityId(i, 0)
                    else
                        call this.setDuration(i, this.duration(i) - this.count)
                    endif
                endif
                set i = i + 1
            endloop
            set this.count = this.count - COUNT_COOLDOWN
        endif
        set this.count = this.count + T32_PERIOD
    endmethod
    
    private method AIDS_onDestroy takes nothing returns nothing
        call this.stopPeriodic()
        call thistype.T[this].flush()
    endmethod
    
    implement T32x
    
    private method AIDS_onCreate takes nothing returns nothing
        set this.count = 0.
        call this.startPeriodic()
        set thistype.T[this] = Table.create()
    endmethod
    
    private static method AIDS_onInit takes nothing returns nothing
        set thistype.Cooldown_Ability[0] = COOLDOWN_ABILITY_Q
        set thistype.Cooldown_Ability[1] = COOLDOWN_ABILITY_W
        set thistype.Cooldown_Ability[2] = COOLDOWN_ABILITY_E
        set thistype.Cooldown_Ability[3] = COOLDOWN_ABILITY_R
        
        set thistype.Cooldown_Ability[4] = COOLDOWN_ABILITY_S
        set thistype.Cooldown_Ability[5] = COOLDOWN_ABILITY_D
        
        set thistype.START = Event.create()
        set thistype.FINISH = Event.create()
    endmethod
    
    private static method AIDS_filter takes unit u returns boolean
        return System_Filter(u)
    endmethod
    
    //! runtextmacro AIDS()
endstruct
endlibrary
</i></i></i>



Easy API (Plugin)
JASS:
library CooldownAPI /* v1.0.0.0
*************************************************************************************
*
*   Description
*   ¯¯¯¯¯¯¯¯¯¯¯
*        -    Easy API
*
*************************************************************************************
*
*   */uses/*
*   
*       */  Cooldown  /*   thehelper.net/forums/showthread.php/166181-Custom-Cooldown-System
*
************************************************************************************
*
*    Functions
*    ¯¯¯¯¯¯¯¯¯
*       - Basic
*         ¯¯¯¯¯
*           function StartCooldown takes unit whichUnit, integer abilId, integer hotkey, real duration returns nothing
*           function SetCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
*           function GetCooldownDuration takes unit whichUnit, integer hotkey returns real
*           function SetCooldownAbilityId takes unit whichUnit, integer hotkey, integer abilId returns nothing
*           function GetCooldownAbilityId takes unit whichUnit, integer hotkey returns integer
*
*       - Event
*         ¯¯¯¯¯
*           function CooldownRegisterEvent takes trigger whichTrigger returns nothing
*               -   Fire when some cooldown starts
*           function CooldownRegisterFinishEvent takes trigger whichTrigger returns nothing
*               -   Fire when some cooldown ends
*           function GetEventCooldownUnit takes nothing returns unit
*               -   Matching unit of Events above
*           function GetEventCooldownAbilityId takes nothing returns integer
*               -   Matching ability id of Events above
*           function GetEventCooldownDuration takes nothing returns real
*               -   Remainer duration of Events above
*           function GetEventCooldownHotkey takes nothing returns integer
*               -   Matching hotkey of Events above
*
*       - Advanced Single
*         ¯¯¯¯¯¯¯¯ ¯¯¯¯¯¯
*           function AddCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
*           function ReduceCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
*           function MultiplyCooldownDuration takes unit whichUnit, integer hotkey, real multiplier returns nothing
*           function DivideCooldownDuration takes unit whichUnit, integer hotkey, real diviser returns nothing
*           function StopCooldown takes unit whichUnit, integer hotkey returns nothing
*
*       - Advanced All
*         ¯¯¯¯¯¯¯¯ ¯¯¯
*           function SetAllCooldownDuration takes unit whichUnit, real duration returns nothing
*           function AddAllCooldownDuration takes unit whichUnit, real duration returns nothing
*           function ReduceAllCooldownDuration takes unit whichUnit, real duration returns nothing
*           function MultiplyAllCooldownDuration takes unit whichUnit, real multiplier returns nothing
*           function DivideAllCooldownDuration takes unit whichUnit, real diviser returns nothing
*           function StopAllCooldown takes unit whichUnit returns nothing
*
************************************************************************************/
function StartCooldown takes unit whichUnit, integer abilId, integer hotkey, real duration returns nothing
    call Cooldown[whichUnit].start(abilId, hotkey, duration)
endfunction

function SetCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
    call Cooldown[whichUnit].setDuration(hotkey, duration)
endfunction

function GetCooldownDuration takes unit whichUnit, integer hotkey returns real
    return Cooldown[whichUnit].duration(hotkey)
endfunction

function SetCooldownAbilityId takes unit whichUnit, integer hotkey, integer abilId returns nothing
    call Cooldown[whichUnit].setAbilityId(hotkey, abilId)
endfunction

function GetCooldownAbilityId takes unit whichUnit, integer hotkey returns integer
    return Cooldown[whichUnit].abilityId(hotkey)
endfunction

/************************************************************************************/

function StopCooldown takes unit whichUnit, integer hotkey returns nothing
    call SetCooldownDuration(whichUnit, hotkey, 0.)
endfunction

function AddCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
    call SetCooldownDuration(whichUnit, hotkey, GetCooldownDuration(whichUnit, hotkey) + duration)
endfunction

function ReduceCooldownDuration takes unit whichUnit, integer hotkey, real duration returns nothing
    call SetCooldownDuration(whichUnit, hotkey, GetCooldownDuration(whichUnit, hotkey) - duration)  
endfunction

function MultiplyCooldownDuration takes unit whichUnit, integer hotkey, real multiplier returns nothing
    call SetCooldownDuration(whichUnit, hotkey, GetCooldownDuration(whichUnit, hotkey) * multiplier)
endfunction

function DivideCooldownDuration takes unit whichUnit, integer hotkey, real diviser returns nothing
    call SetCooldownDuration(whichUnit, hotkey, GetCooldownDuration(whichUnit, hotkey) / diviser)
endfunction

/************************************************************************************/

function SetAllCooldownDuration takes unit whichUnit, real duration returns nothing
    local integer i = 0
    
    loop
        exitwhen i == 6
        call SetCooldownDuration(whichUnit, i, duration)
        set i = i + 1
    endloop
endfunction

function StopAllCooldown takes unit whichUnit returns nothing
    call SetAllCooldownDuration(whichUnit, 0)
endfunction

function AddAllCooldownDuration takes unit whichUnit, real duration returns nothing
    local integer i = 0
    
    loop
        exitwhen i == 6
        call SetCooldownDuration(whichUnit, i, GetCooldownDuration(whichUnit, i) + duration)
        set i = i + 1
    endloop
endfunction

function ReduceAllCooldownDuration takes unit whichUnit, real duration returns nothing
    local integer i = 0
    
    loop
        exitwhen i == 6
        call SetCooldownDuration(whichUnit, i, GetCooldownDuration(whichUnit, i) - duration)
        set i = i + 1
    endloop    
endfunction

function MultiplyAllCooldownDuration takes unit whichUnit, real multiplier returns nothing
    local integer i = 0
    
    loop
        exitwhen i == 6
        call SetCooldownDuration(whichUnit, i, GetCooldownDuration(whichUnit, i) * multiplier)
        set i = i + 1
    endloop    
endfunction

function DivideAllCooldownDuration takes unit whichUnit, real diviser returns nothing
    local integer i = 0
    
    loop
        exitwhen i == 6
        call SetCooldownDuration(whichUnit, i, GetCooldownDuration(whichUnit, i) / diviser)
        set i = i + 1
    endloop    
endfunction

/************************************************************************************/

function CooldownRegisterEvent takes trigger whichTrigger returns nothing
    call Cooldown.START.register(whichTrigger)
endfunction

function CooldownRegisterFinishEvent takes trigger whichTrigger returns nothing
    call Cooldown.FINISH.register(whichTrigger)
endfunction

function GetEventCooldownUnit takes nothing returns unit
    return Cooldown.Unit
endfunction

function GetEventCooldownAbilityId takes nothing returns integer
    return Cooldown.AbilityId
endfunction

function GetEventCooldownDuration takes nothing returns real
    return Cooldown.Duration
endfunction

function GetEventCooldownHotkey takes nothing returns integer
    return Cooldown.Hotkey
endfunction
endlibrary

Changelog
7.0.0.0
  • Rewrited code
  • Improved performance
  • Added Table as requirement
  • No bad code generated by normal struct anymore
  • Main struct now just have basic and important things
  • Created other library just for easy API

API 1.0.0.0
  • Release

6.2
  • Now uses GetVarObject to generate the abilities

6.1
  • Added globals for easy use
  • Added condition to check if want to refresh the cooldown

6.0
  • Added two events (onFinish and onStart)
  • Added API (and Tesh)
  • Public released since the contest
  • Fixed wrong position of the icon R
  • Fixed a bug with Object Editor abilities
  • Fixed a bug with crash using morph abilities
 

Attachments

  • Cooldown System 6.1.w3x
    99.7 KB · Views: 598

tooltiperror

Super Moderator
Reaction score
231
It should be using Nestharus' safe generation scripts.

It'd be nice if the demomap was attached directly to the post, not hotlinked.

Why would I use this instead of WC3 native cooldowns?
 

Laiev

Hey Listen!!
Reaction score
188
>>It should be using Nestharus' safe generation scripts
I don't know how to use that hack :(

>>It'd be nice if the demomap was attached directly to the post, not hotlinked.
Fixed.

>>Why would I use this instead of WC3 native cooldowns?
What Natives?
 

Laiev

Hey Listen!!
Reaction score
188
He meant normal object editor cooldown.

Oh... Well

Is impossible to Add/Remove/Manipulate Cooldown on Warcraft

An example of what my System do is, for example:

Ability A - Reduce the cooldown of all abilities in 10 seconds.
Ability B - Has 15 second of cooldown.


Cast B, cast A, now second ability will just need 5 more seconds to refresh the cooldown.
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
This system looks really cool! I don't suppose there is an easy way to add additional hotkeys (like for units that do not have the hero level up icon, move icon, etc. and have abilities in place of them)

It should be using Nestharus' safe generation scripts.

Those are obnoxious for the user as it requires them to go through a complex installation process to use this system.
 

Laiev

Hey Listen!!
Reaction score
188

Well..

I read everything and it don't work for me... I tried with 2 different newgens and the same error occur...

I really don't how what is and how to fix, searched about it and nothing....

The log is this: unfinished string near '"'

Also before save the log, editor show the error occur in FileExternal $FILENAME$
 

Nestharus

o-o
Reaction score
84
It'll tell you which line is bugging in the log... look in the Lua script (in temp folder) and find the line. It also tells you which Lua script it was (V#### or w/e).
 

Laiev

Hey Listen!!
Reaction score
188
Updated |:

Not sure if all right, but it generate the abilities right.
 

Nestharus

o-o
Reaction score
84
Don't import the constants ; P. You're using an array for this already, so the constants seem relatively pointless ; P.


Check out the writejass function in LUA_FILE_HEADER


I used writejass in my Bonus script ^)^.

JASS:

    /**********************************************************************
    *                                                                     *
    *                          GENERATE SCRIPT                            *
    *                                                                     *
    **********************************************************************/
    //generate globals
        //pw            powers
        //bd            bonus ability id
        //bp            bonus power
        //pm            power max
    //! i local script =
        //! i [[//! textmacro BONUS_DATA
        //! i globals
        //! i private integer array bd
        //! i private integer array bp
        //! i private integer array pw
        //! i private integer array pm
        //! i ]]
    //! i script = script .. const              --ability constant sets
    
    //generate script onInit
    //! i script = script ..
        //! i [[endglobals
        //! i private module I
        //! i private static method onInit takes nothing returns nothing
        //! i ]]
        
    //generate script PRELOAD
    //! i script = script ..
        //! i [[static if PRELOAD then
        //! i local unit u = CreateUnit(Player(14),&#039;hpea&#039;,0,0,0)
        //! i ]]
    //! i script = script .. preload
    
    //generate rest of onInit
    //! i script = script ..
    //! i [[call RemoveUnit(u)
    //! i set u = null
    //! i endif
    //! i ]]
    //! i script = script .. abil2              --ability data
    //! i script = script .. powmax             --max power (n)
    //! i script = script .. pows               --max power range (2^n)
    //! i script = script .. powerarray         --power on ability
    
    //write functions?
    //! i script = script..
    //! i [[endmethod
    //! i endmodule
    //! i private struct O extends array
    //! i implement I
    //! i endstruct
    //! i ]]
    
    //finish script
    //! i script = script .. [[//! endtextmacro]]
    
    //write script
    //! i writejass(&quot;BONUS&quot;,script)
    
    //create objects
    //! i updateobjects()
 

Laiev

Hey Listen!!
Reaction score
188
Nest

I'm not sure if you're talking about this

JASS:
            constant integer COOLDOWN_HOTKEY_Q  = 0
            constant integer COOLDOWN_HOTKEY_W  = 1
            constant integer COOLDOWN_HOTKEY_E  = 2
            constant integer COOLDOWN_HOTKEY_R  = 3
            
            constant integer COOLDOWN_HOTKEY_S  = 4
            constant integer COOLDOWN_HOTKEY_D  = 5


or this

JASS:
        set Cooldown_Ability[0] = COOLDOWN_ABILITY_Q
        set Cooldown_Ability[1] = COOLDOWN_ABILITY_W
        set Cooldown_Ability[2] = COOLDOWN_ABILITY_E
        set Cooldown_Ability[3] = COOLDOWN_ABILITY_R
        
        set Cooldown_Ability[4] = COOLDOWN_ABILITY_S
        set Cooldown_Ability[5] = COOLDOWN_ABILITY_D


But there's no reason to use a textmacro just to prevent some constants...

You said to me change the 'true' to 'false' but if you check, most of your system use the same way with 'true' and no textmacro as you said.

Anyway... If an moderator say to me do, I'll try.


I did all what tooltiperror said to do, and why I should prevent use of constants?

Me and most of all system here will need to use textmacro just to don't use constant?

I'm sorry Nest, but I disagree that.
 

Nestharus

o-o
Reaction score
84
Just saying that the constants aren't needed.


The script can obviously be improved. You're just being lazy about it =p.
 

Laiev

Hey Listen!!
Reaction score
188
I'm not being lazy >.> I just want to understand why I need to avoid constants when people don't avoid them >.<
 

Laiev

Hey Listen!!
Reaction score
188
(Fun when people still using something and tell you to don't use it, make really non-sense to me)...

I'll wait a Mod.
 

Narks

Vastly intelligent whale-like being from the stars
Reaction score
90
He's right, you should remove those public constants. You should also probably remove public functions that you don't use as well, like that StartCooldown function, I don't see it called anywhere in your script.

:trollface:
 

Nestharus

o-o
Reaction score
84
I'm saying that the only reason you are creating those constants is to store them into an array, which seems pointless. It makes more sense to just store the ids directly into the array and avoid the constants altogether considering that those constants are being generated to access the ids.

If you were actually using them, then np, but you aren't.

Why not eliminate the useless middle man?
 
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