• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Trigger Cooldown System

Status
Not open for further replies.
Level 22
Joined
Feb 6, 2014
Messages
2,466
A System that allows you to trigger an ability's cooldown (still showing the cooldown indicator). Still have some issues though.


JASS:
//            ----------------------------------------------------------------                     //
//                        Trigger Cooldown System v1.00 by Flux                                    //
//            ----------------------------------------------------------------                     //
//                                                                                                 //
//    This system allows you to make any unit's ability goes into cooldown via trigger             //
//    Though written in Jass, it has GUI support and easy to use for GUI users                     //
//                                                                                                 //
//    HOW TO USE:                                                                                  //
//       1. Set the TCD_Unit variable. This refers to the unit that will have its ability          //
//          goes into cooldown via trigger.                                                        //
//       2. Set the TCD_Ability variable. This refers to the ability that will go into cooldown.   //
//       3. Set the TCD_DummyAbility variable. This refers to the ability based on Spell Shield    //
//          that you have created. It must have the same tooltip, manacost and icon.               //
//       4. Set the TCD_Time variable. This refers how long the TCD_Ability will be replaced by    //
//          the TCD_DummyAbility. It should match the 'Stats - Cooldown' of the TCD_DummyAbility.  //
//       5. Set the TCD_Manacost variable. This is the manacost of the TCD_Ability which should    //
//          match the manacost of the TCD_DummyAbility 'Stats - Manacost'                          //
//       6. Execute by "Trigger - Run Trigger Cooldown System <gen> (ignoring conditions)"         //
//                                                                                                 //
//                                                                                                 //
//                                                                                                 //
//                                                                                                 //
//                                                                                                 //
//      KNOWN ISSUE:                                                                               //
//          - When triggering the cooldown of an active ability, it will reset the original        //
//            ability's cooldown. Example: Original Ability's cooldown is 20 seconds but           //
//            the triggered cooldown only last 5 seconds, when that 5 seconds is finished,         //
//            the original ability is now ready to use again.                                      //
//          - Can only trigger Unit ability so far, so to trigger a Hero's ability, a dummy hero   //
//            ability must be used and when the dummy ability is learned, add the real ability.    //
//            (As shown in Map Demo 2)                                                             //
//          - Removes Invisibility.
//          - Triggering a Cycloned unit's ability will reset its cooldown.



function Trig_Trigger_Cooldown_System_TimerExpires takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local unit u = LoadUnitHandle(udg_TCD_Hashtable, id, 0)
    local integer origAbil = LoadInteger(udg_TCD_Hashtable, id, 0)
    local integer lvl = LoadInteger(udg_TCD_Hashtable, id, 1)
    local integer fakeAbil = LoadInteger(udg_TCD_Hashtable, id, 2)

    call UnitAddAbility(u, origAbil)
    if lvl > 1 then
        call SetUnitAbilityLevel(u, origAbil, lvl)
    endif
    call UnitRemoveAbility(u, fakeAbil)
    call BJDebugMsg("Original Ability added")
    
    //Destroy the timer reference data
    call FlushChildHashtable(udg_TCD_Hashtable, id)
    //Destroy the unit reference data
    call FlushChildHashtable(udg_TCD_Hashtable, GetHandleId(u))
    
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function Trig_Trigger_Cooldown_System_Actions takes nothing returns nothing
    local timer t
    local integer id
    local integer unitId
    local integer lvl
    
    set lvl = GetUnitAbilityLevel(udg_TCD_Unit, udg_TCD_Ability)

    if lvl > 0 then
        call UnitRemoveAbility(udg_TCD_Unit, udg_TCD_Ability)
    else
        set lvl = GetUnitAbilityLevel(udg_TCD_Unit, udg_TCD_DummyAbility)
        call UnitRemoveAbility(udg_TCD_Unit, udg_TCD_DummyAbility)
    endif
     
    //Add the fake ability
    call UnitAddAbility(udg_TCD_Unit, udg_TCD_DummyAbility)
    call SetUnitAbilityLevel(udg_TCD_Unit, udg_TCD_DummyAbility, lvl)
    
    //Trigger the Cooldown Indicator
    call SetUnitX(udg_TCD_DummyCaster, GetUnitX(udg_TCD_Unit))
    call SetUnitY(udg_TCD_DummyCaster, GetUnitY(udg_TCD_Unit))
    call BJDebugMsg("TCD system executed")
    if IssueTargetOrderById(udg_TCD_DummyCaster, 852075, udg_TCD_Unit) then
        call BJDebugMsg("success")
        set unitId = GetHandleId(udg_TCD_Unit)
        //[unitId][5] is for timers
        //If there is already a timer, just reset it
        if HaveSavedHandle(udg_TCD_Hashtable, unitId, 5) then
            set udg_TCD_Time = LoadReal(udg_TCD_Hashtable, unitId, 6)
            call TimerStart(LoadTimerHandle(udg_TCD_Hashtable, unitId, 5), udg_TCD_Time, false, function Trig_Trigger_Cooldown_System_TimerExpires)
            call BJDebugMsg("timer already existing, time = " + R2S(udg_TCD_Time))
        else
            call BJDebugMsg("new timer created time = " + R2S(udg_TCD_Time))
            set t = CreateTimer()
            set id = GetHandleId(t)
            //Save the timer in reference to the unit
            call SaveTimerHandle(udg_TCD_Hashtable, unitId, 5, t)
            //Save the cooldown time in reference to the unit
            call SaveReal(udg_TCD_Hashtable, unitId, 6, udg_TCD_Time)
            call TimerStart(t, udg_TCD_Time, false, function Trig_Trigger_Cooldown_System_TimerExpires)
            set t = null
            
            //Save the unit
            call SaveUnitHandle(udg_TCD_Hashtable, id, 0, udg_TCD_Unit)
            //Save the original ability replaced
            call SaveInteger(udg_TCD_Hashtable, id, 0, udg_TCD_Ability)
            //Save the level of the original ability
            if lvl > 1 then
                call SaveInteger(udg_TCD_Hashtable, id, 1, lvl)
            endif
            //Save the fake ability
            call SaveInteger(udg_TCD_Hashtable, id, 2, udg_TCD_DummyAbility)
            
        endif
        
        if udg_TCD_Manacost > 0 then
            call SetUnitState(udg_TCD_Unit, UNIT_STATE_MANA, GetUnitState(udg_TCD_Unit, UNIT_STATE_MANA) + udg_TCD_Manacost)
        endif
    else
        call UnitAddAbility(udg_TCD_Unit, udg_TCD_Ability)
        if lvl > 1 then
            call SetUnitAbilityLevel(udg_TCD_Unit, udg_TCD_Ability, lvl)
        endif
        call UnitRemoveAbility(udg_TCD_Unit, udg_TCD_DummyAbility)
    endif

