using UnityEngine; /// /// ScriptableObject defining item properties. /// Implements IUsableItem and IEquippableItem for extensibility. /// [CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")] public class ItemData : ScriptableObject, IUsableItem, IEquippableItem { [Header("Basic Info")] public int itemID; public string itemName; public Sprite icon; [TextArea] public string description; [Header("Stack & Weight")] public float weight = 1f; public int maxStack = 99; [Header("Visual Source")] [Tooltip("Original prefab for dropped item visuals")] public GameObject originalBlockPrefab; [Header("Item Behavior")] [Tooltip("Defines what happens when the item is used")] public ItemBehavior behavior; [Header("Equipment Settings")] [Tooltip("Whether this item can be equipped (shows in hand)")] public bool isEquippable; [Tooltip("Prefab spawned in player's hand when equipped")] public GameObject equipmentPrefab; public Vector3 equipPositionOffset; public Vector3 equipRotationOffset; [Tooltip("Name of the transform to attach equipment to")] public string attachmentPointName = "ToolAnchor"; #region IUsableItem Implementation public bool IsConsumable => behavior != null && behavior.IsConsumable; public bool CanUse(GameObject user, GameObject target) { return behavior != null && behavior.CanUse(user, target); } public void Use(GameObject user, GameObject target) { if (behavior != null) { behavior.Use(user, target); } } public ActionDescriptor GetUseAction() { return behavior?.GetActionDescriptor(); } #endregion #region IEquippableItem Implementation public GameObject GetEquipmentPrefab() => equipmentPrefab; public Vector3 GetPositionOffset() => equipPositionOffset; public Vector3 GetRotationOffset() => equipRotationOffset; public string GetAttachmentPointName() => attachmentPointName; public Transform FindAttachmentPoint(GameObject user) { if (string.IsNullOrEmpty(attachmentPointName)) return user.transform; var transforms = user.GetComponentsInChildren(); foreach (var t in transforms) { if (t.name == attachmentPointName) return t; } return user.transform; } #endregion #region Utility Properties /// /// Check if this item has any usable behavior. /// public bool HasBehavior => behavior != null; /// /// Check if this item can be equipped. /// public bool CanBeEquipped => isEquippable && equipmentPrefab != null; #endregion #region Utility Methods /// /// Get display name for UI. /// public string GetDisplayName() => string.IsNullOrEmpty(itemName) ? name : itemName; /// /// Get description for UI. /// public string GetDescription() => description; /// /// Calculate total weight for a stack. /// public float GetStackWeight(int count) => weight * count; #endregion }