✨ Merge stack
💫 Better miner tile vfx
This commit is contained in:
@@ -1,9 +1,14 @@
|
|||||||
|
using System.Collections;
|
||||||
|
using AceFieldNewHorizon.Scripts.Entities;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
|
||||||
namespace AceFieldNewHorizon.Scripts.System;
|
namespace AceFieldNewHorizon.Scripts.System;
|
||||||
|
|
||||||
public partial class ItemPickup : Area2D
|
public partial class ItemPickup : Area2D
|
||||||
{
|
{
|
||||||
|
[Signal]
|
||||||
|
public delegate void StackMergedEventHandler(string itemId, int totalQuantity);
|
||||||
|
|
||||||
public const string PickupGroupName = "ItemPickupTarget";
|
public const string PickupGroupName = "ItemPickupTarget";
|
||||||
|
|
||||||
[Export] public string ItemId { get; set; } = "";
|
[Export] public string ItemId { get; set; } = "";
|
||||||
@@ -11,6 +16,50 @@ public partial class ItemPickup : Area2D
|
|||||||
[Export] public bool Infinite { get; set; } = false;
|
[Export] public bool Infinite { get; set; } = false;
|
||||||
[Export] public float MagnetRange { get; set; } = 64f;
|
[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 Sprite2D _sprite;
|
||||||
private Label _quantityLabel;
|
private Label _quantityLabel;
|
||||||
private Sprite2D _shadowSprite;
|
private Sprite2D _shadowSprite;
|
||||||
@@ -19,7 +68,8 @@ public partial class ItemPickup : Area2D
|
|||||||
// Called when the node enters the scene tree
|
// Called when the node enters the scene tree
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
BodyEntered += OnBodyEntered;
|
BodyEntered += OnEntered;
|
||||||
|
AreaEntered += OnEntered;
|
||||||
|
|
||||||
_sprite = GetNode<Sprite2D>("Sprite2D");
|
_sprite = GetNode<Sprite2D>("Sprite2D");
|
||||||
UpdateTexture();
|
UpdateTexture();
|
||||||
@@ -65,11 +115,9 @@ public partial class ItemPickup : Area2D
|
|||||||
if (_playerTarget != null)
|
if (_playerTarget != null)
|
||||||
{
|
{
|
||||||
var distance = Position.DistanceTo(_playerTarget.Position);
|
var distance = Position.DistanceTo(_playerTarget.Position);
|
||||||
|
const float speed = 10f;
|
||||||
if (distance <= MagnetRange)
|
if (distance <= MagnetRange)
|
||||||
{
|
|
||||||
float speed = 10f;
|
|
||||||
Position = Position.Lerp(_playerTarget.Position, (float)delta * speed);
|
Position = Position.Lerp(_playerTarget.Position, (float)delta * speed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,37 +156,32 @@ public partial class ItemPickup : Area2D
|
|||||||
_sprite.Texture = texture;
|
_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
|
player.AddItem(ItemId, Quantity);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Infinite)
|
if (!Infinite)
|
||||||
QueueFree(); // remove the pickup from the world
|
QueueFree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -40,11 +40,12 @@ public partial class MinerTile : BaseTile
|
|||||||
itemPickup.Quantity = 1;
|
itemPickup.Quantity = 1;
|
||||||
|
|
||||||
// Initial position (slightly below the spawn point)
|
// Initial position (slightly below the spawn point)
|
||||||
|
const int halfTileSize = GridUtils.TileSize / 2;
|
||||||
var spawnPosition = GridUtils.GridToWorld(_gridPosition);
|
var spawnPosition = GridUtils.GridToWorld(_gridPosition);
|
||||||
var targetY = spawnPosition.Y - 27f; // Target Y position
|
var targetY = spawnPosition.Y - halfTileSize; // Target Y position
|
||||||
var targetX = spawnPosition.X + 27f + (GD.Randf() * 10f - 5f);
|
var targetX = spawnPosition.X + halfTileSize + (GD.Randf() * 10f - 5f);
|
||||||
itemPickup.Position =
|
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
|
itemPickup.Scale = Vector2.Zero; // Start invisible
|
||||||
|
|
||||||
// Add to the scene
|
// Add to the scene
|
||||||
|
Reference in New Issue
Block a user