(Feat) Item Dqta
This commit is contained in:
@@ -131,7 +131,13 @@ namespace Ashwild.Inventory
|
||||
/// Server-side: sends a granted item to this inventory's owning client, where it is added.
|
||||
/// Called after the server authorises a pickup.
|
||||
/// </summary>
|
||||
public void GrantItemFromServer(ItemData item, int quantity)
|
||||
public void GrantItemFromServer(ItemData item, int quantity) => GrantItemFromServer(item, quantity, -1);
|
||||
|
||||
/// <summary>
|
||||
/// Server-side grant that also restores a specific remaining-uses value, used when a partially
|
||||
/// used instance is picked back up off the ground. A negative value means "grant at full uses".
|
||||
/// </summary>
|
||||
public void GrantItemFromServer(ItemData item, int quantity, int uses)
|
||||
{
|
||||
if (item == null) return;
|
||||
|
||||
@@ -142,14 +148,15 @@ namespace Ashwild.Inventory
|
||||
return;
|
||||
}
|
||||
|
||||
TargetGrantItem(Owner, id, quantity);
|
||||
TargetGrantItem(Owner, id, quantity, uses);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs on the owning client: resolves the granted item and adds it locally.
|
||||
/// Runs on the owning client: resolves the granted item and adds it locally, restoring its
|
||||
/// remaining uses when one was carried across the drop.
|
||||
/// </summary>
|
||||
[TargetRpc]
|
||||
private void TargetGrantItem(NetworkConnection conn, ushort itemId, int quantity)
|
||||
private void TargetGrantItem(NetworkConnection conn, ushort itemId, int quantity, int uses)
|
||||
{
|
||||
ItemData item = ItemDatabase.Instance != null ? ItemDatabase.Instance.GetItem(itemId) : null;
|
||||
if (item == null)
|
||||
@@ -158,7 +165,7 @@ namespace Ashwild.Inventory
|
||||
return;
|
||||
}
|
||||
|
||||
AddItem(item, quantity);
|
||||
AddItem(item, quantity, uses);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -173,7 +180,12 @@ namespace Ashwild.Inventory
|
||||
|
||||
public InventorySlot GetSelectedSlot() => slots[selectedHotbarIndex];
|
||||
|
||||
public bool AddItem(ItemData item, int quantity = 1)
|
||||
/// <summary>
|
||||
/// Adds an item, stacking into existing slots first. Uses-tracked items never stack: each unit
|
||||
/// takes its own slot with its own uses bar. The optional uses value restores a partially used
|
||||
/// instance (negative = full); it only applies to uses-tracked items.
|
||||
/// </summary>
|
||||
public bool AddItem(ItemData item, int quantity = 1, int uses = -1)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
@@ -183,21 +195,32 @@ namespace Ashwild.Inventory
|
||||
|
||||
int remaining = quantity;
|
||||
|
||||
for (int i = 0; i < inventorySize && remaining > 0; i++)
|
||||
if (!item.HasUses)
|
||||
{
|
||||
if (!slots[i].IsEmpty && slots[i].ItemData == item && slots[i].CanAccept(item))
|
||||
for (int i = 0; i < inventorySize && remaining > 0; i++)
|
||||
{
|
||||
remaining = slots[i].AddQuantity(remaining);
|
||||
NotifySlotChanged(i);
|
||||
if (!slots[i].IsEmpty && slots[i].ItemData == item && slots[i].CanAccept(item))
|
||||
{
|
||||
remaining = slots[i].AddQuantity(remaining);
|
||||
NotifySlotChanged(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < inventorySize && remaining > 0; i++)
|
||||
{
|
||||
if (slots[i].IsEmpty)
|
||||
{
|
||||
int toPlace = (item.IsStackable && remaining > item.MaxStackSize) ? item.MaxStackSize : remaining;
|
||||
slots[i].Set(item, toPlace);
|
||||
remaining -= toPlace;
|
||||
if (item.HasUses)
|
||||
{
|
||||
slots[i].Set(item, 1, uses);
|
||||
remaining -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
int toPlace = (item.IsStackable && remaining > item.MaxStackSize) ? item.MaxStackSize : remaining;
|
||||
slots[i].Set(item, toPlace);
|
||||
remaining -= toPlace;
|
||||
}
|
||||
NotifySlotChanged(i);
|
||||
}
|
||||
}
|
||||
@@ -257,6 +280,12 @@ namespace Ashwild.Inventory
|
||||
NotifySlotChanged(indexB);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Consumes one use of a consumable: applies its restores once (per bite, for multi-use food)
|
||||
/// then either spends a use or removes one unit. A multi-use item is kept at 0 uses (red,
|
||||
/// unusable) when KeepWhenDepleted is set, otherwise it is destroyed. Ignores an already
|
||||
/// depleted item.
|
||||
/// </summary>
|
||||
public void UseItem(int index)
|
||||
{
|
||||
if (index < 0 || index >= inventorySize) return;
|
||||
@@ -264,6 +293,7 @@ namespace Ashwild.Inventory
|
||||
|
||||
ItemData item = slots[index].ItemData;
|
||||
if (item.ItemType != ItemType.Consumable) return;
|
||||
if (slots[index].IsDepleted) return;
|
||||
|
||||
if (PlayerStats.Instance != null)
|
||||
{
|
||||
@@ -273,7 +303,39 @@ namespace Ashwild.Inventory
|
||||
}
|
||||
PlayerEvents.RaiseItemConsumed(item);
|
||||
|
||||
RemoveItem(index, 1);
|
||||
if (item.HasUses)
|
||||
{
|
||||
slots[index].ConsumeUse(1);
|
||||
if (slots[index].IsDepleted && !item.KeepWhenDepleted)
|
||||
RemoveItem(index, 1);
|
||||
else
|
||||
NotifySlotChanged(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveItem(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spends durability on the currently selected hotbar item after a successful tool hit. The
|
||||
/// tool is kept at 0 uses (red, unusable until repaired) when KeepWhenDepleted is set, otherwise
|
||||
/// it is destroyed. Returns false when the selected slot holds a depleted repairable tool, so
|
||||
/// the caller can block the swing; true otherwise (including non-uses items).
|
||||
/// </summary>
|
||||
public bool ConsumeSelectedToolUse(int amount = 1)
|
||||
{
|
||||
InventorySlot slot = slots[selectedHotbarIndex];
|
||||
if (slot.IsEmpty || !slot.ItemData.HasUses) return true;
|
||||
if (slot.IsDepleted) return false;
|
||||
|
||||
ItemData item = slot.ItemData;
|
||||
slot.ConsumeUse(amount);
|
||||
if (slot.IsDepleted && !item.KeepWhenDepleted)
|
||||
RemoveItem(selectedHotbarIndex, 1);
|
||||
else
|
||||
NotifySlotChanged(selectedHotbarIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void DropItem(int index, int quantity = 1)
|
||||
@@ -282,13 +344,14 @@ namespace Ashwild.Inventory
|
||||
if (slots[index].IsEmpty) return;
|
||||
|
||||
ItemData item = slots[index].ItemData;
|
||||
int uses = item.HasUses ? slots[index].CurrentUses : -1;
|
||||
Transform origin = dropOrigin != null ? dropOrigin : transform;
|
||||
if (item.WorldPrefab != null && origin != null && PickableRegistry.Instance != null)
|
||||
{
|
||||
Vector3 dropPos = origin.position + origin.forward * dropForwardDistance;
|
||||
ushort id = ItemDatabase.Instance != null ? ItemDatabase.Instance.GetId(item) : (ushort)0;
|
||||
if (id != 0)
|
||||
PickableRegistry.Instance.RequestDropServerRpc(id, quantity, dropPos, origin.rotation);
|
||||
PickableRegistry.Instance.RequestDropServerRpc(id, quantity, uses, dropPos, origin.rotation);
|
||||
else
|
||||
Debug.LogWarning($"[PlayerInventory] '{item.ItemName}' is not in the ItemDatabase — drop not spawned. Run Rebuild Item Database.", this);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user