Manage combat music with a quest, removed _00E_CombatSoundtrackScript from 800+ objects
This commit is contained in:
parent
e15bec3672
commit
fbbf0bd7f7
BIN
CombatMusicControl update.esp
Normal file
BIN
CombatMusicControl update.esp
Normal file
Binary file not shown.
BIN
SKSE/Plugins/EnderalSE.dll
(Stored with Git LFS)
BIN
SKSE/Plugins/EnderalSE.dll
(Stored with Git LFS)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -12,6 +12,7 @@ void EventListener::Install()
|
|||||||
//RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESContainerChangedEvent>(EventListener::GetSingleton());
|
//RE::ScriptEventSourceHolder::GetSingleton()->AddEventSink<RE::TESContainerChangedEvent>(EventListener::GetSingleton());
|
||||||
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
||||||
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
||||||
|
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESCombatEvent>()->AddEventSink(EventListener::GetSingleton());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EventListener::ProcessEvent(
|
auto EventListener::ProcessEvent(
|
||||||
@ -75,3 +76,26 @@ auto EventListener::ProcessEvent(
|
|||||||
|
|
||||||
return RE::BSEventNotifyControl::kContinue;
|
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;
|
||||||
|
}
|
||||||
|
@ -9,7 +9,8 @@ class EventListener :
|
|||||||
public RE::BSTEventSink<SKSE::ModCallbackEvent>,
|
public RE::BSTEventSink<SKSE::ModCallbackEvent>,
|
||||||
public RE::BSTEventSink<RE::TESContainerChangedEvent>,
|
public RE::BSTEventSink<RE::TESContainerChangedEvent>,
|
||||||
public RE::BSTEventSink<RE::MenuOpenCloseEvent>,
|
public RE::BSTEventSink<RE::MenuOpenCloseEvent>,
|
||||||
public RE::BSTEventSink<RE::TESActivateEvent>
|
public RE::BSTEventSink<RE::TESActivateEvent>,
|
||||||
|
public RE::BSTEventSink<RE::TESCombatEvent>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~EventListener() = default;
|
~EventListener() = default;
|
||||||
@ -26,7 +27,6 @@ public:
|
|||||||
RE::BSTEventSource<RE::TESContainerChangedEvent>* a_eventSource)
|
RE::BSTEventSource<RE::TESContainerChangedEvent>* a_eventSource)
|
||||||
-> RE::BSEventNotifyControl override;
|
-> RE::BSEventNotifyControl override;
|
||||||
|
|
||||||
|
|
||||||
auto ProcessEvent(
|
auto ProcessEvent(
|
||||||
const RE::MenuOpenCloseEvent* a_event,
|
const RE::MenuOpenCloseEvent* a_event,
|
||||||
RE::BSTEventSource<RE::MenuOpenCloseEvent>* a_eventSource)
|
RE::BSTEventSource<RE::MenuOpenCloseEvent>* a_eventSource)
|
||||||
@ -42,6 +42,11 @@ public:
|
|||||||
RE::BSTEventSource<RE::TESActivateEvent>* a_eventSource)
|
RE::BSTEventSource<RE::TESActivateEvent>* a_eventSource)
|
||||||
-> RE::BSEventNotifyControl override;
|
-> RE::BSEventNotifyControl override;
|
||||||
|
|
||||||
|
auto ProcessEvent(
|
||||||
|
const RE::TESCombatEvent* a_event,
|
||||||
|
RE::BSTEventSource<RE::TESCombatEvent>* a_eventSource)
|
||||||
|
-> RE::BSEventNotifyControl override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventListener() = default;
|
EventListener() = default;
|
||||||
};
|
};
|
@ -103,6 +103,25 @@ namespace Papyrus::PapyrusFunctions
|
|||||||
return ComputeNeededExpPoints(CurrentLevel, Slope, Mult, fExpAcc, fExpAcc_Level20, fExpAcc_Level30, fExpAcc_Level40);
|
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)
|
inline void Bind(VM& a_vm)
|
||||||
{
|
{
|
||||||
BIND(CreatePotion);
|
BIND(CreatePotion);
|
||||||
@ -123,5 +142,7 @@ namespace Papyrus::PapyrusFunctions
|
|||||||
logger::info("{}", "Registered EnableDialogueQuitting"sv);
|
logger::info("{}", "Registered EnableDialogueQuitting"sv);
|
||||||
BIND(ComputeNeededExp);
|
BIND(ComputeNeededExp);
|
||||||
logger::info("{}", "Registered ComputeNeededExp"sv);
|
logger::info("{}", "Registered ComputeNeededExp"sv);
|
||||||
|
BIND(IsInRegion);
|
||||||
|
logger::info("{}", "Registered IsInRegion"sv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,8 @@ Event OnInit()
|
|||||||
EndEvent
|
EndEvent
|
||||||
|
|
||||||
Function InitCombatMusic()
|
Function InitCombatMusic()
|
||||||
|
RegisterForModEvent("Enderal_CombatStateChanged", "OnCombatStateChange")
|
||||||
|
|
||||||
If ActiveCombatMusics.Length == 0
|
If ActiveCombatMusics.Length == 0
|
||||||
ActiveCombatMusics = _NewMusicArray()
|
ActiveCombatMusics = _NewMusicArray()
|
||||||
EndIf
|
EndIf
|
||||||
@ -30,6 +32,41 @@ Function InitCombatMusic()
|
|||||||
EndIf
|
EndIf
|
||||||
EndFunction
|
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)
|
Bool Function StartCombatMusic(MusicType newMusic)
|
||||||
; Debug.Trace(self + ", StartCombatMusic, newMusic = " + newMusic)
|
; Debug.Trace(self + ", StartCombatMusic, newMusic = " + newMusic)
|
||||||
|
|
||||||
@ -95,11 +132,9 @@ State CombatMusicTracking
|
|||||||
|
|
||||||
Event OnUpdate()
|
Event OnUpdate()
|
||||||
|
|
||||||
; Debug.Trace("_00E_PlayerFunctions, OnUpdate")
|
|
||||||
|
|
||||||
RegisterForSingleUpdate(3.5)
|
RegisterForSingleUpdate(3.5)
|
||||||
|
|
||||||
If (Game.GetForm(0x14) as Actor).IsInCombat() || CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE
|
If CombatMusicLockLevel > COMBAT_MUSIC_LOCK_NONE || PlayerRef.IsInCombat()
|
||||||
Return
|
Return
|
||||||
EndIf
|
EndIf
|
||||||
|
|
||||||
@ -170,4 +205,17 @@ Function RemoveCombatSoundtracks()
|
|||||||
|
|
||||||
EndFunction
|
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_MUS_AllCombatSoundtracks Auto
|
||||||
|
FormList Property _00E_ActorsCombatMusicEpic Auto
|
||||||
|
|
||||||
|
Form Property Wueste Auto ; Powder Desert
|
||||||
|
|
||||||
|
Actor Property PlayerRef Auto
|
||||||
|
@ -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
|
|
@ -12,25 +12,26 @@ Actor[] function GetPlayerFollowers() native global
|
|||||||
|
|
||||||
; Gets the player hash used to uniquely identify the player's save profile.
|
; Gets the player hash used to uniquely identify the player's save profile.
|
||||||
; RETURN - Returns the player hash as an 8-digit string.
|
; 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.
|
; Converts the given string to it's hexadecimal equivalent. Preserves case.
|
||||||
; a_string - The string to convert to hexadecimal.
|
; a_string - The string to convert to hexadecimal.
|
||||||
; RETURN - Returns the hexadecimal equivalent of the passed string.
|
; 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.
|
; Disables the TAB Key during dialogue. Resets automatically upon dialogue exit via Goodbye.
|
||||||
Function DisableDialogueQuitting() Global Native
|
Function DisableDialogueQuitting() native global
|
||||||
Function EnableDialogueQuitting() Global Native
|
Function EnableDialogueQuitting() native global
|
||||||
|
|
||||||
|
bool function IsInRegion(Form region) native global
|
||||||
|
|
||||||
bool function IsDLLLoaded() global
|
bool function IsDLLLoaded() global
|
||||||
int iVer = SKSE.GetPluginVersion("EnderalSE")
|
return SKSE.GetPluginVersion("EnderalSE") > 0
|
||||||
return iVer > 0
|
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
String Function GetPlayerClassNameGlobal() Global
|
String Function GetPlayerClassNameGlobal() global
|
||||||
{Called by EnderalSE.dll}
|
{Called by EnderalSE.dll}
|
||||||
Quest AffinityQuest = Game.GetFormFromFile(0x1597B, "Enderal - Forgotten Stories.esm") as Quest
|
Quest AffinityQuest = Game.GetFormFromFile(0x1597B, "Enderal - Forgotten Stories.esm") as Quest
|
||||||
return (AffinityQuest.GetAlias(0) as _00E_AffinityControl).GetPlayerClassName()
|
return (AffinityQuest.GetAlias(0) as _00E_AffinityControl).GetPlayerClassName()
|
||||||
|
Loading…
Reference in New Issue
Block a user