enderalse/scripts/source/_00e_playerfunctions.psc

198 lines
5.0 KiB
Plaintext

Scriptname _00E_PlayerFunctions extends actor
;=====================================================================================
; Equip/unequip torches
;=====================================================================================
Int Function GetHandSlotEx(int iHand)
; By default, iHand = 0 for left hand, 1 for right hand
; In SKSE's "Equip Ex" functions though: iHand = 2 for left hand, 1 for right hand
Return 2 - iHand
EndFunction
Bool Function UnequipTorches(Form[] equippedTorches)
Bool unequipping = False
Int iHand = 0
While iHand < equippedTorches.Length
If GetEquippedItemType(iHand) == 11 ; A torch is in the hand?
Form torch = GetEquippedObject(iHand)
If torch
UnequipItemEx(torch, GetHandSlotEx(iHand))
equippedTorches[iHand] = torch
unequipping = True
EndIf
EndIf
iHand += 1
EndWhile
Return unequipping
EndFunction
Function ReequipTorches(Form[] equippedTorches)
Int iHand = 0
While iHand < equippedTorches.Length
Form torch = equippedTorches[iHand]
If torch
If GetItemCount(torch) > 0
EquipItemEx(torch, GetHandSlotEx(iHand), False, True)
EndIf
; "Forget" about the form to not keep it persistent if equippedTorches is a script's property or variable
equippedTorches[iHand] = None
EndIf
iHand += 1
EndWhile
EndFunction
;=====================================================================================
; Combat music control
;=====================================================================================
MusicType[] ActiveCombatMusics
MusicType[] StoppingCombatMusics
Int StoppingCombatMusicCounter = 0
Int Property COMBAT_MUSIC_LOCK_NONE = 0 AutoReadOnly
Int Property COMBAT_MUSIC_LOCK_START = 1 AutoReadOnly
Int Property COMBAT_MUSIC_LOCK_STOP = 2 AutoReadOnly
Int Property COMBAT_MUSIC_LOCK_FAILSAFE = 3 AutoReadOnly
Int CombatMusicLockLevel = 0 ; = COMBAT_MUSIC_LOCK_NONE
Function InitCombatMusic()
If ActiveCombatMusics.Length == 0
ActiveCombatMusics = _NewMusicArray()
EndIf
If StoppingCombatMusics.Length == 0
StoppingCombatMusics = _NewMusicArray()
EndIf
If StoppingCombatMusicCounter > 0 || ActiveCombatMusics[0]
GoToState("CombatMusicTracking")
EndIf
EndFunction
Bool Function StartCombatMusic(MusicType newMusic)
; Debug.Trace(self + ", StartCombatMusic, newMusic = " + newMusic)
Bool result = False
While CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE
Utility.Wait(0.03) ; wait for two frames
EndWhile
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_START
Int Index = _AddUniqueMusicToArray(ActiveCombatMusics, newMusic)
If Index >= 0
ActiveCombatMusics[Index].Add()
result = (Index == 0) ; Is this the first combat music in this fight?
EndIf
StoppingCombatMusicCounter = 0
GoToState("CombatMusicTracking")
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_NONE
Return result
EndFunction
Function StopCombatMusic()
; Debug.Trace(self + ", StopCombatMusic")
While CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE
If CombatMusicLockLevel == COMBAT_MUSIC_LOCK_START || CombatMusicLockLevel == COMBAT_MUSIC_LOCK_STOP
Return
EndIf
Utility.Wait(0.03)
EndWhile
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_STOP
Int Index = 0
While Index < ActiveCombatMusics.Length && ActiveCombatMusics[Index]
ActiveCombatMusics[Index].Remove()
_AddUniqueMusicToArray(StoppingCombatMusics, ActiveCombatMusics[Index])
Index += 1
EndWhile
ActiveCombatMusics = _NewMusicArray()
StoppingCombatMusicCounter = 8
GoToState("CombatMusicTracking")
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_NONE
EndFunction
State CombatMusicTracking
Event OnUpdate()
; _00E_EPUpdateFunctions that is also attached to the player, does the job of registering for updates.
; That's why there is no RegisterForUpdate anywhere in this script.
; Debug.Trace("_00E_PlayerFunctions, OnUpdate")
If IsInCombat() || CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE
Return
EndIf
If StoppingCombatMusicCounter > 0
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_FAILSAFE
; Debug.Trace(self + ", OnUpdate: failsaving")
Int Index = 0
While Index < StoppingCombatMusics.Length && StoppingCombatMusics[Index]
StoppingCombatMusics[Index].Add()
StoppingCombatMusics[Index].Remove()
Index += 1
EndWhile
StoppingCombatMusicCounter -= 1
If StoppingCombatMusicCounter <= 0
StoppingCombatMusics = _NewMusicArray()
EndIf
CombatMusicLockLevel = COMBAT_MUSIC_LOCK_NONE
ElseIf ActiveCombatMusics[0] ; Failsafe in case StopCombatMusic is not called for whatever reason
StopCombatMusic()
Else
GoToState("")
EndIf
EndEvent
EndState
MusicType[] Function _NewMusicArray()
Return New MusicType[10]
EndFunction
Int Function _AddUniqueMusicToArray(MusicType[] musics, MusicType newMusic)
Int n = musics.Length
Int Index = 0
; Loop through array until we reach the end or newMusic or an empty entry
While Index < n && musics[Index] != newMusic && musics[Index] != None
Index += 1
EndWhile
If Index < n && musics[Index] == None
musics[Index] = newMusic
Return Index
Else
Return -1
EndIf
EndFunction