UI/JumperHeightBar.razor
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
@if (Network.OwnerConnection is Connection owner && owner == Connection.Local)
{
    <root class=@(IsOpen ? "open" : "closed")>
        <div class="bar">

            <label class="heightbar"></label>
            <label class="flag"></label>

            <div class="heightbarpos" style="height:@(CalculateProgress(Height) * 100)%;">
                <label class="heighttext" text="< @(Height)" />
            </div>

            <div class="maxheightbarpos" style="height:@(CalculateProgress(MaxHeight) * 100)%;">
                <label class="maxheighttext" text="@(MaxHeight)>" />
            </div>

            @foreach (var player in Scene.GetAllComponents<JumperPlayerStuff>())
            {
                if (owner == player.Network.OwnerConnection) continue;
                <div class="maxheightotherbarpos" style="border-top: 4px solid @player.rndColor; height:@(CalculateProgress(player.Height) * 100)%;">
                    <img class="maxheightothertext" style=" box-shadow: 3px 3px @player.rndColor; background-image: url( avatar:@player.Network.OwnerConnection.SteamId )">
                </div>
            }
        </div>
    </root>
}

@code
{
    float TotalHeight { get; set; }
    float Height { get; set; }
    float MaxHeight { get; set; }
    bool IsOpen { get; set; }

    // Find first player stats class that isn't owned by a proxy (is ours)
    JumperPlayerStuff PlayerStats => GameObject.Components.Get<JumperPlayerStuff>(FindMode.InParent);
    JumperDistanceRuler Ruler { get; set; }

    public Color32 rndColor = Color.Random;
    public string hexColor;

    protected override void OnUpdate()
    {
        base.OnUpdate();

        if (IsProxy) return;

        Height = PlayerStats.Height;
        MaxHeight = PlayerStats.MaxHeight;

        TotalHeight = Scene.GetAllComponents<JumperDistanceRuler>().FirstOrDefault().Distance;
    }

    private float CalculateProgress(float height)
    {
        return height.LerpInverse(0, Scene.GetAllComponents<JumperDistanceRuler>().FirstOrDefault().Distance);
    }
    protected override int BuildHash()
    {
        IsOpen ^= Input.Pressed("slot1");

        return HashCode.Combine(Time.Delta);
    }
}