Black hole + white hole pairing

This commit is contained in:
Nick J. Connors 2022-01-02 20:28:22 -05:00
parent d52a21bce4
commit 6759a4af76
10 changed files with 286 additions and 42 deletions

View File

@ -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>();
singularityLOD.SetSector(sector);
/*
var meshRenderer = blackHoleRenderer.GetComponent<MeshRenderer>();
meshRenderer.material.SetFloat("_Radius", module.BlackHoleSize * 0.4f);
var owRenderer = blackHoleRenderer.gameObject.AddComponent<OWRenderer>();
var propID_Radius = Shader.PropertyToID("_Radius");
owRenderer.SetMaterialProperty(propID_Radius, module.BlackHoleSize * 0.4f);
*/
}
}
}

View File

@ -43,11 +43,11 @@ namespace NewHorizons.Builder.Body
var mat = new Material(RingShader); var mat = new Material(RingShader);
mat.mainTexture = texture; mat.mainTexture = texture;
mat.renderQueue = 3000; mat.renderQueue = 2895;
ringMR.material = mat; ringMR.material = mat;
// Make mesh // 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); BuildRingMesh(ringMesh, segments, ring.InnerRadius, ring.OuterRadius);
} }

View File

@ -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<BlackHoleVolume>()._whiteHole = pairedSingularityAO.GetComponentInChildren<WhiteHoleVolume>();
break;
case Polarity.WhiteHole:
pairedSingularityAO.GetComponentInChildren<BlackHoleVolume>()._whiteHole = newSingularity.GetComponentInChildren<WhiteHoleVolume>();
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>();
meshFilter.mesh = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent<MeshFilter>().mesh;
var meshRenderer = blackHoleRender.AddComponent<MeshRenderer>();
if (blackHoleShader == null) blackHoleShader = GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleRenderer").GetComponent<MeshRenderer>().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>();
sphereCollider.radius = size * 0.4f;
sphereCollider.isTrigger = true;
destructionVolumeGO.AddComponent<BlackHoleDestructionVolume>();
}
else
{
var blackHoleVolume = GameObject.Instantiate(GameObject.Find("BrittleHollow_Body/BlackHole_BH/BlackHoleVolume"), blackHole.transform);
blackHoleVolume.name = "BlackHoleVolume";
blackHoleVolume.GetComponent<SphereCollider>().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>();
meshFilter.mesh = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent<MeshFilter>().mesh;
var meshRenderer = whiteHoleRenderer.AddComponent<MeshRenderer>();
if (whiteHoleShader == null) whiteHoleShader = GameObject.Find("WhiteHole_Body/WhiteHoleVisuals/Singularity").GetComponent<MeshRenderer>().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<Light>().range = size * 7f;
var proxyShadow = sector.gameObject.AddComponent<ProxyShadowCasterSuperGroup>();
// 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<SphereCollider>().radius = size;
whiteHoleVolumeGO.name = "WhiteHoleVolume";
var whiteHoleFluidVolume = whiteHoleVolumeGO.GetComponent<WhiteHoleFluidVolume>();
whiteHoleFluidVolume._innerRadius = size * 0.5f;
whiteHoleFluidVolume._outerRadius = size;
whiteHoleFluidVolume._attachedBody = OWRB;
var whiteHoleVolume = whiteHoleVolumeGO.GetComponent<WhiteHoleVolume>();
whiteHoleVolume._debrisDistMax = size * 6.5f;
whiteHoleVolume._debrisDistMin = size * 2f;
whiteHoleVolume._whiteHoleSector = sector;
whiteHoleVolume._fluidVolume = whiteHoleFluidVolume;
whiteHoleVolume._whiteHoleBody = OWRB;
whiteHoleVolume._whiteHoleProxyShadowSuperGroup = proxyShadow;
whiteHoleVolumeGO.GetComponent<SphereCollider>().radius = size;
whiteHoleVolume.enabled = true;
whiteHoleFluidVolume.enabled = true;
var zeroGVolume = GameObject.Instantiate(GameObject.Find("WhiteHole_Body/ZeroGVolume"), whiteHole.transform);
zeroGVolume.name = "ZeroGVolume";
zeroGVolume.GetComponent<SphereCollider>().radius = size * 10f;
zeroGVolume.GetComponent<ZeroGVolume>()._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<SphereShape>().enabled = true;
whiteHole.SetActive(true);
return whiteHole;
}
}
}

View File

@ -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<SurveyorProbe>();
if (requiredComponent.IsLaunched())
{
UnityEngine.Object.Destroy(requiredComponent.gameObject);
}
}
}
}

View File

@ -16,10 +16,12 @@ namespace NewHorizons.External
public float SurfaceSize { get; set; } public float SurfaceSize { get; set; }
public float WaterSize { get; set; } public float WaterSize { get; set; }
public float GroundSize { get; set; } public float GroundSize { get; set; }
public float BlackHoleSize { get; set; }
public float LavaSize { get; set; } public float LavaSize { get; set; }
public bool HasCometTail { get; set; } public bool HasCometTail { get; set; }
public bool HasReferenceFrame { get; set; } = true; public bool HasReferenceFrame { get; set; } = true;
public bool CenterOfSolarSystem { get; set; } = false; public bool CenterOfSolarSystem { get; set; } = false;
// Old, see SingularityModule instead
public float BlackHoleSize { get; set; }
} }
} }

