ui/GameOverScreen.razor

A Razor UI panel for the game over screen. It displays win/lose title, player profile or result and leaderboard columns, offers Restart and Return/Leave buttons, shows a confirmation overlay, handles controller and keyboard input, and triggers Manager and Networking actions to restart, return to lobby, or disconnect.

NetworkingFile Access
@namespace Sandbox
@using Sandbox;
@using Sandbox.UI;
@using System;
@inherits Panel
@attribute [StyleSheet("GameOverScreen.razor.scss")]

<root>
	@if(Manager.Instance.IsBossDead)
	{
		<div class="title_win"></div>
	}
	else
	{
		<div class="title_lose"></div>
	}

	@* <div class="title">@(Manager.Instance.IsBossDead ? "Victory!" : "Game Over")</div> *@
	<div class="content">
		@if(Manager.Instance.PlayerProfileToShow != null)
		{
			<PlayerProfilePanel />
		}
		else
		{
			<div class="col left">
				<GameOverResultPanel />
			</div>
			<div class="col right">
				<LeaderboardPanel [email protected] IsOnMainMenu=@false />
			</div>
		}
	</div>

	<div class="row controls">
		<button class="restart_button @(Input.UsingController && Networking.IsHost ? "controller" : "") @(_restartActivated ? "ctrl-activated" : _restartHeld ? "ctrl-held" : "")" style="opacity:@(Networking.IsHost ? 1f : 0.1f);" onclick=@(() => Restart())>
		</button>
		<button class="@(Networking.IsHost ? "lobby_button" : "leave_button") @(Input.UsingController ? "controller" : "") @(_lobbyActivated ? "ctrl-activated" : _lobbyHeld ? "ctrl-held" : "")" onclick=@(() => ReturnToLobby())>
		</button>
		@* <button class="lobby_button" style="opacity:@(Networking.IsHost ? 1f : 0.1f);" onclick=@(() => ReturnToLobby())></button> *@
	</div>
	@if(AreYouSureAction is not null)
	{
		<div class="are-you-sure" onclick=@(() => { Manager.Instance.PlaySfxUI("click", pitch: 0.75f, volume: 0.6f); AreYouSureAction = null; })>
			<div class="panel">
				<label class="title">@AreYouSureText</label>
				<div class="row">
					<button class="confirm_no_button" style="width: 25%;" onclick=@(() => { AreYouSureAction = null; })>
						@if(Input.UsingController) { <InputHint class="inputbutton" Button="Back" /> }
					</button>
					<button class="confirm_yes_button" style="width: 25%;" onclick=@(() => { AreYouSureAction?.Invoke(); AreYouSureAction = null; })>
						@if(Input.UsingController) { <InputHint class="inputbutton" Button="Dash" /> }
					</button>
				</div>
			</div>
		</div>
	}
</root>

@code
{
	Action AreYouSureAction = null;
	string AreYouSureText = "Are you sure?";
	bool _restartHeld;
	bool _restartActivated;
	bool _lobbyHeld;
	bool _lobbyActivated;

	public void Restart()
	{
		if (!Networking.IsHost)
			return;

		Manager.Instance.Restart();

		Manager.Instance.SetEscMenuOpen(false);
	}

	public void ReturnToLobby()
	{
		if (!Networking.IsHost)
		{
			AreYouSureText = "Quit the party?";
			AreYouSureAction = () =>
			{
				DoClientLeave();
			};

			return;
		}
		
		Manager.Instance.SetGameState(GameState.Lobby);
		Manager.Instance.SetEscMenuOpen(false);
	}

	public override void Tick()
	{
		base.Tick();
		if (!Input.UsingController)
		{
			_restartHeld = false;
			_restartActivated = false;
			_lobbyHeld = false;
			_lobbyActivated = false;
			return;
		}

		if (AreYouSureAction is not null)
		{
			if (Input.Pressed("Dash")) { Manager.Instance.PlaySfxUI("click", pitch: 1.15f, volume: 0.75f); AreYouSureAction?.Invoke(); AreYouSureAction = null; }
			else if (Input.Pressed("Back")) { Manager.Instance.PlaySfxUI("click", pitch: 0.75f, volume: 0.6f); AreYouSureAction = null; }
			return;
		}

		if (_restartActivated)
		{
			_restartActivated = false;
			Restart();
			return;
		}

		if (_lobbyActivated)
		{
			_lobbyActivated = false;
			ReturnToLobby();
			return;
		}

		bool restartDown = Input.Down("R");
		if (_restartHeld && !restartDown) { _restartHeld = false; _restartActivated = true; Manager.Instance.PlaySfxUI("click", pitch: 1.15f, volume: 0.75f); }
		else { if (!_restartHeld && restartDown) Manager.Instance.PlaySfxUI("click", pitch: 0.85f, volume: 0.6f); _restartHeld = restartDown; }

		bool lobbyDown = Input.Down("banish");
		if (_lobbyHeld && !lobbyDown) { _lobbyHeld = false; _lobbyActivated = true; Manager.Instance.PlaySfxUI("click", pitch: 1.15f, volume: 0.75f); }
		else { if (!_lobbyHeld && lobbyDown) Manager.Instance.PlaySfxUI("click", pitch: 0.85f, volume: 0.6f); _lobbyHeld = lobbyDown; }
	}

	protected override int BuildHash()
	{
		int buttonHash = System.HashCode.Combine(
			_restartHeld,
			_restartActivated,
			_lobbyHeld,
			_lobbyActivated
		);

		return System.HashCode.Combine(
			Manager.Instance.IsEscMenuOpen,
			Input.UsingController,
			AreYouSureAction is not null,
			RealTime.Now, // todo:
			buttonHash
		);
	}

	void DoClientLeave()
	{
		if(!Networking.IsHost)
		{
			Networking.Disconnect();
			Scene.LoadFromFile("scenes/game.scene");
		}

		Manager.Instance.SetEscMenuOpen(false);

		DoClientLeaveAsync();
	}

	async void DoClientLeaveAsync()
	{
		Manager.Instance.FadeRpc(fadeIn: false);

		await Task.Frame();

		Manager.Instance.SetGameState(GameState.Lobby);
	}
}