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.
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();
}
}