Added item stacking

pull/3/head
cblech 9 months ago
parent fb362e10ad
commit fb0c14c3f1

@ -41,4 +41,22 @@ label_settings = SubResource("LabelSettings_7emux")
horizontal_alignment = 1 horizontal_alignment = 1
vertical_alignment = 1 vertical_alignment = 1
[node name="AmountLabel" type="Label" parent="."]
layout_mode = 1
anchors_preset = -1
anchor_left = 1.0
anchor_top = 1.0
anchor_right = 1.0
anchor_bottom = 1.0
offset_left = -409.0
offset_top = -329.0
offset_right = -10.0
offset_bottom = -10.0
grow_horizontal = 0
grow_vertical = 0
theme_override_colors/font_color = Color(0, 0, 0, 1)
text = "999"
horizontal_alignment = 2
vertical_alignment = 2
[connection signal="gui_input" from="." to="." method="_on_gui_input"] [connection signal="gui_input" from="." to="." method="_on_gui_input"]

@ -12,6 +12,7 @@ public partial class InventoryInstance : Node
[Signal] [Signal]
public delegate void SlotAmountChangedEventHandler(); public delegate void SlotAmountChangedEventHandler();
[Signal] [Signal]
public delegate void InventoryContentsChangedEventHandler(); public delegate void InventoryContentsChangedEventHandler();
@ -32,54 +33,99 @@ public partial class InventoryInstance : Node
_slots.Add(new InventorySlot()); _slots.Add(new InventorySlot());
} }
} }
EmitSignal(SignalName.SlotAmountChanged); EmitSignal(SignalName.SlotAmountChanged);
} }
} }
public InventoryActionResult AddItem(ItemInstance newItem, int inventorySlot = -1) public InventoryActionResult AddItem(ItemInstance newItem)
{ {
if (inventorySlot < 0) var result = AddItemAndStackRecursive(newItem, 0);
EmitSignal(SignalName.InventoryContentsChanged);
return result;
}
private InventoryActionResult AddItemAndStackRecursive(ItemInstance newItem, int slotSearch)
{
if (newItem.blueprint == null || newItem.amount == 0)
return InventoryActionResult.SourceDoesNotExists;
var slotIndex = -1;
// find stackable slot
for (var i = slotSearch; i < _slots.Count; i++)
{ {
inventorySlot = _slots.FindIndex(slot => slot.IsEmpty()); if (_slots[i].itemInstance?.blueprint == newItem.blueprint)
{
slotIndex = i;
break;
}
} }
if (inventorySlot < 0 || !_slots[inventorySlot].IsEmpty()) if (slotIndex < 0)
{ {
return InventoryActionResult.DestinationFull; // find empty slot
for (var i = slotSearch; i < _slots.Count; i++)
{
if (_slots[i].IsEmpty())
{
slotIndex = i;
break;
}
}
} }
if (inventorySlot >= _slots.Count) if (slotIndex < 0)
{ {
return InventoryActionResult.DestinationDoesNotExists; return InventoryActionResult.DestinationFull;
} }
_slots[inventorySlot].itemInstance = newItem; var itemInstance = _slots[slotIndex].itemInstance ?? new ItemInstance { blueprint = newItem.blueprint, amount = 0 };
EmitSignal(SignalName.InventoryContentsChanged); var maxStack = itemInstance!.blueprint.maxStack;
return InventoryActionResult.Success; var freeOnStack = maxStack - itemInstance.amount;
var moveAmount = Math.Min(freeOnStack, newItem.amount);
itemInstance.amount += moveAmount;
newItem.amount -= moveAmount;
_slots[slotIndex].itemInstance = itemInstance;
return newItem.amount <= 0
? InventoryActionResult.Success
: AddItemAndStackRecursive(newItem, slotIndex + 1);
} }
public InventoryActionResult RemoveItem(int inventorySlot, out ItemInstance? itemInstance ) public InventoryActionResult RemoveItem(int inventorySlot, out ItemInstance? itemInstance)
{ {
if (inventorySlot < 0 || inventorySlot >= _slots.Count) if (inventorySlot < 0 || inventorySlot >= _slots.Count)
{ {
itemInstance = null; itemInstance = null;
return InventoryActionResult.SourceDoesNotExists; return InventoryActionResult.SourceDoesNotExists;
} }
if (_slots[inventorySlot].IsEmpty()) if (_slots[inventorySlot].IsEmpty())
{ {
itemInstance = null; itemInstance = null;
return InventoryActionResult.SourceIsEmpty; return InventoryActionResult.SourceIsEmpty;
} }
itemInstance = _slots[inventorySlot].itemInstance; itemInstance = _slots[inventorySlot].itemInstance;
_slots[inventorySlot].itemInstance = null; _slots[inventorySlot].itemInstance = null;
EmitSignal(SignalName.InventoryContentsChanged); EmitSignal(SignalName.InventoryContentsChanged);
return InventoryActionResult.Success; return InventoryActionResult.Success;
} }
public InventoryActionResult RemoveItem(int inventorySlot) public InventoryActionResult RemoveItem(int inventorySlot)
{ {
return RemoveItem(inventorySlot, out _); return RemoveItem(inventorySlot, out _);
} }
}
public InventoryActionResult AddItemToSlot(ItemInstance itemInstance, int destinationSlot)
{
if (destinationSlot < 0 || destinationSlot >= _slots.Count)
return InventoryActionResult.DestinationDoesNotExists;
if (!_slots[destinationSlot].IsEmpty())
return InventoryActionResult.DestinationFull;
_slots[destinationSlot].itemInstance = itemInstance;
EmitSignal(SignalName.InventoryContentsChanged);
return InventoryActionResult.Success;
}
}

