126 lines
3.1 KiB
C#
126 lines
3.1 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
public partial class Tile
|
|
{
|
|
public Dictionary<string, MeshInstance3D> tileMeshes;
|
|
public string collapsedMesh;
|
|
public Vector3 Position;
|
|
public Vector2I GridPosition;
|
|
public Node3D ContentNode;
|
|
|
|
public bool containsDecoration, containsResource;
|
|
public GameResource resource;
|
|
public bool wasVisited;
|
|
public event EventHandler OnTileVisited;
|
|
|
|
public void SetMeshes(Dictionary<string, MeshInstance3D> tileMeshes)
|
|
{
|
|
this.tileMeshes = new Dictionary<string, MeshInstance3D>(tileMeshes);
|
|
}
|
|
|
|
public string Collapse(string tile)
|
|
{
|
|
if (collapsedMesh != null) return "";
|
|
if (tileMeshes.Keys.Count <= 0) return "ERR";
|
|
|
|
collapsedMesh = (tile.Length > 0) ? tile : ChooseWeighted();
|
|
tileMeshes.Clear();
|
|
return collapsedMesh;
|
|
}
|
|
|
|
private string ChooseWeighted()
|
|
{
|
|
float totalWeight = 0f;
|
|
|
|
foreach (string tile in tileMeshes.Keys)
|
|
{
|
|
totalWeight += WFC.weights[tile];
|
|
}
|
|
|
|
float r = (float)(GameData.rand.NextDouble() * totalWeight);
|
|
|
|
float cumulative = 0f;
|
|
|
|
foreach (string tile in tileMeshes.Keys)
|
|
{
|
|
cumulative += WFC.weights[tile];
|
|
|
|
if (r <= cumulative)
|
|
return tile;
|
|
}
|
|
|
|
return "junction";
|
|
}
|
|
|
|
public int Propagate(HashSet<string> possibleKeys)
|
|
{
|
|
int amountRemoved = 0;
|
|
if (collapsedMesh != null) return 0;
|
|
foreach (string key in tileMeshes.Keys.ToList())
|
|
{
|
|
if (!possibleKeys.Contains(key))
|
|
{
|
|
tileMeshes.Remove(key);
|
|
amountRemoved++;
|
|
}
|
|
}
|
|
if (tileMeshes.Count == 0) return int.MaxValue;
|
|
return amountRemoved;
|
|
}
|
|
|
|
public void Reset(Dictionary<string, MeshInstance3D> tileMeshes)
|
|
{
|
|
collapsedMesh = null;
|
|
containsDecoration = false;
|
|
containsResource = false;
|
|
resource = null;
|
|
wasVisited = false;
|
|
SetMeshes(tileMeshes);
|
|
}
|
|
|
|
public void SpawnContent(Dictionary<string, MeshInstance3D> contentMeshes, Transform3D transform, List<Placeholder> placeholders)
|
|
{
|
|
foreach (Placeholder placeholder in placeholders)
|
|
{
|
|
if (containsResource && placeholder.name == "resource") SpawnResource(contentMeshes["resource"], placeholder, transform);
|
|
else if (containsDecoration && placeholder.name != "light" && placeholder.name != "resource") SpawnDecorations(contentMeshes, placeholder, transform);
|
|
}
|
|
}
|
|
|
|
private void SpawnResource(MeshInstance3D resourceMesh, Placeholder placeholder, Transform3D transform)
|
|
{
|
|
MeshInstance3D resource = new MeshInstance3D
|
|
{
|
|
Mesh = resourceMesh.Mesh,
|
|
Position = placeholder.transform.Origin
|
|
};
|
|
ContentNode.AddChild(resource);
|
|
resource.LookAt(transform.Origin, Vector3.Up);
|
|
}
|
|
|
|
private void SpawnDecorations(Dictionary<string, MeshInstance3D> contentMeshes, Placeholder placeholder, Transform3D transform)
|
|
{
|
|
foreach (string key in contentMeshes.Keys)
|
|
{
|
|
if (key.ToLower() != placeholder.name) continue;
|
|
|
|
MeshInstance3D decoration = new MeshInstance3D
|
|
{
|
|
Mesh = contentMeshes[key].Mesh,
|
|
Position = placeholder.transform.Origin
|
|
};
|
|
ContentNode.AddChild(decoration);
|
|
}
|
|
}
|
|
|
|
public void VisitTile()
|
|
{
|
|
wasVisited = true;
|
|
OnTileVisited?.Invoke(this, EventArgs.Empty);
|
|
ContentNode.Visible = true;
|
|
}
|
|
}
|