using UnityEngine; using Ashwild.Interaction; using Ashwild.Inventory; namespace Ashwild.Network { /// /// 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. /// [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 /// /// The item this pickup grants. /// public ItemData ItemData => itemData; /// /// How many of the item this pickup grants. /// public int Quantity => quantity; /// /// Crosshair label such as "Pick up Wood". /// public string InteractionPrompt => itemData != null ? $"{interactionVerb} {itemData.ItemName}" : interactionVerb; /// /// Configures a runtime drop instance (called by the registry on each client after spawn). /// public void InitializeAsDrop(int dropId, ItemData data, int qty) { SetId(dropId); itemData = data; quantity = qty; } /// /// IInteractable entry point — runs on the interacting (owner) client. /// public void Interact() => Pickup(); /// /// Asks the registry (server) to claim this pickup for the local player. Aborts if already /// claimed or the local inventory is full. /// 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 /// /// Only scene pickups self-register; drops are registered by the registry on spawn. /// protected override bool ShouldAutoRegister => Id >= 0; /// /// This pickup belongs to the PickableRegistry. /// protected override WorldObjectRegistry GetRegistry() => PickableRegistry.Instance; #endregion } }