Jesus4Lyf
Good Idea™
- Reaction score
- 397
Can you tell us where in the code that is?
Warning SetTimerStructA(1048718, 0) - index: 270, collision: 1
library DynamicCooldown initializer Init_DynamicCooldown uses ABC,DynamicCooldownDatabase
globals
private constant integer MAX_ABILITY = 4
private group DC_Group = CreateGroup()
endglobals
private function Fake takes integer whichslot returns integer
if whichslot == 0 then
return 039;A000039;
elseif whichslot == 1 then
return 039;A001039;
elseif whichslot == 2 then
return 039;A002039;
elseif whichslot == 3 then
return 039;A003039;
endif
return 0
endfunction
struct Skill
integer abid
integer slot
integer fake
real cd
unit u
boolean ready
endstruct
struct CD
Skill array S [MAX_ABILITY]
timer array T [MAX_ABILITY]
unit u
static method remove takes nothing returns nothing
local Skill skill = GetTimerStructA(GetExpiredTimer())
call PauseTimer(GetExpiredTimer())
call SetPlayerAbilityAvailable(GetOwningPlayer(skill.u),skill.abid,true)
call SetPlayerAbilityAvailable(GetOwningPlayer(skill.u),Fake(skill.slot),false)
call UnitResetCooldown(skill.u)
call BJDebugMsg("|cffffcc00"+GetAbilityName(skill.abid)+"|r is ready!")
set skill.ready=true
call ClearTimerStructA(GetExpiredTimer())
endmethod
method add takes integer abid returns nothing
local integer level = GetUnitAbilityLevel(this.u,abid)
local integer whichslot = slot[abid]
set this.S[whichslot].cd = DC_Base(abid,level)
set this.S[whichslot].ready = false
call BJDebugMsg("Player|cffffcc00"+I2S(GetPlayerId(GetOwningPlayer(this.u)))+"039;|rs |cffffcc00"+GetUnitName(this.u)+"|r has casted the skill: |cffffcc00"+GetAbilityName(abid))
call BJDebugMsg("Skill039;s level is: |cffffcc00"+I2S(level))
call BJDebugMsg("Skill039;s cooldown: |cffffcc00"+R2S(this.S[whichslot].cd))
call BJDebugMsg("Testskill039;s level is: |cffffcc00"+I2S(GetUnitAbilityLevel(this.u,039;TEST039;)))
call SetPlayerAbilityAvailable(GetOwningPlayer(this.u),abid,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(this.u),Fake(whichslot),true)
call SetTimerStructA(this.T[whichslot],this.S[whichslot])
call TimerStart(this.T[whichslot],this.S[whichslot].cd,false,function CD.remove)
endmethod
method make takes integer abid returns nothing
local integer level = GetUnitAbilityLevel(this.u,abid)
local integer whichslot = slot[abid]
set this.S[whichslot].u = this.u
set this.S[whichslot].slot = whichslot
set this.S[whichslot].abid = abid
set this.S[whichslot].fake = Fake(whichslot)
if this.T[whichslot] == null then
set this.T[whichslot]=CreateTimer()
endif
endmethod
method reset takes integer whichslot returns nothing
if not (this.T[whichslot] == null and this.S[whichslot].cd ==0 ) and this.S[whichslot].ready== false then
call PauseTimer(this.T[whichslot])
call TimerStart(this.T[whichslot],0.0,false,function CD.remove)
endif
endmethod
method resetall takes nothing returns nothing
local integer i=0
loop
exitwhen i>MAX_ABILITY
call this.reset(i)
set i = i + 1
endloop
endmethod
endstruct
globals
CD array DC
endglobals
function SkillCast takes nothing returns nothing
local integer abid=GetSpellAbilityId()
local unit caster = GetTriggerUnit()
local integer level =GetUnitAbilityLevel(caster,abid)
set DC[GetPlayerId(GetOwningPlayer(caster))].u=caster
call DC[GetPlayerId(GetOwningPlayer(caster))].add(abid)
set caster = null
endfunction
function SkillLearn takes nothing returns nothing
local integer abid=GetLearnedSkill()
local unit caster = GetTriggerUnit()
local integer level =GetUnitAbilityLevel(caster,abid)
set DC[GetPlayerId(GetOwningPlayer(caster))].u=caster
call DC[GetPlayerId(GetOwningPlayer(caster))].make(abid)
if GetUnitAbilityLevel(caster,039;A000039;) == 0 then
call UnitAddAbility(caster,039;A000039;)
call UnitAddAbility(caster,039;A001039;)
call UnitAddAbility(caster,039;A002039;)
call UnitAddAbility(caster,039;A003039;)
call SetPlayerAbilityAvailable(GetOwningPlayer(caster),039;A000039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(caster),039;A001039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(caster),039;A002039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(caster),039;A003039;,false)
endif
set caster = null
endfunction
private function Heroes takes nothing returns boolean
return (IsUnitType(GetEnumUnit(),UNIT_TYPE_HERO) == true and IsUnitInGroup(GetEnumUnit(), DC_Group) == false )
endfunction
private function GetHeroes takes nothing returns nothing
call GroupEnumUnitsInRect(DC_Group,bj_mapInitialPlayableArea,Condition(function Heroes))
endfunction
//===========================================================================
function Init_DynamicCooldown takes nothing returns nothing
local trigger t = CreateTrigger( )
local trigger t2= CreateTrigger( )
local trigger t3= CreateTrigger( )
call GroupEnumUnitsInRect(DC_Group,bj_mapInitialPlayableArea,Condition(function Heroes))
call TriggerRegisterEnterRectSimple(t,bj_mapInitialPlayableArea)
call TriggerAddAction(t,function GetHeroes)
call TriggerRegisterAnyUnitEventBJ(t2,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddAction(t2,function SkillCast)
call TriggerRegisterAnyUnitEventBJ(t3,EVENT_PLAYER_HERO_SKILL)
call TriggerAddAction(t3,function SkillLearn)
set t=null
set t2=null
set t3=null
endfunction
endlibrary
edit. System bugged when I had 2 cooldowns going on, and I hit esc few times. It gave me some ABC hash collinsion error. I guess you should use TimerUtils anyways. Its better and kinda standard stuff, if you are planning to submit something like this.
Anyways, Ive always wanted to have some neat cooldown/ability system to manipulate stuff like mana cost and cooldown.
I think it would be neat to get some custom icons with numbers or something, one dummy ability for each second, so you can see the cooldown counting down from 5 to 4 and to 3 and to 2 and so on.
Its pretty damn cool actually.
library Cooldown initializer Init requires PUI, ABC
globals
private constant integer MAX_ABILITY = 4
private integer array DisabledAbilities
private constant integer MaxAbilityPlusOne = MAX_ABILITY + 1
endglobals
struct Slot extends array
private static integer array Data
static method operator []= takes integer id, integer value returns nothing
set thistype.Data[id-(id/8191)*8191] = value
endmethod
static method operator[] takes integer id returns integer
return thistype.Data[id-(id/8191)*8191]
endmethod
endstruct
struct Cooldown extends array
private static hashtable ht = InitHashtable()
static method operator [] takes integer id returns thistype
return id
endmethod
method operator [] takes integer level returns real
return LoadReal(thistype.ht,this,level)
endmethod
method operator []= takes integer level, real value returns nothing
call SaveReal(thistype.ht,this,level,value)
endmethod
endstruct
struct HeroAbilities extends array
private static hashtable ht = InitHashtable()
static method operator [] takes integer pos returns thistype
return pos
endmethod
method operator [] takes integer pos returns integer
return LoadInteger(thistype.ht,this,pos)
endmethod
method operator []= takes integer pos, integer value returns nothing
call SaveInteger(thistype.ht,this,pos,value)
endmethod
endstruct
public struct Data
unit hero
timer array t [MaxAbilityPlusOne]
boolean array ready [MaxAbilityPlusOne]
method reset takes integer pos returns nothing
set .ready[pos] = true
call PauseTimer(.t[pos])
call UnitRemoveAbility(.hero,DisabledAbilities[pos])
call UnitAddAbility(.hero,HeroAbilities[GetUnitTypeId(.hero)][pos])
endmethod
static method removeCooldown takes nothing returns nothing
call thistype(GetTimerStructA(GetExpiredTimer())).reset(GetTimerStructB(GetExpiredTimer()))
endmethod
method add takes nothing returns nothing
local integer abil_id = GetSpellAbilityId()
local integer pos = Slot[abil_id]
local integer lv = 0
if .t[pos] == null then
set .t[pos] = CreateTimer()
call SetTimerStructA(.t[pos],this)
call SetTimerStructB(.t[pos],pos)
endif
set .ready[pos] = false
set lv = GetUnitAbilityLevel(.hero,abil_id)
call UnitRemoveAbility(.hero,abil_id)
call UnitAddAbility(.hero,DisabledAbilities[pos])
call TimerStart(.t[pos],Cooldown[abil_id][lv],false,function thistype.removeCooldown)
call BJDebugMsg("Slot : " + I2S(pos))
call BJDebugMsg("Cooldown : " + R2S(Cooldown[abil_id][lv]))
endmethod
method resetall takes nothing returns nothing
local integer i = 1
loop
call .reset(i)
exitwhen i == MAX_ABILITY
endloop
endmethod
static method create takes unit hero returns thistype
local thistype this = thistype.allocate()
set .hero = hero
return this
endmethod
//! runtextmacro PUI()
endstruct
private function Cond takes nothing returns boolean
if Data[GetTriggerUnit()] == 0 then
set Data[GetTriggerUnit()] = Data.create(GetTriggerUnit())
endif
call Data(Data[GetTriggerUnit()]).add()
return false
endfunction
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_ENDCAST)
call TriggerAddCondition(trig,Condition(function Cond))
//Declare the disabled abilities here.
set DisabledAbilities[1] = 039;A000039;
set DisabledAbilities[2] = 039;A001039;
set DisabledAbilities[3] = 039;A002039;
set DisabledAbilities[4] = 039;A003039;
//
endfunction
endlibrary
library DynamicCooldowns initializer Init uses TimerUtils, AutoIndex, DynamicCooldownDatabase
//===============================================================================
//===============================================================================
globals
private constant integer MAX_SKILL = 4
//===============================================================================
//===============================================================================
private code RemovingFunction
endglobals
private function Fake takes integer whichslot returns integer
if whichslot == 0 then
return 039;A000039;
elseif whichslot == 1 then
return 039;A001039;
elseif whichslot == 2 then
return 039;A002039;
elseif whichslot == 3 then
return 039;A003039;
endif
return 0
endfunction
struct Skill
readonly integer level
readonly integer abid
readonly integer slot
readonly integer fake
readonly boolean ready
readonly real cd
readonly unit unit
readonly timer timer
method startCooldown takes real duration returns nothing
local player owner = GetOwningPlayer(.unit)
set .cd = duration
set .ready = false
debug call BJDebugMsg("Player|cffffcc00"+I2S(GetPlayerId(GetOwningPlayer(.unit)))+"039;|rs |cffffcc00"+GetUnitName(.unit)+"|r has casted the skill: |cffffcc00"+GetAbilityName(abid))
debug call BJDebugMsg("Skill039;s level is: |cffffcc00"+I2S(level))
debug call BJDebugMsg("Skill039;s cooldown: |cffffcc00"+R2S(.cd))
debug call BJDebugMsg("Testskill039;s level is: |cffffcc00"+I2S(GetUnitAbilityLevel(.unit,039;TEST039;)))
call SetPlayerAbilityAvailable(owner,.abid,false)
call SetPlayerAbilityAvailable(owner,Fake(.slot),true)
set .timer=NewTimer()
call SetTimerData(.timer,this)
call TimerStart(.timer,duration,false,RemovingFunction)
endmethod
method stopCooldown takes nothing returns nothing
local player owner=GetOwningPlayer(.unit)
call SetPlayerAbilityAvailable(owner,.abid,true)
call SetPlayerAbilityAvailable(owner,Fake(.slot),false)
call UnitResetCooldown(.unit)
set .ready=true
debug call BJDebugMsg("|cffffcc00"+GetAbilityName(.abid)+"|r is ready!")
endmethod
static method create takes unit u, integer whichslot, integer abid returns Skill
local Skill this=Skill.allocate()
set .unit = u
set .slot = whichslot
set .abid = abid
set .fake = Fake(whichslot)
set .level = GetUnitAbilityLevel(u,abid)
return this
endmethod
static method Expire takes nothing returns nothing
local timer t=GetExpiredTimer()
local Skill skill=GetTimerData(t)
call ReleaseTimer(t)
call skill.stopCooldown()
endmethod
endstruct
struct UnitSkillData
readonly unit unit
private Skill array S [MAX_SKILL]
private static UnitSkillData array array
method startCooldownById takes integer abid returns nothing
local integer level = GetUnitAbilityLevel(this.unit,abid)
local integer whichslot = slot[abid]
local Skill skill = .S[whichslot]
local real duration = DC_Base(abid,level)
call skill.startCooldown( duration )
endmethod
// When hero learns a new skill, call this
method addSkill takes integer abid returns nothing
local integer whichslot = slot[abid]
set .S[whichslot] = Skill.create(.unit,whichslot,abid)
endmethod
method resetCooldownById takes integer whichslot returns nothing
local Skill skill=.S[whichslot]
if skill.cd > 0 and not skill.ready then
call PauseTimer(skill.timer)
call skill.stopCooldown()
endif
endmethod
method resetCooldowns takes nothing returns nothing
local integer i=0
loop
exitwhen i>MAX_SKILL
call .S<i>.stopCooldown()
set i = i + 1
endloop
endmethod
// When new hero is created, this is used to create cooldown data for it
static method create takes unit u returns UnitSkillData
local UnitSkillData this=UnitSkillData.allocate()
set .unit=u
set .array[ GetUnitId(u) ] = this
call UnitAddAbility(u,039;A000039;)
call UnitAddAbility(u,039;A001039;)
call UnitAddAbility(u,039;A002039;)
call UnitAddAbility(u,039;A003039;)
call SetPlayerAbilityAvailable(GetOwningPlayer(u),039;A000039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(u),039;A001039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(u),039;A002039;,false)
call SetPlayerAbilityAvailable(GetOwningPlayer(u),039;A003039;,false)
return this
endmethod
// this is used to get units cooldown data
static method getFromUnit takes unit u returns UnitSkillData
return .array[ GetUnitId( u ) ]
endmethod
endstruct
private function Init takes nothing returns nothing
set RemovingFunction=function Skill.Expire
endfunction
endlibrary
</i>