Map/SellArea.cs

Trigger component placed on map geometry that sells Loot objects when they enter the trigger, credits the last holder, updates stats/achievements, plays a sound, shows UI feedback, and destroys the loot.

NetworkingFile Access
using System.Linq;
using Sandbox;

namespace BrickJam;

/// <summary>
/// Trigger volume that sells any <see cref="Loot"/> dropped into it, crediting the loot's last
/// holder. Scene-System port of legacy <c>SellArea : BaseTrigger</c>.
///
/// DEFERRED: the <c>MoneyWaft</c> particles and the event-log "you sold X" message (UI system).
/// </summary>
[Title( "Sell Area" )]
[Category( "Map" )]
public sealed partial class SellArea : LegacyMapComponent, Component.ITriggerListener
{
	protected override void OnStart()
	{
		// The map brush gives us collider(s); make sure they act as triggers. If the brush didn't
		// produce one, fall back to a box.
		var colliders = Components.GetAll<Collider>().ToList();
		if ( colliders.Count == 0 )
		{
			var box = Components.Create<BoxCollider>();
			box.Scale = new Vector3( 256f, 256f, 256f );
			box.IsTrigger = true;
		}
		else
		{
			foreach ( var collider in colliders )
				collider.IsTrigger = true;
		}
	}

	public void OnTriggerEnter( Collider other )
	{
		if ( !Networking.IsHost )
			return;

		var loot = other.GameObject?.Components.Get<Loot>();
		if ( loot is null || !loot.LastPlayer.IsValid() )
			return;

		loot.LastPlayer.AddMoney( loot.MonetaryValue );

		// Services stats/achievement for the seller (routed to their own client).
		// money_earned also backs the stat-mode "the_one_percent" achievement (unlock at 10,000).
		loot.LastPlayer.TrackStat( GameStats.MoneyEarned, loot.MonetaryValue );
		loot.LastPlayer.TrackStat( GameStats.LootSold, 1 );
		loot.LastPlayer.TrackAchievement( GameStats.AchFirstSale );

		SoundExtensions.BroadcastPlay( "sounds/store/store.sound", loot.WorldPosition, 0.25f );

		MansionGame.Instance?.ShowEventlog(
			$"You sold the <gray>{loot.FullName}<white> for <rgb(50,205,50)>$</><white>{loot.MonetaryValue}." );
		MansionGame.Instance?.ShowMoneyWaft( loot.WorldPosition, loot.MonetaryValue );

		loot.GameObject.Destroy();
	}
}