Merge remote-tracking branch 'origin/main' into c_sharp_setup

# Conflicts:
#	scripts/CSharp/Common/CharacterControls/VesnaBehaviour.cs.uid
#	scripts/CSharp/Common/Farming/FieldService.cs.uid
This commit is contained in:
2025-04-24 21:22:56 +02:00
21 changed files with 317 additions and 37 deletions
@@ -12,6 +12,7 @@ public partial class InventoryInstance : Node
[Signal]
public delegate void SlotAmountChangedEventHandler();
[Signal]
public delegate void InventoryContentsChangedEventHandler();
@@ -32,54 +33,99 @@ public partial class InventoryInstance : Node
_slots.Add(new InventorySlot());
}
}
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)
{
// find empty slot
for (var i = slotSearch; i < _slots.Count; i++)
{
if (_slots[i].IsEmpty())
{
slotIndex = i;
break;
}
}
}
if (slotIndex < 0)
{
return InventoryActionResult.DestinationFull;
}
if (inventorySlot >= _slots.Count)
{
return InventoryActionResult.DestinationDoesNotExists;
}
_slots[inventorySlot].itemInstance = newItem;
EmitSignal(SignalName.InventoryContentsChanged);
return InventoryActionResult.Success;
var itemInstance = _slots[slotIndex].itemInstance ?? new ItemInstance { blueprint = newItem.blueprint, amount = 0 };
var maxStack = itemInstance!.blueprint.maxStack;
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)
{
itemInstance = null;
return InventoryActionResult.SourceDoesNotExists;
}
if (_slots[inventorySlot].IsEmpty())
{
itemInstance = null;
return InventoryActionResult.SourceIsEmpty;
}
itemInstance = _slots[inventorySlot].itemInstance;
_slots[inventorySlot].itemInstance = null;
EmitSignal(SignalName.InventoryContentsChanged);
return InventoryActionResult.Success;
}
public InventoryActionResult RemoveItem(int inventorySlot)
{
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 static InventoryManager Instance { get; private set; }
public InventoryInstance playerInventory;
public override void _EnterTree()
@@ -23,11 +23,13 @@ public partial class InventoryManager : Node
public InventoryActionResult CreateItem(
ItemResource itemBlueprint,
InventoryInstance inventory,
int amount = 1,
int inventorySlot = -1)
{
var newItem = new ItemInstance { blueprint = itemBlueprint };
var addResult = inventory.AddItem(newItem, inventorySlot);
return addResult;
var newItem = new ItemInstance { blueprint = itemBlueprint, amount = amount };
return inventorySlot < 0
? inventory.AddItem(newItem)
: inventory.AddItemToSlot(newItem, inventorySlot);
}
public InventoryActionResult MoveItem(
@@ -39,10 +41,11 @@ public partial class InventoryManager : Node
var remResult = sourceInventory.RemoveItem(sourceSlot, out var item);
if (remResult != InventoryActionResult.Success) return remResult;
var addResult = destinationInventory.AddItem(item!, destinationSlot);
if(addResult == InventoryActionResult.Success) return InventoryActionResult.Success;
var addResult = destinationInventory.AddItemToSlot(item!, destinationSlot);
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;
}
@@ -60,4 +63,9 @@ public partial class InventoryManager : Node
{
return inventory.RemoveItem(inventorySlot);
}
}
public InventoryActionResult CollectItem(ItemInstance itemInstance)
{
return playerInventory.AddItem(itemInstance);
}
}
+12 -3
View File
@@ -25,6 +25,7 @@ public partial class InventoryUi : Control
PopulateSlots();
SetSlotContent();
SetSlotSelectPosition();
InventoryManager.Instance.playerInventory.InventoryContentsChanged += SetSlotContent;
}
public override void _ExitTree()
@@ -42,6 +43,12 @@ public partial class InventoryUi : Control
uiSlot!.nameLabel.Text = inventorySlot.itemInstance?.blueprint.name ?? "";
uiSlot!.nameLabel.LabelSettings = uiSlot!.nameLabel.LabelSettings.Duplicate() as LabelSettings;
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;
}
}
@@ -88,7 +95,7 @@ public partial class InventoryUi : Control
var destinationSlot = index;
InventoryManager.Instance.MoveItem(_playerInventory, sourceSlot, _playerInventory, destinationSlot);
_slotOnMouse = null;
SetSlotContent();
//SetSlotContent();
}
}
@@ -98,6 +105,7 @@ public partial class InventoryUi : Control
{
InputInventoryOpenClose();
}
if (Input.IsActionJustPressed("ui_inventory_disadvance"))
{
_selectedSlot++;
@@ -105,7 +113,8 @@ public partial class InventoryUi : Control
_selectedSlot = 0;
SetSlotSelectPosition();
}
if(Input.IsActionJustPressed("ui_inventory_advance"))
if (Input.IsActionJustPressed("ui_inventory_advance"))
{
_selectedSlot--;
if (_selectedSlot < 0)
@@ -142,4 +151,4 @@ public partial class InventoryUi : Control
_slotOnMouse = null;
}
}
}
}
@@ -3,4 +3,14 @@
public class ItemInstance
{
public ItemResource blueprint;
public int amount = 1;
public ItemInstance Clone()
{
return new ItemInstance
{
blueprint = blueprint,
amount = amount
};
}
}
@@ -0,0 +1,49 @@
using Godot;
namespace Babushka.scripts.CSharp.Common.Inventory;
public partial class ItemOnGround : Node3D
{
private ItemInstance _itemInstance;
[Export]
private bool _infiniteSupply = false;
private Label3D _itemLabel => GetNode<Label3D>("ItemLabel");
private Label3D _pickupErrorLabel => GetNode<Label3D>("PickupErrorLabel");
public ItemInstance itemInstance
{
get => _itemInstance;
set
{
_itemInstance = value;
UpdateVisuals();
}
}
public void TryPickUp()
{
GD.Print("Trying to pick up item");
var result = InventoryManager.Instance.CollectItem(itemInstance.Clone());
if (result == InventoryActionResult.Success)
{
if (!_infiniteSupply)
{
QueueFree();
}
}
else
{
_pickupErrorLabel.Text = "Inventory Full";
var tween = GetTree().CreateTween();
tween.TweenInterval(2);
tween.TweenCallback(Callable.From(() => _pickupErrorLabel.Text = ""));
}
}
public void UpdateVisuals()
{
_itemLabel.Text = itemInstance.blueprint?.name ?? "Error Item";
}
}
@@ -0,0 +1 @@
uid://udhigottc8rg
@@ -0,0 +1,16 @@
#nullable enable
using Godot;
namespace Babushka.scripts.CSharp.Common.Inventory;
public partial class ItemOnGroundSpawnWith : Node
{
[Export] private ItemResource? _blueprint = null;
public override void _EnterTree()
{
if(_blueprint == null) return;
var parent = GetParent<ItemOnGround>();
parent.itemInstance = new ItemInstance { blueprint = _blueprint };
}
}
@@ -0,0 +1 @@
uid://c8suoi3i6kqai
@@ -2,17 +2,21 @@
namespace Babushka.scripts.CSharp.Common.Inventory;
[GlobalClass]
public partial class ItemResource: Resource
public partial class ItemResource : Resource
{
[Export]
public string name;
[Export]
public Color color;
[Export]
public int maxStack;
public ItemResource()
{
name = "";
color = Colors.Red;
maxStack = 1;
}
}
@@ -7,12 +7,14 @@ public partial class SlotUi : Control
{
public Label nameLabel;
public int index;
public Label amountLabel;
[Signal] public delegate void ClickedEventHandler(int index);
public override void _EnterTree()
{
nameLabel = GetNode<Label>("NameLabel");
amountLabel = GetNode<Label>("AmountLabel");
}
public void _on_gui_input(InputEvent ev)