From 6759a4af76c89ee5132fad497ef92927916b7dfb Mon Sep 17 00:00:00 2001 From: "Nick J. Connors" Date: Sun, 2 Jan 2022 20:28:22 -0500 Subject: [PATCH] Black hole + white hole pairing --- NewHorizons/Builder/Body/BlackHoleBuilder.cs | 36 ---- NewHorizons/Builder/Body/RingBuilder.cs | 4 +- .../Builder/Body/SingularityBuilder.cs | 203 ++++++++++++++++++ .../Components/BlackHoleDestructionVolume.cs | 29 +++ NewHorizons/External/BaseModule.cs | 4 +- NewHorizons/External/IPlanetConfig.cs | 1 + NewHorizons/External/PlanetConfig.cs | 1 + NewHorizons/External/SingularityModule.cs | 15 ++ NewHorizons/Main.cs | 6 +- NewHorizons/Utility/Patches.cs | 29 +++ 10 files changed, 286 insertions(+), 42 deletions(-) delete mode 100644 NewHorizons/Builder/Body/BlackHoleBuilder.cs create mode 100644 NewHorizons/Builder/Body/SingularityBuilder.cs create mode 100644 NewHorizons/Components/BlackHoleDestructionVolume.cs create mode 100644 NewHorizons/External/SingularityModule.cs diff --git a/NewHorizons/Builder/Body/BlackHoleBuilder.cs b/NewHorizons/Builder/Body/BlackHoleBuilder.cs deleted file mode 100644 index 850651b4..00000000 --- a/NewHorizons/Builder/Body/BlackHoleBuilder.cs +++ /dev/null @@ -1,36 +0,0 @@ -using NewHorizons.External; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UnityEngine; - -namespace NewHorizons.Builder.Body -{ - static class BlackHoleBuilder - { - public static void Make(GameObject body, BaseModule module, Sector sector) - { - var blackHole = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH"), body.transform); - blackHole.name = "BlackHole"; - blackHole.transform.localPosition = Vector3.zero; - //blackHole.transform.localScale = Vector3.one; //* module.BlackHoleSize; - - var blackHoleRenderer = blackHole.transform.Find("BlackHoleRenderer"); - //blackHoleRenderer.transform.localScale = Vector3.one; - - var singularityLOD = blackHoleRenderer.GetComponent(); - singularityLOD.SetSector(sector); - - /* - var meshRenderer = blackHoleRenderer.GetComponent(); - meshRenderer.material.SetFloat("_Radius", module.BlackHoleSize * 0.4f); - - var owRenderer = blackHoleRenderer.gameObject.AddComponent(); - var propID_Radius = Shader.PropertyToID("_Radius"); - owRenderer.SetMaterialProperty(propID_Radius, module.BlackHoleSize * 0.4f); - */ - } - } -} diff --git a/NewHorizons/Builder/Body/RingBuilder.cs b/NewHorizons/Builder/Body/RingBuilder.cs index 03df9906..673dcb42 100644 --- a/NewHorizons/Builder/Body/RingBuilder.cs +++ b/NewHorizons/Builder/Body/RingBuilder.cs @@ -43,11 +43,11 @@ namespace NewHorizons.Builder.Body var mat = new Material(RingShader); mat.mainTexture = texture; - mat.renderQueue = 3000; + mat.renderQueue = 2895; ringMR.material = mat; // Make mesh - var segments = (int)Math.Max(20, ring.OuterRadius); + var segments = (int)Mathf.Clamp(ring.OuterRadius, 20, 20000); BuildRingMesh(ringMesh, segments, ring.InnerRadius, ring.OuterRadius); } diff --git a/NewHorizons/Builder/Body/SingularityBuilder.cs b/NewHorizons/Builder/Body/SingularityBuilder.cs new file mode 100644 index 00000000..58ca2e68 --- /dev/null +++ b/NewHorizons/Builder/Body/SingularityBuilder.cs @@ -0,0 +1,203 @@ +using NewHorizons.Components; +using NewHorizons.External; +using NewHorizons.Utility; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UnityEngine; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Builder.Body +{ + static class SingularityBuilder + { + enum Polarity + { + BlackHole, + WhiteHole + } + + private static Shader blackHoleShader = null; + private static Shader whiteHoleShader = null; + + public static void Make(GameObject body, Sector sector, OWRigidbody OWRB, IPlanetConfig config) + { + + var size = config.Base.BlackHoleSize; + string pairedSingularity = null; + var polarity = Polarity.BlackHole; + + if (config.Singularity != null) + { + size = config.Singularity.Size; + pairedSingularity = config.Singularity.PairedSingularity; + if(config.Singularity.Type != null && config.Singularity.Type.ToUpper().Equals("WHITEHOLE")) + { + polarity = Polarity.WhiteHole; + } + } + bool hasHazardVolume = pairedSingularity == null; + + GameObject newSingularity = null; + switch (polarity) + { + case Polarity.BlackHole: + newSingularity = MakeBlackHole(body, sector, size, hasHazardVolume); + break; + case Polarity.WhiteHole: + newSingularity = MakeWhiteHole(body, sector, OWRB, size); + break; + } + + // Try to pair them + if(pairedSingularity != null && newSingularity != null) + { + var pairedSingularityAO = AstroObjectLocator.GetAstroObject(pairedSingularity); + if(pairedSingularityAO != null) + { + Logger.Log($"Pairing singularities {pairedSingularity}, {config.Name}"); + try + { + switch (polarity) + { + case Polarity.BlackHole: + newSingularity.GetComponentInChildren()._whiteHole = pairedSingularityAO.GetComponentInChildren(); + break; + case Polarity.WhiteHole: + pairedSingularityAO.GetComponentInChildren()._whiteHole = newSingularity.GetComponentInChildren(); + break; + } + } + catch(Exception) + { + Logger.LogError($"Couldn't pair singularities {pairedSingularity}, {config.Name}"); + } + } + } + } + + private static GameObject MakeBlackHole(GameObject body, Sector sector, float size, bool hasDestructionVolume) + { + var blackHole = new GameObject("BlackHole"); + blackHole.SetActive(false); + blackHole.transform.parent = body.transform; + blackHole.transform.localPosition = Vector3.zero; + + var blackHoleRender = new GameObject("BlackHoleRender"); + blackHoleRender.transform.parent = blackHole.transform; + blackHoleRender.transform.localPosition = Vector3.zero; + blackHoleRender.transform.localScale = Vector3.one * size; + + var meshFilter = blackHoleRender.AddComponent(); + meshFilter.mesh = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent().mesh; + + var meshRenderer = blackHoleRender.AddComponent(); + if (blackHoleShader == null) blackHoleShader = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent().sharedMaterial.shader; + meshRenderer.material = new Material(blackHoleShader); + meshRenderer.material.SetFloat("_Radius", size * 0.4f); + meshRenderer.material.SetFloat("_MaxDistortRadius", size * 0.95f); + meshRenderer.material.SetFloat("_MassScale", 1); + meshRenderer.material.SetFloat("_DistortFadeDist", size * 0.55f); + + if(hasDestructionVolume) + { + var destructionVolumeGO = new GameObject("DestructionVolume"); + destructionVolumeGO.layer = LayerMask.NameToLayer("BasicEffectVolume"); + destructionVolumeGO.transform.parent = blackHole.transform; + destructionVolumeGO.transform.localScale = Vector3.one; + destructionVolumeGO.transform.localPosition = Vector3.zero; + + var sphereCollider = destructionVolumeGO.AddComponent(); + sphereCollider.radius = size * 0.4f; + sphereCollider.isTrigger = true; + + destructionVolumeGO.AddComponent(); + } + else + { + var blackHoleVolume = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleVolume"), blackHole.transform); + blackHoleVolume.name = "BlackHoleVolume"; + blackHoleVolume.GetComponent().radius = size * 0.4f; + } + + blackHole.SetActive(true); + return blackHole; + } + + private static GameObject MakeWhiteHole(GameObject body, Sector sector, OWRigidbody OWRB, float size) + { + var whiteHole = new GameObject("WhiteHole"); + whiteHole.SetActive(false); + whiteHole.transform.parent = body.transform; + whiteHole.transform.localPosition = Vector3.zero; + + var whiteHoleRenderer = new GameObject("WhiteHoleRenderer"); + whiteHoleRenderer.transform.parent = whiteHole.transform; + whiteHoleRenderer.transform.localPosition = Vector3.zero; + whiteHoleRenderer.transform.localScale = Vector3.one * size * 2.8f; + + var meshFilter = whiteHoleRenderer.AddComponent(); + meshFilter.mesh = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent().mesh; + + var meshRenderer = whiteHoleRenderer.AddComponent(); + if (whiteHoleShader == null) whiteHoleShader = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent().sharedMaterial.shader; + meshRenderer.material = new Material(whiteHoleShader); + meshRenderer.sharedMaterial.SetFloat("_Radius", size * 0.4f); + meshRenderer.sharedMaterial.SetFloat("_DistortFadeDist", size); + meshRenderer.sharedMaterial.SetFloat("_MaxDistortRadius", size * 2.8f); + meshRenderer.sharedMaterial.SetColor("_Color", new Color(1.88f, 1.88f, 1.88f, 1f)); + + var ambientLight = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/AmbientLight_WH")); + ambientLight.transform.parent = whiteHole.transform; + ambientLight.transform.localScale = Vector3.one; + ambientLight.transform.localPosition = Vector3.zero; + ambientLight.name = "AmbientLight"; + ambientLight.GetComponent().range = size * 7f; + + var proxyShadow = sector.gameObject.AddComponent(); + + // it's going to complain + GameObject whiteHoleVolumeGO = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/WhiteHoleVolume")); + + whiteHoleVolumeGO.transform.parent = whiteHole.transform; + whiteHoleVolumeGO.transform.localPosition = Vector3.zero; + whiteHoleVolumeGO.transform.localScale = Vector3.one; + whiteHoleVolumeGO.GetComponent().radius = size; + whiteHoleVolumeGO.name = "WhiteHoleVolume"; + + var whiteHoleFluidVolume = whiteHoleVolumeGO.GetComponent(); + whiteHoleFluidVolume._innerRadius = size * 0.5f; + whiteHoleFluidVolume._outerRadius = size; + whiteHoleFluidVolume._attachedBody = OWRB; + + var whiteHoleVolume = whiteHoleVolumeGO.GetComponent(); + whiteHoleVolume._debrisDistMax = size * 6.5f; + whiteHoleVolume._debrisDistMin = size * 2f; + whiteHoleVolume._whiteHoleSector = sector; + whiteHoleVolume._fluidVolume = whiteHoleFluidVolume; + whiteHoleVolume._whiteHoleBody = OWRB; + whiteHoleVolume._whiteHoleProxyShadowSuperGroup = proxyShadow; + + whiteHoleVolumeGO.GetComponent().radius = size; + + whiteHoleVolume.enabled = true; + whiteHoleFluidVolume.enabled = true; + + var zeroGVolume = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/ZeroGVolume"), whiteHole.transform); + zeroGVolume.name = "ZeroGVolume"; + zeroGVolume.GetComponent().radius = size * 10f; + zeroGVolume.GetComponent()._attachedBody = OWRB; + + var rulesetVolume = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/Sector_WhiteHole/RulesetVolumes_WhiteHole"), sector.transform); + rulesetVolume.name = "RulesetVolume"; + rulesetVolume.transform.localPosition = Vector3.zero; + rulesetVolume.transform.localScale = Vector3.one * size / 100f; + rulesetVolume.GetComponent().enabled = true; + + whiteHole.SetActive(true); + return whiteHole; + } + } +} diff --git a/NewHorizons/Components/BlackHoleDestructionVolume.cs b/NewHorizons/Components/BlackHoleDestructionVolume.cs new file mode 100644 index 00000000..23663f89 --- /dev/null +++ b/NewHorizons/Components/BlackHoleDestructionVolume.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Logger = NewHorizons.Utility.Logger; + +namespace NewHorizons.Components +{ + public class BlackHoleDestructionVolume : DestructionVolume + { + public override void Awake() + { + base.Awake(); + _deathType = DeathType.BlackHole; + } + + public override void VanishProbe(OWRigidbody probeBody, RelativeLocationData entryLocation) + { + Logger.Log($"Uh oh you shot your probe into a black hole"); + SurveyorProbe requiredComponent = probeBody.GetRequiredComponent(); + if (requiredComponent.IsLaunched()) + { + UnityEngine.Object.Destroy(requiredComponent.gameObject); + } + } + } +} + diff --git a/NewHorizons/External/BaseModule.cs b/NewHorizons/External/BaseModule.cs index 8acbbd84..1ae8c966 100644 --- a/NewHorizons/External/BaseModule.cs +++ b/NewHorizons/External/BaseModule.cs @@ -16,10 +16,12 @@ namespace NewHorizons.External public float SurfaceSize { get; set; } public float WaterSize { get; set; } public float GroundSize { get; set; } - public float BlackHoleSize { get; set; } public float LavaSize { get; set; } public bool HasCometTail { get; set; } public bool HasReferenceFrame { get; set; } = true; public bool CenterOfSolarSystem { get; set; } = false; + + // Old, see SingularityModule instead + public float BlackHoleSize { get; set; } } } diff --git a/NewHorizons/External/IPlanetConfig.cs b/NewHorizons/External/IPlanetConfig.cs index 5f726a2a..98e0686e 100644 --- a/NewHorizons/External/IPlanetConfig.cs +++ b/NewHorizons/External/IPlanetConfig.cs @@ -19,5 +19,6 @@ namespace NewHorizons.External PropModule Props { get; } SpawnModule Spawn { get; } SignalModule Signal { get; } + SingularityModule Singularity { get; } } } diff --git a/NewHorizons/External/PlanetConfig.cs b/NewHorizons/External/PlanetConfig.cs index 1cefbd2f..80e9db8a 100644 --- a/NewHorizons/External/PlanetConfig.cs +++ b/NewHorizons/External/PlanetConfig.cs @@ -23,6 +23,7 @@ namespace NewHorizons.External public PropModule Props { get; set; } public SpawnModule Spawn { get; set; } public SignalModule Signal { get; set; } + public SingularityModule Singularity { get; set; } public PlanetConfig(Dictionary dict) { diff --git a/NewHorizons/External/SingularityModule.cs b/NewHorizons/External/SingularityModule.cs new file mode 100644 index 00000000..6d30d96c --- /dev/null +++ b/NewHorizons/External/SingularityModule.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NewHorizons.External +{ + public class SingularityModule : Module + { + public float Size; + public string PairedSingularity; + public string Type; //BlackHole or WhiteHole + } +} diff --git a/NewHorizons/Main.cs b/NewHorizons/Main.cs index f4109066..c0a234c2 100644 --- a/NewHorizons/Main.cs +++ b/NewHorizons/Main.cs @@ -187,7 +187,7 @@ namespace NewHorizons existingPlanet = AstroObjectLocator.GetAstroObject(stringID).gameObject; if (existingPlanet == null) existingPlanet = AstroObjectLocator.GetAstroObject(body.Config.Name.Replace(" ", "")).gameObject; } - catch (Exception e) + catch (Exception) { existingPlanet = GameObject.Find(body.Config.Name.Replace(" ", "") + "_Body"); } @@ -319,8 +319,8 @@ namespace NewHorizons if (body.Config.ProcGen != null) ProcGenBuilder.Make(go, body.Config.ProcGen); - if (body.Config.Base.BlackHoleSize != 0) - BlackHoleBuilder.Make(go, body.Config.Base, sector); + if (body.Config.Base.BlackHoleSize != 0 || body.Config.Singularity != null) + SingularityBuilder.Make(go, sector, owRigidBody, body.Config); if (body.Config.Star != null) StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star)); diff --git a/NewHorizons/Utility/Patches.cs b/NewHorizons/Utility/Patches.cs index 8742b1be..d7f6b01a 100644 --- a/NewHorizons/Utility/Patches.cs +++ b/NewHorizons/Utility/Patches.cs @@ -43,6 +43,10 @@ namespace NewHorizons.Utility var playerDataResetGame = typeof(PlayerData).GetMethod("ResetGame"); Main.Instance.ModHelper.HarmonyHelper.AddPostfix(playerDataResetGame, typeof(Patches), nameof(Patches.OnPlayerDataResetGame)); + Main.Instance.ModHelper.HarmonyHelper.AddPrefix("Start", typeof(Patches), nameof(Patches.OnBlackHoleVolumeStart)); + Main.Instance.ModHelper.HarmonyHelper.AddPrefix("Awake", typeof(Patches), nameof(Patches.OnWhiteHoleVolumeAwake)); + Main.Instance.ModHelper.HarmonyHelper.AddPrefix("UpdateOrbitalLaunchValues", typeof(Patches), nameof(Patches.OnProbeLauncherUpdateOrbitalLaunchValues)); + // Postfixes Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake)); @@ -306,5 +310,30 @@ namespace NewHorizons.Utility NewHorizonsData.Reset(); } #endregion + + public static bool OnBlackHoleVolumeStart(BlackHoleVolume __instance) + { + return __instance._whiteHole == null; + } + + public static bool OnWhiteHoleVolumeAwake(WhiteHoleVolume __instance) + { + __instance._growQueue = new List(8); + __instance._growQueueLocationData = new List(8); + __instance._ejectedBodyList = new List(64); + try + { + __instance._whiteHoleBody = __instance.gameObject.GetAttachedOWRigidbody(false); + __instance._whiteHoleProxyShadowSuperGroup = __instance._whiteHoleBody.GetComponentInChildren(); + __instance._fluidVolume = __instance.gameObject.GetRequiredComponent(); + } + catch (Exception) { } + return false; + } + + public static bool OnProbeLauncherUpdateOrbitalLaunchValues(ProbeLauncher __instance) + { + return (Locator.GetPlayerRulesetDetector()?.GetPlanetoidRuleset()?.GetGravityVolume() != null); + } } }