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