187 lines
5.5 KiB
C#
187 lines
5.5 KiB
C#
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; } = "";
|
|
[Export] public int Quantity { get; set; } = 1;
|
|
[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;
|
|
private Node2D _playerTarget;
|
|
|
|
// Called when the node enters the scene tree
|
|
public override void _Ready()
|
|
{
|
|
BodyEntered += OnEntered;
|
|
AreaEntered += OnEntered;
|
|
|
|
_sprite = GetNode<Sprite2D>("Sprite2D");
|
|
UpdateTexture();
|
|
|
|
// Get the Label node for quantity
|
|
if (HasNode("Label"))
|
|
{
|
|
_quantityLabel = GetNode<Label>("Label");
|
|
if (Quantity > 1)
|
|
_quantityLabel.Text = Quantity.ToString();
|
|
else
|
|
_quantityLabel.Text = string.Empty;
|
|
}
|
|
|
|
// Add or update shadow sprite
|
|
if (HasNode("ShadowSprite"))
|
|
{
|
|
_shadowSprite = GetNode<Sprite2D>("ShadowSprite");
|
|
_shadowSprite.Texture = _sprite.Texture;
|
|
_shadowSprite.Modulate = new Color(0, 0, 0, 0.5f);
|
|
_shadowSprite.Position = _sprite.Position + new Vector2(0, 6);
|
|
_shadowSprite.ZIndex = _sprite.ZIndex - 1;
|
|
}
|
|
else
|
|
{
|
|
_shadowSprite = new Sprite2D();
|
|
_shadowSprite.Scale = _sprite.Scale;
|
|
_shadowSprite.Name = "ShadowSprite";
|
|
_shadowSprite.Texture = _sprite.Texture;
|
|
_shadowSprite.Modulate = new Color(0, 0, 0, 0.5f);
|
|
_shadowSprite.Position = _sprite.Position + new Vector2(0, 6);
|
|
_shadowSprite.ZIndex = _sprite.ZIndex - 1;
|
|
AddChild(_shadowSprite);
|
|
}
|
|
|
|
_playerTarget = GetTree().GetFirstNodeInGroup(PickupGroupName) as Node2D;
|
|
if (_playerTarget == null)
|
|
_playerTarget = GetTree().GetFirstNodeInGroup("Player") as Node2D;
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
if (_playerTarget != null)
|
|
{
|
|
var distance = Position.DistanceTo(_playerTarget.Position);
|
|
const float speed = 10f;
|
|
if (distance <= MagnetRange)
|
|
Position = Position.Lerp(_playerTarget.Position, (float)delta * speed);
|
|
}
|
|
}
|
|
|
|
private void UpdateTexture()
|
|
{
|
|
var file = FileAccess.Open("res://Data/ItemTextures.json", FileAccess.ModeFlags.Read);
|
|
if (file == null)
|
|
{
|
|
GD.PrintErr("Failed to open ItemTextures.json");
|
|
return;
|
|
}
|
|
|
|
var text = file.GetAsText();
|
|
file.Close();
|
|
|
|
var json = new Json();
|
|
var err = json.Parse(text);
|
|
if (err != Error.Ok)
|
|
{
|
|
GD.PrintErr(json.GetErrorMessage());
|
|
return;
|
|
}
|
|
|
|
var dict = json.Data.AsGodotDictionary();
|
|
if (!dict.TryGetValue(ItemId, out var value))
|
|
return;
|
|
|
|
var texturePath = value.AsString();
|
|
if (string.IsNullOrEmpty(texturePath))
|
|
return;
|
|
|
|
var texture = GD.Load<Texture2D>(texturePath);
|
|
if (texture == null)
|
|
return;
|
|
|
|
_sprite.Texture = texture;
|
|
}
|
|
|
|
private void OnEntered(Node body)
|
|
{
|
|
if (body is ItemPickup itemStack)
|
|
{
|
|
// 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)
|
|
{
|
|
player.AddItem(ItemId, Quantity);
|
|
}
|
|
|
|
if (!Infinite)
|
|
QueueFree();
|
|
}
|
|
}
|
|
} |