139 lines
3.6 KiB
C#
139 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)
|
|
{
|
|
MeshInstance3D light = new MeshInstance3D
|
|
{
|
|
Mesh = lightMesh.Mesh,
|
|
Position = placeholder.transform.Origin
|
|
};
|
|
OmniLight3D lightSource = new OmniLight3D()
|
|
{
|
|
OmniAttenuation = 2f,
|
|
LightColor = GameData.lightColor,
|
|
ShadowEnabled = true,
|
|
LightEnergy = 100f,
|
|
LightIndirectEnergy = 1.5f,
|
|
OmniRange = 20f,
|
|
Position = placeholder.transform.Origin
|
|
};
|
|
lightSource.Position.MoveToward(transform.Origin, 0.1f);
|
|
LightHandler.lights.Add(lightSource);
|
|
light.AddChild(lightSource);
|
|
ContentNode.AddChild(light);
|
|
light.LookAt(transform.Origin, Vector3.Up);
|
|
}
|
|
|
|
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.ToLower()) continue;
|
|
MeshInstance3D decoration = new MeshInstance3D
|
|
{
|
|
Mesh = contentMeshes[key].Mesh,
|
|
Position = placeholder.transform.Origin
|
|
};
|
|
ContentNode.AddChild(decoration);
|
|
decoration.LookAt(transform.Origin, Vector3.Up);
|
|
}
|
|
}
|
|
}
|