diff --git a/example_community_patch_settings_en.toml b/example_community_patch_settings_en.toml index 3ab4e2c6..09c003f4 100644 --- a/example_community_patch_settings_en.toml +++ b/example_community_patch_settings_en.toml @@ -685,6 +685,9 @@ auto_open_bulk_claim_flyout = false # Prevent "escape" from prompting to exit the game disable_escape_exit = true +# ⚠️ EXPERIMENTAL: Show only the first ad/interstitial popup after the game starts, then suppress the rest +only_show_first_popup = false + # Maximum gap in milliseconds between Escape presses that opens the exit prompt; 0 disables double-tap exit disable_escape_exit_timer = 0 diff --git a/mods/src/config.cc b/mods/src/config.cc index bc245d2e..8d064d66 100644 --- a/mods/src/config.cc +++ b/mods/src/config.cc @@ -1100,8 +1100,8 @@ void Config::Load() get_config_or_default(config, parsed, "ui", "disable_preview_locate", DCU::disable_preview_locate, write_config); this->disable_preview_recall = get_config_or_default(config, parsed, "ui", "disable_preview_recall", DCU::disable_preview_recall, write_config); - this->disable_first_popup = - get_config_or_default(config, parsed, "ui", "disable_first_popup", DCU::disable_first_popup, write_config); + this->only_show_first_popup = get_config_or_default(config, parsed, "ui", "only_show_first_popup", + DCU::only_show_first_popup, write_config); this->disable_move_keys = get_config_or_default(config, parsed, "ui", "disable_move_keys", DCU::disable_move_keys, write_config); this->disable_toast_banners = diff --git a/mods/src/config.h b/mods/src/config.h index fa36dcd9..039d891e 100644 --- a/mods/src/config.h +++ b/mods/src/config.h @@ -253,6 +253,8 @@ class Config final bool reverse_haven_history; bool arrow_keys_to_select_ship; + bool only_show_first_popup; + bool show_cargo_default; bool show_player_cargo; bool show_station_cargo; diff --git a/mods/src/defaultconfig.h b/mods/src/defaultconfig.h index b6ca962d..85a8da2a 100644 --- a/mods/src/defaultconfig.h +++ b/mods/src/defaultconfig.h @@ -259,6 +259,7 @@ namespace UI constexpr bool auto_open_bulk_claim_flyout = false; constexpr const char* daily_bulk_claim_factions = ""; constexpr bool daily_bulk_claim_toggle_default_on = false; + constexpr bool only_show_first_popup = false; constexpr bool disable_escape_exit = true; // Maximum gap between Escape presses that opens the exit prompt. // 0 disables double-tap and preserves the existing blocked behavior. diff --git a/mods/src/patches/parts/misc.cc b/mods/src/patches/parts/misc.cc index 474907e2..1b1231d3 100644 --- a/mods/src/patches/parts/misc.cc +++ b/mods/src/patches/parts/misc.cc @@ -18,6 +18,7 @@ #endif #include +#include #include #include @@ -249,19 +250,36 @@ class ShopSectionContext } }; -bool isFirstInterstitial = true; +static std::atomic_bool g_first_popup_shown{false}; + +bool ShouldSuppressAdditionalPopup() +{ + bool expected = false; + return !g_first_popup_shown.compare_exchange_strong(expected, true); +} void InterstitialViewController_AboutToShow(auto original, InterstitialViewController* _this) { - if (false /* TEMP: disable_first_popup effect disabled */ && Config::Get().disable_first_popup - && isFirstInterstitial && _this != nullptr) { - isFirstInterstitial = false; - _this->CloseWhenReady(); - } else { - original(_this); + original(_this); + if (Config::Get().only_show_first_popup && _this != nullptr) { + if (ShouldSuppressAdditionalPopup()) { + spdlog::debug("InterstitialViewController_AboutToShow: suppressing interstitial popup (already shown one)"); + _this->CloseWhenReady(); + } else { + spdlog::debug("InterstitialViewController_AboutToShow: allowing first popup of the session to show"); + } } } +void ShopSceneManager_ShowPlcOfferPopup(auto original, void* _this) +{ + if (Config::Get().only_show_first_popup && ShouldSuppressAdditionalPopup()) { + spdlog::debug("ShopSceneManager_ShowPlcOfferPopup: suppressing PLC offer popup (already shown one)"); + return; + } + original(_this); +} + void ActionQueueManager_AddActionToQueue(auto original, ActionQueueManager* _this, long fleet_id) { spdlog::warn("ActionQueueManager_AddActionToQueue({})", fleet_id); @@ -285,7 +303,7 @@ void InstallTempCrashFixes() } } - auto shop_scene_manager = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Shop", "ShopSceneManager"); + static auto shop_scene_manager = il2cpp_get_class_helper("Assembly-CSharp", "Digit.Prime.Shop", "ShopSceneManager"); if (!shop_scene_manager.isValidHelper()) { ErrorMsg::MissingHelper("Shop", "ShopSceneManager"); } else { @@ -295,6 +313,13 @@ void InstallTempCrashFixes() } else { SPUD_STATIC_DETOUR(reveal_show, ShouldShowRevealHook); } + + auto show_plc = shop_scene_manager.GetMethod("ShowPlcOfferPopup", 0); + if (!show_plc) { + ErrorMsg::MissingMethod("ShopSceneManager", "ShowPlcOfferPopup"); + } else { + SPUD_STATIC_DETOUR(show_plc, ShopSceneManager_ShowPlcOfferPopup); + } } static auto interstitial_controller =