158 lines
4.3 KiB
C#
158 lines
4.3 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;
|
|
// Called when the node enters the scene tree for the first time.
|
|
public override void _Ready()
|
|
{
|
|
WFC.FillAdjacencies();
|
|
tileMeshes = ResourceLoader.LoadTiles();
|
|
decorationMeshes = ResourceLoader.LoadDecorations();
|
|
tilePlaceholders = new Dictionary<string, List<Placeholder>>();
|
|
foreach (var kvp in tileMeshes)
|
|
{
|
|
tilePlaceholders.Add(kvp.Key, new List<Placeholder>());
|
|
foreach (MeshInstance3D child in kvp.Value.GetChildren())
|
|
{
|
|
tilePlaceholders[kvp.Key].Add(new Placeholder(child.Name, child.Transform.Origin));
|
|
}
|
|
var temp = kvp.Value;
|
|
meshLibrary[kvp.Key] = temp.Mesh;
|
|
temp.QueueFree();
|
|
}
|
|
foreach (var kvp in meshLibrary)
|
|
{
|
|
var mm = new MultiMesh();
|
|
mm.Mesh = kvp.Value;
|
|
mm.TransformFormat = MultiMesh.TransformFormatEnum.Transform3D;
|
|
|
|
var instance = new MultiMeshInstance3D();
|
|
instance.Multimesh = mm;
|
|
|
|
AddChild(instance);
|
|
multiMeshes[kvp.Key] = instance;
|
|
}
|
|
map = new Layer[ruinSize];
|
|
GenerateWorld();
|
|
GD.Print("World generated");
|
|
BuildMeshesForLayer(0);
|
|
}
|
|
|
|
// 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)
|
|
{
|
|
BuildMeshesForLayer(currentLayer);
|
|
visibleLayer = currentLayer;
|
|
}
|
|
}
|
|
|
|
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 void BuildMeshesForLayer(int layerIndex)
|
|
{
|
|
foreach (MultiMeshInstance3D mm in multiMeshes.Values)
|
|
{
|
|
mm.Multimesh.InstanceCount = 0;
|
|
}
|
|
|
|
Layer layer = map[layerIndex];
|
|
|
|
Dictionary<string, List<Transform3D>> batches = new();
|
|
|
|
for (int x = 0; x < layerSize; x++)
|
|
{
|
|
for (int y = 0; y < layerSize; y++)
|
|
{
|
|
Tile tile = layer.tiles[x, y];
|
|
string key = tile.collapsedMesh;
|
|
|
|
if (!batches.ContainsKey(key))
|
|
batches[key] = new List<Transform3D>();
|
|
|
|
batches[key].Add(new Transform3D(
|
|
Basis.Identity,
|
|
tile.Position
|
|
));
|
|
}
|
|
}
|
|
|
|
foreach (var kvp in batches)
|
|
{
|
|
MultiMesh mm = multiMeshes[kvp.Key].Multimesh;
|
|
List<Placeholder> placeholders = tilePlaceholders[kvp.Key];
|
|
List<Transform3D> list = kvp.Value;
|
|
|
|
mm.InstanceCount = list.Count;
|
|
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
mm.SetInstanceTransform(i, list[i]);
|
|
if (placeholders.Count > 0)
|
|
{
|
|
Node3D decoration;
|
|
|
|
Mesh mesh = decorationMeshes.Values.ToList()[0].Mesh;
|
|
for(int j = 0; j < placeholders.Count; j++)
|
|
{
|
|
foreach (MeshInstance3D meshes in decorationMeshes.Values)
|
|
{
|
|
if (meshes.Name.ToString().ToLower() == placeholders[j].name.ToLower())
|
|
{
|
|
mesh = meshes.Mesh;
|
|
break;
|
|
}
|
|
}
|
|
decoration = new MeshInstance3D();
|
|
(decoration as MeshInstance3D).Mesh = mesh;
|
|
if (placeholders[j].name.ToLower() == "light")
|
|
{
|
|
GD.Print("Adding OmniLight");
|
|
decoration.AddChild(new OmniLight3D()
|
|
{
|
|
OmniAttenuation = 2f,
|
|
LightColor = new Color("#eae7ad"),
|
|
ShadowEnabled = true,
|
|
LightEnergy = 5f,
|
|
LightIndirectEnergy = 1.5f,
|
|
Position = new Vector3(0.5f, 0, 0)
|
|
});
|
|
}
|
|
decoration.Transform = list[i];
|
|
decoration.Position += placeholders[j].pos;
|
|
decoration.Name = placeholders[j].name + j;
|
|
decoration.Rotate(Vector3.Up, Mathf.DegToRad(-90));
|
|
layer.AddChild(decoration);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|