Files
RuinAdventurer/Scripts/Tile.cs
T

136 lines
3.6 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;
Random rand = new Random();
public Vector3 Position;
public Vector2I GridPosition;
public Node3D ContentNode;
public bool containsLight, containsDecoration, containsResource;
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)(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;
SetMeshes(tileMeshes);
}
public void SpawnContent(Dictionary<string, MeshInstance3D> contentMeshes, Transform3D transform, List<Placeholder> placeholders)
{
foreach (Placeholder placeholder in placeholders)
{
if (containsLight && placeholder.name.ToLower() == "light") SpawnLight(contentMeshes["light"], placeholder, transform);
else if (containsResource && placeholder.name.ToLower() == "resource") SpawnResource(contentMeshes["resource"], placeholder, transform);
else if (containsDecoration) SpawnDecorations(contentMeshes, placeholder, transform);
}
}
private void SpawnLight(MeshInstance3D lightMesh, Placeholder placeholder, Transform3D transform)
{
Vector3 forward = (transform.Origin - placeholder.transform.Origin).Normalized();
MeshInstance3D light = new MeshInstance3D
{
Mesh = lightMesh.Mesh,
Position = placeholder.transform.Origin
};
light.AddChild(new OmniLight3D()
{
OmniAttenuation = 2f,
LightColor = new Color("#eae7ad"),
ShadowEnabled = true,
LightEnergy = 5f,
LightIndirectEnergy = 1.5f,
Position = new Vector3(0.5f, 0, 0)
});
ContentNode.AddChild(light);
light.LookAt(light.Position + forward, Vector3.Up);
}
private void SpawnResource(MeshInstance3D resourceMesh, Placeholder placeholder, Transform3D transform)
{
Vector3 forward = (transform.Origin - placeholder.transform.Origin).Normalized();
MeshInstance3D resource = new MeshInstance3D
{
Mesh = resourceMesh.Mesh,
Position = placeholder.transform.Origin
};
ContentNode.AddChild(resource);
resource.LookAt(resource.Position + forward, Vector3.Up);
}
private void SpawnDecorations(Dictionary<string, MeshInstance3D> contentMeshes, Placeholder placeholder, Transform3D transform)
{
foreach (string key in contentMeshes.Keys)
{
if (key.ToLower() != placeholder.name.ToLower()) continue;
MeshInstance3D decoration = new MeshInstance3D
{
Mesh = contentMeshes[key].Mesh,
Position = placeholder.transform.Origin
};
ContentNode.AddChild(decoration);
}
}
}