Files
2026-06-22 16:18:34 +02:00

101 lines
3.2 KiB
C#

using UnityEngine;
using Ashwild.Interaction;
using Ashwild.Inventory;
namespace Ashwild.Network
{
/// <summary>
/// The single component for every world pickup — scattered ground items, hand-placed items, and
/// runtime drops alike. A WorldObject backed by the PickableRegistry: scene pickups self-register
/// with a baked id (>= 0); drops are spawned by the registry with a negative id.
/// </summary>
[DisallowMultipleComponent]
public class Pickable : WorldObject, IInteractable
{
#region Serialized Fields
[Header("Item")]
[SerializeField] private ItemData itemData;
[SerializeField] private int quantity = 1;
[Header("Interaction")]
[SerializeField] private string interactionVerb = "Pick up";
#endregion
#region Public API
/// <summary>
/// The item this pickup grants.
/// </summary>
public ItemData ItemData => itemData;
/// <summary>
/// How many of the item this pickup grants.
/// </summary>
public int Quantity => quantity;
/// <summary>
/// Crosshair label such as "Pick up Wood".
/// </summary>
public string InteractionPrompt =>
itemData != null ? $"{interactionVerb} {itemData.ItemName}" : interactionVerb;
/// <summary>
/// Configures a runtime drop instance (called by the registry on each client after spawn).
/// </summary>
public void InitializeAsDrop(int dropId, ItemData data, int qty)
{
SetId(dropId);
itemData = data;
quantity = qty;
}
/// <summary>
/// IInteractable entry point — runs on the interacting (owner) client.
/// </summary>
public void Interact() => Pickup();
/// <summary>
/// Asks the registry (server) to claim this pickup for the local player. Aborts if already
/// claimed or the local inventory is full.
/// </summary>
public void Pickup()
{
if (itemData == null)
{
Debug.LogError($"[Pickable] '{name}' has no ItemData assigned.", this);
return;
}
if (PickableRegistry.Instance == null)
{
Debug.LogError("[Pickable] No PickableRegistry in the scene.", this);
return;
}
if (PickableRegistry.Instance.IsClaimed(Id)) return;
// Client-side pre-check so we don't claim something we can't hold.
if (PlayerInventory.Instance != null && !PlayerInventory.Instance.CanFit(itemData, quantity))
return;
PickableRegistry.Instance.RequestPickupServerRpc(Id);
}
#endregion
#region WorldObject
/// <summary>
/// Only scene pickups self-register; drops are registered by the registry on spawn.
/// </summary>
protected override bool ShouldAutoRegister => Id >= 0;
/// <summary>
/// This pickup belongs to the PickableRegistry.
/// </summary>
protected override WorldObjectRegistry GetRegistry() => PickableRegistry.Instance;
#endregion
}
}