From ac032738e18cd875c98f1e5c0876f8152f69debc Mon Sep 17 00:00:00 2001 From: Lukas Denda Date: Thu, 9 Jul 2026 23:41:34 +0200 Subject: [PATCH] Adds an optional visual super countdown after the first siren sounds --- GameMod/GameMod.csproj | 1 + GameMod/MPSetup.cs | 2 ++ GameMod/MPSuperAlert.cs | 59 +++++++++++++++++++++++++++++++++++++++++ GameMod/Menus.cs | 25 ++++++++++------- 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 GameMod/MPSuperAlert.cs diff --git a/GameMod/GameMod.csproj b/GameMod/GameMod.csproj index cb8e7ba8..7e16c64b 100644 --- a/GameMod/GameMod.csproj +++ b/GameMod/GameMod.csproj @@ -188,6 +188,7 @@ + diff --git a/GameMod/MPSetup.cs b/GameMod/MPSetup.cs index 1e01aa2e..405e294c 100644 --- a/GameMod/MPSetup.cs +++ b/GameMod/MPSetup.cs @@ -271,6 +271,7 @@ static void Postfix(string filename) Menus.mms_directional_warnings = ModPrefs.GetBool("MP_PM_DIRECTIONAL_WARNINGS", Menus.mms_directional_warnings); Menus.mms_loadout_hotkeys = ModPrefs.GetInt("MP_PM_LOADOUT_HOTKEYS2", Menus.mms_loadout_hotkeys); Menus.mms_creeper_colors = ModPrefs.GetBool("MP_CREEPER_COLORS", Menus.mms_creeper_colors); + Menus.mms_super_countdown = ModPrefs.GetBool("MP_PM_SUPER_COUNTDOWN", Menus.mms_super_countdown); MPLoadouts.Loadouts[0].weapons[0] = (WeaponType)ModPrefs.GetInt("MP_PM_LOADOUT_BOMBER1_W1", (int)MPLoadouts.Loadouts[0].weapons[0]); MPLoadouts.Loadouts[0].missiles[0] = (MissileType)ModPrefs.GetInt("MP_PM_LOADOUT_BOMBER1_M1", (int)MPLoadouts.Loadouts[0].missiles[0]); @@ -359,6 +360,7 @@ private static void Prefix(string filename) ModPrefs.SetInt("MP_LAG_COMPENSATION_ROTATION_STRENGTH", Menus.mms_lag_compensation_rotation_strength); ModPrefs.SetBool("MP_PM_STICKY_DEATH_SUMMARY", Menus.mms_sticky_death_summary); ModPrefs.SetBool("MP_PM_REDUCED_SHIP_EXPLOSIONS", Menus.mms_reduced_ship_explosions); + ModPrefs.SetBool("MP_PM_SUPER_COUNTDOWN", Menus.mms_super_countdown); ModPrefs.SetInt("MP_PM_DAMAGEEFFECT_ALPHA_MULT", Menus.mms_damageeffect_alpha_mult); ModPrefs.SetInt("MP_PM_DAMAGEEFFECT_DRUNK_BLUR_MULT", Menus.mms_damageeffect_drunk_blur_mult); ModPrefs.SetInt("MP_PM_MATCH_TIME_LIMIT", Menus.mms_match_time_limit); diff --git a/GameMod/MPSuperAlert.cs b/GameMod/MPSuperAlert.cs new file mode 100644 index 00000000..1629a3d3 --- /dev/null +++ b/GameMod/MPSuperAlert.cs @@ -0,0 +1,59 @@ +using HarmonyLib; +using Overload; +using UnityEngine; + +namespace GameMod{ + static class MPSuperAlert{ + public static bool active_countdown = false; + public static float start_time = 0f; + + [HarmonyPatch(typeof(Player), "RpcShowWarningMessage")] + class MPSuperAlert_Player_RpcShowWarningMessage{ + static void Postfix(int type){ + if (!NetworkMatch.InGameplay() || !Menus.mms_super_countdown) + return; + + if(type == 0){ + MPSuperAlert.start_time = Time.time; + MPSuperAlert.active_countdown = true; + } + if(type == 1) + MPSuperAlert.active_countdown = false; + } + } + + [HarmonyPatch(typeof(UIElement), "DrawHUD")] + class MPSuperAlert_UIElement_DrawHUD{ + static void Postfix(UIElement __instance){ + if (!Menus.mms_super_countdown || !MPSuperAlert.active_countdown + || GameManager.m_local_player == null || GameManager.m_local_player.m_spectator + || (bool)GameManager.m_player_ship.m_dying || (bool)GameManager.m_player_ship.m_dead) + return; + + if (GameplayManager.IsMultiplayerActive && NetworkMatch.m_match_state != MatchState.PLAYING){ + MPSuperAlert.active_countdown = false; + return; + } + + float remaining_countdown = 10.0f + start_time - Time.time; + if (remaining_countdown <= 0f){ + MPSuperAlert.active_countdown = false; + return; + } + + float pulse = 0.3f + 0.5f * Mathf.Cos(Time.time * Mathf.PI * 2f); + float alpha = Mathf.Lerp(0.35f, 1f, pulse); + Color col = Color.Lerp(UIManager.m_col_em2, UIManager.m_col_em5, pulse); + + Vector2 pos = Vector2.zero; + pos.x = 0f; + pos.y = UIManager.UI_TOP + 120f; + __instance.DrawStringSmall(Loc.LS("SUPER IN"), pos, 0.6f, StringOffset.CENTER, col, alpha); + pos.y += 40f; + + __instance.DrawStringSmall(Mathf.CeilToInt(remaining_countdown).ToString(), pos, 0.9f, StringOffset.CENTER, col, alpha); + } + } + + } +} diff --git a/GameMod/Menus.cs b/GameMod/Menus.cs index 55fc67de..caa44af1 100644 --- a/GameMod/Menus.cs +++ b/GameMod/Menus.cs @@ -298,6 +298,7 @@ public static void SetLagCompensationDefaults() public static int mms_selected_loadout_idx = 0; public static int mms_collision_mesh = 0; public static bool mms_distinct_kill_sound = false; + public static bool mms_super_countdown = false; } @@ -818,23 +819,25 @@ static bool Prefix(UIElement __instance) { case 0: __instance.SelectAndDrawStringOptionItem(Loc.LS("TEXT CHAT"), position, 0, MenuManager.GetMPTextChat(), string.Empty, 1.5f, false); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("AUTO-RESPAWN TIMER"), position, 2, MenuManager.GetToggleSetting(MenuManager.opt_mp_auto_respawn), string.Empty, 1.5f, false); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("STICKY DEATH SUMMARY"), position, 3, Menus.mms_sticky_death_summary ? "YES" : "NO", "KEEP DEATH SUMMARY ON THE SCREEN AFTER LETTING GO OF THE TOGGLE"); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawSliderItem(Loc.LS("DAMAGE BLUR INTENSITY"), position, 4, ((float)Menus.mms_damageeffect_drunk_blur_mult) / 100f); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawSliderItem(Loc.LS("DAMAGE COLOR INTENSITY"), position, 5, ((float)Menus.mms_damageeffect_alpha_mult) / 100f); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("SHIP EXPLOSION EFFECTS"), position, 6, Menus.mms_reduced_ship_explosions ? Loc.LS("REDUCED") : Loc.LS("FULL"), Loc.LS("REDUCED VISUAL CLUTTER DURING DEATH ROLL")); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("INDIVIDUAL PLAYER COLORS"), position, 7, MPColoredPlayerNames.isActive ? "ON" : "OFF", Loc.LS("MAKES NAMES MORE RECOGNIZABLE AND DISTINCT BY MAKING THEM BIGGER AND COLORING THEM BY PLAYER [ANARCHY ONLY]")); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("PROFANITY FILTER"), position, 8, DisableProfanityFilter.profanity_filter ? "ON" : "OFF", Loc.LS("")); - position.y += 52f; + position.y += 49f; __instance.SelectAndDrawStringOptionItem(Loc.LS("LOADOUT SELECTION HOTKEYS"), position, 9, Menus.GetMMSLoadoutHotkeys(), Loc.LS("WEAPON SELECTION HOTKEYS WILL QUICK-SWAP BETWEEN LOADOUTS")); - position.y += 68f; + position.y += 49f; + __instance.SelectAndDrawStringOptionItem(Loc.LS("SUPER SPAWN COUNTDOWN"), position, 10, Menus.mms_super_countdown ? "ON" : "OFF", Loc.LS("FLASH A COUNTDOWN TO THE NEXT SUPER WHEN THE SUPER SIREN SOUNDS")); + position.y += 49f; __instance.SelectAndDrawItem(Loc.LS("QUICK CHAT"), position, 1, false, 1f, 0.75f); break; case 1: @@ -1203,6 +1206,10 @@ static bool Prefix(ref float ___m_menu_state_timer) } MenuManager.PlaySelectSound(1f); break; + case 10: + Menus.mms_super_countdown = !Menus.mms_super_countdown; + MenuManager.PlaySelectSound(1f); + break; } break; case 1: