✨ Miner tile
This commit is contained in:
		| @@ -19,7 +19,7 @@ | ||||
| 	"buildTime": 3.0, | ||||
| 	"allowedRotations": [0], | ||||
| 	"layer": 1, | ||||
| 	"size": [3, 3] | ||||
| 	"size": [1, 1] | ||||
|   }, | ||||
|   "ground": { | ||||
| 	"scene": "res://Scenes/Tiles/GroundTile.tscn", | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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="."] | ||||
|   | ||||
| @@ -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="."] | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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}"); | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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(); | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user