Scriptname _00E_CombatMusicControl extends Quest Hidden 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 Event OnInit() ; Yes, OnInit() runs in idle quests as well InitCombatMusic() ; also called from OnPlayerLoadGame() in _00E_PlayerFunctions EndEvent 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 OnBeginState() RegisterForSingleUpdate(0.1) EndEvent Event OnEndState() UnregisterForUpdate() EndEvent Event OnUpdate() ; Debug.Trace("_00E_PlayerFunctions, OnUpdate") RegisterForSingleUpdate(3.5) If (Game.GetForm(0x14) as Actor).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 Function RemoveCombatSoundtracks() int iIndex = _00E_MUS_AllCombatSoundtracks.GetSize() while iIndex > 0 iIndex -= 1 MusicType musicToRemove = _00E_MUS_AllCombatSoundtracks.GetAt(iIndex) as MusicType musicToRemove.Remove() endwhile EndFunction FormList Property _00E_MUS_AllCombatSoundtracks Auto