using NewHorizons.Components.SizeControllers; using NewHorizons.Utility; using UnityEngine; using NewHorizons.External.Modules.VariableSize; using Tessellation; using NewHorizons.Utility.OWMLUtilities; namespace NewHorizons.Builder.Body { public static class WaterBuilder { private static MeshGroup _oceanMeshGroup; private static Material[] _oceanLowAltitudeMaterials; private static GameObject _oceanFog; private static GameObject _oceanAmbientLight; private static bool _isInit; internal static void InitPrefabs() { if (_isInit) return; _isInit = true; if (_oceanMeshGroup == null) { _oceanMeshGroup = ScriptableObject.CreateInstance().Rename("Ocean").DontDestroyOnLoad(); var gdVariants = SearchUtilities.Find("Ocean_GD").GetComponent().tessellationMeshGroup.variants; for (int i = 0; i < 16; i++) { var mesh = new Mesh(); mesh.CopyPropertiesFrom(gdVariants[i]); mesh.name = gdVariants[i].name; mesh.DontDestroyOnLoad(); _oceanMeshGroup.variants[i] = mesh; } } if (_oceanLowAltitudeMaterials == null) _oceanLowAltitudeMaterials = SearchUtilities.Find("Ocean_GD").GetComponent()._lowAltitudeMaterials.MakePrefabMaterials(); if (_oceanFog == null) _oceanFog = SearchUtilities.Find("GiantsDeep_Body/Sector_GD/Sector_GDInterior/Effects_GDInterior/OceanFog").InstantiateInactive().Rename("Prefab_GD_OceanFog").DontDestroyOnLoad(); if (_oceanAmbientLight == null) _oceanAmbientLight = SearchUtilities.Find("Ocean_GD").GetComponent()._ambientLight.gameObject.InstantiateInactive().Rename("OceanAmbientLight").DontDestroyOnLoad(); } public static RadialFluidVolume Make(GameObject planetGO, Sector sector, OWRigidbody rb, WaterModule module) { InitPrefabs(); var waterSize = module.size; GameObject waterGO = new GameObject("Water"); waterGO.SetActive(false); waterGO.transform.parent = sector?.transform ?? planetGO.transform; waterGO.transform.localScale = new Vector3(waterSize, waterSize, waterSize); // Don't ignore sun when not under clouds waterGO.layer = 0; Delay.FireOnNextUpdate(() => { if (planetGO.FindChild("Sector/SunOverride") != null) waterGO.layer = 15; }); TessellatedSphereRenderer TSR = waterGO.AddComponent(); TSR.tessellationMeshGroup = ScriptableObject.CreateInstance(); for (int i = 0; i < 16; i++) { var mesh = new Mesh(); mesh.CopyPropertiesFrom(_oceanMeshGroup.variants[i]); TSR.tessellationMeshGroup.variants[i] = mesh; } var GDSharedMaterials = _oceanLowAltitudeMaterials; var tempArray = new Material[GDSharedMaterials.Length]; for (int i = 0; i < GDSharedMaterials.Length; i++) { tempArray[i] = new Material(GDSharedMaterials[i]); if (module.tint != null) { tempArray[i].color = module.tint.ToColor(); tempArray[i].SetColor("_FogColor", module.tint.ToColor()); } } TSR.sharedMaterials = tempArray; // stuff is black without this crap OceanEffectController OEC = waterGO.AddComponent(); OEC._sector = sector; OEC._ocean = TSR; var OLC = waterGO.AddComponent(); OLC._sector = sector; OLC._ambientLight = _oceanAmbientLight.GetComponent(); // this needs to be set or else is black // trigger sector enter Delay.FireOnNextUpdate(() => { OEC._active = true; OEC.enabled = true; OLC.enabled = true; }); //Buoyancy var buoyancyObject = new GameObject("WaterVolume"); buoyancyObject.transform.parent = waterGO.transform; buoyancyObject.transform.localScale = Vector3.one; buoyancyObject.layer = LayerMask.NameToLayer("BasicEffectVolume"); var sphereCollider = buoyancyObject.AddComponent(); sphereCollider.radius = 1; sphereCollider.isTrigger = true; var owCollider = buoyancyObject.AddComponent(); owCollider._parentBody = rb; owCollider._collider = sphereCollider; var buoyancyTriggerVolume = buoyancyObject.AddComponent(); buoyancyTriggerVolume._owCollider = owCollider; var fluidVolume = buoyancyObject.AddComponent(); fluidVolume._fluidType = FluidVolume.Type.WATER; fluidVolume._attachedBody = rb; fluidVolume._triggerVolume = buoyancyTriggerVolume; fluidVolume._radius = waterSize; fluidVolume._buoyancyDensity = module.buoyancy; fluidVolume._density = module.density; fluidVolume._layer = LayerMask.NameToLayer("BasicEffectVolume"); var fogGO = GameObject.Instantiate(_oceanFog, waterGO.transform); fogGO.name = "OceanFog"; fogGO.transform.localPosition = Vector3.zero; fogGO.transform.localScale = Vector3.one; fogGO.SetActive(true); if (module.tint != null) { var adjustedColour = module.tint.ToColor() / 4f; adjustedColour.a *= 4f; fogGO.GetComponent().material.color = adjustedColour; } if (module.curve != null) { var sizeController = waterGO.AddComponent(); sizeController.SetScaleCurve(module.curve); sizeController.oceanFogMaterial = fogGO.GetComponent().material; sizeController.fluidVolume = fluidVolume; sizeController.size = module.size; } else { fogGO.GetComponent().material.SetFloat("_Radius", module.size); fogGO.GetComponent().material.SetFloat("_Radius2", 0); } // TODO: fix ruleset making the sand bubble pop up waterGO.transform.position = planetGO.transform.position; waterGO.SetActive(true); return fluidVolume; } } }