Demos/TarkovInventory/CrateTheme.cs
using Goo;
using Sandbox;
using Sandbox.UI;
namespace Sandbox.TarkovInventory;
// Industrial crate theme for the TarkovStash demo: matte-black metal panels, a worn
// safety-orange ink-stamp header, nine-slice skins with flat-color fallback. Demo-local
// because the safety-orange industrial look is specific here, not a Goo brand token.
internal static class CrateTheme
{
public static readonly Color Steel = Color.FromBytes( 0x0D, 0x0F, 0x14 ); // panel face / fallback
public static readonly Color Stamp = Color.FromBytes( 0xD4, 0x64, 0x1E ); // safety orange
public static readonly Color StampInk = Color.FromBytes( 0x0A, 0x0A, 0x0C ); // text on the orange stamp
public static readonly Color Edge = new( 1f, 1f, 1f, 0.16f ); // fallback border
public static readonly Color Socket = Color.FromBytes( 0x07, 0x07, 0x09 ); // empty slot recess
public const string Font = "Space Mono";
public static readonly Length Tracking = 3f;
public static readonly Length HeaderHeight = 40f;
// Assets/-relative skin paths (loaded via FileSystem.Mounted, same as NineSliceUI).
public const string PanelSkin = "ui/crate-panel.png";
public const string HeaderSkin = "ui/crate-header.png";
public const string SlotSkin = "ui/crate-slot.png";
// Source-pixel slice insets, measured from the delivered art (1024 panel, 1774x887 header,
// 1254 slot). Must contain each asset's corner bracket. Nudge in-editor at UAT.
public static readonly Length PanelSlice = 190f;
public static readonly Length SlotSlice = 300f;
public static readonly Length HeaderSliceX = 440f;
public static readonly Length HeaderSliceY = 120f;
// On-screen border thickness (smaller than the inset scales the corner art down).
public static readonly Length PanelBorder = 24f;
public static readonly Length SlotBorder = 18f;
// Header is a thin bar, so its borders are per-side: small left/right worn end-caps and a
// sliver top/bottom, leaving the orange center to fill the bar (a uniform border would eat
// the whole height and show only the dark frame).
public static readonly Length HeaderCap = 12f;
public static readonly Length HeaderEdge = 3f;
static Texture? _panel, _header, _slot;
public static Texture? Panel => Load( ref _panel, PanelSkin );
public static Texture? Header => Load( ref _header, HeaderSkin );
public static Texture? Slot => Load( ref _slot, SlotSkin );
// Lazy + self-healing: reload if the cached handle is null or went invalid across a hotload.
// Returns null when the file is missing so callers fall back to flat colors.
static Texture? Load( ref Texture? cache, string path )
{
if ( cache is not null && cache != Texture.Invalid ) return cache;
var t = Texture.LoadFromFileSystem( path, FileSystem.Mounted );
cache = (t is null || t == Texture.Invalid) ? null : t;
return cache;
}
}