A Razor UI component for the game's HUD. It renders HUD subcomponents (money, event log, inventory, crosshair, chat input, hints, death overlay, etc.), handles chat input focus/submit, and updates build hash for change detection.
@using System
@using Sandbox
@using Sandbox.UI
@namespace BrickJam.UI
@inherits PanelComponent
<root>
@{
var player = Player.Local;
var isSpectator = player?.Spectating ?? false;
var isPlayer = player?.IsValid() ?? false;
}
<MoneyCounter />
<Eventlog />
<PlayerCounter />
<StunIndicator />
<QuickPing />
<SubtitlesList />
<Lockpicker />
<BlackScreen />
<div class="input-hints">
@if ( isSpectator )
{
<div class="hint"><inputglyph action="StopFollowing"/>Stop following</div>
<div class="hint"><inputglyph action="FollowNext"/>Next player</div>
<div class="hint"><inputglyph action="FollowPrevious"/>Previous player</div>
}
else
{
<div class="hint"><inputglyph action="inventory"/>Inventory</div>
<div class="hint"><inputglyph action="chat"/>Chat</div>
<div class="hint"><inputglyph action="ping"/>Quick Ping</div>
}
</div>
@if ( player.IsValid() )
{
<Inventory />
<Shop />
<TextInput Ghost="Say something..." class="chat-input" @ref="ChatInput" onsubmit=@OnChatSubmit />
@if ( !player.SeenTips )
{
<TutorialTips />
}
}
@if ( player.IsValid() && player.IsAlive && !LockpickerBus.IsOpen )
{
<div class="crosshair">
<div class="mark">+</div>
<RadialProgress />
<InteractionTip />
</div>
}
@if ( player.IsValid() && !player.IsAlive )
{
<div class="death">
<span class="title">YOU'RE DEAD!</span>
</div>
}
</root>
@code {
private TextInput ChatInput { get; set; }
protected override void OnUpdate()
{
if ( ChatInput is null )
return;
if ( Input.Pressed( "chat" ) )
{
ChatInput.Focus();
ChatInput.AddClass( "visible" );
}
}
private void OnChatSubmit()
{
if ( ChatInput is null )
return;
var text = ChatInput.Text;
if ( !string.IsNullOrWhiteSpace( text ) )
Player.Local?.Say( text );
ChatInput.Text = "";
ChatInput.RemoveClass( "visible" );
}
protected override int BuildHash() => HashCode.Combine(
Player.Local,
Player.Local?.IsAlive ?? false,
LockpickerBus.IsOpen );
}
<style>
Hud {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
font-family: "alagard";
justify-content: flex-start;
.crosshair {
position: absolute;
top: 0; left: 0;
width: 100%;
height: 100%;
flex-direction: column;
align-items: center;
justify-content: center;
.mark {
color: white;
font-size: 28px;
text-shadow: 2px 2px 0px black;
}
}
.input-hints {
position: absolute;
bottom: 30px;
right: 0px;
align-items: flex-end;
flex-direction: column;
z-index: 3;
.hint {
color: white;
height: 32px;
justify-content: center;
font-size: 32px;
padding-left: 50px;
padding-top: 10px;
padding-bottom: 40px;
padding-right: 10px;
background: linear-gradient(to left, rgba(black, 0.5) 0%, rgba(black, 0.2) 75%, rgba(black, 0) 100%);
margin-top: 5px;
text-shadow: 3px 3px 0px black;
InputGlyph {
width: 32px;
aspect-ratio: 1;
margin-right: 10px;
}
}
}
.chat-input {
position: absolute;
width: 450px;
min-height: 20px;
font-size: 24px;
opacity: 0;
pointer-events: all;
background-color: rgba(37, 64, 98, 1);
box-shadow: 3px 3px 0px 0px rgba(17, 44, 78, 1);
transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
transform: translate(-50% 200px);
text-shadow: 3px 3px 0px black;
left: 50%;
top: 50%;
margin-top: 40px;
&.visible {
opacity: 1;
transform: translate(-50% 0px);
}
}
.death {
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
color: white;
font-size: 32px;
z-index: 2;
backdrop-filter: grayscale(100%);
justify-content: center;
transition: opacity 1s ease-in-out;
opacity: 0;
text-shadow: 4px 4px 0px black;
&.visible {
opacity: 1;
}
.container {
flex-direction: column;
align-items: center;
}
span {
background: linear-gradient(to left, rgba(black, 0) 0%, rgba(black, 0.4) 20%, rgba(black, 0.4) 80%, rgba(black, 0) 100%);
padding: 10px;
padding-left: 40px;
padding-right: 40px;
}
.title {
color: red;
font-size: 64px;
margin-top: 150px;
margin-bottom: 20px;
}
}
}
</style>