using NewHorizons.Components.EOTE; using NewHorizons.Components.Props; using NewHorizons.External; using NewHorizons.External.Configs; using NewHorizons.Utility; using NewHorizons.Utility.OuterWilds; using NewHorizons.Utility.OWML; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using UnityEngine; namespace NewHorizons.Builder.Body { public static class DreamDimensionBuilder { private static Material gridMaterial; private static Material waterMaterial; private readonly static string[] EXCLUDED_OBJECT_NAMES = { "Prefab_IP_SIM_", "Props_IP_SIM_", "Effects_IP_SIM_", }; private readonly static string[] EXCLUDED_SHADER_NAMES = { "Fog", "Simulation Bubble", "Foliage", "Flame", }; public static void Make(GameObject planetGO, Sector sector, NewHorizonsBody body) { var bodyWantsSimMeshes = body.Config.Dream?.generateSimulationMeshes ?? false; var propsWantSimMeshes = body.Config.Props?.dreamArrivalPoints?.Any(p => p.generateSimulationMeshes) ?? false; if (bodyWantsSimMeshes || propsWantSimMeshes) { MakeDreamSimulationMeshes(sector ? sector.gameObject : planetGO); } if (body.Config?.Dream?.inDreamWorld ?? false) { var dreamDimension = planetGO.AddComponent(); Delay.FireInNUpdates(() => { dreamDimension.Initialize(); }, 4); } } public static void MakeDreamSimulationMeshes(GameObject go) { if (gridMaterial == null) gridMaterial = SearchUtilities.FindResourceOfTypeAndName("Terrain_IP_DreamGrid_mat"); if (waterMaterial == null) waterMaterial = SearchUtilities.FindResourceOfTypeAndName("Terrain_IP_DreamGrid_mat"); foreach (var mr in go.GetComponentsInChildren(true)) { if (mr.GetType() != typeof(MeshRenderer)) continue; var mf = mr.GetComponent(); if (mf == null) continue; if (!CheckMeshCreationHeuristic(mr.gameObject, mr.sharedMaterials)) continue; var simMesh = new GameObject("SimulationMesh").AddComponent(); simMesh.Init(mr.transform, GetMeshMaterial(go, mr.sharedMaterials)); } } private static Material GetMeshMaterial(GameObject go, Material[] materials) { if (materials.Any(m => m.name.Contains("Ocean_Stencil_mat"))) return waterMaterial; return gridMaterial; } private static bool CheckMeshCreationHeuristic(GameObject go, Material[] materials) { if (go.layer == Layer.DreamSimulation) return false; var mr = go.GetComponent(); if (EXCLUDED_SHADER_NAMES.Any(name => materials.Any(mat => mat.shader.name.Contains(name)))) return false; if (go.transform.parent) { foreach (Transform c in go.transform.parent) { if (c && c.gameObject.layer == Layer.DreamSimulation) return false; } if (go.transform.parent.parent) { foreach (Transform c in go.transform.parent.parent) { if (c && c.gameObject.layer == Layer.DreamSimulation) return false; } } } var t = go.transform; while (t != null) { if (EXCLUDED_OBJECT_NAMES.Any(t.name.Contains)) return false; t = t.parent; } return true; } } }