Manage combat music with a quest, removed _00E_CombatSoundtrackScript from 800+ objects

This commit is contained in:
Eddoursul 2024-01-15 02:47:42 +01:00
parent e15bec3672
commit fbbf0bd7f7
11 changed files with 114 additions and 53 deletions

Binary file not shown.

BIN
SKSE/Plugins/EnderalSE.dll (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -12,6 +12,7 @@ void EventListener::Install()
//RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESContainerChangedEvent>(EventListener::GetSingleton());
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESCombatEvent>()->AddEventSink(EventListener::GetSingleton());
}
auto EventListener::ProcessEvent(
@ -75,3 +76,26 @@ auto EventListener::ProcessEvent(
return RE::BSEventNotifyControl::kContinue;
}
auto EventListener::ProcessEvent(
const RE::TESCombatEvent* a_event,
RE::BSTEventSource<RE::TESCombatEvent>* a_eventSource)
-> RE::BSEventNotifyControl
{
if (!a_event) {
return RE::BSEventNotifyControl::kContinue;
}
RE::Actor* sourceActor = a_event->actor ? a_event->actor->As<RE::Actor>() : nullptr;
if (!sourceActor) {
return RE::BSEventNotifyControl::kContinue;
}
RE::Actor* targetActor = a_event->targetActor ? a_event->targetActor->As<RE::Actor>() : nullptr;
SKSE::ModCallbackEvent modEvent{ "Enderal_CombatStateChanged", targetActor && targetActor->IsPlayerRef() ? "1" : "", a_event->newState.underlying(), sourceActor };
SKSE::GetModCallbackEventSource()->SendEvent(&modEvent);
return RE::BSEventNotifyControl::kContinue;
}

View File

@ -9,7 +9,8 @@ class EventListener :
public RE::BSTEventSink<SKSE::ModCallbackEvent>,
public RE::BSTEventSink<RE::TESContainerChangedEvent>,
public RE::BSTEventSink<RE::MenuOpenCloseEvent>,
public RE::BSTEventSink<RE::TESActivateEvent>
public RE::BSTEventSink<RE::TESActivateEvent>,
public RE::BSTEventSink<RE::TESCombatEvent>
{
public:
~EventListener() = default;
@ -26,7 +27,6 @@ public:
RE::BSTEventSource<RE::TESContainerChangedEvent>* a_eventSource)
-> RE::BSEventNotifyControl override;
auto ProcessEvent(
const RE::MenuOpenCloseEvent* a_event,
RE::BSTEventSource<RE::MenuOpenCloseEvent>* a_eventSource)
@ -42,6 +42,11 @@ public:
RE::BSTEventSource<RE::TESActivateEvent>* a_eventSource)
-> RE::BSEventNotifyControl override;
auto ProcessEvent(
const RE::TESCombatEvent* a_event,
RE::BSTEventSource<RE::TESCombatEvent>* a_eventSource)
-> RE::BSEventNotifyControl override;
private:
EventListener() = default;
};

View File

@ -103,6 +103,25 @@ namespace Papyrus::PapyrusFunctions
return ComputeNeededExpPoints(CurrentLevel, Slope, Mult, fExpAcc, fExpAcc_Level20, fExpAcc_Level30, fExpAcc_Level40);
}
bool IsInRegion(RE::StaticFunctionTag*, RE::TESForm* playerRegion)
{
auto* parentCell = RE::PlayerCharacter::GetSingleton()->parentCell;
if (!parentCell) {
return false;
}
auto regions = parentCell->GetRegionList(false);
for (auto it = regions->begin(); it != regions->end(); it++) {
if ((*it)->formID == playerRegion->formID) {
return true;
}
}
return false;
}
inline void Bind(VM& a_vm)
{
BIND(CreatePotion);
@ -123,5 +142,7 @@ namespace Papyrus::PapyrusFunctions
logger::info("{}", "Registered EnableDialogueQuitting"sv);
BIND(ComputeNeededExp);
logger::info("{}", "Registered ComputeNeededExp"sv);
BIND(IsInRegion);
logger::info("{}", "Registered IsInRegion"sv);
}
}

View File