@ -6,7 +6,7 @@ namespace Babushka.scripts.CSharp.Common.Inventory;
public partial class InventoryManager : Node public partial class InventoryManager : Node
{ {
public static InventoryManager Instance { get; private set; } public static InventoryManager Instance { get; private set; }
public InventoryInstance playerInventory; public InventoryInstance playerInventory;
public override void _EnterTree() public override void _EnterTree()
@ -23,11 +23,13 @@ public partial class InventoryManager : Node
public InventoryActionResult CreateItem( public InventoryActionResult CreateItem(
ItemResource itemBlueprint, ItemResource itemBlueprint,
InventoryInstance inventory, InventoryInstance inventory,
int amount = 1,
int inventorySlot = -1) int inventorySlot = -1)
{ {
var newItem = new ItemInstance { blueprint = itemBlueprint }; var newItem = new ItemInstance { blueprint = itemBlueprint, amount = amount };
var addResult = inventory.AddItem(newItem, inventorySlot); return inventorySlot < 0
return addResult; ? inventory.AddItem(newItem)
: inventory.AddItemToSlot(newItem, inventorySlot);
} }
public InventoryActionResult MoveItem( public InventoryActionResult MoveItem(
@ -39,10 +41,11 @@ public partial class InventoryManager : Node
var remResult = sourceInventory.RemoveItem(sourceSlot, out var item); var remResult = sourceInventory.RemoveItem(sourceSlot, out var item);
if (remResult != InventoryActionResult.Success) return remResult; if (remResult != InventoryActionResult.Success) return remResult;
var addResult = destinationInventory.AddItem(item!, destinationSlot); var addResult = destinationInventory.AddItemToSlot(item!, destinationSlot);
if(addResult == InventoryActionResult.Success) return InventoryActionResult.Success; if (addResult == InventoryActionResult.Success) return InventoryActionResult.Success;
sourceInventory.AddItem(item!, sourceSlot); // can not fail ... in theory // if adding in the destination failed, re-add the item into the source
sourceInventory.AddItemToSlot(item!, sourceSlot); // can not fail ... in theory
return addResult; return addResult;
} }
@ -60,8 +63,9 @@ public partial class InventoryManager : Node
{ {
return inventory.RemoveItem(inventorySlot); return inventory.RemoveItem(inventorySlot);
} }
public InventoryActionResult CollectItem(ItemInstance itemInstance) public InventoryActionResult CollectItem(ItemInstance itemInstance)
{ {
return playerInventory.AddItem(itemInstance); return playerInventory.AddItem(itemInstance);
} }
} }

