139 lines
3.5 KiB
C#
139 lines
3.5 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using static GameData;
|
|
|
|
public partial class World : Node3D
|
|
{
|
|
public Dictionary<string, MeshInstance3D> tileMeshes;
|
|
public Dictionary<string, MeshInstance3D> decorationMeshes;
|
|
public Dictionary<string, List<Placeholder>> tilePlaceholders;
|
|
PackedScene layerPrefab = ResourceLoader.LoadLayerPrefab();
|
|
private Dictionary<string, MultiMeshInstance3D> multiMeshes = new();
|
|
private Dictionary<string, Mesh> meshLibrary = new();
|
|
Layer[] map;
|
|
Layer layerNode;
|
|
|
|
private MultiMeshHandler multiMeshHandler;
|
|
|
|
public override void _Ready()
|
|
{
|
|
WFC.FillAdjacencies();
|
|
|
|
tileMeshes = ResourceLoader.LoadTiles();
|
|
decorationMeshes = ResourceLoader.LoadDecorations();
|
|
|
|
tilePlaceholders = new Dictionary<string, List<Placeholder>>();
|
|
|
|
foreach (var kvp in tileMeshes)
|
|
{
|
|
tilePlaceholders[kvp.Key] = new List<Placeholder>();
|
|
foreach (MeshInstance3D child in kvp.Value.GetChildren())
|
|
{
|
|
tilePlaceholders[kvp.Key].Add(new Placeholder(child.Name, child.Transform.Origin));
|
|
}
|
|
meshLibrary[kvp.Key] = kvp.Value.Mesh;
|
|
kvp.Value.QueueFree();
|
|
}
|
|
|
|
multiMeshes = CreateMultiMeshes(meshLibrary);
|
|
multiMeshHandler = new MultiMeshHandler(multiMeshes);
|
|
|
|
map = new Layer[ruinSize];
|
|
GenerateWorld();
|
|
|
|
GD.Print("World generated");
|
|
|
|
HandleRenderData(BuildRenderData(0));
|
|
}
|
|
|
|
private Dictionary<string, MultiMeshInstance3D> CreateMultiMeshes(Dictionary<string, Mesh> meshLibrary)
|
|
{
|
|
var result = new Dictionary<string, MultiMeshInstance3D>();
|
|
|
|
foreach (var kvp in meshLibrary)
|
|
{
|
|
var mm = new MultiMesh
|
|
{
|
|
Mesh = kvp.Value,
|
|
TransformFormat = MultiMesh.TransformFormatEnum.Transform3D
|
|
};
|
|
|
|
var instance = new MultiMeshInstance3D
|
|
{
|
|
Multimesh = mm
|
|
};
|
|
|
|
AddChild(instance);
|
|
|
|
result[kvp.Key] = instance;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
public override void _Process(double delta)
|
|
{
|
|
if (Input.IsActionJustPressed("layer_up") && currentLayer > 0) currentLayer--;
|
|
if (Input.IsActionJustPressed("layer_down") && currentLayer < ruinSize - 1) currentLayer++;
|
|
if (currentLayer != visibleLayer)
|
|
{
|
|
map[visibleLayer].ClearDecorations();
|
|
HandleRenderData(BuildRenderData(currentLayer));
|
|
visibleLayer = currentLayer;
|
|
}
|
|
|
|
if (Input.IsActionJustPressed("spawn_robot"))
|
|
{
|
|
Robot robot = ResourceLoader.LoadRobotPrefab().Instantiate<Robot>();
|
|
robot.Position = map[0].tiles[1,1].Position;
|
|
AddChild(robot);
|
|
}
|
|
}
|
|
|
|
private void GenerateWorld()
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
for (int layer = 0; layer < ruinSize; layer++)
|
|
{
|
|
layerNode = layerPrefab.Instantiate<Layer>();
|
|
AddChild(layerNode);
|
|
layerNode.SetupLayer(layerSize, layer, tileMeshes);
|
|
map[layer] = layerNode;
|
|
}
|
|
GD.Print("Time for map generation: " + (DateTime.Now - now).Seconds);
|
|
}
|
|
|
|
private List<TileRenderData> BuildRenderData(int layerIndex)
|
|
{
|
|
var result = new List<TileRenderData>();
|
|
Layer layer = map[layerIndex];
|
|
layer.ClearDecorations();
|
|
|
|
for (int x = 0; x < layerSize; x++)
|
|
{
|
|
for (int y = 0; y < layerSize; y++)
|
|
{
|
|
Tile tile = layer.tiles[x, y];
|
|
result.Add(new TileRenderData
|
|
{
|
|
Tile = tile,
|
|
MeshKey = tile.collapsedMesh,
|
|
Transform = new Transform3D(Basis.Identity, tile.Position),
|
|
Placeholders = tilePlaceholders[tile.collapsedMesh]
|
|
});
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void HandleRenderData(List<TileRenderData> renderData)
|
|
{
|
|
multiMeshHandler.Build(renderData);
|
|
DecorationHandler.Spawn(renderData, decorationMeshes);
|
|
}
|
|
}
|