Decompiled source of MaxDensityUnlock v1.1.0

MaxDensityUnlock.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MaxDensityUnlock")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Raises the Dark Fog Max Density limit above 3x")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+1db0338fe956af0b6d3c90a21d1b7013d21187f0")]
[assembly: AssemblyProduct("Max Density Unlock")]
[assembly: AssemblyTitle("MaxDensityUnlock")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MaxDensityUnlock
{
	[BepInPlugin("MaxDensityUnlock", "Max Density Unlock", "1.1.0")]
	[BepInProcess("DSPGAME.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string GalacticScaleGuid = "dsp.galactic-scale.2";

		private const int HiveSlotsPerStar = 8;

		private const float MinDensity = 1f;

		private const float NoInitialColonizeThreshold = 0.015f;

		internal static ManualLogSource Logger;

		private static ConfigEntry<float> maxDensityLimit;

		private static ConfigEntry<float> densityStep;

		private static ConfigEntry<bool> fillStartingSystem;

		private static int displayUpdateDepth;

		private static int NotchCount => Mathf.Max(0, Mathf.CeilToInt((maxDensityLimit.Value - 1f) / densityStep.Value - 0.001f));

		private void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			maxDensityLimit = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxDensityLimit", 8f, new ConfigDescription("Highest Dark Fog Max Density (x multiplier) selectable on the new-game combat settings slider. Vanilla max is 3. A star holds at most 8 hives (engine limit), so above ~8 extra density only raises relay counts and the difficulty rating.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), Array.Empty<object>()));
			densityStep = ((BaseUnityPlugin)this).Config.Bind<float>("General", "DensityStep", 0.5f, new ConfigDescription("Max Density added per slider notch (x multiplier). Vanilla is 0.5.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 10f), Array.Empty<object>()));
			fillStartingSystem = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FillStartingSystem", true, "true: a new game's starting star system begins with as many Dark Fog hives as Max Density allows (e.g. 8x -> 8 hives, capped at 8). false: vanilla, about 60% x Initial Occupied of that. Either way, Initial Occupied at its minimum still means no starting hives.");
			Harmony harmony = Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
			if (Chainloader.PluginInfos.ContainsKey("dsp.galactic-scale.2"))
			{
				PatchGalacticScale(harmony);
			}
			Logger.LogInfo((object)$"Max Density slider: {1f}x-{maxDensityLimit.Value}x, step {densityStep.Value}x, {NotchCount + 1} notches; fill starting system: {fillStartingSystem.Value}");
		}

		private static float DensityAt(int notch)
		{
			return Mathf.Min(1f + (float)notch * densityStep.Value, maxDensityLimit.Value);
		}

		private static int NotchOf(float density)
		{
			return Mathf.Clamp(Mathf.RoundToInt((density - 1f) / densityStep.Value), 0, NotchCount);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UICombatSettingsDF), "_OnOpen")]
		private static void WidenSlider(UICombatSettingsDF __instance)
		{
			__instance.maxDensitySlider.wholeNumbers = true;
			__instance.maxDensitySlider.maxValue = NotchCount;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UICombatSettingsDF), "OnMaxDensitySliderChanged")]
		private static bool OnMaxDensitySliderChanged(UICombatSettingsDF __instance)
		{
			if (displayUpdateDepth == 0)
			{
				__instance.combatSettings.maxDensity = DensityAt(Mathf.RoundToInt(__instance.maxDensitySlider.value));
				__instance.UpdateUIParametersDisplay();
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(UICombatSettingsDF), "UpdateUIParametersDisplay")]
		private static void EnterDisplayUpdate()
		{
			displayUpdateDepth++;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(UICombatSettingsDF), "UpdateUIParametersDisplay")]
		private static void FixSliderPosition(UICombatSettingsDF __instance)
		{
			__instance.maxDensitySlider.SetValueWithoutNotify((float)NotchOf(__instance.combatSettings.maxDensity));
		}

		[HarmonyFinalizer]
		[HarmonyPatch(typeof(UICombatSettingsDF), "UpdateUIParametersDisplay")]
		private static void ExitDisplayUpdate()
		{
			displayUpdateDepth--;
		}

		private static IEnumerable<CodeInstruction> CapMaxHiveCount(IEnumerable<CodeInstruction> code, string method)
		{
			FieldInfo field = AccessTools.Field(typeof(StarData), "maxHiveCount");
			MethodInfo min = AccessTools.Method(typeof(Math), "Min", new Type[2]
			{
				typeof(int),
				typeof(int)
			}, (Type[])null);
			int patched = 0;
			foreach (CodeInstruction ci in code)
			{
				if (CodeInstructionExtensions.StoresField(ci, field))
				{
					yield return new CodeInstruction(OpCodes.Ldc_I4, (object)8);
					yield return new CodeInstruction(OpCodes.Call, (object)min);
					patched++;
				}
				yield return ci;
			}
			if (patched == 0)
			{
				Logger.LogError((object)(method + ": maxHiveCount assignment not found, hive cap NOT applied (game update?)"));
			}
			else
			{
				Logger.LogInfo((object)$"{method}: capped {patched} maxHiveCount assignment(s) at {8}");
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(StarGen), "CreateStar")]
		private static IEnumerable<CodeInstruction> CapCreateStar(IEnumerable<CodeInstruction> code)
		{
			return CapMaxHiveCount(code, "CreateStar");
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(StarGen), "CreateBirthStar")]
		private static IEnumerable<CodeInstruction> CapCreateBirthStar(IEnumerable<CodeInstruction> code)
		{
			return CapMaxHiveCount(code, "CreateBirthStar");
		}

		private static void FillStartingSystem(StarData star, bool startsOccupied)
		{
			if (fillStartingSystem.Value && startsOccupied)
			{
				star.initialHiveCount = star.maxHiveCount;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StarGen), "CreateBirthStar")]
		private static void FillVanillaStartingSystem(StarData __result, GameDesc gameDesc)
		{
			FillStartingSystem(__result, gameDesc.combatSettings.initialColonize >= 0.015f);
		}

		private static void FillGalacticScaleStartingSystem(StarData starData)
		{
			FillStartingSystem(starData, starData.initialHiveCount > 0);
		}

		private static void PatchGalacticScale(Harmony harmony)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("GalacticScale.GS2"), "ConfigureBirthStarHiveSettings", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				Logger.LogError((object)"Galactic Scale 2 found but GS2.ConfigureBirthStarHiveSettings is missing (GS2 update?); FillStartingSystem will not apply to GS2 galaxies");
				return;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Plugin), "FillGalacticScaleStartingSystem", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Logger.LogInfo((object)"Galactic Scale 2 found: FillStartingSystem also patched into its birth-star generator");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StarGen), "CreateStar")]
		private static void CapInitialHiveCount(StarData __result)
		{
			__result.initialHiveCount = Math.Min(__result.initialHiveCount, __result.maxHiveCount);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MaxDensityUnlock";

		public const string PLUGIN_NAME = "Max Density Unlock";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}