GameHud.razor
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@namespace BottomsUp
<root style="width:100%;height:100%;position:absolute;top:0;left:0;">
@if ( ShouldShowGameplayHud )
{
<div class="hud" style="position:absolute;top:24px;left:24px;display:flex;flex-direction:column;gap:12px;pointer-events:none;">
<div class="bar-container" style="display:flex;flex-direction:column;">
<div class="bar-label" style="color:white;font-size:18px;font-weight:bold;text-shadow:1px 1px 2px black;margin-bottom:4px;">Fill: @((int)FillValue) / @((int)FillGoal)</div>
<div class="bar-track" style="width:260px;height:22px;background-color:rgba(0,0,0,0.5);border:2px solid white;border-radius:4px;overflow:hidden;">
<div class="bar-fill fill-bar" style="height:100%;background-color:#4ba3f0;width:@(FillPercent)%;"></div>
</div>
</div>
<div class="bar-container" style="display:flex;flex-direction:column;">
<div class="bar-label" style="color:white;font-size:18px;font-weight:bold;text-shadow:1px 1px 2px black;margin-bottom:4px;">Pour: @((int)PourValue) / @((int)PourBudget)</div>
<div class="bar-track" style="width:260px;height:22px;background-color:rgba(0,0,0,0.5);border:2px solid white;border-radius:4px;overflow:hidden;">
<div class="bar-fill pour-bar" style="height:100%;background-color:#e8b23c;width:@(PourPercent)%;"></div>
</div>
</div>
<div class="score-label" style="color:#f4d35e;font-size:18px;font-weight:bold;text-shadow:1px 1px 2px black;">Score: @((int)Score)</div>
<div class="score-label" style="color:#f4d35e;font-size:18px;font-weight:bold;text-shadow:1px 1px 2px black;">High Score: @((int)HighScore)</div>
</div>
@if ( ShowBanner )
{
<div class="round-banner" style="position:absolute;top:40%;left:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;pointer-events:none;">
<span style="color:white;font-size:48px;font-weight:bold;text-shadow:2px 2px 4px black;">Round @(RoundNumber)</span>
<span class="sub" style="color:white;font-size:22px;text-shadow:2px 2px 4px black;margin-top:8px;">Click to Start</span>
</div>
}
}
</root>
@code
{
[Property] public RoundManager RoundManager { get; set; }
[Property] public PourController Pour { get; set; }
[Property] public MenuManager Menu { get; set; }
// Hide the whole gameplay HUD until the menu/splash flow has
// finished (or if no MenuManager is wired up at all, so this
// doesn't break setups that haven't added the menu yet).
private bool ShouldShowGameplayHud => Menu is null || Menu.State == MenuManager.MenuState.Playing;
private float FillValue => Pour?.FillProgress ?? 0;
private float FillGoal => Pour?.FillGoal ?? 100;
private float FillPercent => FillGoal > 0 ? (FillValue / FillGoal) * 100f : 0;
private float PourValue => Pour?.TotalPoured ?? 0;
private float PourBudget => Pour?.PourBudget ?? 200;
private float PourPercent => PourBudget > 0 ? (PourValue / PourBudget) * 100f : 0;
private int RoundNumber => RoundManager?.CurrentRound ?? 1;
private bool ShowBanner => RoundManager?.CurrentState == RoundManager.State.WaitingToStart;
private float Score => RoundManager?.TotalScore ?? 0;
private float HighScore => RoundManager?.HighScore ?? 0;
protected override int BuildHash()
{
// Rebuild whenever any displayed value changes.
return System.HashCode.Combine( FillValue, PourValue, RoundNumber, ShowBanner, Score, HighScore, Menu?.State );
}
}