diff --git a/example_community_patch_settings_da.toml b/example_community_patch_settings_da.toml index 55e29aed..1bad8e14 100644 --- a/example_community_patch_settings_da.toml +++ b/example_community_patch_settings_da.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_de.toml b/example_community_patch_settings_de.toml index b00e903d..0bbd1ce0 100644 --- a/example_community_patch_settings_de.toml +++ b/example_community_patch_settings_de.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_en-GB-x-cockney.toml b/example_community_patch_settings_en-GB-x-cockney.toml index 53d73320..fe7c1d7c 100644 --- a/example_community_patch_settings_en-GB-x-cockney.toml +++ b/example_community_patch_settings_en-GB-x-cockney.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_en-x-minionese.toml b/example_community_patch_settings_en-x-minionese.toml index cad31a7e..8ab2dc1b 100644 --- a/example_community_patch_settings_en-x-minionese.toml +++ b/example_community_patch_settings_en-x-minionese.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_en.toml b/example_community_patch_settings_en.toml index 09c003f4..05588e2a 100644 --- a/example_community_patch_settings_en.toml +++ b/example_community_patch_settings_en.toml @@ -778,34 +778,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_es.toml b/example_community_patch_settings_es.toml index 535cffdb..27dccbae 100644 --- a/example_community_patch_settings_es.toml +++ b/example_community_patch_settings_es.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_fr.toml b/example_community_patch_settings_fr.toml index 2364d54f..25128bd7 100644 --- a/example_community_patch_settings_fr.toml +++ b/example_community_patch_settings_fr.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_nl.toml b/example_community_patch_settings_nl.toml index b601977e..2555d285 100644 --- a/example_community_patch_settings_nl.toml +++ b/example_community_patch_settings_nl.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_ru.toml b/example_community_patch_settings_ru.toml index fa66b9da..72f174e6 100644 --- a/example_community_patch_settings_ru.toml +++ b/example_community_patch_settings_ru.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/example_community_patch_settings_tlh.toml b/example_community_patch_settings_tlh.toml index a74a1073..544d8af5 100644 --- a/example_community_patch_settings_tlh.toml +++ b/example_community_patch_settings_tlh.toml @@ -761,34 +761,29 @@ pinned_ships = "" # Subgroup: HUD # ------------- -# HUD visibility mode: auto, show, or hide -# "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item -hud_daily_goals = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_field_training = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_missions = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_outposts = "auto" -# HUD visibility mode: auto, show, or hide +# HUD visibility mode: auto, always, or never # "auto" - Use the game's default visibility behaviour -# "show" - Always show this HUD item -# "hide" - Always hide this HUD item +# "always" - Always show this HUD item +# "never" - Always hide this HUD item hud_q_trials = "auto" # Subgroup: Options diff --git a/mods/src/config.cc b/mods/src/config.cc index 8d064d66..8cb005c9 100644 --- a/mods/src/config.cc +++ b/mods/src/config.cc @@ -1206,9 +1206,6 @@ void Config::Load() write_config)); this->mission_hud_buttons.emplace( "outposts", get_mission_hud_visibility(config, parsed, "hud_outposts", DCU::hud_outposts, write_config)); - this->mission_hud_buttons.emplace( - "daily_goals", - get_mission_hud_visibility(config, parsed, "hud_daily_goals", DCU::hud_daily_goals, write_config)); this->mission_hud_buttons.emplace( "missions", get_mission_hud_visibility(config, parsed, "hud_missions", DCU::hud_missions, write_config)); this->disable_exchange_all = get_config_or_default_with_alias( diff --git a/mods/src/defaultconfig.h b/mods/src/defaultconfig.h index 85a8da2a..0ce3a01f 100644 --- a/mods/src/defaultconfig.h +++ b/mods/src/defaultconfig.h @@ -278,7 +278,6 @@ namespace UI constexpr bool officer_sort = true; constexpr bool reverse_haven_history = true; constexpr const char* disabled_banner_types = ""; - constexpr const char* hud_daily_goals = "auto"; constexpr const char* hud_field_training = "auto"; constexpr const char* hud_missions = "auto"; constexpr const char* hud_outposts = "auto"; diff --git a/mods/src/patches/parts/mission_hud_tweaks.cc b/mods/src/patches/parts/mission_hud_tweaks.cc index 512890be..8eeee11f 100644 --- a/mods/src/patches/parts/mission_hud_tweaks.cc +++ b/mods/src/patches/parts/mission_hud_tweaks.cc @@ -2,6 +2,7 @@ #include "errormsg.h" #include +#include #include #include @@ -26,17 +27,17 @@ struct MissionHudButtonDefinition { using ComponentGetGameObjectFn = void* (*)(void*); using GameObjectSetActiveFn = void (*)(void*, bool); -std::array g_button_definitions{{ +std::array g_button_definitions{{ {"q_trials", "_challengesButton"}, {"field_training", "_achievementsButton"}, {"outposts", "_outpostsButton"}, - {"daily_goals", "_dailyGoalsButton"}, {"missions", "_missionsButton"}, }}; std::vector g_configured_buttons; ComponentGetGameObjectFn g_get_game_object = nullptr; GameObjectSetActiveFn g_set_active = nullptr; +bool g_ready = false; std::string_view to_string(MissionHudVisibility visibility) { @@ -78,12 +79,19 @@ std::string ConfiguredButtonModes() return modes; } -bool ResolveButtonFields(IL2CppClassHelper& controller_helper) +bool ResolveButtonFields(IL2CppClassHelper& controller_helper, Il2CppClass* component_class) { auto valid_count = 0; for (auto* button : g_configured_buttons) { auto field = controller_helper.GetField(button->field_name); - if (!field.isValidHelper()) { + auto* info = field.get_info(); + const auto* type = info ? info->type : nullptr; + auto* field_class = type ? il2cpp_class_from_type(type) : nullptr; + if (!info || !type || type->byref || (il2cpp_field_get_flags(info) & FIELD_ATTRIBUTE_STATIC) + || (type->type != IL2CPP_TYPE_CLASS && type->type != IL2CPP_TYPE_GENERICINST) + || !field_class || !il2cpp_class_is_assignable_from(component_class, field_class) + || info->offset < sizeof(Il2CppObject) + || info->offset + sizeof(void*) > il2cpp_class_instance_size(controller_helper.get_cls())) { spdlog::error("MissionHudTweaks: unable to find MissionsHudViewController field '{}'", button->field_name); continue; } @@ -114,18 +122,49 @@ void ApplyButtonVisibility(void* controller, const MissionHudButtonDefinition& b } } // namespace -int32_t MissionsHudViewController_UpdateButtons_Hook(auto original, void* controller) +// Visibility is now refreshed through several independent paths. Keep the game's +// setup/notification work, then apply only explicitly configured overrides. +void ApplyConfiguredButtonVisibility(void* controller) { - const auto result = original(controller); - + if (!g_ready) + return; for (auto* button : g_configured_buttons) { button->visibility = Config::Get().MissionHudButtonVisibility(button->canonical_name); - if (button->visibility != MissionHudVisibility::Auto) { + if (button->visibility != MissionHudVisibility::Auto) ApplyButtonVisibility(controller, *button); - } } +} + +void MissionsHudViewController_OnEnable_Hook(auto original, void* controller) +{ + original(controller); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_SetupAchievementsButton_Hook(auto original, void* controller) +{ + original(controller); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_SetupChallengesButton_Hook(auto original, void* controller, bool replace_with_outposts) +{ + original(controller, replace_with_outposts); + ApplyConfiguredButtonVisibility(controller); +} - return result; +void MissionsHudViewController_SetupOutpostsButton_Hook(auto original, void* controller, bool show_outposts) +{ + original(controller, show_outposts); + ApplyConfiguredButtonVisibility(controller); +} + +void MissionsHudViewController_HandleOutpostsAndChallengesHUD_Hook(auto original, void* controller) +{ + // In planetary view this method hides challenges directly, bypassing its setup + // method. Reapply after the whole operation, including the planetary branch. + original(controller); + ApplyConfiguredButtonVisibility(controller); } void InstallMissionHudTweaksHooks() @@ -138,17 +177,17 @@ void InstallMissionHudTweaksHooks() return; } - if (!ResolveButtonFields(controller_helper)) { - return; - } - auto component_helper = il2cpp_get_class_helper("UnityEngine.CoreModule", "UnityEngine", "Component"); if (!component_helper.isValidHelper()) { ErrorMsg::MissingHelper("UnityEngine", "Component"); return; } - g_get_game_object = reinterpret_cast(component_helper.GetMethod("get_gameObject")); + if (!ResolveButtonFields(controller_helper, component_helper.get_cls())) + return; + const auto* get_game_object = method_contract::Resolve( + component_helper.get_cls(), "get_gameObject", false, "UnityEngine.GameObject", {}); + g_get_game_object = reinterpret_cast(method_contract::Pointer(get_game_object)); if (!g_get_game_object) { ErrorMsg::MissingMethod("Component", "get_gameObject"); return; @@ -160,22 +199,73 @@ void InstallMissionHudTweaksHooks() return; } - g_set_active = reinterpret_cast(game_object_helper.GetMethod("SetActive", 1)); + const auto* set_active = method_contract::Resolve( + game_object_helper.get_cls(), "SetActive", false, "System.Void", {"System.Boolean"}); + g_set_active = reinterpret_cast(method_contract::Pointer(set_active)); if (!g_set_active) { ErrorMsg::MissingMethod("GameObject", "SetActive"); return; } - auto update_buttons = controller_helper.GetMethod("UpdateButtons", 0); - if (!update_buttons) { - ErrorMsg::MissingMethod("MissionsHudViewController", "UpdateButtons"); + // Resolve the complete surface before installing anything. Avoid the tiny + // planetary/outpost event wrappers: these substantive methods own the work. + const auto* on_enable = method_contract::Resolve( + controller_helper.get_cls(), "OnEnable", false, "System.Void", {}); + const auto* achievements = method_contract::Resolve( + controller_helper.get_cls(), "SetupAchievementsButton", false, "System.Void", {}); + const auto* challenges = method_contract::Resolve( + controller_helper.get_cls(), "SetupChallengesButton", false, "System.Void", {"System.Boolean"}); + const auto* outposts = method_contract::Resolve( + controller_helper.get_cls(), "SetupOutpostsButton", false, "System.Void", {"System.Boolean"}); + const auto* combined = method_contract::Resolve( + controller_helper.get_cls(), "HandleOutpostsAndChallengesHUD", false, "System.Void", {}); + const std::array targets{on_enable, achievements, challenges, outposts, combined}; + const std::array names{"OnEnable()", "SetupAchievementsButton()", "SetupChallengesButton(Boolean)", + "SetupOutpostsButton(Boolean)", "HandleOutpostsAndChallengesHUD()"}; + for (std::size_t i = 0; i < targets.size(); ++i) { + if (!targets[i]) { + ErrorMsg::MissingMethod("MissionsHudViewController", names[i]); + return; + } + } + for (std::size_t i = 0; i < targets.size(); ++i) { + if (targets[i]->has_full_generic_sharing_signature) { + spdlog::error("MissionHudTweaks: MissionsHudViewController.{} uses unsupported generic sharing; overrides disabled", + names[i]); + return; + } + for (std::size_t j = 0; j < i; ++j) + if (targets[i]->methodPointer == targets[j]->methodPointer) { + spdlog::error("MissionHudTweaks: MissionsHudViewController.{} and {} share a native target; overrides disabled", + names[i], names[j]); + return; + } + } + if (get_game_object->has_full_generic_sharing_signature || set_active->has_full_generic_sharing_signature) { + spdlog::error("MissionHudTweaks: {} uses unsupported generic sharing; overrides disabled", + get_game_object->has_full_generic_sharing_signature ? "Component.get_gameObject()" + : "GameObject.SetActive(Boolean)"); return; } - - const auto configured_modes = ConfiguredButtonModes(); - if (!configured_modes.empty()) { - spdlog::info("MissionHudTweaks: applying {}", configured_modes); + const auto modes = ConfiguredButtonModes(); + if (!modes.empty()) + spdlog::info("MissionHudTweaks: applying {}", modes); + const bool enabled = SPUD_STATIC_DETOUR(on_enable->methodPointer, MissionsHudViewController_OnEnable_Hook); + const bool achievement_hook = SPUD_STATIC_DETOUR(achievements->methodPointer, MissionsHudViewController_SetupAchievementsButton_Hook); + const bool challenge_hook = SPUD_STATIC_DETOUR(challenges->methodPointer, MissionsHudViewController_SetupChallengesButton_Hook); + const bool outpost_hook = SPUD_STATIC_DETOUR(outposts->methodPointer, MissionsHudViewController_SetupOutpostsButton_Hook); + const bool combined_hook = SPUD_STATIC_DETOUR(combined->methodPointer, MissionsHudViewController_HandleOutpostsAndChallengesHUD_Hook); + const std::array installed{enabled, achievement_hook, challenge_hook, outpost_hook, combined_hook}; + for (std::size_t i = 0; i < installed.size(); ++i) + if (!installed[i]) + spdlog::error("MissionHudTweaks: failed to install MissionsHudViewController.{}; overrides disabled", names[i]); + g_ready = enabled && achievement_hook && challenge_hook && outpost_hook && combined_hook; + if (g_ready) { + spdlog::info("MissionHudTweaks: installed current HUD lifecycle/setup hooks"); + } else { + // Successfully installed detours still call through, but must not partially + // enforce preferences when another refresh path could undo them. + g_configured_buttons.clear(); + spdlog::error("MissionHudTweaks: hook installation incomplete; overrides disabled"); } - SPUD_STATIC_DETOUR(update_buttons, MissionsHudViewController_UpdateButtons_Hook); - spdlog::info("MissionHudTweaks: installed MissionsHudViewController.UpdateButtons hook"); }