UI/PowerupBannerState.cs

Static UI state holder for the powerup banner. Stores the banner text, duration and elapsed time, provides Show to raise the banner, maps PowerupKind enum values to display names, and exposes a console command to trigger the banner.

using Sandbox;

namespace NZombies;

/// <summary>
/// The name of the powerup you just took, for the banner to render.
///
/// ⚠️ A STATIC, for the same reason `LobbyState` and `ToolPanelState` are: razor
/// components are GENERATED types and a plain .cs file cannot reference one, so
/// `Powerup.Collect` has no way to talk to the panel directly. This is the seam.
/// </summary>
public static class PowerupBannerState
{
	/// <summary>What to show. Empty when nothing is showing.</summary>
	public static string Text { get; private set; } = "";

	/// <summary>How long the banner stays up.</summary>
	public static float Duration { get; set; } = 2.5f;

	static RealTimeSince _since;

	/// <summary>Seconds since it was raised.</summary>
	public static float Elapsed => _since;

	/// <summary>Is a banner currently up?</summary>
	public static bool Showing => !string.IsNullOrEmpty( Text ) && _since < Duration;

	/// <summary>
	/// Raise the banner.
	///
	/// ⚠️ RESTARTS the timer if one is already up, rather than queueing. Two powerups
	/// collected together is a real case — a Nuke clears the room onto a Max Ammo —
	/// and a queue would show the second one after the first had finished, by which
	/// point the player has stopped looking.
	/// </summary>
	public static void Show( string text )
	{
		Text = text ?? "";
		_since = 0f;
	}

	/// <summary>Human-readable name for a kind. "MaxAmmo" is not what to put on screen.</summary>
	public static string NameFor( PowerupKind kind ) => kind switch
	{
		PowerupKind.MaxAmmo => "MAX AMMO",
		PowerupKind.InstaKill => "INSTA-KILL",
		PowerupKind.DoublePoints => "DOUBLE POINTS",
		PowerupKind.Nuke => "NUKE",
		PowerupKind.Carpenter => "CARPENTER",
		PowerupKind.FireSale => "FIRE SALE",
		PowerupKind.DeathMachine => "DEATH MACHINE",
		_ => kind.ToString().ToUpper(),
	};

	/// <summary>Show the banner from the console: `nz_banner &lt;text&gt;`.</summary>
	[ConCmd( "nz_banner" )]
	public static void Cmd( string text = "MAX AMMO" )
	{
		Show( text );
		Log.Info( $"[nz] banner: '{Text}' for {Duration:0.#}s" );
	}
}