// ---------------------------------------------------------------- //
// Passive Cooldown System [GUI Friendly] v1.04 //
// by Flux //
// http://www.hiveworkshop.com/forums/members/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 //
// Even if the name shows "Passive Cooldown", it can be applied on Active Abilities as well //
// (as show in Demo 3) but this system is mostly intended for Passive Abilities. //
// //
// HOW TO IMPORT: //
// 1. Copy the PCD_IndicatorStart and PCD_ValidTargetCheck Ability to your map //
// 2. Copy the PCD_DummyCaster Unit to your map //
// 3. Configure the PCD_DummyCasterId, PCD_IndicatorStartId, PCD_ValidTargetCheckId //
// and PCD_VTCBaseOrderId in PCD System Configuration Trigger. //
// 4. Copy PCD Variable Creator to your map to automatically create the system's variables. //
// Make sure you check the "Automatically create unknown variables while pasting trigger //
// data" in File->Preferences of World Editor. After the variables are created, you can //
// then delete the 'PCD Variable Creator' trigger. //
// //
// //
// HOW TO USE: //
// 1. Set the PCD_Unit variable. This refers to the unit that will have its ability //
// goes into cooldown via trigger. //
// 2. Set the PCD_Ability variable. This refers to the ability that will go into cooldown. //
// 3. Set the PCD_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 PCD_Time variable. This refers how long the PCD_Ability will be replaced by //
// the PCD_DummyAbility. It should match the 'Stats - Cooldown' of the PCD_DummyAbility. //
// 5. Set the PCD_Manacost variable. This is the manacost of the PCD_Ability which should //
// match the manacost of the PCD_DummyAbility 'Stats - Manacost' if you don't want //
// the unit to lose mana when you trigger it's cooldown. //
// 6. Execute by "Trigger - Run Trigger Cooldown System <gen> (checking conditions)" //
// //
// //
// Notes: //
// - When triggering the cooldown of an active ability, it will reset the original //
// ability's cooldown. Example: Original Ability's is on cooldown for 20 seconds but //
// the triggered cooldown only last 5 seconds, when that 5 seconds is finished, //
// the original ability is now ready to be 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 3) //
// //
// Works on: //
// - Invulnerable, Spell Immune, Structures, Ancient, //
// Mechanical, Invisible (but removes it) //
// Does not work on: //
// - Hidden, Cycloned //
// //
// CREDITS: //
// Xonok - for the Spell Block trick to simulate cooldown //
// Wietlol - for finding bugs and suggesting solutions to it. //
//-------------------------------------------------------------------------------------------------//
//-------------------------------------- SYSTEM CORE ----------------------------------------------//
//-------------------------------------------------------------------------------------------------//
function Trig_Passive_Cooldown_System_TimerExpires takes nothing returns nothing
local timer t = GetExpiredTimer()
local integer id = GetHandleId(t)
local unit u = LoadUnitHandle(udg_PCD_Hashtable, id, 0)
local integer origAbil = LoadInteger(udg_PCD_Hashtable, id, 0)
local integer fakeAbil = LoadInteger(udg_PCD_Hashtable, id, 1)
local integer lvl = GetUnitAbilityLevel(u, fakeAbil)
call UnitAddAbility(u, origAbil)
if lvl > 1 then
call SetUnitAbilityLevel(u, origAbil, lvl)
endif
call UnitRemoveAbility(u, fakeAbil)
//Destroy the timer reference data
call FlushChildHashtable(udg_PCD_Hashtable, id)
//Destroy the unit reference data
call FlushChildHashtable(udg_PCD_Hashtable, GetHandleId(u))
call DestroyTimer(t)
set t = null
set u = null
endfunction
function Trig_Passive_Cooldown_System_Execute takes nothing returns boolean
local timer t
local integer id
local integer unitId
local integer lvl
set lvl = GetUnitAbilityLevel(udg_PCD_Unit, udg_PCD_Ability)
call SetUnitX(udg_PCD_DummyCaster, GetUnitX(udg_PCD_Unit))
call SetUnitY(udg_PCD_DummyCaster, GetUnitY(udg_PCD_Unit))
//For checking if it is castable
call SetPlayerAlliance(Player(14), GetOwningPlayer(udg_PCD_Unit), ALLIANCE_PASSIVE, true)
if IssueTargetOrder(udg_PCD_DummyCaster, udg_PCD_VTCBaseOrderId, udg_PCD_Unit) then
if lvl > 0 then
call UnitRemoveAbility(udg_PCD_Unit, udg_PCD_Ability)
else
set lvl = GetUnitAbilityLevel(udg_PCD_Unit, udg_PCD_DummyAbility)
call UnitRemoveAbility(udg_PCD_Unit, udg_PCD_DummyAbility)
endif
//Add the fake ability
call UnitAddAbility(udg_PCD_Unit, udg_PCD_DummyAbility)
call SetUnitAbilityLevel(udg_PCD_Unit, udg_PCD_DummyAbility, lvl)
call IssueTargetOrderById(udg_PCD_DummyCaster, 852075, udg_PCD_Unit)
set unitId = GetHandleId(udg_PCD_Unit)
//[unitId][5] is for timers
//If there is already a timer, just reset it
if HaveSavedHandle(udg_PCD_Hashtable, unitId, udg_PCD_Ability) then
call TimerStart(LoadTimerHandle(udg_PCD_Hashtable, unitId, udg_PCD_Ability), udg_PCD_Time, false, function Trig_Passive_Cooldown_System_TimerExpires)
else
set t = CreateTimer()
set id = GetHandleId(t)
//Save the timer in reference to the unit
call SaveTimerHandle(udg_PCD_Hashtable, unitId, udg_PCD_Ability, t)
call TimerStart(t, udg_PCD_Time, false, function Trig_Passive_Cooldown_System_TimerExpires)
set t = null
//Save the unit
call SaveUnitHandle(udg_PCD_Hashtable, id, 0, udg_PCD_Unit)
//Save the original ability replaced
call SaveInteger(udg_PCD_Hashtable, id, 0, udg_PCD_Ability)
//Save the fake ability
call SaveInteger(udg_PCD_Hashtable, id, 1, udg_PCD_DummyAbility)
endif
if udg_PCD_Manacost > 0 then
call SetUnitState(udg_PCD_Unit, UNIT_STATE_MANA, GetUnitState(udg_PCD_Unit, UNIT_STATE_MANA) + udg_PCD_Manacost)
endif
endif
call SetPlayerAlliance(Player(14), GetOwningPlayer(udg_PCD_Unit), ALLIANCE_PASSIVE, false)
return false
endfunction
function Trig_Passive_Cooldown_System_LastInit takes nothing returns nothing
set udg_PCD_DummyCaster = CreateUnit(Player(14), udg_PCD_DummyCasterId, 0, 0, 0)
call SetHeroLevel(udg_PCD_DummyCaster, 6, false)
call UnitAddAbility(udg_PCD_DummyCaster, udg_PCD_IndicatorStartId)
call SelectHeroSkill(udg_PCD_DummyCaster, udg_PCD_IndicatorStartId)
call UnitAddAbility(udg_PCD_DummyCaster, udg_PCD_ValidTargetCheckId)
call DestroyTimer(GetExpiredTimer())
endfunction
//===========================================================================
function InitTrig_Passive_Cooldown_System takes nothing returns nothing
set gg_trg_Passive_Cooldown_System = CreateTrigger()
set udg_PCD_Hashtable = InitHashtable()
call TimerStart(CreateTimer(), 0, false, function Trig_Passive_Cooldown_System_LastInit)
call TriggerAddCondition(gg_trg_Passive_Cooldown_System, Condition(function Trig_Passive_Cooldown_System_Execute))
endfunction