Player/Player.Inventory.cs

Player partial class handling the player's inventory and item interactions. Exposes an Inventory container component, RPC to open the shop UI for the owner, and a host RPC to throw an item from the inventory into the world with physics and logging.

NetworkingNative Interop
using Sandbox;

namespace BrickJam;

public sealed partial class Player
{
	public ContainerComponent Inventory => Components.Get<ContainerComponent>();

	[Rpc.Owner]
	public void OpenShopUi()
	{
		UI.ShopBus.Open();
	}

	[Rpc.Host]
	public void ThrowItem( string prefabName, LootRarity rarity )
	{
		// Dead / spectating players can't drop loot (the inventory UI is still reachable while spectating).
		if ( !IsAlive )
			return;

		var prefab = LootPrefab.Get( prefabName );
		if ( prefab is null || Inventory is null )
			return;

		var entry = new ItemEntry { Prefab = prefab, Rarity = rarity };
		if ( !Inventory.Remove( entry ) )
			return;

		var loot = Loot.CreateFromEntry( entry, EyePosition, Rotation.FromYaw( WorldRotation.Yaw() ) );
		if ( loot is null )
			return;

		loot.LastPlayer = this;
		loot.GameObject.WorldScale = Vector3.One * 0.01f;

		if ( loot.Components.TryGet<Rigidbody>( out var body ) )
		{
			body.MotionEnabled = true;
			// Set velocity directly (mass-independent) so light props aren't flung across the room - just
			// toss it out in front. ApplyImpulse scales by 1/mass, which sent low-mass loot flying.
			body.Velocity = InputRotation.Forward * 130f + Vector3.Up * 80f;
		}

		MansionGame.Instance?.ShowEventlog( $"You threw <gray>1x {entry.Name}." );
	}
}