An inventory pickup component named Coffin. It holds items and ammo counts, auto-destroys after 30 seconds, transfers contained items and ammo to a PlayerInventory when a player enters its trigger, plays a pickup sound via a broadcast RPC, and then destroys itself.
/// <summary>
/// It's not the coughing you're coughin', it's the coffin they carry you off in
/// </summary>
public sealed class Coffin : BaseInventoryComponent, Component.ITriggerListener
{
/// <summary>
/// Sound to play when this coffin is picked up
/// </summary>
[Property] public SoundEvent PickupSound { get; set; }
/// <summary>
/// How much ammo are we holding on this coffin?
/// </summary>
[Sync] public Dictionary<BaseAmmoResource, int> AmmoCounts { get; set; }
TimeUntil timeUntilDestroy;
protected override void OnEnabled()
{
base.OnEnabled();
timeUntilDestroy = 30;
}
protected override void OnUpdate()
{
base.OnUpdate();
if ( IsProxy ) return;
if ( timeUntilDestroy > 0 ) return;
DestroyGameObject();
}
/// <summary>
/// Called when a gameobject enters the trigger.
/// </summary>
void ITriggerListener.OnTriggerEnter( GameObject other )
{
if ( IsProxy ) return;
if ( GameObject.IsDestroyed ) return;
var player = other.GetComponent<Player>();
if ( !player.IsValid() )
return;
PlayPickupEffects();
if ( player.Components.TryGet<PlayerInventory>( out var inventory ) )
{
foreach ( var item in Items.ToArray() )
{
Transfer( item, inventory );
}
// A coffin placed in a map by hand never gets its counts filled in.
foreach ( var pair in AmmoCounts ?? [] )
{
if ( pair.Key.IsValid() )
inventory.GiveAmmo( pair.Key, pair.Value, true );
}
}
DestroyGameObject();
}
/// <summary>
/// Broadcasts a pickup effect for everyone.
/// </summary>
[Rpc.Broadcast]
public void PlayPickupEffects()
{
if ( Application.IsDedicatedServer ) return;
Sound.Play( PickupSound, WorldPosition );
}
}