✨ Natural resource generator
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://c22aprj452aha"]
|
||||
[gd_scene load_steps=6 format=3 uid="uid://c22aprj452aha"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cudpc3w17mbsw" path="res://Scripts/System/GridManager.cs" id="1_knkkn"]
|
||||
[ext_resource type="Script" uid="uid://cfbj72nm0eovg" path="res://Scripts/System/BuildingRegistry.cs" id="1_sxhdm"]
|
||||
[ext_resource type="Script" uid="uid://cugfbvw70clgd" path="res://Scripts/System/NaturalResourceGenerator.cs" id="2_oss8w"]
|
||||
[ext_resource type="Script" uid="uid://bx1wj7gn6vrqe" path="res://Scripts/System/PlacementManager.cs" id="2_sxhdm"]
|
||||
[ext_resource type="PackedScene" uid="uid://doxy60afddg1m" path="res://Scenes/Entities/Player.tscn" id="3_oss8w"]
|
||||
|
||||
@@ -10,6 +11,11 @@
|
||||
[node name="BuildingRegistry" type="Node" parent="."]
|
||||
script = ExtResource("1_sxhdm")
|
||||
|
||||
[node name="NaturalResourceGenerator" type="Node2D" parent="." node_paths=PackedStringArray("Grid", "Registry")]
|
||||
script = ExtResource("2_oss8w")
|
||||
Grid = NodePath("../GridSystem")
|
||||
Registry = NodePath("../BuildingRegistry")
|
||||
|
||||
[node name="GridSystem" type="Node2D" parent="."]
|
||||
script = ExtResource("1_knkkn")
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
size = Vector2(54, 54)
|
||||
|
||||
[node name="GroundTile" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
script = ExtResource("1_mqsaf")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
@@ -7,6 +7,7 @@
|
||||
size = Vector2(54, 54)
|
||||
|
||||
[node name="StoneIronTile" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
script = ExtResource("1_ewklp")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
@@ -7,6 +7,7 @@
|
||||
size = Vector2(54, 54)
|
||||
|
||||
[node name="StoneTile" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
script = ExtResource("1_rndy8")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
|
||||
namespace AceFieldNewHorizon.Scripts.System;
|
||||
@@ -21,21 +22,13 @@ public partial class GridManager : Node
|
||||
{
|
||||
// Initialize all layers
|
||||
foreach (GridLayer layer in Enum.GetValues(typeof(GridLayer)))
|
||||
{
|
||||
_layers[layer] = new Dictionary<Vector2I, (Node2D, Vector2I, float)>();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAreaFree(Vector2I topLeft, Vector2I size, float rotation, GridLayer layer = GridLayer.Building)
|
||||
{
|
||||
var occupiedCells = GridUtils.GetOccupiedCells(topLeft, size, rotation);
|
||||
foreach (var cell in occupiedCells)
|
||||
{
|
||||
if (_layers[layer].ContainsKey(cell))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return occupiedCells.All(cell => !_layers[layer].ContainsKey(cell));
|
||||
}
|
||||
|
||||
public void OccupyArea(Vector2I topLeft, Node2D building, Vector2I size, float rotation,
|
||||
|
153
Scripts/System/NaturalResourceGenerator.cs
Normal file
153
Scripts/System/NaturalResourceGenerator.cs
Normal file
@@ -0,0 +1,153 @@
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
using AceFieldNewHorizon.Scripts.Tiles;
|
||||
|
||||
namespace AceFieldNewHorizon.Scripts.System;
|
||||
|
||||
public partial class NaturalResourceGenerator : Node2D
|
||||
{
|
||||
[Export] public GridManager Grid { get; set; }
|
||||
[Export] public BuildingRegistry Registry { get; set; }
|
||||
|
||||
[Export] public int MapWidth = 100;
|
||||
[Export] public int MapHeight = 100;
|
||||
[Export] public float StoneDensity = 0.1f; // 10% chance for stone
|
||||
[Export] public float IronDensity = 0.03f; // 3% chance for iron (within stone)
|
||||
[Export] public int MinStoneVeinSize = 1;
|
||||
[Export] public int MaxStoneVeinSize = 5;
|
||||
[Export] public int MinIronVeinSize = 1;
|
||||
[Export] public int MaxIronVeinSize = 3;
|
||||
[Export] public int Seed;
|
||||
|
||||
private RandomNumberGenerator _rng;
|
||||
private readonly List<Vector2I> _groundTiles = [];
|
||||
private readonly List<Vector2I> _stoneTiles = [];
|
||||
private readonly List<Vector2I> _ironTiles = [];
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_rng = new RandomNumberGenerator();
|
||||
_rng.Seed = (ulong)(Seed != 0 ? Seed : (int)GD.Randi());
|
||||
|
||||
GenerateTerrain();
|
||||
PlaceResources();
|
||||
}
|
||||
|
||||
private void GenerateTerrain()
|
||||
{
|
||||
// First pass: Generate base ground tiles
|
||||
for (int x = 0; x < MapWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < MapHeight; y++)
|
||||
{
|
||||
var cell = new Vector2I(x, y);
|
||||
_groundTiles.Add(cell);
|
||||
PlaceTile("ground", cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PlaceResources()
|
||||
{
|
||||
// Create a copy of ground tiles for iteration
|
||||
var groundTilesToProcess = new List<Vector2I>(_groundTiles);
|
||||
|
||||
// Place stone veins
|
||||
foreach (var cell in groundTilesToProcess)
|
||||
{
|
||||
if (_rng.Randf() < StoneDensity)
|
||||
{
|
||||
var veinSize = _rng.RandiRange(MinStoneVeinSize, MaxStoneVeinSize);
|
||||
PlaceVein(cell, "stone", veinSize, _stoneTiles);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a copy of stone tiles for iteration
|
||||
var stoneTilesToProcess = new List<Vector2I>(_stoneTiles);
|
||||
|
||||
// Place iron veins within stone
|
||||
foreach (var stoneCell in stoneTilesToProcess)
|
||||
{
|
||||
if (_rng.Randf() < IronDensity)
|
||||
{
|
||||
var veinSize = _rng.RandiRange(MinIronVeinSize, MaxIronVeinSize);
|
||||
PlaceVein(stoneCell, "stone_iron", veinSize, _ironTiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PlaceVein(Vector2I startCell, string tileType, int maxVeinSize, ICollection<Vector2I> tileList)
|
||||
{
|
||||
var queue = new Queue<Vector2I>();
|
||||
var placed = new HashSet<Vector2I>();
|
||||
queue.Enqueue(startCell);
|
||||
|
||||
int placedCount = 0;
|
||||
|
||||
while (queue.Count > 0 && placedCount < maxVeinSize)
|
||||
{
|
||||
var cell = queue.Dequeue();
|
||||
if (placed.Contains(cell)) continue;
|
||||
if (!IsInBounds(cell)) continue;
|
||||
|
||||
switch (tileType)
|
||||
{
|
||||
// For iron, make sure we're placing on stone
|
||||
case "stone_iron" when !_stoneTiles.Contains(cell):
|
||||
continue;
|
||||
// Remove from previous layer if needed
|
||||
case "stone_iron" when _stoneTiles.Contains(cell):
|
||||
_stoneTiles.Remove(cell);
|
||||
break;
|
||||
case "stone" when _groundTiles.Contains(cell):
|
||||
_groundTiles.Remove(cell);
|
||||
break;
|
||||
}
|
||||
|
||||
PlaceTile(tileType, cell);
|
||||
tileList.Add(cell);
|
||||
placed.Add(cell);
|
||||
placedCount++;
|
||||
|
||||
// Add adjacent cells to queue
|
||||
for (var dx = -1; dx <= 1; dx++)
|
||||
{
|
||||
for (var dy = -1; dy <= 1; dy++)
|
||||
{
|
||||
if (dx == 0 && dy == 0) continue; // Skip self
|
||||
var neighbor = new Vector2I(cell.X + dx, cell.Y + dy);
|
||||
if (!placed.Contains(neighbor) && IsInBounds(neighbor))
|
||||
{
|
||||
queue.Enqueue(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsInBounds(Vector2I cell)
|
||||
{
|
||||
return cell.X >= 0 && cell.X < MapWidth &&
|
||||
cell.Y >= 0 && cell.Y < MapHeight;
|
||||
}
|
||||
|
||||
private void PlaceTile(string tileType, Vector2I cell)
|
||||
{
|
||||
var building = Registry.GetBuilding(tileType);
|
||||
if (building == null) return;
|
||||
|
||||
var scene = building.Scene;
|
||||
var instance = (BaseTile)scene.Instantiate();
|
||||
|
||||
// Match PlacementManager's positioning logic
|
||||
var rotatedSize = building.GetRotatedSize(0f);
|
||||
var offset = GridUtils.GetCenterOffset(rotatedSize, 0f);
|
||||
instance.Position = GridUtils.GridToWorld(cell) + offset;
|
||||
|
||||
instance.ZIndex = (int)building.Layer;
|
||||
AddChild(instance);
|
||||
|
||||
// Make sure to use the building's size from the registry
|
||||
Grid.OccupyArea(cell, instance, building.Size, 0f, building.Layer);
|
||||
}
|
||||
}
|
1
Scripts/System/NaturalResourceGenerator.cs.uid
Normal file
1
Scripts/System/NaturalResourceGenerator.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cugfbvw70clgd
|
@@ -165,8 +165,8 @@ public partial class PlacementManager : Node2D
|
||||
return layer switch
|
||||
{
|
||||
GridLayer.Ground => [GridLayer.Ground],
|
||||
GridLayer.Building => [GridLayer.Ground, GridLayer.Building],
|
||||
GridLayer.Decoration => [GridLayer.Ground, GridLayer.Building, GridLayer.Decoration],
|
||||
GridLayer.Building => [GridLayer.Building],
|
||||
GridLayer.Decoration => [GridLayer.Decoration],
|
||||
_ => []
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user