Decompiled source of DarkFogAwakening v1.1.0

BepInEx/plugins/DarkFogAwakening/DarkFogAwakening.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
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(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DarkFogAwakening")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+e977c79d5a7d058f109148e1241b1028eed785da")]
[assembly: AssemblyProduct("DarkFogAwakening")]
[assembly: AssemblyTitle("DarkFogAwakening")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 DarkFogAwakening
{
	internal static class DarkFogAwakener
	{
		private static bool _awakened;

		private const BindingFlags ALL_INSTANCE = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo? _spaceSectorIsCombatMode = typeof(SpaceSector).GetField("isCombatMode", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly MethodInfo? _tryCreateNewHive = typeof(SpaceSector).GetMethod("TryCreateNewHive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(StarData) }, null);

		private static readonly string[] InitMethodNames = new string[6] { "InitForNewGame", "NewGame", "Init", "GameInit", "InitNewGame", "LoadPattern" };

		internal static bool HasAwakened => _awakened;

		internal static void Awaken()
		{
			if (_awakened)
			{
				return;
			}
			_awakened = true;
			GameData data = GameMain.data;
			if (data == null)
			{
				Plugin.Log.LogError((object)"[DarkFogAwakener] GameMain.data is null — cannot awaken.");
				return;
			}
			Plugin.Log.LogInfo((object)"[DarkFogAwakener] Awakening the Dark Fog…");
			SetBoolField(data.gameDesc, "isPeaceMode", value: false);
			SetBoolField(data.spaceSector, "isCombatMode", value: true);
			SetCombatSettingsDefaults(data.gameDesc);
			SeedHives(data, GetColonisedStarIds(data));
			int num = 0;
			PlanetFactory[] factories = data.factories;
			foreach (PlanetFactory val in factories)
			{
				if (val != null)
				{
					if (IsPlanetBuiltOn(val))
					{
						num++;
					}
					else
					{
						TryInvokeInit(val.enemySystem, "ground-enemy system");
					}
				}
			}
			Plugin.Log.LogInfo((object)("[DarkFogAwakener] The Dark Fog has awakened. " + $"({num} planet(s) protected from ground spawns.)"));
		}

		internal static void ResetOnLoad()
		{
			GameData data = GameMain.data;
			if (data == null)
			{
				_awakened = false;
			}
			else
			{
				_awakened = _spaceSectorIsCombatMode != null && (bool)(_spaceSectorIsCombatMode.GetValue(data.spaceSector) ?? ((object)false));
			}
		}

		internal static Dictionary<string, float>? ReadCombatSettings()
		{
			GameData data = GameMain.data;
			if (data == null)
			{
				return null;
			}
			FieldInfo field = typeof(GameDesc).GetField("combatSettings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			object value = field.GetValue(data.gameDesc);
			Type type = value.GetType();
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			foreach (KeyValuePair<string, ConfigEntry<float>> combatValue in Plugin.CombatValues)
			{
				FieldInfo field2 = type.GetField(combatValue.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field2?.FieldType != typeof(float)))
				{
					dictionary[combatValue.Key] = (float)field2.GetValue(value);
				}
			}
			return dictionary;
		}

		internal static void ReApplyCombatSettings()
		{
			GameData data = GameMain.data;
			if (data == null)
			{
				Plugin.Log.LogError((object)"[DarkFogAwakener] GameMain.data is null — cannot re-apply.");
			}
			else
			{
				SetCombatSettingsDefaults(data.gameDesc);
			}
		}

		private static void SetCombatSettingsDefaults(GameDesc gameDesc)
		{
			FieldInfo field = typeof(GameDesc).GetField("combatSettings", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				Plugin.Log.LogWarning((object)"[DarkFogAwakener] combatSettings field not found on GameDesc.");
				return;
			}
			object value = field.GetValue(gameDesc);
			Type type = value.GetType();
			foreach (KeyValuePair<string, ConfigEntry<float>> combatValue in Plugin.CombatValues)
			{
				FieldInfo field2 = type.GetField(combatValue.Key, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field2?.FieldType != typeof(float)))
				{
					field2.SetValue(value, combatValue.Value.Value);
					Plugin.Log.LogDebug((object)$"[DarkFogAwakener]   {combatValue.Key} = {combatValue.Value.Value:F3}");
				}
			}
			field.SetValue(gameDesc, value);
			Plugin.Log.LogInfo((object)"[DarkFogAwakener] CombatSettings applied with per-field values.");
		}

		private static void SeedHives(GameData game, HashSet<int> colonisedStarIds)
		{
			if (_tryCreateNewHive == null)
			{
				Plugin.Log.LogWarning((object)"[DarkFogAwakener] TryCreateNewHive(StarData) not found on SpaceSector.");
				return;
			}
			int value = Plugin.HiveCount.Value;
			List<(StarData, double)> list = new List<(StarData, double)>();
			StarData[] stars = game.galaxy.stars;
			foreach (StarData val in stars)
			{
				if (val != null && !colonisedStarIds.Contains(val.id))
				{
					double item = val.position.x * val.position.x + val.position.y * val.position.y + val.position.z * val.position.z;
					list.Add((val, item));
				}
			}
			list.Sort(((StarData star, double distSq) a, (StarData star, double distSq) b) => b.distSq.CompareTo(a.distSq));
			MethodInfo methodInfo = null;
			MethodInfo methodInfo2 = null;
			int num = 0;
			for (int j = 0; j < list.Count; j++)
			{
				if (num >= value)
				{
					break;
				}
				(StarData, double) tuple = list[j];
				StarData item2 = tuple.Item1;
				double item3 = tuple.Item2;
				object obj = _tryCreateNewHive.Invoke(game.spaceSector, new object[1] { item2 });
				if (obj != null)
				{
					if (methodInfo == null)
					{
						Type type = obj.GetType();
						methodInfo = type.GetMethod("SetForNewGame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
						methodInfo2 = type.GetMethod("Realize", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					}
					methodInfo?.Invoke(obj, null);
					methodInfo2?.Invoke(obj, null);
					Plugin.Log.LogInfo((object)($"[DarkFogAwakener]   Hive {num + 1}/{value} at '{item2.displayName}' " + $"({Math.Sqrt(item3):F1} ly from centre)."));
					num++;
				}
			}
			Plugin.Log.LogInfo((object)$"[DarkFogAwakener] Hives: {num}/{value} seeded at the farthest stars.");
		}

		private static bool IsPlanetBuiltOn(PlanetFactory factory)
		{
			EntityData[] entityPool = factory.entityPool;
			for (int i = 1; i < factory.entityCursor; i++)
			{
				if (entityPool[i].id == i)
				{
					return true;
				}
			}
			return false;
		}

		private static HashSet<int> GetColonisedStarIds(GameData game)
		{
			HashSet<int> hashSet = new HashSet<int>();
			PlanetFactory[] factories = game.factories;
			foreach (PlanetFactory val in factories)
			{
				if (((val == null) ? null : val.planet?.star) != null && IsPlanetBuiltOn(val))
				{
					hashSet.Add(val.planet.star.id);
				}
			}
			return hashSet;
		}

		private static bool TryInvokeInit(object? obj, string label)
		{
			if (obj == null)
			{
				return false;
			}
			Type type = obj.GetType();
			string[] initMethodNames = InitMethodNames;
			foreach (string text in initMethodNames)
			{
				MethodInfo method = type.GetMethod(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
				if (!(method == null))
				{
					method.Invoke(obj, null);
					Plugin.Log.LogDebug((object)("[DarkFogAwakener] Called " + type.Name + "." + text + "() on " + label + "."));
					return true;
				}
			}
			Plugin.Log.LogWarning((object)("[DarkFogAwakener] No init method found on " + type.Name + " (" + label + "). Tried: " + string.Join(", ", InitMethodNames) + "."));
			return false;
		}

		private static bool SetBoolField(object obj, string fieldName, bool value)
		{
			FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field?.FieldType == typeof(bool))
			{
				field.SetValue(obj, value);
				Plugin.Log.LogDebug((object)$"[DarkFogAwakener] Set {obj.GetType().Name}.{fieldName} = {value}");
				return true;
			}
			Plugin.Log.LogWarning((object)("[DarkFogAwakener] Bool field '" + fieldName + "' not found on " + obj.GetType().Name + "."));
			return false;
		}
	}
	[HarmonyPatch(typeof(GameData), "Import")]
	internal static class Patch_GameData_Import
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			DarkFogAwakener.ResetOnLoad();
			if (!DarkFogAwakener.HasAwakened && Plugin.AutoActivate.Value)
			{
				Plugin.Log.LogInfo((object)"[Patches] AutoActivate is enabled — awakening Dark Fog on load.");
				DarkFogAwakener.Awaken();
			}
		}
	}
	[HarmonyPatch(typeof(CombatSettings), "SetDefault")]
	internal static class Patch_CombatSettings_SetDefault
	{
		[HarmonyPrefix]
		private static bool Prefix(ref CombatSettings __instance)
		{
			if (!DarkFogAwakener.HasAwakened)
			{
				return true;
			}
			__instance.aggressiveness = Plugin.CombatValues["aggressiveness"].Value;
			__instance.initialLevel = Plugin.CombatValues["initialLevel"].Value;
			__instance.initialGrowth = Plugin.CombatValues["initialGrowth"].Value;
			__instance.initialColonize = Plugin.CombatValues["initialColonize"].Value;
			__instance.maxDensity = Plugin.CombatValues["maxDensity"].Value;
			__instance.growthSpeedFactor = Plugin.CombatValues["growthSpeedFactor"].Value;
			__instance.powerThreatFactor = Plugin.CombatValues["powerThreatFactor"].Value;
			__instance.battleThreatFactor = Plugin.CombatValues["battleThreatFactor"].Value;
			__instance.battleExpFactor = Plugin.CombatValues["battleExpFactor"].Value;
			Plugin.Log.LogDebug((object)"[Patches] CombatSettings.SetDefault intercepted — applied config values.");
			return false;
		}
	}
	[HarmonyPatch(typeof(CombatSettings), "Export")]
	internal static class Patch_CombatSettings_Export
	{
		[HarmonyPrefix]
		private static bool Prefix(BinaryWriter w)
		{
			if (!DarkFogAwakener.HasAwakened)
			{
				return true;
			}
			w.Write(0);
			w.Write(Plugin.CombatValues["aggressiveness"].Value);
			w.Write(Plugin.CombatValues["initialLevel"].Value);
			w.Write(Plugin.CombatValues["initialGrowth"].Value);
			w.Write(Plugin.CombatValues["initialColonize"].Value);
			w.Write(Plugin.CombatValues["maxDensity"].Value);
			w.Write(Plugin.CombatValues["growthSpeedFactor"].Value);
			w.Write(Plugin.CombatValues["powerThreatFactor"].Value);
			w.Write(Plugin.CombatValues["battleThreatFactor"].Value);
			w.Write(Plugin.CombatValues["battleExpFactor"].Value);
			Plugin.Log.LogDebug((object)"[Patches] CombatSettings.Export intercepted — wrote config values to save.");
			return false;
		}
	}
	[BepInPlugin("com.darkfogawakening.mod", "Dark Fog Awakening", "1.1.0")]
	[BepInProcess("DSPGAME.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log = null;

		internal static ConfigEntry<bool> AutoActivate = null;

		internal static ConfigEntry<bool> ShowButton = null;

		internal static ConfigEntry<KeyboardShortcut> SettingsKey = null;

		internal static ConfigEntry<int> HiveCount = null;

		internal static readonly Dictionary<string, ConfigEntry<float>> CombatValues = new Dictionary<string, ConfigEntry<float>>();

		internal static ConfigEntry<float> Aggressiveness = null;

		internal static ConfigEntry<float> LastAppliedMultiplier = null;

		private Harmony _harmony;

		private bool _showConfirm;

		private Rect _windowRect = new Rect(0f, 0f, 360f, 0f);

		private bool _showSettings;

		private Rect _settingsRect = new Rect(0f, 0f, 560f, 0f);

		private Vector2 _settingsScroll;

		private bool _settingsPositioned;

		private string _hivesStr = "";

		private readonly Dictionary<string, string> _fieldStr = new Dictionary<string, string>();

		private GUIStyle? _labelStyle;

		private GUIStyle? _smallStyle;

		private static readonly (string field, string label, string desc, float sliderMin, float sliderMax, float gameDefault)[] s_combatFields = new(string, string, string, float, float, float)[9]
		{
			("aggressiveness", "Aggressiveness", "Root threat scalar the game uses as a base for most attack calculations. Raising this makes every part of the Dark Fog more dangerous at the same time. -1 = the Fog is fully passive and will not attack.", -1f, 3f, 1f),
			("initialLevel", "Initial Level", "Power level of each hive the moment it spawns. Higher = tougher, more numerous units from the very first wave. Game default is 0 (minimum).", 0f, 10f, 0f),
			("initialGrowth", "Initial Growth", "How structurally developed each hive already is when it appears. Higher = hives arrive in a more advanced, harder-to-destroy state.", 0f, 6f, 1f),
			("initialColonize", "Initial Colonize", "The Dark Fog's territorial footprint at the time of awakening. Higher = more star systems already claimed by the Fog on day one.", 0f, 6f, 1f),
			("maxDensity", "Max Density", "Population cap per hive / region. Higher = larger swarms, denser attack formations, and bigger raids.", 0f, 4f, 1f),
			("growthSpeedFactor", "Growth Speed", "How fast hives build up over time. Higher = the Fog snowballs more quickly; the longer the game runs, the stronger they get.", 0f, 4f, 1f),
			("powerThreatFactor", "Power Threat", "How much your total power production aggravates the Dark Fog. Higher = every megawatt you generate draws faster, more determined attacks.", 0f, 8f, 1f),
			("battleThreatFactor", "Battle Threat", "How much fighting back escalates future attack waves. Higher = the more you kill, the angrier and better-prepared they become.", 0f, 8f, 1f),
			("battleExpFactor", "Battle XP Gain", "How quickly the Dark Fog gains experience from each engagement. Higher = they evolve, level up, and field more dangerous unit types sooner.", 0f, 8f, 1f)
		};

		private void Awake()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			AutoActivate = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoActivate", false, "When true the Dark Fog awakens automatically the moment a save is loaded. No button press required.");
			ShowButton = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowButton", true, "Show the in-game 'Awaken the Dark Fog' button when combat is disabled.");
			SettingsKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SettingsShortcut", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "Keyboard shortcut to open / close the Dark Fog settings window in-game.");
			HiveCount = ((BaseUnityPlugin)this).Config.Bind<int>("Combat", "HiveCount", 4, "How many hives to spawn. They are placed at the stars farthest from the galactic centre so the threat starts distant and spreads inward.");
			Aggressiveness = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "Aggressiveness", 1f, "Deprecated — no longer used. Kept to prevent errors in existing config files.");
			LastAppliedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Internal", "_LastAppliedMultiplier", 0f, "Deprecated — no longer used. Kept to prevent errors in existing config files.");
			(string, string, string, float, float, float)[] array = s_combatFields;
			for (int i = 0; i < array.Length; i++)
			{
				var (text, arg, arg2, _, _, num) = array[i];
				CombatValues[text] = ((BaseUnityPlugin)this).Config.Bind<float>("CombatSettings", text, num, $"{arg} — {arg2}  (game default: {num})");
			}
			_harmony = new Harmony("com.darkfogawakening.mod");
			_harmony.PatchAll();
			Log.LogInfo((object)"Dark Fog Awakening v1.1.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = SettingsKey.Value;
			if (!((KeyboardShortcut)(ref value)).IsDown())
			{
				return;
			}
			UIRoot instance = UIRoot.instance;
			if (instance == null)
			{
				return;
			}
			UIGame uiGame = instance.uiGame;
			if (((uiGame != null) ? new bool?(((Component)uiGame).gameObject.activeSelf) : null).GetValueOrDefault())
			{
				_showSettings = !_showSettings;
				if (_showSettings)
				{
					SyncFieldStrings();
				}
			}
		}

		private void SyncFieldStrings()
		{
			(string, string, string, float, float, float)[] array;
			if (DarkFogAwakener.HasAwakened)
			{
				Dictionary<string, float> dictionary = DarkFogAwakener.ReadCombatSettings();
				if (dictionary != null)
				{
					array = s_combatFields;
					for (int i = 0; i < array.Length; i++)
					{
						string item = array[i].Item1;
						if (dictionary.TryGetValue(item, out var value) && CombatValues.TryGetValue(item, out ConfigEntry<float> value2))
						{
							value2.Value = value;
						}
					}
				}
			}
			_hivesStr = HiveCount.Value.ToString();
			array = s_combatFields;
			for (int i = 0; i < array.Length; i++)
			{
				string item2 = array[i].Item1;
				if (CombatValues.TryGetValue(item2, out ConfigEntry<float> value3))
				{
					_fieldStr[item2] = value3.Value.ToString((value3.Value == Mathf.Round(value3.Value)) ? "F0" : "F2");
				}
			}
		}

		private void OnGUI()
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			UIRoot instance = UIRoot.instance;
			if (instance == null)
			{
				return;
			}
			UIGame uiGame = instance.uiGame;
			if (!((uiGame != null) ? new bool?(((Component)uiGame).gameObject.activeSelf) : null).GetValueOrDefault())
			{
				return;
			}
			if (_showSettings)
			{
				if (!_settingsPositioned)
				{
					((Rect)(ref _settingsRect)).x = ((float)Screen.width - ((Rect)(ref _settingsRect)).width) / 2f;
					((Rect)(ref _settingsRect)).y = Mathf.Max(10f, ((float)Screen.height - 680f) / 2f);
					_settingsPositioned = true;
				}
				_settingsRect = GUILayout.Window(234487810, _settingsRect, new WindowFunction(DrawSettingsWindow), $"  Dark Fog Settings  —  [{SettingsKey.Value}] to close", Array.Empty<GUILayoutOption>());
			}
			if (ShowButton.Value && !DarkFogAwakener.HasAwakened)
			{
				if (((Rect)(ref _windowRect)).x == 0f && ((Rect)(ref _windowRect)).y == 0f)
				{
					((Rect)(ref _windowRect)).x = ((float)Screen.width - ((Rect)(ref _windowRect)).width) / 2f;
					((Rect)(ref _windowRect)).y = ((float)Screen.height - 180f) / 2f;
				}
				_windowRect = GUILayout.Window(234487809, _windowRect, new WindowFunction(DrawWindow), "  Dark Fog Awakening", Array.Empty<GUILayoutOption>());
			}
		}

		private void DrawWindow(int _)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			EnsureStyles();
			GUILayout.Space(6f);
			GUILayout.Label("This save was started with the Dark Fog disabled.\nYou can awaken them now.\n\n<b>Warning: this cannot be undone.</b>\n" + $"Press  <b>[{SettingsKey.Value}]</b>  to adjust settings before awakening.", _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			if (!_showConfirm)
			{
				if (GUILayout.Button("Awaken the Dark Fog", Array.Empty<GUILayoutOption>()))
				{
					_showConfirm = true;
				}
			}
			else
			{
				GUILayout.Label("Are you sure? The Dark Fog will spread immediately.", _labelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("Yes — Awaken Now", Array.Empty<GUILayoutOption>()))
				{
					_showConfirm = false;
					DarkFogAwakener.Awaken();
				}
				if (GUILayout.Button("Cancel", Array.Empty<GUILayoutOption>()))
				{
					_showConfirm = false;
				}
				GUILayout.EndHorizontal();
			}
			GUILayout.Space(4f);
			GUI.DragWindow();
		}

		private void DrawSettingsWindow(int _)
		{
			//IL_0008: 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)
			EnsureStyles();
			_settingsScroll = GUILayout.BeginScrollView(_settingsScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(640f) });
			GUILayout.Space(4f);
			(string, string, string, float, float, float)[] array;
			if (GUILayout.Button("Reset all fields to game defaults (Normal difficulty)", Array.Empty<GUILayoutOption>()))
			{
				array = s_combatFields;
				for (int i = 0; i < array.Length; i++)
				{
					var (key, _, _, _, _, value) = array[i];
					if (CombatValues.TryGetValue(key, out ConfigEntry<float> value2))
					{
						value2.Value = value;
					}
				}
				SyncFieldStrings();
			}
			GUILayout.Space(10f);
			DrawHorizontalLine();
			GUILayout.Space(8f);
			GUILayout.Label("<b>Hive Count</b>", _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Number of Dark Fog hives spawned at awakening. Placed at the stars farthest from the galactic centre so the threat starts distant and spreads inward over time. <i>Cannot be changed after awakening.</i>", _smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			int num = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)HiveCount.Value, 1f, 20f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) }));
			if (num != HiveCount.Value)
			{
				HiveCount.Value = num;
				_hivesStr = num.ToString();
			}
			string text = GUILayout.TextField(_hivesStr, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
			if (text != _hivesStr)
			{
				_hivesStr = text;
				if (int.TryParse(text, out var result) && result >= 1)
				{
					HiveCount.Value = result;
				}
			}
			GUILayout.Label(" hives", _smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			DrawHorizontalLine();
			GUILayout.Space(8f);
			GUILayout.Label("<b>Individual Combat Settings</b>", _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Values match the game's own new-game sliders. Scroll down and click Apply Now to push changes into an already-awakened save.", _smallStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(8f);
			bool hasAwakened = DarkFogAwakener.HasAwakened;
			string[] array2 = new string[3] { "initialLevel", "initialGrowth", "initialColonize" };
			array = s_combatFields;
			for (int i = 0; i < array.Length; i++)
			{
				var (text2, arg, text3, num2, num3, num4) = array[i];
				if ((hasAwakened && Array.IndexOf(array2, text2) >= 0) || !CombatValues.TryGetValue(text2, out ConfigEntry<float> value3))
				{
					continue;
				}
				if (!_fieldStr.TryGetValue(text2, out string value4))
				{
					value4 = value3.Value.ToString("F2");
				}
				GUILayout.Label($"<b>{arg}</b>  <i>(default: {num4})</i>", _labelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label(text3, _smallStyle, Array.Empty<GUILayoutOption>());
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				float num5 = Mathf.Round(GUILayout.HorizontalSlider(value3.Value, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) }));
				if (Mathf.Abs(num5 - value3.Value) > 0.005f)
				{
					value3.Value = num5;
					_fieldStr[text2] = num5.ToString("F0");
					value4 = _fieldStr[text2];
				}
				string text4 = GUILayout.TextField(value4, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) });
				if (text4 != value4)
				{
					_fieldStr[text2] = text4;
					if (float.TryParse(text4, out var result2) && result2 >= num2)
					{
						value3.Value = result2;
					}
				}
				GUILayout.Label($"  [{(int)num2} – {(int)num3}]", _smallStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
				GUILayout.Space(6f);
			}
			GUILayout.Space(8f);
			DrawHorizontalLine();
			GUILayout.Space(8f);
			if (DarkFogAwakener.HasAwakened)
			{
				GUILayout.Label("<b>Dark Fog is already active in this save.</b>", _labelStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("Click Apply Now to write your current values into the live game immediately — no reload needed.", _smallStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(4f);
				if (GUILayout.Button("Apply Now — update combat settings in this save", Array.Empty<GUILayoutOption>()))
				{
					DarkFogAwakener.ReApplyCombatSettings();
				}
				GUILayout.Label("<i>Hive Count only affects the initial spawn and cannot be changed mid-game.</i>", _smallStyle, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Values are written into the save the moment you click \"Awaken the Dark Fog\".", _smallStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(8f);
			if (GUILayout.Button("Close", Array.Empty<GUILayoutOption>()))
			{
				_showSettings = false;
			}
			GUILayout.Space(4f);
			GUILayout.EndScrollView();
			GUI.DragWindow();
		}

		private static void DrawHorizontalLine()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			GUI.Box(GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }), GUIContent.none);
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_002c: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_004f: Expected O, but got Unknown
			if (_labelStyle == null)
			{
				_labelStyle = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					richText = true
				};
				_smallStyle = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					richText = true
				};
			}
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "com.darkfogawakening.mod";

		public const string NAME = "Dark Fog Awakening";

		public const string VERSION = "1.1.0";
	}
}