diff --git a/StyxBladesOfGreed/dllmain.cpp b/StyxBladesOfGreed/dllmain.cpp index b9cdfe1..5a907d9 100644 --- a/StyxBladesOfGreed/dllmain.cpp +++ b/StyxBladesOfGreed/dllmain.cpp @@ -2,18 +2,19 @@ #include "CommonHeaders.h" #include "UEngine.hpp" #include "UETools.hpp" +#include "UEWidgets.hpp" #include "UEvars.hpp" #include "UEMath.hpp" #include "Logger.hpp" #include "SDK/Basic.hpp" #include "SDK/Engine_classes.hpp" #include "SDK/UI_Settings_classes.hpp" -#include "SDK/UI_InputButton_Menu_classes.hpp" #include "SDK/UI_Profile_classes.hpp" #include "SDK/UI_MainMenu_classes.hpp" #include "SDK/UI_Difficulty_classes.hpp" #include "SDK/UI_InGameMenu_classes.hpp" #include "SDK/UI_PauseMenu_classes.hpp" +#include "SDK/UI_Saves_classes.hpp" #include "SDK/Styx3_classes.hpp" using namespace SDK; @@ -30,7 +31,7 @@ std::shared_ptr logger; static int screenWidth = GetSystemMetrics(SM_CXSCREEN); static int screenHeight = GetSystemMetrics(SM_CYSCREEN); float g_AspectRatio = (float)screenWidth / screenHeight; -float g_BaseAspectRatio = 2.39; +float g_BaseAspectRatio = 2.39f; // Plugin states static bool AOBScanDone = false; @@ -94,14 +95,16 @@ static void EnableConsole(); static void EnableCheats(Cheat cheat); static void ProcessEvent(); // UEngine variable -static UWidget* g_UIMainMenuWidget = nullptr; -static UWidget* g_UISettingsWidget = nullptr; -static UWidget* g_UISettingsDescWidget = nullptr; -static UWidget* g_DifficultyWidget = nullptr; -static UWidget* g_difficultyMenusWidget = nullptr; -static UWidget* g_ProfileWidget = nullptr; -static UWidget* g_InGameMenuWidget = nullptr; -static UWidget* g_PauseWidget = nullptr; +static UUserWidget* g_UIMainMenuWidget = nullptr; +static UUserWidget* g_UISettingsWidget = nullptr; +static UUserWidget* g_DifficultyWidget = nullptr; +static UUserWidget* g_ProfileWidget = nullptr; +static UUserWidget* g_InGameMenuWidget = nullptr; +static UUserWidget* g_PauseWidget = nullptr; +static UUserWidget* g_SavesWidget = nullptr; +static UUserWidget* g_MapWidget = nullptr; +static UUserWidget* g_GameOverWidget = nullptr; +static UUserWidget* g_LoadingWidget = nullptr; static UWidget* g_StatusWidget = nullptr; static UWidget* g_GaugesWidget = nullptr; static UWidget* g_ChangeWheelWidget = nullptr; @@ -135,7 +138,7 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled, bool init) { Make(&Vignettingaddress, VignettingStringObfuscated, "Vignetting"), Make(&Fogaddress, FogStringObfuscated, "Fog"), Make(&WorldTimedilationaddress, WorldTimeDilationStringObfuscated, "World time dilation"), - Make(&Timedilationaddress, TimeDilationStringObfuscated, "Actor time dilation") + Make(&Timedilationaddress, TimeDilationStringObfuscated, "Actor time dilation"), }; // Scan all signature in a batch Memory::AOBScanBatch(signatures, logger); @@ -238,7 +241,7 @@ static void ProcessEvent() { PEHook = safetyhook::create_mid(ProcessEventaddress + 0xc, [](SafetyHookContext& ctx) { ULONGLONG now = GetTickCount64(); - if (now - lastScanTick >= DEFAULT_DELAY_BETWEEN_TICK) { // si le délai est passé + if (now - lastScanTick >= DEFAULT_DELAY_BETWEEN_TICK) { // Delay between each tick to avoid ProcessEvent stuttering lastScanTick = now; GetResolution(screenWidth, screenHeight, g_AspectRatio); } @@ -248,62 +251,52 @@ static void ProcessEvent() { if (!object || !func) return; std::string funcName = func->GetName(); + // Full stealth fix: disable AI perception. if (object->IsA(AStyx3AIController::StaticClass()) && funcName == "OnPerceptionIntensityUpdated") { auto* AIController = static_cast(object); if (g_Player && AIController->PerceptionGaugeComponent) { - if (g_Stealth_fix_enabled) + if (g_Stealth_fix_enabled) { AIController->PerceptionGaugeComponent->ResetGauges(g_Player); - else + if (g_Player) g_Player->bIsPerceptible = false; + } + else { AIController->PerceptionGaugeComponent->SetActiveBufferDetection(g_Player, true); + if (g_Player) g_Player->bIsPerceptible = true; + } } } if (object->IsA(UUserWidget::StaticClass()) && (funcName == "Construct" || funcName == "Destruct" || funcName == "Tick")) { std::string objectName = object->GetName(); - auto UpdateUI = [&](const std::vector& targets, const std::vector& values) { + // UI scaling + auto HandleWidget = [&](auto* typedWidget, auto*& gWidgetPtr) { // Lambda to initialize pointers on Construct and nullify them on Destruct if (funcName == "Construct") { - for (size_t i = 0; i < targets.size(); ++i) - *targets[i] = values[i]; - + gWidgetPtr = typedWidget; HUDUpdate(false); } - else if (funcName == "Destruct") - for (auto* t : targets) *t = nullptr; + else if (funcName == "Destruct") gWidgetPtr = nullptr; }; - // UI scaling - if (object->IsA(UUI_Settings_C::StaticClass())) { - auto* settings = static_cast(object); - auto* widget = static_cast(object); - UpdateUI({ &g_UISettingsWidget, &g_UISettingsDescWidget }, { widget->WidgetTree->RootWidget, settings->Description_Holder }); - } - else if (object->IsA(UUI_Difficulty_C::StaticClass())) { - auto* difficulty = static_cast(object); - auto* widget = static_cast(object); - - UpdateUI({ &g_DifficultyWidget, &g_difficultyMenusWidget }, { widget->WidgetTree->RootWidget, difficulty->VerticalBox_Menu }); - } - else if (object->IsA(UUI_InGameMenu_C::StaticClass())) { - auto* inGameMenu = static_cast(object); - - UpdateUI({ &g_InGameMenuWidget }, { inGameMenu->WidgetTree->RootWidget }); - } - else if (object->IsA(UUI_PauseMenu_C::StaticClass())) { - auto* pauseMenu = static_cast(object); - - UpdateUI({ &g_PauseWidget }, { pauseMenu->WidgetTree->RootWidget }); - } - else if (object->IsA(UUI_Profile_C::StaticClass())) { - auto* profile = static_cast(object); - - UpdateUI({ &g_ProfileWidget }, { profile->WidgetTree->RootWidget }); - } - else if (object->IsA(UUI_MainMenu_C::StaticClass())) { - auto* mainmenu = static_cast(object); - - UpdateUI({ &g_UIMainMenuWidget }, { mainmenu->WidgetTree->RootWidget }); - } - // HUD scaling + if (object->IsA(UUI_Settings_C::StaticClass())) + HandleWidget(static_cast(object), g_UISettingsWidget); + else if (object->IsA(UUI_Difficulty_C::StaticClass())) + HandleWidget(static_cast(object), g_DifficultyWidget); + else if (object->IsA(UUI_InGameMenu_C::StaticClass())) + HandleWidget(static_cast(object), g_InGameMenuWidget); + else if (object->IsA(UUI_PauseMenu_C::StaticClass())) + HandleWidget(static_cast(object), g_PauseWidget); + else if (object->IsA(UUI_Profile_C::StaticClass())) + HandleWidget(static_cast(object), g_ProfileWidget); + else if (object->IsA(UUI_MainMenu_C::StaticClass())) + HandleWidget(static_cast(object), g_UIMainMenuWidget); + else if (object->IsA(UUI_Saves_C::StaticClass())) + HandleWidget(static_cast(object), g_SavesWidget); + else if (objectName.rfind("UI_Map_C", 0) == 0) + HandleWidget(static_cast(object), g_MapWidget); + else if (objectName.rfind("UI_GameOver_C", 0) == 0) + HandleWidget(static_cast(object), g_GameOverWidget); + else if (objectName.rfind("UI_Loading_C", 0) == 0) + HandleWidget(static_cast(object), g_LoadingWidget); else { std::function FindWidgets; FindWidgets = [&](SDK::UWidget* Widget) { // Find all HUD important widgets in container @@ -341,14 +334,11 @@ static void ProcessEvent() { }; if (objectName.rfind("Crafting", 0) == 0) { - auto* crafting = static_cast(object); if (funcName == "Construct") { g_CraftingWidget = static_cast(object); HUDUpdate(false); } - else if (funcName == "Destruct") { - g_CraftingWidget = nullptr; - } + else if (funcName == "Destruct") g_CraftingWidget = nullptr; } else if (objectName.rfind("HUD_Widget_C", 0) == 0) { auto* HUDWidget = static_cast(object); @@ -373,36 +363,29 @@ static void ProcessEvent() { } } // -- HUD positionning -- -static void HUDFixEnabled(UWidget* widget, float left, float right, bool writeLog, int depth) { - if (writeLog) logger->info("HUD fix {}", g_fix_enabled && g_HUD_fix_enabled ? "enabled" : "disabled"); - if (!widget) return; - - float targetOffsetLeft = g_fix_enabled && g_HUD_fix_enabled ? left : 100.f; - float targetOffsetRight = g_fix_enabled && g_HUD_fix_enabled ? right : 100.f; - - if (widget->IsA(UCanvasPanel::StaticClass()) || (widget->Slot && widget->Slot->IsA(UCanvasPanelSlot::StaticClass()))) // Apply offsets To CanvasPanel - ApplyOffsetsSmart(widget, targetOffsetLeft, targetOffsetRight, depth); -} - static void HUDUpdate(bool writeLog) { - if (writeLog) logger->info("HUD & UI scaling {}", g_fix_enabled && g_HUD_fix_enabled ? "enabled" : "disabled"); - if (g_fix_enabled && g_HUD_fix_enabled) { - HUDFixEnabled(g_UIMainMenuWidget, g_UIOffsets, g_UIOffsets , false, 1); - HUDFixEnabled(g_UISettingsWidget, g_UIOffsets, g_UIOffsets, false, 1); - HUDFixEnabled(g_UISettingsDescWidget, g_UIOffsets + 1500.f, 675.f, false, 1); - HUDFixEnabled(g_ProfileWidget, g_UIOffsets, g_UIOffsets, false, 1); - HUDFixEnabled(g_DifficultyWidget, g_UIOffsets, g_UIOffsets, false, 1); - HUDFixEnabled(g_difficultyMenusWidget, g_UIOffsets + 576.f + 100.f, 576, false, 1); - HUDFixEnabled(g_InGameMenuWidget, g_UIOffsets, g_UIOffsets, false, 1); - HUDFixEnabled(g_PauseWidget, g_UIOffsets, g_UIOffsets, false, 1); - HUDFixEnabled(g_StatusWidget, g_HUDOffsets, 0.f, false, 1); - HUDFixEnabled(g_GaugesWidget, 0 , g_HUDOffsets + 690.f, false, 1); // Use original left and right offset + for Anchors of type 1, 1, 1, 1 - HUDFixEnabled(g_AbilityWheelWidget,0 , g_HUDOffsets + 78.f, false, 1); // Use original left and right offset + for Anchors of type 1, 1, 1, 1 - HUDFixEnabled(g_ChangeWheelWidget, 0, g_HUDOffsets + 24.f, false, 1); // Use original left and right offset for Anchors of type 1, 1, 1, 1 - ApplyPositionOffset(g_CraftingWidget, g_UIOffsets, FVector2D(0.5f, 0.5f)); // for widgets that only display at left (nothing at right) - ApplyTransformOffset(g_LootWidget, g_HUDOffsets); - ApplyTransformOffset(g_QuestWidget, g_HUDOffsets); - } + if (writeLog) logger->info("HUD & UI scaling fix {}", g_fix_enabled && g_HUD_fix_enabled ? "enabled" : "disabled"); + float UIoffset = (g_fix_enabled && g_HUD_fix_enabled) ? g_UIOffsets : 0.f; + float HUDoffset = (g_fix_enabled && g_HUD_fix_enabled) ? g_HUDOffsets : 0.f; + float compensation = (g_fix_enabled && g_HUD_fix_enabled) ? 90.f : 0.f; + float targetAspect = 16.f / 9.f; + + CenterWidget(g_UIMainMenuWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_UISettingsWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_ProfileWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_DifficultyWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_InGameMenuWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_PauseWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_SavesWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_MapWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + CenterWidget(g_GameOverWidget, UIoffset, screenWidth, screenHeight, g_AspectRatio, targetAspect, compensation); + ApplyOffsetsSmart(g_StatusWidget, HUDoffset, 0.f, 1); + ApplyOffsetsSmart(g_GaugesWidget, 0, HUDoffset + 690.f, 1); // Use original left and right offset + for Anchors of type 1, 1, 1, 1 + ApplyOffsetsSmart(g_AbilityWheelWidget, 0, HUDoffset + 78.f, 1); // Use original left and right offset + for Anchors of type 1, 1, 1, 1 + ApplyOffsetsSmart(g_ChangeWheelWidget, 0, HUDoffset + 24.f, 1); // Use original left and right offset for Anchors of type 1, 1, 1, 1 + ApplyPositionOffset(g_CraftingWidget, UIoffset, FVector2D(0.5f, 0.5f)); // for widgets that only display at left (nothing at right) + ApplyTransformOffset(g_LootWidget, HUDoffset); + ApplyTransformOffset(g_QuestWidget, HUDoffset); } static void FOVFixEnabled() { @@ -496,11 +479,8 @@ static void EnableCheats(Cheat cheat) { if (percentageHealth > 0.0001f) g_Player->CurrentHealth = g_Player->CurrentHealth / percentageHealth; } - g_PlayerAmber = g_Player->CurrentAmber; if (g_Amber_fix_enabled) g_Player->CurrentAmber = g_Player->MaxAmber; - - g_Player->bIsPerceptible = false; } if (object->IsA(AStyx3AICharacter::StaticClass())) { AStyx3AICharacter* enemy = static_cast(object);