Miner tile

This commit is contained in:
2025-08-29 16:59:59 +08:00
parent 7720e74a3d
commit 56cd4c2db2
9 changed files with 105 additions and 23 deletions

View File

@@ -19,7 +19,7 @@
"buildTime": 3.0,
"allowedRotations": [0],
"layer": 1,
"size": [3, 3]
"size": [1, 1]
},
"ground": {
"scene": "res://Scenes/Tiles/GroundTile.tscn",

View File

@@ -38,10 +38,8 @@ Inventory = NodePath("../ResourceSystem")
position = Vector2(-496, -245)
ItemId = "stone"
Quantity = 64
Infinite = true
[node name="ItemPickup2" parent="." instance=ExtResource("7_is6ib")]
position = Vector2(-495, 5)
ItemId = "ore_iron"
Quantity = 16
Infinite = true

View File

@@ -4,18 +4,17 @@
[ext_resource type="Script" uid="uid://qgcue2doj2lf" path="res://Scripts/System/ItemPickup.cs" id="1_ps3kh"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4weev"]
size = Vector2(160, 160)
size = Vector2(50, 50)
[node name="ItemPickup" type="Node2D"]
[node name="ItemPickup" type="Area2D"]
script = ExtResource("1_ps3kh")
MagnetRange = 96.0
[node name="Sprite2D" type="Sprite2D" parent="."]
scale = Vector2(0.05, 0.05)
texture = ExtResource("1_4weev")
[node name="Area2D" type="Area2D" parent="."]
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("RectangleShape2D_4weev")
[node name="Label" type="Label" parent="."]

View File

@@ -1,14 +1,15 @@
[gd_scene load_steps=4 format=3 uid="uid://cbu81slklwq3u"]
[gd_scene load_steps=5 format=3 uid="uid://cbu81slklwq3u"]
[ext_resource type="Script" uid="uid://dyubkyqtpcg3a" path="res://Scripts/Tiles/MinerTile.cs" id="1_mecoy"]
[ext_resource type="Texture2D" uid="uid://bt6xmcgrbb078" path="res://Scenes/Tiles/MinerTile.png" id="2_mecoy"]
[ext_resource type="PackedScene" uid="uid://xwkplaxmye3v" path="res://Scenes/System/ItemPickup.tscn" id="2_xhk0k"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_8o613"]
size = Vector2(54, 54)
[node name="MinerTile" type="StaticBody2D"]
scale = Vector2(3, 3)
script = ExtResource("1_mecoy")
ItemPickup = ExtResource("2_xhk0k")
TileId = "miner"
[node name="Sprite2D" type="Sprite2D" parent="."]

View File

@@ -2,7 +2,7 @@ using Godot;
namespace AceFieldNewHorizon.Scripts.System;
public partial class ItemPickup : Node2D
public partial class ItemPickup : Area2D
{
public const string PickupGroupName = "ItemPickupTarget";
@@ -19,8 +19,7 @@ public partial class ItemPickup : Node2D
// Called when the node enters the scene tree
public override void _Ready()
{
var area = GetNode<Area2D>("Area2D");
area.BodyEntered += OnBodyEntered;
BodyEntered += OnBodyEntered;
_sprite = GetNode<Sprite2D>("Sprite2D");
UpdateTexture();
@@ -114,7 +113,29 @@ public partial class ItemPickup : Node2D
if (body.IsInGroup(PickupGroupName))
{
if (body.HasMethod("AddItem"))
body.Call("AddItem", ItemId, Quantity);
{
// 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);
}
}
if (!Infinite)
QueueFree(); // remove the pickup from the world

View File

@@ -4,6 +4,7 @@ using Godot;
using System.Collections.Generic;
using System.Threading.Tasks;
using AceFieldNewHorizon.Scripts.Entities;
using AceFieldNewHorizon.Scripts.Tiles;
namespace AceFieldNewHorizon.Scripts.System;
@@ -376,7 +377,7 @@ public partial class NaturalResourceGenerator : Node2D
return false;
}
if (scene.Instantiate() is not Node2D instance)
if (scene.Instantiate() is not BaseTile instance)
{
GD.PrintErr($"{LogPrefix} Failed to instantiate scene for: {tileType}");
return false;
@@ -387,6 +388,7 @@ public partial class NaturalResourceGenerator : Node2D
var offset = GridUtils.GetCenterOffset(rotatedSize, 0f); // 0f for no rotation
instance.GlobalPosition = GridUtils.GridToWorld(cell) + offset;
instance.ZIndex = (int)building.Layer;
instance.Grid = Grid;
AddChild(instance);
Grid.OccupyArea(cell, instance, building.Size, 0f, building.Layer);
// GD.Print($"{LogPrefix} Successfully placed {tileType} at {cell}");

View File

@@ -199,6 +199,7 @@ public partial class PlacementManager : Node2D
var scene = building.Scene;
_ghostBuilding = (BaseTile)scene.Instantiate();
_ghostBuilding.Grid = Grid;
_ghostBuilding.SetGhostMode(true);
_ghostBuilding.RotationDegrees = _currentRotation;
_ghostBuilding.ZAsRelative = false;
@@ -232,6 +233,7 @@ public partial class PlacementManager : Node2D
// Create the building instance first
var scene = building.Scene;
var buildingInstance = (BaseTile)scene.Instantiate();
buildingInstance.Grid = Grid;
buildingInstance.RotationDegrees = _currentRotation;
buildingInstance.ZIndex = (int)building.Layer;
buildingInstance.Position = _ghostBuilding.Position;

View File

@@ -9,12 +9,15 @@ namespace AceFieldNewHorizon.Scripts.Tiles;
public partial class BaseTile : Node2D
{
[Export] public string TileId { get; set; }
[Export] public GridManager Grid { get; set; }
private CollisionShape2D _collisionShape;
private Sprite2D _sprite;
private ColorRect _progressOverlay;
private Action _onConstructionComplete;
private bool _isConstructing = false;
public bool IsConstructing;
public bool IsConstructed;
public override void _Ready()
{
@@ -28,7 +31,7 @@ public partial class BaseTile : Node2D
public void SetGhostMode(bool canPlace)
{
// Don't modify collision for constructing buildings
if (_isConstructing) return;
if (IsConstructing) return;
if (_collisionShape != null)
_collisionShape.Disabled = true;
@@ -50,13 +53,13 @@ public partial class BaseTile : Node2D
// Building progress visualization
public void StartConstruction(float buildTime, Action onComplete = null)
{
_isConstructing = true;
IsConstructing = true;
if (_collisionShape != null)
_collisionShape.Disabled = true;
if (_progressOverlay == null || _sprite?.Texture == null)
{
_isConstructing = false;
IsConstructing = false;
onComplete?.Invoke();
return;
}
@@ -97,11 +100,12 @@ public partial class BaseTile : Node2D
if (_sprite != null)
_sprite.Modulate = Colors.White;
_isConstructing = false;
IsConstructing = false;
if (_collisionShape != null)
_collisionShape.Disabled = false;
_onConstructionComplete?.Invoke();
IsConstructed = true;
}
RunProgress();

View File

@@ -1,8 +1,63 @@
using AceFieldNewHorizon.Scripts.System;
using Godot;
namespace AceFieldNewHorizon.Scripts.Tiles;
public partial class MinerTile : BaseTile
{
[Export] public PackedScene ItemPickup { get; set; }
[Export] public string ItemToMine { get; set; } = "OreIron";
[Export] public int MiningRate = 1; // Items per second
private Vector2I _gridPosition;
private float _timeSinceLastMine;
public override void _Ready()
{
base._Ready();
_gridPosition = GridUtils.WorldToGrid(Position);
}
public override void _Process(double delta)
{
// Don't mine if building is not completed
if (!IsConstructed || ItemPickup == null)
return;
_timeSinceLastMine += (float)delta;
if (!(_timeSinceLastMine >= 1f / MiningRate)) return;
_timeSinceLastMine = 0f;
SpawnItem();
}
private void SpawnItem()
{
var itemPickup = ItemPickup?.Instantiate<ItemPickup>();
if (itemPickup == null) return;
itemPickup.ItemId = ItemToMine;
itemPickup.Quantity = 1;
// Initial position (slightly below the spawn point)
var spawnPosition = GridUtils.GridToWorld(_gridPosition);
var targetY = spawnPosition.Y - 27f; // Target Y position
var targetX = spawnPosition.X + 27f + (GD.Randf() * 10f - 5f);
itemPickup.Position =
new Vector2(spawnPosition.X + 27f, spawnPosition.Y + 16); // Start below
itemPickup.Scale = Vector2.Zero; // Start invisible
// Add to the scene
GetTree().CurrentScene.AddChild(itemPickup);
// Create the pop-up animation
var tween = CreateTween().SetTrans(Tween.TransitionType.Elastic).SetEase(Tween.EaseType.Out);
// Animate the pop-up effect
tween.TweenProperty(itemPickup, "position:y", targetY, 0.6f);
tween.Parallel().TweenProperty(itemPickup, "scale", Vector2.One, 0.6f);
// Optional: Add a slight horizontal wobble
tween.Parallel().TweenProperty(itemPickup, "position:x", targetX, 0.6f);
}
}