Razor UI component for the teleport overlay shown while a player is riding a teleporter. It renders a single panel and each frame sets its background image and opacity every update using values from TeleportOverlayState.
@using Sandbox;
@using Sandbox.UI;
@using System;
@using NZombies;
@inherits PanelComponent
@*
TELEPORT OVERLAY — what a rider sees while in transit.
⛔ IT PLAYS ELEMENTAL POP'S FRAMES. `ui/nz/cherry/shock_NN.png` is 21 frames of blue
electrical arcs that already carry alpha. Der Riese's own `codtele.vtf` was the
alternative and is worse on every axis: 41 DXT1 frames with NO alpha channel, so it
would need alpha derived from luminance, and it costs 4 MB (75 MB for all four
upstream styles). Same read, no new assets.
⛔ A SEPARATE PANEL FROM CherryShockHud, NOT A REUSE OF IT. Cherry Shock is a fixed
0.7s one-shot with a decaying shake; a transit is a variable hold with no shake.
Sharing the panel would mean one of them driving the other's playback. They share
the FRAMES, which is the expensive part, and nothing else.
⚠️ DRAWS INDEPENDENTLY OF THE SURVIVAL HUD'S `Visible`, like the powerup banner and
Cherry Shock — a teleporter can be ridden in creative, where that HUD is hidden.
*@
<root class="teleport-overlay">
<div @ref="Frame" class="frame"></div>
</root>
@code
{
/// <summary>
/// ⛔ CONSTANT, like CherryShockHud's. Every visible property — the frame image and
/// the opacity — is written to Style per frame, and a hash tracking the frame index
/// would rebuild the tree 24 times a second for something a style write handles.
/// </summary>
protected override int BuildHash() => 0;
Panel Frame;
// ⚠️ NO STATE HERE. The phase, length, frame index and switch all live in
// TeleportOverlayState, because gameplay code has to reach them and a generated
// razor class is not reachable from it. This file is only the drawing.
protected override void OnUpdate()
{
if ( Frame is null ) return;
var index = TeleportOverlayState.Frame;
if ( index < 0 )
{
Frame.Style.Opacity = 0f;
return;
}
Frame.Style.Opacity = TeleportOverlayState.Opacity;
Frame.Style.SetBackgroundImage( $"ui/nz/cherry/shock_{index:00}.png" );
}
}