diff --git a/.gitmodules b/.gitmodules index 990f00f..5f5acbc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ [submodule "extern/GreenSock-AS2"] path = extern/GreenSock-AS2 url = https://github.com/greensock/GreenSock-AS2 +[submodule "extern/CommonLibVR"] + path = extern/CommonLibVR + url = https://github.com/alandtse/CommonLibVR.git + branch = ng diff --git a/README.md b/README.md index 1ca1d91..b548656 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ * [Visual Studio Community 2022](https://visualstudio.microsoft.com/) * Desktop development with C++ * [CommonLibSSE-NG](https://github.com/alandtse/CommonLibVR/tree/ng) - * Add the environment variable `CommonLibSSEPath_NG` with the value as the path to the folder containing CommonLibSSE-NG + * Add this as as an environment variable `CommonLibSSEPath` ## User Requirements * [Address Library for SKSE](https://www.nexusmods.com/skyrimspecialedition/mods/32444) @@ -17,6 +17,7 @@ ``` git clone https://github.com/ersh1/TrueHUD/ cd TrueHUD +# pull commonlib /extern to override the path settings git submodule init git submodule update diff --git a/extern/CommonLibVR b/extern/CommonLibVR new file mode 160000 index 0000000..8593e41 --- /dev/null +++ b/extern/CommonLibVR @@ -0,0 +1 @@ +Subproject commit 8593e41c1f780b5b16b227f4f62e574d01e0ac3d diff --git a/src/HUDHandler.cpp b/src/HUDHandler.cpp index b6864c3..c9dc06d 100644 --- a/src/HUDHandler.cpp +++ b/src/HUDHandler.cpp @@ -350,7 +350,7 @@ void HUDHandler::AddActorInfoBar(RE::ObjectRefHandle a_actorHandle) return; } - if (a_actorHandle.native_handle() == 0x100000) { + if (a_actorHandle.native_handle() == 0x100000 && !extAddedActorInfoBars.contains(a_actorHandle)) { return; } @@ -363,7 +363,7 @@ void HUDHandler::AddActorInfoBar(RE::ObjectRefHandle a_actorHandle) void HUDHandler::RemoveActorInfoBar(RE::ObjectRefHandle a_actorHandle, WidgetRemovalMode a_removalMode /*= kImmediate*/) { - if (a_actorHandle) { + if (a_actorHandle && !extAddedActorInfoBars.contains(a_actorHandle)) { AddHUDTask([a_actorHandle, a_removalMode](TrueHUDMenu& a_menu) { a_menu.RemoveActorInfoBar(a_actorHandle, a_removalMode); }); @@ -381,7 +381,7 @@ void HUDHandler::AddBossInfoBar(RE::ObjectRefHandle a_actorHandle) return; } - if (a_actorHandle.native_handle() == 0x100000) { + if (a_actorHandle.native_handle() == 0x100000 && !extAddedActorInfoBars.contains(a_actorHandle)) { return; } @@ -394,7 +394,7 @@ void HUDHandler::AddBossInfoBar(RE::ObjectRefHandle a_actorHandle) void HUDHandler::RemoveBossInfoBar(RE::ObjectRefHandle a_actorHandle, WidgetRemovalMode a_removalMode /*= kImmediate*/) { - if (a_actorHandle) { + if (a_actorHandle && !extAddedActorInfoBars.contains(a_actorHandle)) { AddHUDTask([a_actorHandle, a_removalMode](TrueHUDMenu& a_menu) { a_menu.RemoveBossInfoBar(a_actorHandle, a_removalMode); }); @@ -692,6 +692,7 @@ void HUDHandler::RemoveAllWidgets() AddHUDTask([](TrueHUDMenu& a_menu) { a_menu.RemoveAllWidgets(); }); + extAddedActorInfoBars.clear(); } bool HUDHandler::CheckActorForBoss(RE::ObjectRefHandle a_refHandle) diff --git a/src/HUDHandler.h b/src/HUDHandler.h index 1ac9828..8021cca 100644 --- a/src/HUDHandler.h +++ b/src/HUDHandler.h @@ -117,6 +117,7 @@ class HUDHandler : SpecialResourceCallback GetMaxSpecial = nullptr; bool bSpecialMode; bool bDisplaySpecialForPlayer; + std::set> extAddedActorInfoBars; protected: friend class TrueHUDMenu; diff --git a/src/ModAPI.cpp b/src/ModAPI.cpp index e9d2e74..20d058c 100644 --- a/src/ModAPI.cpp +++ b/src/ModAPI.cpp @@ -83,6 +83,7 @@ namespace Messaging { auto hudHandler = HUDHandler::GetSingleton(); if (hudHandler) { + hudHandler->extAddedActorInfoBars.insert(a_actorHandle); hudHandler->AddActorInfoBar(a_actorHandle); } } @@ -91,6 +92,7 @@ namespace Messaging { auto hudHandler = HUDHandler::GetSingleton(); if (hudHandler) { + hudHandler->extAddedActorInfoBars.erase(a_actorHandle); hudHandler->RemoveActorInfoBar(a_actorHandle, static_cast(a_removalMode)); } } @@ -99,6 +101,7 @@ namespace Messaging { auto hudHandler = HUDHandler::GetSingleton(); if (hudHandler) { + hudHandler->extAddedActorInfoBars.insert(a_actorHandle); hudHandler->AddBossInfoBar(a_actorHandle); } } @@ -107,6 +110,7 @@ namespace Messaging { auto hudHandler = HUDHandler::GetSingleton(); if (hudHandler) { + hudHandler->extAddedActorInfoBars.erase(a_actorHandle); hudHandler->RemoveBossInfoBar(a_actorHandle, static_cast(a_removalMode)); } } diff --git a/src/Scaleform/TrueHUDMenu.h b/src/Scaleform/TrueHUDMenu.h index df19357..52fae0c 100644 --- a/src/Scaleform/TrueHUDMenu.h +++ b/src/Scaleform/TrueHUDMenu.h @@ -24,6 +24,15 @@ namespace std }; } +template +struct HandleComp +{ + bool operator()(const RE::BSPointerHandle& a_lhs, const RE::BSPointerHandle& a_rhs) const + { + return std::hash>()(a_lhs) < std::hash>()(a_rhs); + } +}; + namespace Scaleform { class DebugLine diff --git a/src/Widgets/InfoBarBase.cpp b/src/Widgets/InfoBarBase.cpp index f634664..b87be72 100644 --- a/src/Widgets/InfoBarBase.cpp +++ b/src/Widgets/InfoBarBase.cpp @@ -117,6 +117,8 @@ namespace Scaleform auto softTargetHandle = hudMenu->GetSoftTarget(); bool bIsTeammate = Utils::IsPlayerTeammateOrSummon(actor); + bool bIsPlayer = actor == playerCharacter; + bool bExtManaged = HUDHandler::GetSingleton()->extAddedActorInfoBars.contains(actor->GetHandle()); TargetType targetType; if (targetHandle && _refHandle == targetHandle) { @@ -125,7 +127,7 @@ namespace Scaleform targetType = kTarget; } else if (actor->IsHostileToActor(playerCharacter)) { targetType = kEnemy; - } else if (bIsTeammate) { + } else if (bIsTeammate || bIsPlayer) { targetType = kTeammate; } else { targetType = kOther; @@ -153,9 +155,9 @@ namespace Scaleform const auto shouldBarBeDisplayed = [&]() { if (_barType == BarType::kBossInfoBar) { - return !bIsTeammate && actor->IsInCombat() && actor->IsHostileToActor(playerCharacter); + return (bExtManaged) || (!bIsTeammate && actor->IsInCombat() && actor->IsHostileToActor(playerCharacter)); } else if (_barType == BarType::kActorInfoBar) { - if (targetType > kTarget && !actor->IsInCombat()) { + if (!bExtManaged && targetType > kTarget && !actor->IsInCombat()) { return false; } switch (targetType) { @@ -181,7 +183,7 @@ namespace Scaleform SetWidgetState(WidgetStateMode::kHide); } else { bool r8 = false; - bool bHasLOS = targetType == kTarget ? true : playerCharacter->HasLineOfSight(actor, r8); + bool bHasLOS = targetType == kTarget || bExtManaged || bIsPlayer ? true : playerCharacter->HasLineOfSight(actor, r8); bool bVisible = bHasLOS && !(actor->AsActorValueOwner()->GetActorValue(RE::ActorValue::kInvisibility) > 0); if (bVisible) { SetWidgetState(WidgetStateMode::kShow); @@ -197,7 +199,7 @@ namespace Scaleform uint32_t levelColor = Settings::uDefaultColor; uint32_t outlineColor = Settings::uDefaultColorOutline; - if (bIsTeammate) { + if (bIsTeammate || bIsPlayer) { levelColor = Settings::uTeammateColor; outlineColor = Settings::uTeammateColorOutline; } else if (playerLevel - targetLevel > Settings::uInfoBarLevelThreshold) { diff --git a/src/main.cpp b/src/main.cpp index d858eac..1195f0c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -90,9 +90,9 @@ extern "C" DLLEXPORT constinit auto SKSEPlugin_Version = []() { v.PluginVersion(Plugin::VERSION); v.PluginName(Plugin::NAME); v.AuthorName("Ersh"); - v.UsesAddressLibrary(true); + v.UsesAddressLibrary(); v.CompatibleVersions({ SKSE::RUNTIME_SSE_LATEST }); - v.HasNoStructUse(true); + v.UsesNoStructs(); return v; }();