Enemy and nest

This commit is contained in:
2025-08-30 02:06:58 +08:00
parent 630dbf0800
commit 32f96d488d
12 changed files with 327 additions and 10 deletions

View File

@@ -25,6 +25,10 @@ public partial class NaturalResourceGenerator : Node2D
[Export] public int MaxIronVeinSize = 3;
[Export] public int Seed;
[Export] public bool SpawnEnemyNest = true;
[Export] public int MinDistanceFromOrigin = 20; // Minimum distance from world origin (0,0)
[Export] public int MaxDistanceFromOrigin = 50; // Maximum distance from world origin
private const string LogPrefix = "[NaturalGeneration]";
private RandomNumberGenerator _rng;
@@ -41,6 +45,32 @@ public partial class NaturalResourceGenerator : Node2D
{
_rng = new RandomNumberGenerator();
_rng.Seed = (ulong)(Seed != 0 ? Seed : (int)GD.Randi());
// Test if building registry is assigned
if (Registry == null)
{
GD.PrintErr($"{LogPrefix} BuildingRegistry is not assigned!");
return;
}
// Test if enemy_nest is in the registry
var testBuilding = Registry.GetBuilding("enemy_nest");
if (testBuilding == null)
{
GD.PrintErr($"{LogPrefix} 'enemy_nest' is not found in BuildingRegistry!");
}
else
{
GD.Print($"{LogPrefix} Found enemy_nest in registry!");
}
GD.Print($"{LogPrefix} NaturalResourceGenerator ready, SpawnEnemyNest = {SpawnEnemyNest}");
if (SpawnEnemyNest)
{
GD.Print($"{LogPrefix} Attempting to spawn enemy nest...");
SpawnRandomEnemyNest();
}
}
public override void _Process(double delta)
@@ -361,12 +391,52 @@ public partial class NaturalResourceGenerator : Node2D
GD.Print($"{LogPrefix} Finished placing vein - placed {placedCount}/{maxSize} {tileType} tiles");
}
private void SpawnRandomEnemyNest()
{
// Generate a random position within the specified distance from origin
var angle = _rng.Randf() * Mathf.Pi * 2;
var distance = _rng.RandfRange(MinDistanceFromOrigin, MaxDistanceFromOrigin);
var offset = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * distance;
var nestPosition = new Vector2I((int)offset.X, (int)offset.Y);
// Try to find a valid position for the nest
int attempts = 0;
const int maxAttempts = 10;
while (attempts < maxAttempts)
{
if (PlaceTile("enemy_nest", nestPosition))
{
GD.Print($"{LogPrefix} Placed enemy nest at {nestPosition}");
return;
}
// Try a different position if placement failed
angle = _rng.Randf() * Mathf.Pi * 2;
distance = _rng.RandfRange(MinDistanceFromOrigin, MaxDistanceFromOrigin);
offset = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * distance;
nestPosition = new Vector2I((int)offset.X, (int)offset.Y);
attempts++;
}
GD.PrintErr($"{LogPrefix} Failed to place enemy nest after {maxAttempts} attempts");
}
private bool PlaceTile(string tileType, Vector2I cell)
{
try
{
// First, remove any existing tile at this position
Grid.FreeArea(cell, Vector2I.One, 0f, GridLayer.Ground);
// For enemy nest, we want to place it on top of existing ground
if (tileType != "enemy_nest")
{
// Original behavior for other tile types
Grid.FreeArea(cell, Vector2I.One, 0f, GridLayer.Ground);
}
else
{
// For enemy nest, check if there's ground below (skip for now)
GD.Print($"{LogPrefix} Attempting placing nest at {cell}.");
}
var building = Registry.GetBuilding(tileType);
if (building == null)
@@ -374,6 +444,7 @@ public partial class NaturalResourceGenerator : Node2D
GD.PrintErr($"{LogPrefix} Building type not found in registry: {tileType}");
return false;
}
// GD.Print($"{LogPrefix} Found building in registry: {tileType}");
var scene = building.Scene;
if (scene == null)
@@ -381,27 +452,35 @@ public partial class NaturalResourceGenerator : Node2D
GD.PrintErr($"{LogPrefix} Scene is null for building type: {tileType}");
return false;
}
// GD.Print($"{LogPrefix} Scene loaded for {tileType}");
if (scene.Instantiate() is not BaseTile instance)
{
GD.PrintErr($"{LogPrefix} Failed to instantiate scene for: {tileType}");
return false;
}
// GD.Print($"{LogPrefix} Successfully instantiated {tileType}");
// Use the same positioning logic as PlacementManager
var rotatedSize = building.GetRotatedSize(0f); // 0f for no rotation
var offset = GridUtils.GetCenterOffset(rotatedSize, 0f); // 0f for no rotation
instance.GlobalPosition = GridUtils.GridToWorld(cell) + offset;
var rotatedSize = building.GetRotatedSize(0f);
var offset = GridUtils.GetCenterOffset(rotatedSize, 0f);
instance.ZIndex = (int)building.Layer;
instance.GlobalPosition = GridUtils.GridToWorld(cell) + offset;
instance.Grid = Grid;
AddChild(instance);
Grid.OccupyArea(cell, instance, building.Size, 0f, building.Layer);
// GD.Print($"{LogPrefix} Successfully placed {tileType} at {cell}");
// For enemy nest, use Building layer
var layer = tileType == "enemy_nest" ? GridLayer.Building : building.Layer;
Grid.OccupyArea(cell, instance, building.Size, 0f, layer);
// GD.Print($"{LogPrefix} Successfully placed {tileType} at {cell} on layer {layer}");
return true;
}
catch (Exception e)
{
GD.PrintErr($"{LogPrefix} Error placing {tileType} at {cell}: {e.Message}");
GD.Print($"{LogPrefix} Stack trace: {e.StackTrace}");
return false;
}
}