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