From fb7adc4ebfae36136ebcf099f495b3574520e91d Mon Sep 17 00:00:00 2001 From: shad0wshayd3 Date: Sat, 11 May 2024 17:06:26 +0000 Subject: [PATCH] chore: style formatting --- Plugin/src/Hooks/Hooks.h | 633 ++++++++++----------- Plugin/src/MCM/MCM.cpp | 52 +- Plugin/src/MCM/MCM.h | 166 +++--- Plugin/src/Menus/PowerArmorConditionMenu.h | 408 ++++++------- Plugin/src/PCH.cpp | 74 +-- Plugin/src/PCH.h | 56 +- Plugin/src/Scripts/Papyrus.h | 48 +- Plugin/src/Settings.h | 92 +-- Plugin/src/main.cpp | 196 +++---- 9 files changed, 862 insertions(+), 863 deletions(-) diff --git a/Plugin/src/Hooks/Hooks.h b/Plugin/src/Hooks/Hooks.h index 995a9e1..ca2ceb9 100644 --- a/Plugin/src/Hooks/Hooks.h +++ b/Plugin/src/Hooks/Hooks.h @@ -1,317 +1,316 @@ -#pragma once - -#include "MCM/MCM.h" -#include "Menus/PowerArmorConditionMenu.h" - -class Hooks -{ -public: - static void Install() - { - hkGetPowerArmorShouldBeVisible<1402809, 0x1D>::Install(); // HUDActionPointMeter::CanPlaySoundEffects - hkGetPowerArmorShouldBeVisible<742970, 0x190>::Install(); // HUDActiveEffectsDisplay::UpdateDisplayObject - hkGetPowerArmorShouldBeVisible<756668, 0x5D9>::Install(); // HUDCompassMarker::SetCompassMarkerData - hkGetPowerArmorShouldBeVisible<259269, 0xB6>::Install(); // HUDMarkerData::GetMinorFrame - hkGetPowerArmorShouldBeVisible<1511766, 0x107>::Install(); // PowerArmorGeometry::UpdatePowerArmorHUD - hkSetPowerArmorMode<1187476, 0xE6B>::Install(); // PowerArmor::SwitchToPowerArmor - hkSetPowerArmorMode<1150710, 0x1E8>::Install(); // PowerArmor::SwitchFromPowerArmorFurnitureLoaded - hkQActorInPowerArmor<31293, 0x14C, false>::Install(); // HUDRadiationModel::CalcEnvDamage - hkQActorInPowerArmor<733718, 0xA8, false>::Install(); // HUDMenu::InitializeHUD - hkQActorInPowerArmorPAHC<34363, 0x2D>::Install(); // HUDMenuUtils::GetGameplayHUDColor - hkCanBeVisible<893789, 0x12>::Install(); // HUDCompass::CanBeVisible - hkGetPowerArmorHUDColor<523665, 0x56>::Install(); // GameUIModel::SetGameColors - } - - static void InstallPostLoad() - { - MCM::Settings::Update(); - Menus::Register(); - - if (auto PlayerCharacter = RE::PlayerCharacter::GetSingleton()) - { - if (auto EventSource = - static_cast< - RE::BSTEventSource< - RE::ActorValueEvents::ActorValueChangedEvent>*>( - PlayerCharacter)) - { - EventSource->RegisterSink(ActorValueChangedHandler::GetSingleton()); - } - } - } - -private: - class detail - { - public: - static bool IsExempt() - { - if (!MCM::Settings::General::bEnable) - { - return true; - } - - return false; - } - - template - static void Notify() - { - if (auto EventSource = T::GetEventSource()) - { - auto eventData = T{}; - EventSource->Notify(eventData); - } - } - - template - static void Notify(bool a_value) - { - if (auto EventSource = T::GetEventSource()) - { - auto eventData = T{ a_value }; - EventSource->Notify(eventData); - } - } - }; - - template - class hkGetPowerArmorShouldBeVisible - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _GetPowerArmorShouldBeVisible = trampoline.write_call<5>(target.address(), GetPowerArmorShouldBeVisible); - } - - private: - static bool GetPowerArmorShouldBeVisible( - [[maybe_unused]] RE::PowerArmorGeometry* a_this) - { - if (detail::IsExempt()) - { - return _GetPowerArmorShouldBeVisible(a_this); - } - - return false; - } - - inline static REL::Relocation _GetPowerArmorShouldBeVisible; - }; - - template - class hkSetPowerArmorMode - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _SetPowerArmorMode = trampoline.write_call<5>(target.address(), SetPowerArmorMode); - } - - private: - static void SetPowerArmorMode( - [[maybe_unused]] bool a_inPowerArmor) - { - if (detail::IsExempt()) - { - return _SetPowerArmorMode(a_inPowerArmor); - } - - if (MCM::Settings::General::bDisableColor) - { - return; - } - - detail::Notify(); - } - - inline static REL::Relocation _SetPowerArmorMode; - }; - - template - class hkQActorInPowerArmor - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _QActorInPowerArmor = trampoline.write_call<5>(target.address(), QActorInPowerArmor); - } - - private: - static bool QActorInPowerArmor( - [[maybe_unused]] RE::Actor* a_actor) - { - if (detail::IsExempt()) - { - return _QActorInPowerArmor(a_actor); - } - - return RETN; - } - - inline static REL::Relocation _QActorInPowerArmor; - }; - - template - class hkQActorInPowerArmorPAHC - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _QActorInPowerArmor = trampoline.write_call<5>(target.address(), QActorInPowerArmor); - } - - private: - static bool QActorInPowerArmor( - [[maybe_unused]] RE::Actor* a_actor) - { - if (detail::IsExempt()) - { - return _QActorInPowerArmor(a_actor); - } - - if (MCM::Settings::General::bDisableColor) - { - return _QActorInPowerArmor(a_actor); - } - - if (!MCM::Settings::General::bDisablePAColor) - { - return _QActorInPowerArmor(a_actor); - } - - return false; - } - - inline static REL::Relocation _QActorInPowerArmor; - }; - - template - class hkCanBeVisible - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _CanBeVisible = trampoline.write_call<5>(target.address(), CanBeVisible); - } - - private: - static bool CanBeVisible( - [[maybe_unused]] void* a_this) - { - if (detail::IsExempt()) - { - return _CanBeVisible(a_this); - } - - auto bCanBeVisible = _CanBeVisible(a_this); - if (bCanBeVisible - && RE::PowerArmor::PlayerInPowerArmor()) - { - Menus::PowerArmorConditionMenu::ShowMenu(); - } - else - { - Menus::PowerArmorConditionMenu::HideMenu(); - } - - return bCanBeVisible; - } - - inline static REL::Relocation _CanBeVisible; - }; - - template - class hkGetPowerArmorHUDColor - { - public: - static void Install() - { - static REL::Relocation target{ REL::ID(ID), OFF }; - auto& trampoline = F4SE::GetTrampoline(); - _GetPowerArmorHUDColor = trampoline.write_call<5>(target.address(), GetPowerArmorHUDColor); - } - - private: - static RE::NiColor GetPowerArmorHUDColor() - { - if (detail::IsExempt()) - { - return _GetPowerArmorHUDColor(); - } - - if (MCM::Settings::General::bDisableColor) - { - return _GetPowerArmorHUDColor(); - } - - if (!MCM::Settings::General::bDisablePAColor) - { - return _GetPowerArmorHUDColor(); - } - - return GetGameplayHUDColor(); - } - - static RE::NiColor GetGameplayHUDColor() - { - using func_t = decltype(&GetGameplayHUDColor); - REL::Relocation func{ REL::ID(34363) }; - return func(); - } - - inline static REL::Relocation _GetPowerArmorHUDColor; - }; - - class ActorValueChangedHandler : - public RE::BSTEventSink - { - public: - [[nodiscard]] static ActorValueChangedHandler* GetSingleton() - { - static ActorValueChangedHandler singleton; - return std::addressof(singleton); - } - - virtual RE::BSEventNotifyControl ProcessEvent( - const RE::ActorValueEvents::ActorValueChangedEvent& a_event, - RE::BSTEventSource*) override - { - if (detail::IsExempt()) - { - return RE::BSEventNotifyControl::kContinue; - } - - auto ActorValue = RE::ActorValue::GetSingleton(); - if (!ActorValue) - { - return RE::BSEventNotifyControl::kContinue; - } - - switch (a_event.actorValue.formID) - { - case 0x0000035C: // PowerArmorBattery - if (!RE::PowerArmor::PlayerInPowerArmor()) - { - detail::Notify(false); - } - break; - - default: - break; - } - - return RE::BSEventNotifyControl::kContinue; - } - }; -}; +#pragma once + +#include "MCM/MCM.h" +#include "Menus/PowerArmorConditionMenu.h" + +class Hooks +{ +public: + static void Install() + { + hkGetPowerArmorShouldBeVisible<1402809, 0x1D>::Install(); // HUDActionPointMeter::CanPlaySoundEffects + hkGetPowerArmorShouldBeVisible<742970, 0x190>::Install(); // HUDActiveEffectsDisplay::UpdateDisplayObject + hkGetPowerArmorShouldBeVisible<756668, 0x5D9>::Install(); // HUDCompassMarker::SetCompassMarkerData + hkGetPowerArmorShouldBeVisible<259269, 0xB6>::Install(); // HUDMarkerData::GetMinorFrame + hkGetPowerArmorShouldBeVisible<1511766, 0x107>::Install(); // PowerArmorGeometry::UpdatePowerArmorHUD + hkSetPowerArmorMode<1187476, 0xE6B>::Install(); // PowerArmor::SwitchToPowerArmor + hkSetPowerArmorMode<1150710, 0x1E8>::Install(); // PowerArmor::SwitchFromPowerArmorFurnitureLoaded + hkQActorInPowerArmor<31293, 0x14C, false>::Install(); // HUDRadiationModel::CalcEnvDamage + hkQActorInPowerArmor<733718, 0xA8, false>::Install(); // HUDMenu::InitializeHUD + hkQActorInPowerArmorPAHC<34363, 0x2D>::Install(); // HUDMenuUtils::GetGameplayHUDColor + hkCanBeVisible<893789, 0x12>::Install(); // HUDCompass::CanBeVisible + hkGetPowerArmorHUDColor<523665, 0x56>::Install(); // GameUIModel::SetGameColors + } + + static void InstallPostLoad() + { + MCM::Settings::Update(); + Menus::Register(); + + if (auto PlayerCharacter = RE::PlayerCharacter::GetSingleton()) + { + if (auto EventSource = + static_cast< + RE::BSTEventSource< + RE::ActorValueEvents::ActorValueChangedEvent>*>( + PlayerCharacter)) + { + EventSource->RegisterSink(ActorValueChangedHandler::GetSingleton()); + } + } + } + +private: + class detail + { + public: + static bool IsExempt() + { + if (!MCM::Settings::General::bEnable) + { + return true; + } + + return false; + } + + template + static void Notify() + { + if (auto EventSource = T::GetEventSource()) + { + auto eventData = T{}; + EventSource->Notify(eventData); + } + } + + template + static void Notify(bool a_value) + { + if (auto EventSource = T::GetEventSource()) + { + auto eventData = T{ a_value }; + EventSource->Notify(eventData); + } + } + }; + + template + class hkGetPowerArmorShouldBeVisible + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _GetPowerArmorShouldBeVisible = trampoline.write_call<5>(target.address(), GetPowerArmorShouldBeVisible); + } + + private: + static bool GetPowerArmorShouldBeVisible( + [[maybe_unused]] RE::PowerArmorGeometry* a_this) + { + if (detail::IsExempt()) + { + return _GetPowerArmorShouldBeVisible(a_this); + } + + return false; + } + + inline static REL::Relocation _GetPowerArmorShouldBeVisible; + }; + + template + class hkSetPowerArmorMode + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _SetPowerArmorMode = trampoline.write_call<5>(target.address(), SetPowerArmorMode); + } + + private: + static void SetPowerArmorMode( + [[maybe_unused]] bool a_inPowerArmor) + { + if (detail::IsExempt()) + { + return _SetPowerArmorMode(a_inPowerArmor); + } + + if (MCM::Settings::General::bDisableColor) + { + return; + } + + detail::Notify(); + } + + inline static REL::Relocation _SetPowerArmorMode; + }; + + template + class hkQActorInPowerArmor + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _QActorInPowerArmor = trampoline.write_call<5>(target.address(), QActorInPowerArmor); + } + + private: + static bool QActorInPowerArmor( + [[maybe_unused]] RE::Actor* a_actor) + { + if (detail::IsExempt()) + { + return _QActorInPowerArmor(a_actor); + } + + return RETN; + } + + inline static REL::Relocation _QActorInPowerArmor; + }; + + template + class hkQActorInPowerArmorPAHC + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _QActorInPowerArmor = trampoline.write_call<5>(target.address(), QActorInPowerArmor); + } + + private: + static bool QActorInPowerArmor( + [[maybe_unused]] RE::Actor* a_actor) + { + if (detail::IsExempt()) + { + return _QActorInPowerArmor(a_actor); + } + + if (MCM::Settings::General::bDisableColor) + { + return _QActorInPowerArmor(a_actor); + } + + if (!MCM::Settings::General::bDisablePAColor) + { + return _QActorInPowerArmor(a_actor); + } + + return false; + } + + inline static REL::Relocation _QActorInPowerArmor; + }; + + template + class hkCanBeVisible + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _CanBeVisible = trampoline.write_call<5>(target.address(), CanBeVisible); + } + + private: + static bool CanBeVisible( + [[maybe_unused]] void* a_this) + { + if (detail::IsExempt()) + { + return _CanBeVisible(a_this); + } + + auto bCanBeVisible = _CanBeVisible(a_this); + if (bCanBeVisible && RE::PowerArmor::PlayerInPowerArmor()) + { + Menus::PowerArmorConditionMenu::ShowMenu(); + } + else + { + Menus::PowerArmorConditionMenu::HideMenu(); + } + + return bCanBeVisible; + } + + inline static REL::Relocation _CanBeVisible; + }; + + template + class hkGetPowerArmorHUDColor + { + public: + static void Install() + { + static REL::Relocation target{ REL::ID(ID), OFF }; + auto& trampoline = F4SE::GetTrampoline(); + _GetPowerArmorHUDColor = trampoline.write_call<5>(target.address(), GetPowerArmorHUDColor); + } + + private: + static RE::NiColor GetPowerArmorHUDColor() + { + if (detail::IsExempt()) + { + return _GetPowerArmorHUDColor(); + } + + if (MCM::Settings::General::bDisableColor) + { + return _GetPowerArmorHUDColor(); + } + + if (!MCM::Settings::General::bDisablePAColor) + { + return _GetPowerArmorHUDColor(); + } + + return GetGameplayHUDColor(); + } + + static RE::NiColor GetGameplayHUDColor() + { + using func_t = decltype(&GetGameplayHUDColor); + REL::Relocation func{ REL::ID(34363) }; + return func(); + } + + inline static REL::Relocation _GetPowerArmorHUDColor; + }; + + class ActorValueChangedHandler : + public RE::BSTEventSink + { + public: + [[nodiscard]] static ActorValueChangedHandler* GetSingleton() + { + static ActorValueChangedHandler singleton; + return std::addressof(singleton); + } + + virtual RE::BSEventNotifyControl ProcessEvent( + const RE::ActorValueEvents::ActorValueChangedEvent& a_event, + RE::BSTEventSource*) override + { + if (detail::IsExempt()) + { + return RE::BSEventNotifyControl::kContinue; + } + + auto ActorValue = RE::ActorValue::GetSingleton(); + if (!ActorValue) + { + return RE::BSEventNotifyControl::kContinue; + } + + switch (a_event.actorValue.formID) + { + case 0x0000035C: // PowerArmorBattery + if (!RE::PowerArmor::PlayerInPowerArmor()) + { + detail::Notify(false); + } + break; + + default: + break; + } + + return RE::BSEventNotifyControl::kContinue; + } + }; +}; diff --git a/Plugin/src/MCM/MCM.cpp b/Plugin/src/MCM/MCM.cpp index cbdc3b1..ea16682 100644 --- a/Plugin/src/MCM/MCM.cpp +++ b/Plugin/src/MCM/MCM.cpp @@ -1,26 +1,26 @@ -#include "MCM/MCM.h" - -#include "Menus/PowerArmorConditionMenu.h" - -namespace MCM -{ - void Settings::ResetStatePost() - { - if (RE::PowerArmor::PlayerInPowerArmor()) - { - if (General::bEnable) - { - RE::SendHUDMessage::SetPowerArmorMode(false); - Menus::PowerArmorConditionMenu::ShowMenu(); - } - else - { - RE::SendHUDMessage::SetPowerArmorMode(true); - Menus::PowerArmorConditionMenu::HideMenu(); - } - } - - m_ini_base.Reset(); - m_ini_user.Reset(); - } -} +#include "MCM/MCM.h" + +#include "Menus/PowerArmorConditionMenu.h" + +namespace MCM +{ + void Settings::ResetStatePost() + { + if (RE::PowerArmor::PlayerInPowerArmor()) + { + if (General::bEnable) + { + RE::SendHUDMessage::SetPowerArmorMode(false); + Menus::PowerArmorConditionMenu::ShowMenu(); + } + else + { + RE::SendHUDMessage::SetPowerArmorMode(true); + Menus::PowerArmorConditionMenu::HideMenu(); + } + } + + m_ini_base.Reset(); + m_ini_user.Reset(); + } +} diff --git a/Plugin/src/MCM/MCM.h b/Plugin/src/MCM/MCM.h index 1536394..1f72af7 100644 --- a/Plugin/src/MCM/MCM.h +++ b/Plugin/src/MCM/MCM.h @@ -1,83 +1,83 @@ -#pragma once - -namespace MCM -{ - class Settings - { - public: - class General - { - public: - inline static bool bEnable{ true }; - inline static bool bDisablePAColor{ false }; - inline static bool bDisableColor{ false }; - - inline static double fConditionMeterX{ 136.0 }; - inline static double fConditionMeterY{ 675.0 }; - inline static double fConditionMeterScale{ 1.0 }; - }; - - static void Update() - { - ResetStateInit(); - - GetModSettingBool("General", "bEnable", General::bEnable); - GetModSettingBool("General", "bDisablePAColor", General::bDisablePAColor); - GetModSettingBool("General", "bDisableColor", General::bDisableColor); - - GetModSettingDouble("General", "fConditionMeterX", General::fConditionMeterX); - GetModSettingDouble("General", "fConditionMeterY", General::fConditionMeterY); - GetModSettingDouble("General", "fConditionMeterScale", General::fConditionMeterScale); - - ResetStatePost(); - } - - inline static bool m_FirstRun{ true }; - - private: - static void ResetStateInit() - { - if (m_FirstRun) - { - m_FirstRun = false; - } - - m_ini_base.LoadFile("Data/MCM/Config/BakaPowerArmorHUD/settings.ini"); - m_ini_user.LoadFile("Data/MCM/Settings/BakaPowerArmorHUD.ini"); - } - - static void ResetStatePost(); - - protected: - static void GetModSettingChar(const std::string& a_section, const std::string& a_setting, std::string_view& a_value) - { - auto base = m_ini_base.GetValue(a_section.c_str(), a_setting.c_str(), a_value.data()); - auto user = m_ini_user.GetValue(a_section.c_str(), a_setting.c_str(), base); - a_value = user; - } - - static void GetModSettingBool(const std::string& a_section, const std::string& a_setting, bool& a_value) - { - auto base = m_ini_base.GetBoolValue(a_section.c_str(), a_setting.c_str(), a_value); - auto user = m_ini_user.GetBoolValue(a_section.c_str(), a_setting.c_str(), base); - a_value = user; - } - - static void GetModSettingDouble(const std::string& a_section, const std::string& a_setting, double& a_value) - { - auto base = m_ini_base.GetDoubleValue(a_section.c_str(), a_setting.c_str(), a_value); - auto user = m_ini_user.GetDoubleValue(a_section.c_str(), a_setting.c_str(), base); - a_value = user; - } - - static void GetModSettingLong(const std::string& a_section, const std::string& a_setting, std::int32_t& a_value) - { - auto base = m_ini_base.GetLongValue(a_section.c_str(), a_setting.c_str(), a_value); - auto user = m_ini_user.GetLongValue(a_section.c_str(), a_setting.c_str(), base); - a_value = static_cast(user); - } - - inline static CSimpleIniA m_ini_base{ true }; - inline static CSimpleIniA m_ini_user{ true }; - }; -} +#pragma once + +namespace MCM +{ + class Settings + { + public: + class General + { + public: + inline static bool bEnable{ true }; + inline static bool bDisablePAColor{ false }; + inline static bool bDisableColor{ false }; + + inline static double fConditionMeterX{ 136.0 }; + inline static double fConditionMeterY{ 675.0 }; + inline static double fConditionMeterScale{ 1.0 }; + }; + + static void Update() + { + ResetStateInit(); + + GetModSettingBool("General", "bEnable", General::bEnable); + GetModSettingBool("General", "bDisablePAColor", General::bDisablePAColor); + GetModSettingBool("General", "bDisableColor", General::bDisableColor); + + GetModSettingDouble("General", "fConditionMeterX", General::fConditionMeterX); + GetModSettingDouble("General", "fConditionMeterY", General::fConditionMeterY); + GetModSettingDouble("General", "fConditionMeterScale", General::fConditionMeterScale); + + ResetStatePost(); + } + + inline static bool m_FirstRun{ true }; + + private: + static void ResetStateInit() + { + if (m_FirstRun) + { + m_FirstRun = false; + } + + m_ini_base.LoadFile("Data/MCM/Config/BakaPowerArmorHUD/settings.ini"); + m_ini_user.LoadFile("Data/MCM/Settings/BakaPowerArmorHUD.ini"); + } + + static void ResetStatePost(); + + protected: + static void GetModSettingChar(const std::string& a_section, const std::string& a_setting, std::string_view& a_value) + { + auto base = m_ini_base.GetValue(a_section.c_str(), a_setting.c_str(), a_value.data()); + auto user = m_ini_user.GetValue(a_section.c_str(), a_setting.c_str(), base); + a_value = user; + } + + static void GetModSettingBool(const std::string& a_section, const std::string& a_setting, bool& a_value) + { + auto base = m_ini_base.GetBoolValue(a_section.c_str(), a_setting.c_str(), a_value); + auto user = m_ini_user.GetBoolValue(a_section.c_str(), a_setting.c_str(), base); + a_value = user; + } + + static void GetModSettingDouble(const std::string& a_section, const std::string& a_setting, double& a_value) + { + auto base = m_ini_base.GetDoubleValue(a_section.c_str(), a_setting.c_str(), a_value); + auto user = m_ini_user.GetDoubleValue(a_section.c_str(), a_setting.c_str(), base); + a_value = user; + } + + static void GetModSettingLong(const std::string& a_section, const std::string& a_setting, std::int32_t& a_value) + { + auto base = m_ini_base.GetLongValue(a_section.c_str(), a_setting.c_str(), a_value); + auto user = m_ini_user.GetLongValue(a_section.c_str(), a_setting.c_str(), base); + a_value = static_cast(user); + } + + inline static CSimpleIniA m_ini_base{ true }; + inline static CSimpleIniA m_ini_user{ true }; + }; +} diff --git a/Plugin/src/Menus/PowerArmorConditionMenu.h b/Plugin/src/Menus/PowerArmorConditionMenu.h index 29d4ee8..33aa2fa 100644 --- a/Plugin/src/Menus/PowerArmorConditionMenu.h +++ b/Plugin/src/Menus/PowerArmorConditionMenu.h @@ -1,204 +1,204 @@ -#pragma once - -#include "MCM/MCM.h" - -namespace Menus -{ - class PowerArmorConditionMenu : - public RE::GameMenuBase - { - public: - static constexpr auto MENU_NAME{ "PowerArmorConditionMenu"sv }; - - PowerArmorConditionMenu() - { - menuFlags.set( - RE::UI_MENU_FLAGS::kAllowSaving, - RE::UI_MENU_FLAGS::kDontHideCursorWhenTopmost, - RE::UI_MENU_FLAGS::kCustomRendering); - depthPriority.set(RE::UI_DEPTH_PRIORITY::kSWFLoader); - - auto MoviePath = "Interface\\PowerArmorConditionMenu.swf"sv; - const auto ScaleformManager = RE::BSScaleformManager::GetSingleton(); - [[maybe_unused]] const auto LoadMovieSuccess = - ScaleformManager->LoadMovieEx(*this, MoviePath, "root"); - assert(LoadMovieSuccess); - - filterHolder = RE::msvc::make_unique(*uiMovie, "root.Menu_mc"); - if (filterHolder) - { - shaderFXObjects.push_back(filterHolder.get()); - } - - ConditionMeter_mc = RE::msvc::make_unique(*filterHolder, "ConditionMeter_mc"); - if (ConditionMeter_mc) - { - ConditionMeter_mc->CreateAndSetFiltersToHUD(RE::HUDColorTypes::kPlayerSetColor); - shaderFXObjects.push_back(ConditionMeter_mc.get()); - } - } - - virtual ~PowerArmorConditionMenu() - { - ConditionMeter_mc.release(); - } - - static RE::IMenu* Create(const RE::UIMessage&) - { - return new PowerArmorConditionMenu(); - } - - static void ShowMenu() - { - if (!RE::PowerArmor::PlayerInPowerArmor()) - { - return; - } - - if (auto UI = RE::UI::GetSingleton()) - { - if (UI->GetMenuOpen()) - { - SetConditionMeterVisuals( - static_cast(MCM::Settings::General::fConditionMeterX), - static_cast(MCM::Settings::General::fConditionMeterY), - static_cast(MCM::Settings::General::fConditionMeterScale)); - UpdateBatteryState(); - return; - } - } - else - { - return; - } - - if (auto UIMessageQueue = RE::UIMessageQueue::GetSingleton()) - { - UIMessageQueue->AddMessage( - "PowerArmorConditionMenu"sv, - RE::UI_MESSAGE_TYPE::kShow); - } - } - - static void HideMenu() - { - if (auto UI = RE::UI::GetSingleton()) - { - if (!UI->GetMenuOpen()) - { - return; - } - } - else - { - return; - } - - if (auto UIMessageQueue = RE::UIMessageQueue::GetSingleton()) - { - UIMessageQueue->AddMessage( - "PowerArmorConditionMenu"sv, - RE::UI_MESSAGE_TYPE::kHide); - } - } - - static void SetConditionMeterVisuals(float a_x, float a_y, float a_scale) - { - if (auto UI = RE::UI::GetSingleton()) - { - if (auto Menu = UI->GetMenu()) - { - Menu->SetConditionMeterVisualsImpl(a_x, a_y, a_scale); - } - } - } - - static void UpdateBatteryState() - { - if (auto UI = RE::UI::GetSingleton()) - { - if (auto Menu = UI->GetMenu()) - { - Menu->UpdateBatteryStateImpl(); - } - } - } - - private: - class detail - { - public: - template - static void Notify(bool a_value) - { - if (auto EventSource = T::GetEventSource()) - { - auto eventData = T{ a_value }; - EventSource->Notify(eventData); - } - } - }; - - void SetConditionMeterCountImpl(std::uint32_t a_count) - { - RE::Scaleform::GFx::Value args[1]; - args[0] = a_count; - ConditionMeter_mc->Invoke("SetCount", nullptr, args, 1); - } - - void SetConditionMeterPercentImpl(float a_percent) - { - RE::Scaleform::GFx::Value args[1]; - args[0] = a_percent; - ConditionMeter_mc->Invoke("SetPercent", nullptr, args, 1); - ConditionMeter_mc->SetToHUDColor(a_percent <= fPowerArmorLowBatterySoundThreshold->GetFloat()); - } - - void SetConditionMeterVisualsImpl(float a_x, float a_y, float a_scale) - { - ConditionMeter_mc->SetMember("x", a_x); - ConditionMeter_mc->SetMember("y", a_y); - ConditionMeter_mc->SetMember("scaleX", a_scale); - ConditionMeter_mc->SetMember("scaleY", a_scale); - } - - void UpdateBatteryStateImpl() - { - if (auto PlayerCharacter = RE::PlayerCharacter::GetSingleton()) - { - std::uint32_t count = PlayerCharacter->GetInventoryObjectCount(RE::PowerArmor::GetDefaultBatteryObject()); - SetConditionMeterCountImpl(count); - - if (auto ActorValue = RE::ActorValue::GetSingleton()) - { - float value = PlayerCharacter->GetActorValue(*ActorValue->powerArmorBattery); - if (value <= 0.0f) - { - detail::Notify(true); - } - else - { - detail::Notify(false); - } - - SetConditionMeterPercentImpl(value); - } - } - } - - RE::msvc::unique_ptr ConditionMeter_mc; - - protected: - inline static REL::Relocation*> fPowerArmorLowBatterySoundThreshold{ REL::ID(370701) }; - }; - - inline void Register() - { - if (auto UI = RE::UI::GetSingleton()) - { - UI->RegisterMenu( - "PowerArmorConditionMenu", - PowerArmorConditionMenu::Create); - } - } -} +#pragma once + +#include "MCM/MCM.h" + +namespace Menus +{ + class PowerArmorConditionMenu : + public RE::GameMenuBase + { + public: + static constexpr auto MENU_NAME{ "PowerArmorConditionMenu"sv }; + + PowerArmorConditionMenu() + { + menuFlags.set( + RE::UI_MENU_FLAGS::kAllowSaving, + RE::UI_MENU_FLAGS::kDontHideCursorWhenTopmost, + RE::UI_MENU_FLAGS::kCustomRendering); + depthPriority.set(RE::UI_DEPTH_PRIORITY::kSWFLoader); + + auto MoviePath = "Interface\\PowerArmorConditionMenu.swf"sv; + const auto ScaleformManager = RE::BSScaleformManager::GetSingleton(); + [[maybe_unused]] const auto LoadMovieSuccess = + ScaleformManager->LoadMovieEx(*this, MoviePath, "root"); + assert(LoadMovieSuccess); + + filterHolder = RE::msvc::make_unique(*uiMovie, "root.Menu_mc"); + if (filterHolder) + { + shaderFXObjects.push_back(filterHolder.get()); + } + + ConditionMeter_mc = RE::msvc::make_unique(*filterHolder, "ConditionMeter_mc"); + if (ConditionMeter_mc) + { + ConditionMeter_mc->CreateAndSetFiltersToHUD(RE::HUDColorTypes::kPlayerSetColor); + shaderFXObjects.push_back(ConditionMeter_mc.get()); + } + } + + virtual ~PowerArmorConditionMenu() + { + ConditionMeter_mc.release(); + } + + static RE::IMenu* Create(const RE::UIMessage&) + { + return new PowerArmorConditionMenu(); + } + + static void ShowMenu() + { + if (!RE::PowerArmor::PlayerInPowerArmor()) + { + return; + } + + if (auto UI = RE::UI::GetSingleton()) + { + if (UI->GetMenuOpen()) + { + SetConditionMeterVisuals( + static_cast(MCM::Settings::General::fConditionMeterX), + static_cast(MCM::Settings::General::fConditionMeterY), + static_cast(MCM::Settings::General::fConditionMeterScale)); + UpdateBatteryState(); + return; + } + } + else + { + return; + } + + if (auto UIMessageQueue = RE::UIMessageQueue::GetSingleton()) + { + UIMessageQueue->AddMessage( + "PowerArmorConditionMenu"sv, + RE::UI_MESSAGE_TYPE::kShow); + } + } + + static void HideMenu() + { + if (auto UI = RE::UI::GetSingleton()) + { + if (!UI->GetMenuOpen()) + { + return; + } + } + else + { + return; + } + + if (auto UIMessageQueue = RE::UIMessageQueue::GetSingleton()) + { + UIMessageQueue->AddMessage( + "PowerArmorConditionMenu"sv, + RE::UI_MESSAGE_TYPE::kHide); + } + } + + static void SetConditionMeterVisuals(float a_x, float a_y, float a_scale) + { + if (auto UI = RE::UI::GetSingleton()) + { + if (auto Menu = UI->GetMenu()) + { + Menu->SetConditionMeterVisualsImpl(a_x, a_y, a_scale); + } + } + } + + static void UpdateBatteryState() + { + if (auto UI = RE::UI::GetSingleton()) + { + if (auto Menu = UI->GetMenu()) + { + Menu->UpdateBatteryStateImpl(); + } + } + } + + private: + class detail + { + public: + template + static void Notify(bool a_value) + { + if (auto EventSource = T::GetEventSource()) + { + auto eventData = T{ a_value }; + EventSource->Notify(eventData); + } + } + }; + + void SetConditionMeterCountImpl(std::uint32_t a_count) + { + RE::Scaleform::GFx::Value args[1]; + args[0] = a_count; + ConditionMeter_mc->Invoke("SetCount", nullptr, args, 1); + } + + void SetConditionMeterPercentImpl(float a_percent) + { + RE::Scaleform::GFx::Value args[1]; + args[0] = a_percent; + ConditionMeter_mc->Invoke("SetPercent", nullptr, args, 1); + ConditionMeter_mc->SetToHUDColor(a_percent <= fPowerArmorLowBatterySoundThreshold->GetFloat()); + } + + void SetConditionMeterVisualsImpl(float a_x, float a_y, float a_scale) + { + ConditionMeter_mc->SetMember("x", a_x); + ConditionMeter_mc->SetMember("y", a_y); + ConditionMeter_mc->SetMember("scaleX", a_scale); + ConditionMeter_mc->SetMember("scaleY", a_scale); + } + + void UpdateBatteryStateImpl() + { + if (auto PlayerCharacter = RE::PlayerCharacter::GetSingleton()) + { + std::uint32_t count = PlayerCharacter->GetInventoryObjectCount(RE::PowerArmor::GetDefaultBatteryObject()); + SetConditionMeterCountImpl(count); + + if (auto ActorValue = RE::ActorValue::GetSingleton()) + { + float value = PlayerCharacter->GetActorValue(*ActorValue->powerArmorBattery); + if (value <= 0.0f) + { + detail::Notify(true); + } + else + { + detail::Notify(false); + } + + SetConditionMeterPercentImpl(value); + } + } + } + + RE::msvc::unique_ptr ConditionMeter_mc; + + protected: + inline static REL::Relocation*> fPowerArmorLowBatterySoundThreshold{ REL::ID(370701) }; + }; + + inline void Register() + { + if (auto UI = RE::UI::GetSingleton()) + { + UI->RegisterMenu( + "PowerArmorConditionMenu", + PowerArmorConditionMenu::Create); + } + } +} diff --git a/Plugin/src/PCH.cpp b/Plugin/src/PCH.cpp index 8607860..3b889e8 100644 --- a/Plugin/src/PCH.cpp +++ b/Plugin/src/PCH.cpp @@ -1,37 +1,37 @@ -#include "PCH.h" - -namespace stl -{ - namespace detail - { - struct asm_patch : - Xbyak::CodeGenerator - { - asm_patch(std::uintptr_t a_dst) - { - Xbyak::Label dst; - - jmp(ptr[rip + dst]); - - L(dst); - dq(a_dst); - } - }; - } - - void asm_jump(std::uintptr_t a_from, [[maybe_unused]] std::size_t a_size, std::uintptr_t a_to) - { - detail::asm_patch p{ a_to }; - p.ready(); - assert(p.getSize() <= a_size); - REL::safe_write( - a_from, - std::span{ p.getCode(), p.getSize() }); - } - - void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to) - { - REL::safe_fill(a_from, REL::INT3, a_size); - asm_jump(a_from, a_size, a_to); - } -} +#include "PCH.h" + +namespace stl +{ + namespace detail + { + struct asm_patch : + Xbyak::CodeGenerator + { + asm_patch(std::uintptr_t a_dst) + { + Xbyak::Label dst; + + jmp(ptr[rip + dst]); + + L(dst); + dq(a_dst); + } + }; + } + + void asm_jump(std::uintptr_t a_from, [[maybe_unused]] std::size_t a_size, std::uintptr_t a_to) + { + detail::asm_patch p{ a_to }; + p.ready(); + assert(p.getSize() <= a_size); + REL::safe_write( + a_from, + std::span{ p.getCode(), p.getSize() }); + } + + void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to) + { + REL::safe_fill(a_from, REL::INT3, a_size); + asm_jump(a_from, a_size, a_to); + } +} diff --git a/Plugin/src/PCH.h b/Plugin/src/PCH.h index cbff35f..fe1cc0a 100644 --- a/Plugin/src/PCH.h +++ b/Plugin/src/PCH.h @@ -1,30 +1,30 @@ -#pragma once - -#define WIN32_LEAN_AND_MEAN -#define NOMINMAX - -#include "F4SE/F4SE.h" -#include "RE/Fallout.h" - -#include -#include -#include -#include - -#define DLLEXPORT __declspec(dllexport) - -using namespace std::literals; - -namespace logger = F4SE::log; - -namespace stl -{ - using namespace F4SE::stl; - - void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to); -} - +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX + +#include "F4SE/F4SE.h" +#include "RE/Fallout.h" + +#include +#include +#include +#include + +#define DLLEXPORT __declspec(dllexport) + +using namespace std::literals; + +namespace logger = F4SE::log; + +namespace stl +{ + using namespace F4SE::stl; + + void asm_replace(std::uintptr_t a_from, std::size_t a_size, std::uintptr_t a_to); +} + // clang-format off #include "Version.h" -#include "Settings.h" -// clang-format on +#include "Settings.h" +// clang-format on diff --git a/Plugin/src/Scripts/Papyrus.h b/Plugin/src/Scripts/Papyrus.h index 26f37d5..c524be0 100644 --- a/Plugin/src/Scripts/Papyrus.h +++ b/Plugin/src/Scripts/Papyrus.h @@ -1,24 +1,24 @@ -#pragma once - -#include "MCM/MCM.h" - -namespace Papyrus -{ - namespace BakaPowerArmorHUD - { - constexpr auto SCRIPT_NAME{ "BakaPowerArmorHUD"sv }; - - void UpdateSettings(std::monostate) - { - MCM::Settings::Update(); - } - } - - bool RegisterFunctions(RE::BSScript::IVirtualMachine* a_VM) - { - // BakaPowerArmorHUD - a_VM->BindNativeMethod(BakaPowerArmorHUD::SCRIPT_NAME, "UpdateSettings", BakaPowerArmorHUD::UpdateSettings, true); - - return true; - } -} +#pragma once + +#include "MCM/MCM.h" + +namespace Papyrus +{ + namespace BakaPowerArmorHUD + { + constexpr auto SCRIPT_NAME{ "BakaPowerArmorHUD"sv }; + + void UpdateSettings(std::monostate) + { + MCM::Settings::Update(); + } + } + + bool RegisterFunctions(RE::BSScript::IVirtualMachine* a_VM) + { + // BakaPowerArmorHUD + a_VM->BindNativeMethod(BakaPowerArmorHUD::SCRIPT_NAME, "UpdateSettings", BakaPowerArmorHUD::UpdateSettings, true); + + return true; + } +} diff --git a/Plugin/src/Settings.h b/Plugin/src/Settings.h index ce29340..728eeeb 100644 --- a/Plugin/src/Settings.h +++ b/Plugin/src/Settings.h @@ -1,46 +1,46 @@ -#pragma once - -namespace Settings -{ - namespace - { - using bSetting = AutoTOML::bSetting; - using ISetting = AutoTOML::ISetting; - } - - namespace General - { - inline bSetting EnableDebugLogging{ "General"s, "EnableDebugLogging"s, false }; - } - - inline void Load() - { - try - { - const auto table = toml::parse_file( - fmt::format(FMT_STRING("Data/F4SE/Plugins/{:s}.toml"sv), Version::PROJECT)); - for (const auto& setting : ISetting::get_settings()) - { - setting->load(table); - } - } - catch (const toml::parse_error& e) - { - std::ostringstream ss; - ss - << "Error parsing file \'" << *e.source().path << "\':\n" - << '\t' << e.description() << '\n' - << "\t\t(" << e.source().begin << ')'; - logger::error(FMT_STRING("{:s}"sv), ss.str()); - stl::report_and_fail("Failed to load settings."sv); - } - catch (const std::exception& e) - { - stl::report_and_fail(e.what()); - } - catch (...) - { - stl::report_and_fail("Unknown failure."sv); - } - } -} +#pragma once + +namespace Settings +{ + namespace + { + using bSetting = AutoTOML::bSetting; + using ISetting = AutoTOML::ISetting; + } + + namespace General + { + inline bSetting EnableDebugLogging{ "General"s, "EnableDebugLogging"s, false }; + } + + inline void Load() + { + try + { + const auto table = toml::parse_file( + fmt::format(FMT_STRING("Data/F4SE/Plugins/{:s}.toml"sv), Version::PROJECT)); + for (const auto& setting : ISetting::get_settings()) + { + setting->load(table); + } + } + catch (const toml::parse_error& e) + { + std::ostringstream ss; + ss + << "Error parsing file \'" << *e.source().path << "\':\n" + << '\t' << e.description() << '\n' + << "\t\t(" << e.source().begin << ')'; + logger::error(FMT_STRING("{:s}"sv), ss.str()); + stl::report_and_fail("Failed to load settings."sv); + } + catch (const std::exception& e) + { + stl::report_and_fail(e.what()); + } + catch (...) + { + stl::report_and_fail("Unknown failure."sv); + } + } +} diff --git a/Plugin/src/main.cpp b/Plugin/src/main.cpp index 4633d8a..5e30498 100644 --- a/Plugin/src/main.cpp +++ b/Plugin/src/main.cpp @@ -1,98 +1,98 @@ -#include "Hooks/Hooks.h" -#include "MCM/MCM.h" -#include "Menus/PowerArmorConditionMenu.h" -#include "Scripts/Papyrus.h" - -namespace -{ - void InitializeLog() - { - auto path = logger::log_directory(); - if (!path) - { - stl::report_and_fail("Failed to find standard logging directory"sv); - } - - *path /= fmt::format(FMT_STRING("{:s}.log"sv), Version::PROJECT); - auto sink = std::make_shared(path->string(), true); - - auto log = std::make_shared("global log"s, std::move(sink)); - auto lvl = *Settings::General::EnableDebugLogging - ? spdlog::level::trace - : spdlog::level::info; - - log->set_level(lvl); - log->flush_on(lvl); - - spdlog::set_default_logger(std::move(log)); - spdlog::set_pattern("[%m/%d/%Y - %T] [%^%l%$] %v"s); - - logger::info(FMT_STRING("{:s} v{:s}"sv), Version::PROJECT, Version::NAME); - } - - void MessageHandler(F4SE::MessagingInterface::Message* a_msg) - { - if (!a_msg) - { - return; - } - - switch (a_msg->type) - { - case F4SE::MessagingInterface::kGameDataReady: - Hooks::InstallPostLoad(); - break; - default: - break; - } - } -} - -extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Query(const F4SE::QueryInterface* a_F4SE, F4SE::PluginInfo* a_info) -{ - a_info->infoVersion = F4SE::PluginInfo::kVersion; - a_info->name = Version::PROJECT.data(); - a_info->version = Version::MAJOR; - - const auto rtv = a_F4SE->RuntimeVersion(); - if (rtv < F4SE::RUNTIME_LATEST) - { - stl::report_and_fail( - fmt::format( - FMT_STRING("{:s} does not support runtime v{:s}."sv), - Version::PROJECT, - rtv.string())); - } - - return true; -} - -extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Load(const F4SE::LoadInterface* a_F4SE) -{ - Settings::Load(); - InitializeLog(); - - logger::info(FMT_STRING("{:s} loaded."sv), Version::PROJECT); - logger::debug("Debug logging enabled."sv); - - F4SE::Init(a_F4SE); - F4SE::AllocTrampoline(1u << 8); - - const auto messaging = F4SE::GetMessagingInterface(); - if (!messaging || !messaging->RegisterListener(MessageHandler)) - { - logger::critical("Failed to register messaging handler, marking as incompatible."sv); - return false; - } - - const auto papyrus = F4SE::GetPapyrusInterface(); - if (!papyrus || !papyrus->Register(Papyrus::RegisterFunctions)) - { - logger::critical("Failed to register Papyrus functions, marking as incompatible."sv); - return false; - } - - Hooks::Install(); - - return true; -} +#include "Hooks/Hooks.h" +#include "MCM/MCM.h" +#include "Menus/PowerArmorConditionMenu.h" +#include "Scripts/Papyrus.h" + +namespace +{ + void InitializeLog() + { + auto path = logger::log_directory(); + if (!path) + { + stl::report_and_fail("Failed to find standard logging directory"sv); + } + + *path /= fmt::format(FMT_STRING("{:s}.log"sv), Version::PROJECT); + auto sink = std::make_shared(path->string(), true); + + auto log = std::make_shared("global log"s, std::move(sink)); + auto lvl = *Settings::General::EnableDebugLogging + ? spdlog::level::trace + : spdlog::level::info; + + log->set_level(lvl); + log->flush_on(lvl); + + spdlog::set_default_logger(std::move(log)); + spdlog::set_pattern("[%m/%d/%Y - %T] [%^%l%$] %v"s); + + logger::info(FMT_STRING("{:s} v{:s}"sv), Version::PROJECT, Version::NAME); + } + + void MessageHandler(F4SE::MessagingInterface::Message* a_msg) + { + if (!a_msg) + { + return; + } + + switch (a_msg->type) + { + case F4SE::MessagingInterface::kGameDataReady: + Hooks::InstallPostLoad(); + break; + default: + break; + } + } +} + +extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Query(const F4SE::QueryInterface* a_F4SE, F4SE::PluginInfo* a_info) +{ + a_info->infoVersion = F4SE::PluginInfo::kVersion; + a_info->name = Version::PROJECT.data(); + a_info->version = Version::MAJOR; + + const auto rtv = a_F4SE->RuntimeVersion(); + if (rtv < F4SE::RUNTIME_LATEST) + { + stl::report_and_fail( + fmt::format( + FMT_STRING("{:s} does not support runtime v{:s}."sv), + Version::PROJECT, + rtv.string())); + } + + return true; +} + +extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Load(const F4SE::LoadInterface* a_F4SE) +{ + Settings::Load(); + InitializeLog(); + + logger::info(FMT_STRING("{:s} loaded."sv), Version::PROJECT); + logger::debug("Debug logging enabled."sv); + + F4SE::Init(a_F4SE); + F4SE::AllocTrampoline(1u << 8); + + const auto messaging = F4SE::GetMessagingInterface(); + if (!messaging || !messaging->RegisterListener(MessageHandler)) + { + logger::critical("Failed to register messaging handler, marking as incompatible."sv); + return false; + } + + const auto papyrus = F4SE::GetPapyrusInterface(); + if (!papyrus || !papyrus->Register(Papyrus::RegisterFunctions)) + { + logger::critical("Failed to register Papyrus functions, marking as incompatible."sv); + return false; + } + + Hooks::Install(); + + return true; +}