add cellular automata generator

This commit is contained in:
2026-04-26 04:20:06 +02:00
parent 7f0869ffa4
commit b2a406ca2b
17 changed files with 937 additions and 1 deletions

View File

@@ -0,0 +1,100 @@
#if TOOLS
using Godot;
using Godot.Collections;
namespace Mr.BrickAdventures.Tools.CaLevelGenerator;
public static class TilemapPainter
{
public static void Paint(
TileMapLayer layer,
bool[,] grid,
CaGeneratorSettings settings,
EditorUndoRedoManager undoRedo)
{
var before = layer.TileMapData;
ApplyGrid(layer, grid, settings);
var after = layer.TileMapData;
RegisterUndo(layer, before, after, undoRedo, "CA Generate");
}
public static void Smooth(
TileMapLayer layer,
CaGeneratorSettings settings,
EditorUndoRedoManager undoRedo)
{
var grid = ReadGrid(layer, settings.Offset, new Vector2I(settings.Width, settings.Height));
grid = CaGenerator.Smooth(grid);
var before = layer.TileMapData;
ApplyGrid(layer, grid, settings);
var after = layer.TileMapData;
RegisterUndo(layer, before, after, undoRedo, "CA Smooth");
}
public static void Clear(
TileMapLayer layer,
CaGeneratorSettings settings,
EditorUndoRedoManager undoRedo)
{
var before = layer.TileMapData;
for (int x = 0; x < settings.Width; x++)
for (int y = 0; y < settings.Height; y++)
layer.EraseCell(settings.Offset + new Vector2I(x, y));
var after = layer.TileMapData;
RegisterUndo(layer, before, after, undoRedo, "CA Clear");
}
private static bool[,] ReadGrid(TileMapLayer layer, Vector2I offset, Vector2I size)
{
var grid = new bool[size.X, size.Y];
for (int x = 0; x < size.X; x++)
for (int y = 0; y < size.Y; y++)
grid[x, y] = layer.GetCellSourceId(offset + new Vector2I(x, y)) != -1;
return grid;
}
private static void ApplyGrid(TileMapLayer layer, bool[,] grid, CaGeneratorSettings settings)
{
int w = grid.GetLength(0), h = grid.GetLength(1);
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
layer.EraseCell(settings.Offset + new Vector2I(x, y));
if (settings.TerrainSet >= 0)
{
var solidCells = new Array<Vector2I>();
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
if (grid[x, y])
solidCells.Add(settings.Offset + new Vector2I(x, y));
if (solidCells.Count > 0)
layer.SetCellsTerrainConnect(solidCells, settings.TerrainSet, settings.Terrain);
}
else
{
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
if (grid[x, y])
layer.SetCell(
settings.Offset + new Vector2I(x, y),
settings.SourceId,
settings.AtlasCoords);
}
}
private static void RegisterUndo(
TileMapLayer layer,
byte[] before,
byte[] after,
EditorUndoRedoManager undoRedo,
string actionName)
{
undoRedo.CreateAction(actionName);
undoRedo.AddUndoProperty(layer, "tile_map_data", before);
undoRedo.AddDoProperty(layer, "tile_map_data", after);
undoRedo.CommitAction(false);
}
}
#endif