using Godot; using System; using System.Collections.Generic; using System.Linq; public partial class Tile { public Dictionary tileMeshes; public string collapsedMesh; public Vector3 Position; public Vector2I GridPosition; public Node3D ContentNode; public bool containsLight, containsDecoration, containsResource; public GameResource resource; public bool wasVisited; public void SetMeshes(Dictionary tileMeshes) { this.tileMeshes = new Dictionary(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 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 tileMeshes) { collapsedMesh = null; SetMeshes(tileMeshes); } public void SpawnContent(Dictionary contentMeshes, Transform3D transform, List placeholders) { foreach (Placeholder placeholder in placeholders) { if (containsLight && placeholder.name == "light") SpawnLight(contentMeshes["light"], placeholder, transform); else 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 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 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); decoration.LookAt(transform.Origin, Vector3.Up); } } }