enderalse/scripts/source/_00e_game_talentcooldownsc.psc

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