endfunction

//===========================================================================
function InitTrig_Trigger_Cooldown_System takes nothing returns nothing
    set gg_trg_Trigger_Cooldown_System = CreateTrigger(  )
    set udg_TCD_DummyCaster = CreateUnit(Player(14), 'Htcd', 0, 0, 0)
    set udg_TCD_Hashtable = InitHashtable()
    call SetHeroLevel(udg_TCD_DummyCaster, 6, false)
    call UnitAddAbility(udg_TCD_DummyCaster, 'Atcd')
    call SelectHeroSkill(udg_TCD_DummyCaster, 'Atcd')
    
    call TriggerAddAction(gg_trg_Trigger_Cooldown_System, function Trig_Trigger_Cooldown_System_Actions)
endfunction

Example of using it:
  • Trigger Cooldown by Esc
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to Mountain Giant)) and do (Actions)
        • Loop - Actions
          • -------- Set the unit --------
          • Set TCD_Unit = (Picked unit)
          • -------- Set the original ability --------
          • Set TCD_Ability = Hardened Skin (Mountain Giant)
          • -------- Set the fake ability based on Spell Shield --------
          • Set TCD_DummyAbility = Hardened Skin (For TCD System)
          • -------- TCD_Time = How much time you want the spell to be on cooldown --------
          • -------- It must match the TCD_DummyAbility 'Stats - Cooldown' --------
          • Set TCD_Time = 5.00
          • -------- Set the manacost of the ability --------
          • Set TCD_Manacost = 0.00
          • Trigger - Run Trigger Cooldown System <gen> (ignoring conditions)
That trigger will make all Mountain Giant's Hardened Skin to go into cooldown when Esc is pressed.
So while it is on cooldown, they are temporary easier to kill.

Any feedback?
 

Attachments

  • Trigger Cooldown System v1.00.w3x
    24 KB · Views: 90
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,657
This is hardly near what I have SF :D
What if you would make the spell shield ability have hundreds of levels and have it be set the level of the duration?
For example, I have a duration accuracy of 0.05, then I need 20 levels per second and set a maximum of 300 levels so I allow 6 seconds max.

Then I add the spell shield ability and give it the level of TCD_Time/0.05 level.
What about that?

Also, as far as I can see, your system only supports one spell on cooldown per unit.
That is a horrible limitation on something like this.

There are still two problems that I still cant fix so far though.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
This is hardly near what I have SF :D
What if you would make the spell shield ability have hundreds of levels and have it be set the level of the duration?
For example, I have a duration accuracy of 0.05, then I need 20 levels per second and set a maximum of 300 levels so I allow 6 seconds max.

Then I add the spell shield ability and give it the level of TCD_Time/0.05 level.
What about that?

If you mean using a single Spell Shield for all abilities, I think that wouldn't work because the icons would be different.
Offtopic: not SF anymore ;)

Also, as far as I can see, your system only supports one spell on cooldown per unit.
That is a horrible limitation on something like this.
You're right, didn't saw that one. I'll fix it .
 
Last edited:

Ardenian

A

Ardenian

Flux said:
Removes Invisibility.
This can be easily solved creating a caster dummy who casts invisibility, can't it ?
As the same if you want to get a unit's armor you would have to check whether the unit has an invisibility buff.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
This can be easily solved creating a caster dummy who casts invisibility, can't it ?
As the same if you want to get a unit's armor you would have to check whether the unit has an invisibility buff.

Yes because Invisibility can be caused by Wind walk, Meld, Permanent Invisibility, etc not to mention casting Invisibility will refresh the duration..
Armor? What does that have to do here?
 

Ardenian

A

Ardenian

Oh well, that makes everything complicated, you would have to write a system to keep track of every invisibility and the durations of every buff, refreshing it every second with a one second invisibility, that would be my approach.

But, considering you might not even use invisibility for heroes I every map it might be not a greater limitation.

I referred to armor, as you do it the same, keeping track of every armor-influence, as you would do the same for invisibility here.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Oh well, that makes everything complicated, you would have to write a system to keep track of every invisibility and the durations of every buff, refreshing it every second with a one second invisibility, that would be my approach.

But, considering you might not even use invisibility for heroes I every map it might be not a greater limitation.

I referred to armor, as you do it the same, keeping track of every armor-influence, as you would do the same for invisibility here.

I think Invisibility problem is a dead end. It's the side effect of the Spell Shield so I see no way how to fix that problem. Maybe I'll leave it as is.
 
Status
Not open for further replies.
Top