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
}