UI/OMRScopeReticlePanel.cs
using Sandbox;
using Sandbox.UI;
using System;
namespace Sandbox.UI;
/// <summary>
/// Draws the scope reticle directly in the panel paint pass. This avoids relying
/// on four tiny Razor/CSS rectangles inside a scaled WorldPanel, which proved
/// vulnerable to hotload/layout quirks.
/// </summary>
public sealed class OMRScopeReticlePanel : Panel
{
public OMRScopeReticleStyle ReticleStyle { get; set; } = OMRScopeReticleStyle.FineCross;
public Color ReticleColor { get; set; } = Color.Black;
public float Thickness { get; set; } = 1.5f;
public float Gap { get; set; } = 8f;
public float LineLength { get; set; } = 72f;
public float DotSize { get; set; } = 3f;
public float ReticleOpacity { get; set; } = 1f;
public float OutlineWidth { get; set; } = 0f;
public float OutlineOpacity { get; set; } = 0f;
public override void OnDraw( Painter painter )
{
float opacity = MathX.Clamp( ReticleOpacity, 0f, 1f );
if ( opacity <= 0.001f )
return;
float thickness = MathF.Max( Thickness, 0.5f );
float gap = MathF.Max( Gap, 0f );
float length = MathF.Max( LineLength, 1f );
if ( ReticleStyle == OMRScopeReticleStyle.Duplex )
{
thickness *= 1.75f;
gap *= 1.5f;
}
Vector2 center = new( painter.Bounds.Width * 0.5f, painter.Bounds.Height * 0.5f );
Color main = ReticleColor.WithAlpha( ReticleColor.a * opacity );
float outlineWidth = MathF.Max( OutlineWidth, 0f );
float outlineOpacity = MathX.Clamp( OutlineOpacity, 0f, 1f ) * opacity;
if ( outlineWidth > 0f && outlineOpacity > 0.001f )
{
Color outline = Color.White.WithAlpha( outlineOpacity );
DrawCross( painter, center, thickness + outlineWidth * 2f, gap, length, outline );
}
DrawCross( painter, center, thickness, gap, length, main );
if ( ReticleStyle == OMRScopeReticleStyle.DotCross && DotSize > 0f )
{
if ( outlineWidth > 0f && outlineOpacity > 0.001f )
{
painter.Fill = Color.White.WithAlpha( outlineOpacity );
painter.Circle( center, (DotSize + outlineWidth * 2f) * 0.5f );
}
painter.Fill = main;
painter.Circle( center, DotSize * 0.5f );
}
}
private static void DrawCross( Painter painter, Vector2 center, float thickness, float gap, float length, Color color )
{
float halfThickness = thickness * 0.5f;
painter.Fill = color;
painter.Stroke = Stroke.None;
painter.Rect( new Rect( center.x - gap - length, center.y - halfThickness, length, thickness ) );
painter.Rect( new Rect( center.x + gap, center.y - halfThickness, length, thickness ) );
painter.Rect( new Rect( center.x - halfThickness, center.y - gap - length, thickness, length ) );
painter.Rect( new Rect( center.x - halfThickness, center.y + gap, thickness, length ) );
}
}