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() RegisterForModEvent("Enderal_CombatStateChanged", "OnCombatStateChange") If ActiveCombatMusics.Length == 0 ActiveCombatMusics = _NewMusicArray() EndIf If StoppingCombatMusics.Length == 0 StoppingCombatMusics = _NewMusicArray() EndIf If StoppingCombatMusicCounter > 0 || ActiveCombatMusics[0] GoToState("CombatMusicTracking") EndIf EndFunction function IsStartingBrawling() bIsBrawling = true RegisterForSingleUpdate(1.0) endfunction event OnUpdate() bIsBrawling = false endevent Event OnCombatStateChange(string eventName, string bTargetIsPlayer, float fCombatState, Form sender) return if bTargetIsPlayer ; start combat or searching if fCombatState as int == 1 ; combat if bIsBrawling bIsBrawling = false if GetState() == "" UnregisterForUpdate() else StopCombatMusic() endif return endif ; start music Actor sourceActor = sender as Actor Int encounterLevel = sourceActor.GetLevel() If encounterLevel >= 20 || (encounterLevel >= PlayerLevel.GetValue() - 15) || HasKeyword(ActorTypeBoss) MusicType combatMusic if _00E_ActorsCombatMusicEpic.HasForm(sourceActor.GetActorBase()) combatMusic = _00E_Music_Combat_Epic elseif EnderalFunctions.IsInRegion(Wueste) combatMusic = _00E_Music_Combat_Exotic else combatMusic = _00E_Music_Combat_Regular endif if StartCombatMusic(combatMusic) RegisterForSingleUpdate(5.0) EndIf EndIf elseif ! PlayerRef.IsInCombat() if GetState() == "" GoToState("CombatMusicTracking") endif RegisterForSingleUpdate(2.0) endif elseif ! PlayerRef.IsInCombat() if GetState() == "" GoToState("CombatMusicTracking") endif RegisterForSingleUpdate(2.0) endif endEvent 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() RegisterForSingleUpdate(3.5) If CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE || PlayerRef.IsInCombat() 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 bool bIsBrawling = false Keyword Property ActorTypeBoss Auto GlobalVariable Property PlayerLevel Auto MusicType Property _00E_Music_Combat_Regular Auto MusicType Property _00E_Music_Combat_Exotic Auto MusicType Property _00E_Music_Combat_Epic Auto FormList Property _00E_MUS_AllCombatSoundtracks Auto FormList Property _00E_ActorsCombatMusicEpic Auto Form Property Wueste Auto ; Powder Desert Actor Property PlayerRef Auto