From 483773f0420a683527abc84133bb85f7557a4d85 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 29 Aug 2025 17:44:49 +0800 Subject: [PATCH] :sparkles: Merge stack :dizzy: Better miner tile vfx --- Scripts/System/ItemPickup.cs | 101 +++++++++++++++++++++++++---------- Scripts/Tiles/MinerTile.cs | 7 +-- 2 files changed, 76 insertions(+), 32 deletions(-) diff --git a/Scripts/System/ItemPickup.cs b/Scripts/System/ItemPickup.cs index 6fc294a..cbde9f0 100644 --- a/Scripts/System/ItemPickup.cs +++ b/Scripts/System/ItemPickup.cs @@ -1,9 +1,14 @@ +using System.Collections; +using AceFieldNewHorizon.Scripts.Entities; using Godot; namespace AceFieldNewHorizon.Scripts.System; public partial class ItemPickup : Area2D { + [Signal] + public delegate void StackMergedEventHandler(string itemId, int totalQuantity); + public const string PickupGroupName = "ItemPickupTarget"; [Export] public string ItemId { get; set; } = ""; @@ -11,6 +16,50 @@ public partial class ItemPickup : Area2D [Export] public bool Infinite { get; set; } = false; [Export] public float MagnetRange { get; set; } = 64f; + public int GetItemQuantity(string itemId) + { + if (itemId == ItemId) + return Quantity; + return 0; + } + + public void SetItemQuantity(string itemId, int newQuantity) + { + if (itemId == ItemId) + { + Quantity = newQuantity; + // Update the quantity label if it exists + if (_quantityLabel != null) + { + if (Quantity > 1) + _quantityLabel.Text = Quantity.ToString(); + else + _quantityLabel.Text = string.Empty; + } + } + } + + public bool HasItem(string itemId) + { + return itemId == ItemId; + } + + public void AddItem(string itemId, int amount) + { + if (itemId == ItemId) + { + Quantity += amount; + // Update the quantity label if it exists + if (_quantityLabel != null) + { + if (Quantity > 1) + _quantityLabel.Text = Quantity.ToString(); + else + _quantityLabel.Text = string.Empty; + } + } + } + private Sprite2D _sprite; private Label _quantityLabel; private Sprite2D _shadowSprite; @@ -19,7 +68,8 @@ public partial class ItemPickup : Area2D // Called when the node enters the scene tree public override void _Ready() { - BodyEntered += OnBodyEntered; + BodyEntered += OnEntered; + AreaEntered += OnEntered; _sprite = GetNode("Sprite2D"); UpdateTexture(); @@ -65,11 +115,9 @@ public partial class ItemPickup : Area2D if (_playerTarget != null) { var distance = Position.DistanceTo(_playerTarget.Position); + const float speed = 10f; if (distance <= MagnetRange) - { - float speed = 10f; Position = Position.Lerp(_playerTarget.Position, (float)delta * speed); - } } } @@ -108,37 +156,32 @@ public partial class ItemPickup : Area2D _sprite.Texture = texture; } - private void OnBodyEntered(Node body) + private void OnEntered(Node body) { - if (body.IsInGroup(PickupGroupName)) + if (body is ItemPickup itemStack) { - if (body.HasMethod("AddItem")) + // Only process the merge for the item with the lower instance ID to prevent double merging + if (itemStack.ItemId != ItemId || GetInstanceId() > body.GetInstanceId()) + return; + + // Get current quantity and add to it + var currentQuantity = itemStack.GetItemQuantity(ItemId); + var newQuantity = currentQuantity + Quantity; + itemStack.SetItemQuantity(ItemId, newQuantity); + + // Emit signal for stack merge + EmitSignal(nameof(StackMerged), ItemId, newQuantity); + QueueFree(); + } + else if (body.IsInGroup(PickupGroupName)) + { + if (body is Player player) { - // First check if we can merge with existing items - if (body.HasMethod("HasItem")) - { - var hasItem = (bool)body.Call("HasItem", ItemId); - if (hasItem && body.HasMethod("GetItemQuantity")) - { - // Get current quantity and add to it - var currentQuantity = (int)body.Call("GetItemQuantity", ItemId); - body.Call("SetItemQuantity", ItemId, currentQuantity + Quantity); - } - else - { - // No existing item, add as new - body.Call("AddItem", ItemId, Quantity); - } - } - else - { - // Fallback to original behavior if HasItem method doesn't exist - body.Call("AddItem", ItemId, Quantity); - } + player.AddItem(ItemId, Quantity); } if (!Infinite) - QueueFree(); // remove the pickup from the world + QueueFree(); } } } \ No newline at end of file diff --git a/Scripts/Tiles/MinerTile.cs b/Scripts/Tiles/MinerTile.cs index 4e0cc21..dc317e7 100644 --- a/Scripts/Tiles/MinerTile.cs +++ b/Scripts/Tiles/MinerTile.cs @@ -40,11 +40,12 @@ public partial class MinerTile : BaseTile itemPickup.Quantity = 1; // Initial position (slightly below the spawn point) + const int halfTileSize = GridUtils.TileSize / 2; var spawnPosition = GridUtils.GridToWorld(_gridPosition); - var targetY = spawnPosition.Y - 27f; // Target Y position - var targetX = spawnPosition.X + 27f + (GD.Randf() * 10f - 5f); + var targetY = spawnPosition.Y - halfTileSize; // Target Y position + var targetX = spawnPosition.X + halfTileSize + (GD.Randf() * 10f - 5f); itemPickup.Position = - new Vector2(spawnPosition.X + 27f, spawnPosition.Y + 16); // Start below + new Vector2(spawnPosition.X + halfTileSize, spawnPosition.Y + 16); // Start below itemPickup.Scale = Vector2.Zero; // Start invisible // Add to the scene