188 lines
4.6 KiB
Plaintext
188 lines
4.6 KiB
Plaintext
Scriptname _00E_Game_TalentCooldownSC extends ActiveMagicEffect
|
|
{Script that controls the individual cooldown of talents, rather than have all of them trigger a global cooldown.}
|
|
|
|
Sound Property UISkillsFocus auto
|
|
|
|
_00E_Game_TalentControlSC Player
|
|
Shout[] CooldownShouts
|
|
Float[] CooldownTimes
|
|
Shout CurrentShout
|
|
Bool ShoutIsCoolingDown
|
|
Bool ShoutEquipLocked = False
|
|
Float LastTimeElapsed
|
|
|
|
Float Property IdleUpdatePeriod = 30.0 AutoReadOnly
|
|
|
|
|
|
;=====================================================================================
|
|
; EVENTS
|
|
;=====================================================================================
|
|
|
|
Event OnEffectStart(Actor akTarget, Actor akCaster)
|
|
|
|
LockEquipUpdates()
|
|
|
|
CooldownShouts = New Shout[128]
|
|
CooldownTimes = New Float[128]
|
|
|
|
LastTimeElapsed = 0.0
|
|
|
|
Player = Game.GetPlayer() as _00E_Game_TalentControlSC
|
|
|
|
CurrentShout = Player.GetEquippedShout()
|
|
|
|
UnlockEquipUpdates()
|
|
|
|
Player.RegisterCooldownMagicEffect(self)
|
|
|
|
EndEvent
|
|
|
|
Event OnUpdate()
|
|
If Player.GetVoiceRecoveryTime() <= 0.0 && ShoutIsCoolingDown && (ShoutEquipLocked == False)
|
|
ShoutIsCoolingDown = False
|
|
UISkillsFocus.Play(Player)
|
|
EndIf
|
|
|
|
; Protection against the GetTimeElapsed timer getting stuck
|
|
Float curTimeElapsed = GetTimeElapsed()
|
|
If LastTimeElapsed == curTimeElapsed
|
|
Player.RefreshCooldownSpell()
|
|
Else
|
|
LastTimeElapsed = curTimeElapsed
|
|
RegisterNextUpdate(ResetLastTimeElapsed = False)
|
|
EndIf
|
|
EndEvent
|
|
|
|
Event OnObjectEquipped(Form equippedObject, ObjectReference reference)
|
|
; Is it a shout being equipped?
|
|
Shout equippedShout = equippedObject as Shout
|
|
If !equippedShout
|
|
Return
|
|
EndIf
|
|
|
|
LockEquipUpdates()
|
|
|
|
; Save the old shout's cooldown
|
|
If CurrentShout
|
|
SaveShoutRecoveryTime(CurrentShout, Player.GetVoiceRecoveryTime())
|
|
EndIf
|
|
|
|
; Restore the newly equipped shout's cooldown
|
|
; Due to the Waits and stuff above, it's better to get the equipped shout again.
|
|
equippedShout = Player.GetEquippedShout()
|
|
If equippedShout && equippedShout != CurrentShout
|
|
CurrentShout = equippedShout
|
|
|
|
Float recoveryTime = 0.0
|
|
Int Index = FindShoutIndex(equippedShout)
|
|
If Index >= 0
|
|
recoveryTime = CooldownTimes[Index] - GetTimeElapsed()
|
|
If recoveryTime < 0.0
|
|
recoveryTime = 0.0
|
|
EndIf
|
|
EndIf
|
|
Player.SetVoiceRecoveryTime(recoveryTime)
|
|
EndIf
|
|
|
|
UnlockEquipUpdates()
|
|
EndEvent
|
|
|
|
;=====================================================================================
|
|
; FUNCTIONS
|
|
;=====================================================================================
|
|
|
|
Function LockEquipUpdates()
|
|
While ShoutEquipLocked
|
|
Utility.WaitMenuMode(0.01)
|
|
EndWhile
|
|
ShoutEquipLocked = True
|
|
EndFunction
|
|
|
|
Function UnlockEquipUpdates()
|
|
RegisterNextUpdate()
|
|
ShoutEquipLocked = False
|
|
EndFunction
|
|
|
|
Int Function FindShoutIndex(Shout s)
|
|
Int Index = 0
|
|
Int nShouts = CooldownShouts.Length
|
|
While Index < nShouts && CooldownShouts[Index]
|
|
If CooldownShouts[Index] == s
|
|
Return Index
|
|
Else
|
|
Index += 1
|
|
EndIf
|
|
EndWhile
|
|
|
|
Return -1
|
|
EndFunction
|
|
|
|
Int Function FindShoutOrNoneIndex(Shout s)
|
|
Int Index = 0
|
|
Int nShouts = CooldownShouts.Length
|
|
While Index < nShouts && CooldownShouts[Index] != s && CooldownShouts[Index]
|
|
Index += 1
|
|
EndWhile
|
|
|
|
If Index >= nShouts
|
|
Debug.Notification("_00E_Game_TalentCooldownSC has run out of free shout slots")
|
|
Return -1
|
|
EndIf
|
|
|
|
Return Index
|
|
EndFunction
|
|
|
|
Function SaveShoutRecoveryTime(Shout targetShout, Float recoveryTime)
|
|
Int Index
|
|
If recoveryTime > 0.0
|
|
Index = FindShoutOrNoneIndex(targetShout)
|
|
If Index >= 0
|
|
CooldownShouts[Index] = targetShout ; In case it's None
|
|
CooldownTimes[Index] = recoveryTime + GetTimeElapsed()
|
|
EndIf
|
|
Else ; recoveryTime < 0.0
|
|
Index = FindShoutIndex(targetShout)
|
|
If Index >= 0
|
|
CooldownTimes[Index] = 0
|
|
EndIf
|
|
EndIf
|
|
EndFunction
|
|
|
|
Function RegisterNextUpdate(Bool ResetLastTimeElapsed = True)
|
|
If ResetLastTimeElapsed
|
|
LastTimeElapsed = -1
|
|
EndIf
|
|
|
|
Float recoveryTime = Player.GetVoiceRecoveryTime()
|
|
|
|
ShoutIsCoolingDown = (recoveryTime > 0.0)
|
|
|
|
If recoveryTime > 0.0 && recoveryTime < IdleUpdatePeriod
|
|
RegisterForSingleUpdate(recoveryTime)
|
|
Else
|
|
RegisterForSingleUpdate(IdleUpdatePeriod)
|
|
EndIf
|
|
EndFunction
|
|
|
|
; Called from _00E_Game_TalentCooldownSC
|
|
Function OnShoutCast()
|
|
RegisterNextUpdate()
|
|
EndFunction
|
|
|
|
Function SetShoutRecoveryTime(Shout targetShout, Float newRecoveryTime)
|
|
If !targetShout
|
|
Debug.Trace("_00E_Game_TalentCooldownSC: SetShoutRecoveryTime got empty targetShout")
|
|
Return
|
|
EndIf
|
|
|
|
LockEquipUpdates()
|
|
|
|
If CurrentShout == targetShout
|
|
Player.SetVoiceRecoveryTime(newRecoveryTime)
|
|
Else
|
|
SaveShoutRecoveryTime(targetShout, newRecoveryTime)
|
|
EndIf
|
|
|
|
UnlockEquipUpdates()
|
|
EndFunction
|