@ -43,6 +43,12 @@ public partial class InventoryUi : Control
uiSlot!.nameLabel.Text = inventorySlot.itemInstance?.blueprint.name ?? ""; uiSlot!.nameLabel.Text = inventorySlot.itemInstance?.blueprint.name ?? "";
uiSlot!.nameLabel.LabelSettings = uiSlot!.nameLabel.LabelSettings.Duplicate() as LabelSettings; uiSlot!.nameLabel.LabelSettings = uiSlot!.nameLabel.LabelSettings.Duplicate() as LabelSettings;
uiSlot!.nameLabel.LabelSettings!.FontColor = inventorySlot.itemInstance?.blueprint.color ?? Colors.White; uiSlot!.nameLabel.LabelSettings!.FontColor = inventorySlot.itemInstance?.blueprint.color ?? Colors.White;
var amountText = inventorySlot.itemInstance != null &&
inventorySlot.itemInstance.amount != 1
? inventorySlot.itemInstance.amount.ToString()
: "";
uiSlot!.amountLabel.Text = amountText;
} }
} }
@ -99,6 +105,7 @@ public partial class InventoryUi : Control
{ {
InputInventoryOpenClose(); InputInventoryOpenClose();
} }
if (Input.IsActionJustPressed("ui_inventory_disadvance")) if (Input.IsActionJustPressed("ui_inventory_disadvance"))
{ {
_selectedSlot++; _selectedSlot++;
@ -106,7 +113,8 @@ public partial class InventoryUi : Control
_selectedSlot = 0; _selectedSlot = 0;
SetSlotSelectPosition(); SetSlotSelectPosition();
} }
if(Input.IsActionJustPressed("ui_inventory_advance"))
if (Input.IsActionJustPressed("ui_inventory_advance"))
{ {
_selectedSlot--; _selectedSlot--;
if (_selectedSlot < 0) if (_selectedSlot < 0)
@ -143,4 +151,4 @@ public partial class InventoryUi : Control
_slotOnMouse = null; _slotOnMouse = null;
} }
} }
} }

@ -4,4 +4,13 @@ public class ItemInstance
{ {
public ItemResource blueprint; public ItemResource blueprint;
public int amount = 1; public int amount = 1;
public ItemInstance Clone()
{
return new ItemInstance
{
blueprint = blueprint,
amount = amount
};
}
} }

@ -25,7 +25,7 @@ public partial class ItemOnGround : Node3D
{ {
GD.Print("Trying to pick up item"); GD.Print("Trying to pick up item");
var result = InventoryManager.Instance.CollectItem(itemInstance); var result = InventoryManager.Instance.CollectItem(itemInstance.Clone());
if (result == InventoryActionResult.Success) if (result == InventoryActionResult.Success)
{ {
if (!_infiniteSupply) if (!_infiniteSupply)

@ -7,12 +7,14 @@ public partial class SlotUi : Control
{ {
public Label nameLabel; public Label nameLabel;
public int index; public int index;
public Label amountLabel;
[Signal] public delegate void ClickedEventHandler(int index); [Signal] public delegate void ClickedEventHandler(int index);
public override void _EnterTree() public override void _EnterTree()
{ {
nameLabel = GetNode<Label>("NameLabel"); nameLabel = GetNode<Label>("NameLabel");
amountLabel = GetNode<Label>("AmountLabel");
} }
public void _on_gui_input(InputEvent ev) public void _on_gui_input(InputEvent ev)

Loading…
Cancel
Save