Player/Player.Ping.cs

Player input handler for the ping action. It traces a ray from the player eye, classifies the hit GameObject into a ping type (Enemy, Exit, Loot, Other), and calls MansionGame.Instance.ShowPing on the hit position.

Networking
using Sandbox;
using BrickJam.UI;

namespace BrickJam;

public sealed partial class Player
{
	[Property, InputAction] public string PingButton { get; set; } = "ping";

	/// <summary>Owner-side: trace forward and broadcast a contextual ping. Replaces the legacy
	/// QuickPing creator + <c>[ConCmd.Server] RequestPing</c>.</summary>
	private void UpdatePing()
	{
		if ( !Input.Pressed( PingButton ) )
			return;

		var trace = Scene.Trace
			.Ray( EyePosition, EyePosition + InputRotation.Forward * 1000f )
			.WithAnyTags( "door", "npc", "solid", "loot" )
			.WithoutTags( "doob" )
			.IgnoreGameObjectHierarchy( GameObject )
			.Radius( 10f )
			.Run();

		var go = trace.GameObject;
		var position = trace.Hit ? trace.HitPosition : trace.EndPosition;
		var type = PingBus.PingType.Other;

		if ( go is not null )
		{
			if ( go.Components.Get<NPC>() is not null )
				type = PingBus.PingType.Enemy;
			else if ( go.Components.Get<Trapdoor>() is not null || go.Components.Get<FinalDoor>() is not null )
				type = PingBus.PingType.Exit;
			else if ( go.Components.Get<Loot>() is not null || go.Components.Get<LootContainer>() is not null )
				type = PingBus.PingType.Loot;
		}

		MansionGame.Instance?.ShowPing( position, (int)type );
	}
}