A Blazor-style Razor UI panel that renders a static perk icon. It computes rarity colors, progress bar width, banish scale animation, and shows icon, level/percent/maxed/banish overlays. It also updates a Manager singleton with hover state on mouse events.
@namespace Sandbox
@using Sandbox;
@using Sandbox.UI;
@using System;
@inherits Panel
@attribute [StyleSheet("PerkIconStatic.razor.scss")]
@{
// var player = Manager.Instance.LocalPlayer;
}
<root>
@{
const float banishAnimDuration = 0.5f;
var banishScale = _timeSinceBanished < banishAnimDuration
? Utils.Map( (float)_timeSinceBanished, 0f, banishAnimDuration, 1.75f, 1.0f, EasingType.QuadOut )
: 1.0f;
}
<div class="scale_anim_wrap" style="transform: scale(@(banishScale));">
@{
var attrib = PerkType.GetAttribute<PerkAttribute>();
var rarity = attrib.Rarity;
var curse = attrib.Curse;
var highlightColor = PerkManager.GetCardRarityColor(rarity, curse, alpha: 0.7f);
var rarityBgTint = PerkManager.GetCardRarityColor(rarity, curse);
var maxLevel = PerkManager.GetMaxLevelForRarity(rarity);
var progress = Math.Clamp(ProgressLevel / (float)maxLevel, 0f, 1f);
var width = progress * 100f;
var iconSourceType = IconOverrideType ?? PerkType;
string iconString = IconPathOverride
?? (HideType ? "textures/icons/vector/locked.png" : (IsUnknown ? "textures/icons/vector/unknown.png" : Perk.GetImagePath(iconSourceType.TargetType)));
if( iconString == null )
{
Log.Warning($"iconString null for {PerkType} - restart editor to re-register perk info");
iconString = "textures/icons/vector/unknown.png";
}
if(HideType)
rarityBgTint = Color.Lerp(rarityBgTint, Color.Black, 0.5f);
}
<panel class="rarity" style="background-color: @highlightColor.Rgba; background-image-tint:@rarityBgTint.Rgba;"></panel>
@if (!Banished && !HideLevel && !curse && maxLevel > 1)
{
if (Level > (IsChoice ? 1 : 0))
{
<panel class="progress" style="width:100%; background-color:@(new Color(0f, 0f, 0f, IsChoice ? 0.3f : 0.6f).Rgba); z-index: 1;"></panel>
<panel class="progress" style="width:@(width)%; background-color:@highlightColor.Rgba; z-index: 2;"></panel>
}
}
<panel class="icon" style="background-image: url(@iconString); background-color:@rarityBgTint.Rgba;" />
@if (Level > maxLevel)
{
<div class="maxed">X</div>
}
@if (Banished)
{
<div class="banish">X</div>
}
@if(Percent > 0f && !HideType)
{
<div class="percent">@($"{MathX.FloorToInt(Percent * 100f)}%")</div>
}
</div>
</root>
@code
{
public TypeDescription PerkType { get; set; }
public int Level { get; set; }
public int ProgressLevel { get; set; }
public bool NoTips { get; set; } = false;
public bool Banished;
public bool IsChoice { get; set; }
public bool IsUnknown { get; set; }
public bool HideLevel { get; set; }
public float Percent { get; set; }
public bool HideType {get; set;}
public TypeDescription IconOverrideType { get; set; }
public string IconPathOverride { get; set; }
bool _lastBanished = false;
RealTimeSince _timeSinceBanished = 999f;
protected override void OnMouseOver(MousePanelEvent e)
{
if ( e.Target != this || NoTips || PerkType == null || IsUnknown || HideType )
return;
Manager.Instance.HoveredPerkType = PerkType;
Manager.Instance.HoveredPerkPanel = this;
Manager.Instance.HoveredPerkLevel = Level;
Manager.Instance.HoveredPerkViewedPlayer = null;
Manager.Instance.HoveredPerkChoiceSlot = -1;
Manager.Instance.IsHoveredPerkBanished = Banished;
Manager.Instance.IsHoveredPerkAChoice = IsChoice;
Manager.Instance.IsHoveredPerkHidden = HideType;
Manager.Instance.HoveredPlayer = null;
Manager.Instance.HoveredPlayerIcon = null;
}
protected override void OnMouseOut(MousePanelEvent e)
{
if ( Manager.Instance.HoveredPerkPanel != this ) return;
Manager.Instance.HoveredPerkType = null;
Manager.Instance.HoveredPerkPanel = null;
Manager.Instance.HoveredPerkViewedPlayer = null;
Manager.Instance.HoveredPerkChoiceSlot = -1;
Manager.Instance.IsHoveredPerkBanished = false;
Manager.Instance.IsHoveredPerkHidden = false;
}
public override void OnDeleted()
{
base.OnDeleted();
if ( Manager.Instance.HoveredPerkPanel != this ) return;
Manager.Instance.HoveredPerkType = null;
Manager.Instance.HoveredPerkPanel = null;
Manager.Instance.HoveredPerkViewedPlayer = null;
Manager.Instance.HoveredPerkChoiceSlot = -1;
Manager.Instance.IsHoveredPerkBanished = false;
Manager.Instance.IsHoveredPerkHidden = false;
}
protected override int BuildHash()
{
if (Banished && !_lastBanished)
_timeSinceBanished = 0f;
_lastBanished = Banished;
float animHash = _timeSinceBanished < 0.5f ? _timeSinceBanished.Relative : 0f;
// var player = Manager.Instance?.LocalPlayer;
return HashCode.Combine(
Level,
ProgressLevel,
Manager.Instance?.IsGameOver,
animHash
// locked
);
}
}