✨ Merge stack
💫 Better miner tile vfx
This commit is contained in:
@@ -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>("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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
Reference in New Issue
Block a user