Reworked border placement
This commit is contained in:
@@ -13,6 +13,7 @@ public partial class Layer : Node3D
|
|||||||
int level;
|
int level;
|
||||||
bool updateFailed = false;
|
bool updateFailed = false;
|
||||||
public bool hasContentGenerated = false;
|
public bool hasContentGenerated = false;
|
||||||
|
public Vector2I gateCoordinate;
|
||||||
|
|
||||||
// Called when the node enters the scene tree for the first time.
|
// Called when the node enters the scene tree for the first time.
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
@@ -40,7 +41,7 @@ public partial class Layer : Node3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupLayer(int layerSize, int level, Dictionary<string, MeshInstance3D> tileMeshes)
|
public void SetupLayer(int layerSize, int level, Dictionary<string, MeshInstance3D> tileMeshes, Vector2I collapseOrigin)
|
||||||
{
|
{
|
||||||
this.layerSize = layerSize;
|
this.layerSize = layerSize;
|
||||||
this.level = level;
|
this.level = level;
|
||||||
@@ -49,7 +50,7 @@ public partial class Layer : Node3D
|
|||||||
int safetyCounter = 0;
|
int safetyCounter = 0;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (GenerateLayer()) break;
|
if (GenerateLayer(collapseOrigin)) break;
|
||||||
ResetLayer(tileMeshes);
|
ResetLayer(tileMeshes);
|
||||||
safetyCounter++;
|
safetyCounter++;
|
||||||
if (safetyCounter > 1000) break;
|
if (safetyCounter > 1000) break;
|
||||||
@@ -104,65 +105,30 @@ public partial class Layer : Node3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool GenerateBorder()
|
private void GenerateBorder()
|
||||||
{
|
{
|
||||||
for (int x = 0; x < layerSize; x++)
|
for (int x = 0; x < layerSize; x++)
|
||||||
{
|
{
|
||||||
for (int y = 0; y < layerSize; y++)
|
for (int z = 0; z < layerSize; z++)
|
||||||
{
|
{
|
||||||
if (x == 0 || y == 0 || x == layerSize - 1 || y == layerSize - 1)
|
if (!IsBorder(x, z))
|
||||||
{
|
continue;
|
||||||
var tile = tiles[x, y];
|
|
||||||
|
|
||||||
List<string> possibilities = new();
|
var tile = tiles[x, z];
|
||||||
|
var possibilities = GetBorderPossibilities(x, z);
|
||||||
|
|
||||||
if (x == 0 && y == 0)
|
if (possibilities.Count == 0)
|
||||||
{
|
continue;
|
||||||
possibilities.Add("corner_down_right");
|
|
||||||
|
tile.Collapse(possibilities[rand.Next(possibilities.Count)]);
|
||||||
|
Propagate(new Vector2I(x, z));
|
||||||
}
|
}
|
||||||
else if (x == 0 && y == layerSize - 1)
|
|
||||||
{
|
|
||||||
possibilities.Add("corner_up_right");
|
|
||||||
}
|
}
|
||||||
else if (x == layerSize - 1 && y == 0)
|
|
||||||
{
|
|
||||||
possibilities.Add("corner_down_left");
|
|
||||||
}
|
|
||||||
else if (x == layerSize - 1 && y == layerSize - 1)
|
|
||||||
{
|
|
||||||
possibilities.Add("corner_up_left");
|
|
||||||
}
|
|
||||||
else if (y == 0)
|
|
||||||
{
|
|
||||||
possibilities.Add("straight_left_right");
|
|
||||||
possibilities.Add("t_down");
|
|
||||||
}
|
|
||||||
else if (y == layerSize - 1)
|
|
||||||
{
|
|
||||||
possibilities.Add("straight_left_right");
|
|
||||||
possibilities.Add("t_up");
|
|
||||||
}
|
|
||||||
else if (x == 0)
|
|
||||||
{
|
|
||||||
possibilities.Add("straight_up_down");
|
|
||||||
possibilities.Add("t_right");
|
|
||||||
}
|
|
||||||
else if (x == layerSize - 1)
|
|
||||||
{
|
|
||||||
possibilities.Add("straight_up_down");
|
|
||||||
possibilities.Add("t_left");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string result = tile.Collapse(possibilities[rand.Next(0, possibilities.Count)]);
|
private bool IsBorder(int x, int z)
|
||||||
|
{
|
||||||
if (result == "ERR")
|
return x == 0 || z == 0 || x == layerSize - 1 || z == layerSize - 1;
|
||||||
return false;
|
|
||||||
|
|
||||||
NewPropagate(new Vector2I(x, y));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateNecessaryTiles()
|
private void GenerateNecessaryTiles()
|
||||||
@@ -177,30 +143,28 @@ public partial class Layer : Node3D
|
|||||||
if (tiles[posX, posY].tileMeshes.ContainsKey("gate"))
|
if (tiles[posX, posY].tileMeshes.ContainsKey("gate"))
|
||||||
{
|
{
|
||||||
tiles[posX, posY].Collapse("gate");
|
tiles[posX, posY].Collapse("gate");
|
||||||
NewPropagate(new Vector2I(posX, posY));
|
gateCoordinate = new Vector2I(posX, posY);
|
||||||
|
Propagate(gateCoordinate);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool GenerateLayer()
|
public bool GenerateLayer(Vector2I collapseOrigin)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
int safetyCounter = 0;
|
int safetyCounter = 0;
|
||||||
if (!GenerateBorder())
|
GenerateBorder();
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerateNecessaryTiles();
|
GenerateNecessaryTiles();
|
||||||
Vector2I position = GetSmallestPossibilities();
|
Vector2I position = tiles[collapseOrigin.X, collapseOrigin.Y].collapsedMesh == null ? collapseOrigin : GetSmallestPossibilities();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
string keyword = tiles[position.X, position.Y].Collapse("");
|
string keyword = tiles[position.X, position.Y].Collapse("");
|
||||||
if (keyword == "ERR") return false;
|
if (keyword == "ERR") return false;
|
||||||
if (keyword != "")
|
if (keyword != "")
|
||||||
{
|
{
|
||||||
NewPropagate(position);
|
Propagate(position);
|
||||||
if (updateFailed) break;
|
if (updateFailed) break;
|
||||||
position = GetSmallestPossibilities();
|
position = GetSmallestPossibilities();
|
||||||
if (position == new Vector2(-100, -100))
|
if (position == new Vector2(-100, -100))
|
||||||
@@ -219,7 +183,7 @@ public partial class Layer : Node3D
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NewPropagate(Vector2I startPos)
|
private void Propagate(Vector2I startPos)
|
||||||
{
|
{
|
||||||
Queue<Vector2I> queue = new Queue<Vector2I>();
|
Queue<Vector2I> queue = new Queue<Vector2I>();
|
||||||
queue.Enqueue(startPos);
|
queue.Enqueue(startPos);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class WFC
|
|||||||
|
|
||||||
public static Dictionary<string, HashSet<Direction>> tileConnections = new Dictionary<string, HashSet<Direction>>
|
public static Dictionary<string, HashSet<Direction>> tileConnections = new Dictionary<string, HashSet<Direction>>
|
||||||
{
|
{
|
||||||
["t_right"] = new() { Direction.Backward, Direction.Forward, Direction.Right , Direction.Up},
|
["t_right"] = new() { Direction.Backward, Direction.Forward, Direction.Right, Direction.Up },
|
||||||
["t_left"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Up },
|
["t_left"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Up },
|
||||||
["t_up"] = new() { Direction.Left, Direction.Right, Direction.Backward, Direction.Up },
|
["t_up"] = new() { Direction.Left, Direction.Right, Direction.Backward, Direction.Up },
|
||||||
["t_down"] = new() { Direction.Left, Direction.Right, Direction.Forward, Direction.Up },
|
["t_down"] = new() { Direction.Left, Direction.Right, Direction.Forward, Direction.Up },
|
||||||
@@ -54,8 +54,8 @@ public class WFC
|
|||||||
["corner_down_left"] = new() { Direction.Forward, Direction.Left, Direction.Up },
|
["corner_down_left"] = new() { Direction.Forward, Direction.Left, Direction.Up },
|
||||||
["corner_down_right"] = new() { Direction.Forward, Direction.Right, Direction.Up },
|
["corner_down_right"] = new() { Direction.Forward, Direction.Right, Direction.Up },
|
||||||
|
|
||||||
["junction"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up},
|
["junction"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up },
|
||||||
["gate"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down}
|
["gate"] = new() { Direction.Backward, Direction.Forward, Direction.Left, Direction.Right, Direction.Up, Direction.Down }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Dictionary<string, float> weights = new()
|
public static Dictionary<string, float> weights = new()
|
||||||
@@ -196,4 +196,26 @@ public class WFC
|
|||||||
pos.X < layerSize &&
|
pos.X < layerSize &&
|
||||||
pos.Y < layerSize;
|
pos.Y < layerSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<string> GetBorderPossibilities(int x, int z)
|
||||||
|
{
|
||||||
|
bool left = x == 0;
|
||||||
|
bool right = x == GameData.layerSize - 1;
|
||||||
|
bool top = z == 0;
|
||||||
|
bool bottom = z == GameData.layerSize - 1;
|
||||||
|
|
||||||
|
// Corners
|
||||||
|
if (left && top) return new() { "corner_down_right" };
|
||||||
|
if (left && bottom) return new() { "corner_up_right" };
|
||||||
|
if (right && top) return new() { "corner_down_left" };
|
||||||
|
if (right && bottom) return new() { "corner_up_left" };
|
||||||
|
|
||||||
|
// Edges
|
||||||
|
if (top) return new() { "straight_left_right", "t_down" };
|
||||||
|
if (bottom) return new() { "straight_left_right", "t_up" };
|
||||||
|
if (left) return new() { "straight_up_down", "t_right" };
|
||||||
|
if (right) return new() { "straight_up_down", "t_left" };
|
||||||
|
|
||||||
|
return new();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,15 @@ public partial class World : Node3D
|
|||||||
{
|
{
|
||||||
layerNode = layerPrefab.Instantiate<Layer>();
|
layerNode = layerPrefab.Instantiate<Layer>();
|
||||||
AddChild(layerNode);
|
AddChild(layerNode);
|
||||||
layerNode.SetupLayer(layerSize, layer, tileMeshes);
|
if (layer == 0)
|
||||||
|
{
|
||||||
|
layerNode.SetupLayer(layerSize, layer, tileMeshes, new Vector2I());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
layerNode.SetupLayer(layerSize, layer, tileMeshes, map[layer-1].gateCoordinate);
|
||||||
|
}
|
||||||
|
|
||||||
map[layer] = layerNode;
|
map[layer] = layerNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user