@ -17,6 +17,8 @@ Event OnInit()
EndEvent
Function InitCombatMusic()
RegisterForModEvent("Enderal_CombatStateChanged", "OnCombatStateChange")
If ActiveCombatMusics.Length == 0
ActiveCombatMusics = _NewMusicArray()
EndIf
@ -30,6 +32,41 @@ Function InitCombatMusic()
EndIf
EndFunction
Event OnCombatStateChange(string eventName, string bTargetIsPlayer, float fCombatState, Form sender)
if bTargetIsPlayer ; start combat or searching
if fCombatState as int == 1 ; combat
; 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)
@ -95,11 +132,9 @@ State CombatMusicTracking
Event OnUpdate()
; Debug.Trace("_00E_PlayerFunctions, OnUpdate")
RegisterForSingleUpdate(3.5)
If (Game.GetForm(0x14) as Actor).IsInCombat() || CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE
If CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE || PlayerRef.IsInCombat()
Return
EndIf
@ -170,4 +205,17 @@ Function RemoveCombatSoundtracks()
EndFunction
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

View File

@ -1,38 +0,0 @@
Scriptname _00E_CombatSoundtrackScript extends Actor
Event OnUpdate()
Actor player = Game.GetForm(0x14) as Actor
If player.IsInCombat()
RegisterForSingleUpdate(2.0)
ElseIf Triggered
Triggered = False
_00E_PlayerFunctions.GetCombatMusicControl().StopCombatMusic()
EndIf
EndEvent
Event OnCombatStateChanged(Actor akTarget, int aeCombatState)
If !_00E_Music_Combat_Regular
Debug.Trace(self + ": _00E_Music_Combat_Regular property is empty")
Return
EndIf
If aeCombatState == 1
Actor player = Game.GetForm(0x14) as Actor
If akTarget == player
Int encounterLevel = GetLevel()
If encounterLevel >= 20 || (encounterLevel >= (PlayerLevel.GetValue() - 15)) || HasKeyword(ActorTypeBoss) ; Frage ab ob Gegnerstufe über Spielerstufe oder Boss ist, wenn ja spiele Combatmusic
If Triggered == False ; player.IsInCombat() &&
Triggered = _00E_PlayerFunctions.GetCombatMusicControl().StartCombatMusic(_00E_Music_Combat_Regular)
If Triggered
RegisterForSingleUpdate(5.0)
EndIf
EndIf
EndIf
EndIf
EndIf
EndEvent
MusicType Property _00E_Music_Combat_Regular Auto
GlobalVariable Property PlayerLevel Auto
Keyword Property ActorTypeBoss Auto
Bool Triggered = False

View File

@ -12,25 +12,26 @@ Actor[] function GetPlayerFollowers() native global
; Gets the player hash used to uniquely identify the player's save profile.
; RETURN - Returns the player hash as an 8-digit string.
String Function GetPlayerHash() Global Native
String Function GetPlayerHash() native global
; Converts the given string to it's hexadecimal equivalent. Preserves case.
; a_string - The string to convert to hexadecimal.
; RETURN - Returns the hexadecimal equivalent of the passed string.
String Function StringToHex(String a_string) Global Native
String Function StringToHex(String a_string) native global
float function ComputeNeededExp(int CurrentLevel, float Slope, float Mult, float fExpAcc = 1.0, float fExpAcc_Level20 = 1.2, float fExpAcc_Level30 = 1.5, float fExpAcc_Level40 = 2.0) global native
float function ComputeNeededExp(int CurrentLevel, float Slope, float Mult, float fExpAcc = 1.0, float fExpAcc_Level20 = 1.2, float fExpAcc_Level30 = 1.5, float fExpAcc_Level40 = 2.0) native global
; Disables the TAB Key during dialogue. Resets automatically upon dialogue exit via Goodbye.
Function DisableDialogueQuitting() Global Native
Function EnableDialogueQuitting() Global Native
Function DisableDialogueQuitting() native global
Function EnableDialogueQuitting() native global
bool function IsInRegion(Form region) native global
bool function IsDLLLoaded() global
int iVer = SKSE.GetPluginVersion("EnderalSE")
return iVer > 0
return SKSE.GetPluginVersion("EnderalSE") > 0
endfunction
String Function GetPlayerClassNameGlobal() Global
String Function GetPlayerClassNameGlobal() global
{Called by EnderalSE.dll}
Quest AffinityQuest = Game.GetFormFromFile(0x1597B, "Enderal - Forgotten Stories.esm") as Quest
return (AffinityQuest.GetAlias(0) as _00E_AffinityControl).GetPlayerClassName()