Decompiled source of mooooooon v1.0.2

DSPNestedMoons.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("DSPNestedMoons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+b0b99c7e92e155b9e8c3ceb71cd5ca2263c6c778")]
[assembly: AssemblyProduct("DSPNestedMoons")]
[assembly: AssemblyTitle("DSPNestedMoons")]
[assembly: AssemblyVersion("1.0.2.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace DSPNestedMoons
{
	internal sealed class BodyLayout
	{
		internal int BodyIndex { get; }

		internal bool IsGas { get; }

		internal int ParentIndex { get; set; }

		internal int Depth { get; set; }

		internal int OrbitIndex { get; set; }

		internal int SiblingNumber { get; set; }

		internal List<int> Children { get; }

		internal BodyLayout(int bodyIndex, bool isGas)
		{
			BodyIndex = bodyIndex;
			IsGas = isGas;
			ParentIndex = -1;
			Children = new List<int>();
		}
	}
	internal static class NestedMoonLayoutGenerator
	{
		private sealed class LayoutRandom
		{
			private uint state;

			internal LayoutRandom(int seed)
			{
				state = (uint)(seed ^ -1640531527);
				if (state == 0)
				{
					state = 1831565813u;
				}
			}

			internal double NextDouble()
			{
				uint num = state;
				num ^= num << 13;
				num ^= num >> 17;
				return (double)(state = num ^ (num << 5)) / 4294967296.0;
			}
		}

		internal const double BaseMoonChance = 0.6;

		internal static BodyLayout[] Generate(IReadOnlyList<bool> gasFlags, int seed)
		{
			LayoutRandom layoutRandom = new LayoutRandom(seed);
			return Generate(gasFlags, layoutRandom.NextDouble);
		}

		internal static BodyLayout[] Generate(IReadOnlyList<bool> gasFlags, Func<double> nextDouble)
		{
			if (gasFlags == null)
			{
				throw new ArgumentNullException("gasFlags");
			}
			if (nextDouble == null)
			{
				throw new ArgumentNullException("nextDouble");
			}
			BodyLayout[] array = new BodyLayout[gasFlags.Count];
			int cursor = 0;
			while (cursor < array.Length)
			{
				AddChildrenDepthFirst(CreateBody(array, gasFlags, cursor++, -1, 0), array, gasFlags, ref cursor, nextDouble);
			}
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].ParentIndex < 0)
				{
					AssignSatelliteOrbits(array[i], array);
				}
			}
			return array;
		}

		internal static double GetHostChance(int hostDepth)
		{
			if (hostDepth < 0)
			{
				throw new ArgumentOutOfRangeException("hostDepth");
			}
			return Math.Pow(0.6, hostDepth + 1);
		}

		internal static float GetRadiusForDepth(int depth, float originalRadius)
		{
			if (depth == 3)
			{
				return 160f;
			}
			if (depth >= 4)
			{
				return 80f;
			}
			return originalRadius;
		}

		private static BodyLayout CreateBody(BodyLayout[] layouts, IReadOnlyList<bool> gasFlags, int bodyIndex, int parentIndex, int depth)
		{
			BodyLayout result = (layouts[bodyIndex] = new BodyLayout(bodyIndex, gasFlags[bodyIndex])
			{
				ParentIndex = parentIndex,
				Depth = depth
			});
			if (parentIndex >= 0)
			{
				layouts[parentIndex].Children.Add(bodyIndex);
			}
			return result;
		}

		private static void AddChildrenDepthFirst(BodyLayout parent, BodyLayout[] layouts, IReadOnlyList<bool> gasFlags, ref int cursor, Func<double> nextDouble)
		{
			double hostChance = GetHostChance(parent.Depth);
			while (cursor < layouts.Length && nextDouble() < hostChance)
			{
				AddChildrenDepthFirst(CreateBody(layouts, gasFlags, cursor++, parent.BodyIndex, parent.Depth + 1), layouts, gasFlags, ref cursor, nextDouble);
			}
		}

		private static void AssignSatelliteOrbits(BodyLayout host, BodyLayout[] layouts)
		{
			int num = 0;
			for (int i = 0; i < host.Children.Count; i++)
			{
				BodyLayout bodyLayout = layouts[host.Children[i]];
				int num2 = (bodyLayout.IsGas ? 3 : ((bodyLayout.Children.Count > 0) ? 1 : 0));
				bodyLayout.SiblingNumber = i + 1;
				bodyLayout.OrbitIndex = i + 1 + num + num2;
				num += num2 * 2;
				AssignSatelliteOrbits(bodyLayout, layouts);
			}
		}
	}
	[BepInPlugin("Zincon.DSPNestedMoons", "mooooooon", "1.0.2")]
	[BepInProcess("DSPGAME.exe")]
	[BepInDependency("Zincon.DSPAddPlanetMoon2Patch", "3.0.15")]
	[BepInIncompatibility("dsp.galactic-scale.2")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static class DspAddPlanetCompatibility
		{
			private static object pluginInstance;

			private static FieldInfo orderedPoseUpdateField;

			internal static void Initialize()
			{
				Type type = AccessTools.TypeByName("DSPAddPlanet.Plugin");
				if (type == null)
				{
					throw new TypeLoadException("DSPAddPlanet.Plugin was not found. mooooooon requires Zincon.DSPAddPlanetMoon2Patch 3.0.15 or newer.");
				}
				PropertyInfo propertyInfo = AccessTools.Property(type, "Instance");
				orderedPoseUpdateField = AccessTools.Field(type, "needsOrderedPoseUpdate");
				pluginInstance = propertyInfo?.GetValue(null, null);
				if (pluginInstance == null || orderedPoseUpdateField == null || orderedPoseUpdateField.FieldType != typeof(bool))
				{
					throw new MissingMemberException("The installed DSPAddPlanet recursive-pose compatibility contract has changed.");
				}
			}

			internal static void RequireOrderedPoseUpdates()
			{
				orderedPoseUpdateField.SetValue(pluginInstance, true);
			}
		}

		public const string PluginGuid = "Zincon.DSPNestedMoons";

		public const string PluginName = "mooooooon";

		public const string PluginVersion = "1.0.2";

		public const string DspAddPlanetGuid = "Zincon.DSPAddPlanetMoon2Patch";

		public const string DspAddPlanetMinimumVersion = "3.0.15";

		private Harmony harmony;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			try
			{
				StarGenerationPatch.ValidateTarget();
				DspAddPlanetCompatibility.Initialize();
				harmony = new Harmony("Zincon.DSPNestedMoons");
				harmony.PatchAll(typeof(StarGenerationPatch));
				((BaseUnityPlugin)this).Logger.LogInfo((object)"mooooooon 1.0.2 loaded. Natural recursive moon generation is enabled for new universes.");
			}
			catch (Exception arg)
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
				harmony = null;
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to enable recursive moon generation:\n{arg}");
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			harmony = null;
		}
	}
	[HarmonyPatch(typeof(StarGen), "CreateStarPlanets")]
	internal static class StarGenerationPatch
	{
		private readonly struct OrbitAnchor
		{
			internal int OrbitIndex { get; }

			internal float OrbitRadius { get; }

			internal OrbitAnchor(int orbitIndex, float orbitRadius)
			{
				OrbitIndex = orbitIndex;
				OrbitRadius = orbitRadius;
			}
		}

		private const double StarGravity = 1.3538551990520382E-06;

		private const double SatelliteGravity = 1.0830842106853677E-08;

		private const double FourPiSquared = 39.47841760435743;

		internal static void ValidateTarget()
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(StarGen), "CreateStarPlanets", new Type[3]
			{
				typeof(GalaxyData),
				typeof(StarData),
				typeof(GameDesc)
			}, (Type[])null);
			if (methodInfo == null || methodInfo.ReturnType != typeof(void) || !methodInfo.IsStatic)
			{
				throw new MissingMethodException("StarGen.CreateStarPlanets(GalaxyData, StarData, GameDesc) has changed.");
			}
		}

		[HarmonyPostfix]
		[HarmonyPriority(800)]
		[HarmonyBefore(new string[] { "Zincon.DSPAddPlanetMoon2Patch" })]
		private static void CreateStarPlanetsPostfix(GalaxyData galaxy, StarData star)
		{
			if (galaxy != null && star?.planets != null && star.planets.Length >= 2)
			{
				ApplyNaturalLayout(galaxy, star);
				Plugin.DspAddPlanetCompatibility.RequireOrderedPoseUpdates();
			}
		}

		private static void ApplyNaturalLayout(GalaxyData galaxy, StarData star)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			PlanetData[] planets = star.planets;
			bool[] array = new bool[planets.Length];
			List<OrbitAnchor> list = new List<OrbitAnchor>();
			for (int i = 0; i < planets.Length; i++)
			{
				PlanetData val = planets[i];
				if (val == null)
				{
					throw new InvalidOperationException($"Star {star.id} contains an empty body slot at index {i}.");
				}
				array[i] = (int)val.type == 5;
				if (val.orbitAroundPlanet == null)
				{
					list.Add(new OrbitAnchor(val.orbitIndex, val.orbitRadius));
				}
			}
			int seed = (star.seed * 397) ^ (star.id * 7919) ^ 0x4D6F6F6E;
			BodyLayout[] array2 = NestedMoonLayoutGenerator.Generate(array, seed);
			int num = 0;
			int num2 = 0;
			int val2 = 0;
			for (int j = 0; j < array2.Length; j++)
			{
				BodyLayout bodyLayout = array2[j];
				PlanetData val3 = planets[j];
				val2 = Math.Max(val2, bodyLayout.Depth);
				if (bodyLayout.ParentIndex < 0)
				{
					OrbitAnchor orbitAnchor = ((num < list.Count) ? list[num] : CreateAdditionalRootAnchor(star, num2 + 1));
					val3.orbitAroundPlanet = null;
					val3.orbitAround = 0;
					val3.orbitIndex = orbitAnchor.OrbitIndex;
					val3.number = num + 1;
					val3.orbitRadius = orbitAnchor.OrbitRadius;
					val3.sunDistance = val3.orbitRadius;
					val3.orbitalPeriod = CalculateOrbitPeriod(val3.orbitRadius, 1.3538551990520382E-06 * (double)star.mass);
					num2 = val3.orbitIndex;
					num++;
				}
				else
				{
					PlanetData val4 = (val3.orbitAroundPlanet = planets[bodyLayout.ParentIndex]);
					val3.orbitAround = val4.number;
					val3.orbitIndex = bodyLayout.OrbitIndex;
					val3.number = bodyLayout.SiblingNumber;
					val3.orbitRadius = CalculateSatelliteOrbitRadius(star, val4, val3);
					val3.sunDistance = GetRootOrbitRadius(val4);
					val3.orbitalPeriod = CalculateOrbitPeriod(val3.orbitRadius, 1.0830842106853677E-08);
				}
				ApplyDepthRadius(galaxy, val3, bodyLayout.Depth);
				UpdateRuntimeRotations(val3);
				UpdateLuminosity(val3);
				val3.singularity = (EPlanetSingularity)(val3.singularity & -33);
			}
			for (int k = 0; k < array2.Length; k++)
			{
				if (array2[k].Children.Count > 0)
				{
					PlanetData obj = planets[k];
					obj.singularity = (EPlanetSingularity)(obj.singularity | 0x20);
				}
			}
			Plugin.DspAddPlanetCompatibility.RequireOrderedPoseUpdates();
		}

		private static OrbitAnchor CreateAdditionalRootAnchor(StarData star, int requestedIndex)
		{
			int num = Math.Max(1, requestedIndex);
			float orbitRadius;
			if (num < StarGen.orbitRadius.Length)
			{
				orbitRadius = StarGen.orbitRadius[num] * star.orbitScaler;
			}
			else
			{
				int num2 = StarGen.orbitRadius.Length - 1;
				float num3 = StarGen.orbitRadius[num2] - StarGen.orbitRadius[num2 - 1];
				orbitRadius = (StarGen.orbitRadius[num2] + num3 * (float)(num - num2)) * star.orbitScaler;
			}
			return new OrbitAnchor(num, orbitRadius);
		}

		private static float CalculateSatelliteOrbitRadius(StarData star, PlanetData parent, PlanetData satellite)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			DotNet35Random val = new DotNet35Random(satellite.infoSeed);
			double num = val.NextDouble();
			double num2 = val.NextDouble();
			float num3 = Mathf.Pow(1.2f, (float)(num * (num2 - 0.5) * 0.5));
			return ((1600f * (float)satellite.orbitIndex + 200f) * Mathf.Pow(star.orbitScaler, 0.3f) * Mathf.Lerp(num3, 1f, 0.5f) + parent.realRadius) / 40000f;
		}

		private static double CalculateOrbitPeriod(float orbitRadius, double gravity)
		{
			double num = orbitRadius;
			return Math.Sqrt(39.47841760435743 * num * num * num / gravity);
		}

		private static float GetRootOrbitRadius(PlanetData body)
		{
			PlanetData val = body;
			while (val.orbitAroundPlanet != null)
			{
				val = val.orbitAroundPlanet;
			}
			return val.orbitRadius;
		}

		private static void ApplyDepthRadius(GalaxyData galaxy, PlanetData body, int depth)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			float radiusForDepth = NestedMoonLayoutGenerator.GetRadiusForDepth(depth, body.radius);
			if (!(Math.Abs(radiusForDepth - body.radius) < 0.01f))
			{
				body.radius = radiusForDepth;
				if ((int)body.type != 5)
				{
					body.scale = 1f;
					body.precision = 200;
					body.segment = 5;
				}
				if (body.id >= 0 && body.id < galaxy.astrosData.Length)
				{
					galaxy.astrosData[body.id].uRadius = body.realRadius;
				}
			}
		}

		private static void UpdateRuntimeRotations(PlanetData body)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.AngleAxis(body.orbitLongitude, Vector3.up) * Quaternion.AngleAxis(body.orbitInclination, Vector3.forward);
			body.runtimeOrbitRotation = ((body.orbitAroundPlanet == null) ? val : (body.orbitAroundPlanet.runtimeOrbitRotation * val));
			body.runtimeSystemRotation = body.runtimeOrbitRotation * Quaternion.AngleAxis(body.obliquity, Vector3.forward);
		}

		private static void UpdateLuminosity(PlanetData body)
		{
			body.luminosity = Mathf.Pow(body.star.lightBalanceRadius / (body.sunDistance + 0.01f), 0.6f);
			if (body.luminosity > 1f)
			{
				body.luminosity = Mathf.Log(body.luminosity) + 1f;
				body.luminosity = Mathf.Log(body.luminosity) + 1f;
				body.luminosity = Mathf.Log(body.luminosity) + 1f;
			}
			body.luminosity = Mathf.Round(body.luminosity * 100f) / 100f;
		}
	}
}