View File

@ -19,5 +19,6 @@ namespace NewHorizons.External
PropModule Props { get; } PropModule Props { get; }
SpawnModule Spawn { get; } SpawnModule Spawn { get; }
SignalModule Signal { get; } SignalModule Signal { get; }
SingularityModule Singularity { get; }
} }
} }

View File

@ -23,6 +23,7 @@ namespace NewHorizons.External
public PropModule Props { get; set; } public PropModule Props { get; set; }
public SpawnModule Spawn { get; set; } public SpawnModule Spawn { get; set; }
public SignalModule Signal { get; set; } public SignalModule Signal { get; set; }
public SingularityModule Singularity { get; set; }
public PlanetConfig(Dictionary<string, object> dict) public PlanetConfig(Dictionary<string, object> dict)
{ {

View File

@ -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
}
}

View File

@ -187,7 +187,7 @@ namespace NewHorizons
existingPlanet = AstroObjectLocator.GetAstroObject(stringID).gameObject; existingPlanet = AstroObjectLocator.GetAstroObject(stringID).gameObject;
if (existingPlanet == null) existingPlanet = AstroObjectLocator.GetAstroObject(body.Config.Name.Replace(" ", "")).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"); existingPlanet = GameObject.Find(body.Config.Name.Replace(" ", "") + "_Body");
} }
@ -319,8 +319,8 @@ namespace NewHorizons
if (body.Config.ProcGen != null) if (body.Config.ProcGen != null)
ProcGenBuilder.Make(go, body.Config.ProcGen); ProcGenBuilder.Make(go, body.Config.ProcGen);
if (body.Config.Base.BlackHoleSize != 0) if (body.Config.Base.BlackHoleSize != 0 || body.Config.Singularity != null)
BlackHoleBuilder.Make(go, body.Config.Base, sector); SingularityBuilder.Make(go, sector, owRigidBody, body.Config);
if (body.Config.Star != null) StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star)); if (body.Config.Star != null) StarLightController.AddStar(StarBuilder.Make(go, sector, body.Config.Star));

View File

@ -43,6 +43,10 @@ namespace NewHorizons.Utility
var playerDataResetGame = typeof(PlayerData).GetMethod("ResetGame"); var playerDataResetGame = typeof(PlayerData).GetMethod("ResetGame");
Main.Instance.ModHelper.HarmonyHelper.AddPostfix(playerDataResetGame, typeof(Patches), nameof(Patches.OnPlayerDataResetGame)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix(playerDataResetGame, typeof(Patches), nameof(Patches.OnPlayerDataResetGame));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<BlackHoleVolume>("Start", typeof(Patches), nameof(Patches.OnBlackHoleVolumeStart));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<WhiteHoleVolume>("Awake", typeof(Patches), nameof(Patches.OnWhiteHoleVolumeAwake));
Main.Instance.ModHelper.HarmonyHelper.AddPrefix<ProbeLauncher>("UpdateOrbitalLaunchValues", typeof(Patches), nameof(Patches.OnProbeLauncherUpdateOrbitalLaunchValues));
// Postfixes // Postfixes
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<MapController>("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix<MapController>("Awake", typeof(Patches), nameof(Patches.OnMapControllerAwake));
Main.Instance.ModHelper.HarmonyHelper.AddPostfix<OWCamera>("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake)); Main.Instance.ModHelper.HarmonyHelper.AddPostfix<OWCamera>("Awake", typeof(Patches), nameof(Patches.OnOWCameraAwake));
@ -306,5 +310,30 @@ namespace NewHorizons.Utility
NewHorizonsData.Reset(); NewHorizonsData.Reset();
} }
#endregion #endregion
public static bool OnBlackHoleVolumeStart(BlackHoleVolume __instance)
{
return __instance._whiteHole == null;
}
public static bool OnWhiteHoleVolumeAwake(WhiteHoleVolume __instance)
{
__instance._growQueue = new List<OWRigidbody>(8);
__instance._growQueueLocationData = new List<RelativeLocationData>(8);
__instance._ejectedBodyList = new List<OWRigidbody>(64);
try
{
__instance._whiteHoleBody = __instance.gameObject.GetAttachedOWRigidbody(false);
__instance._whiteHoleProxyShadowSuperGroup = __instance._whiteHoleBody.GetComponentInChildren<ProxyShadowCasterSuperGroup>();
__instance._fluidVolume = __instance.gameObject.GetRequiredComponent<WhiteHoleFluidVolume>();
}
catch (Exception) { }
return false;
}
public static bool OnProbeLauncherUpdateOrbitalLaunchValues(ProbeLauncher __instance)
{
return (Locator.GetPlayerRulesetDetector()?.GetPlanetoidRuleset()?.GetGravityVolume() != null);
}
} }
} }