using System;
using System.Collections.Generic;
using System.Diagnostics;
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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e311995cd5b2f17f628dc506198bfef05d86e80b")]
[assembly: AssemblyProduct("DarkFogAwakening")]
[assembly: AssemblyTitle("DarkFogAwakening")]
[assembly: AssemblyVersion("1.0.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));
}
}
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();
float value2 = Plugin.Aggressiveness.Value;
string[] array = new string[9] { "aggressiveness", "initialLevel", "initialGrowth", "initialColonize", "maxDensity", "growthSpeedFactor", "powerThreatFactor", "battleThreatFactor", "battleExpFactor" };
foreach (string name in array)
{
FieldInfo field2 = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (!(field2?.FieldType != typeof(float)))
{
float num = (float)field2.GetValue(value);
field2.SetValue(value, ((num == 0f) ? 1f : num) * value2);
}
}
field.SetValue(gameDesc, value);
Plugin.Log.LogInfo((object)$"[DarkFogAwakener] CombatSettings set with aggressiveness x{value2:F1}.");
}
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();
}
}
}
[BepInPlugin("com.darkfogawakening.mod", "Dark Fog Awakening", "1.0.0")]
[BepInProcess("DSPGAME.exe")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
internal static ConfigEntry<bool> AutoActivate;
internal static ConfigEntry<bool> ShowButton;
internal static ConfigEntry<int> HiveCount;
internal static ConfigEntry<float> Aggressiveness;
private Harmony _harmony;
private bool _showConfirm;
private Rect _windowRect = new Rect(0f, 0f, 360f, 0f);
private GUIStyle? _labelStyle;
private void Awake()
{
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: 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.");
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", 2f, "Multiplier applied to all CombatSettings difficulty values (growth speed, expansion rate, colonisation rate, etc.). 1.0 = vanilla normal difficulty. 2.0 = twice as fast/aggressive.");
_harmony = new Harmony("com.darkfogawakening.mod");
_harmony.PatchAll();
Log.LogInfo((object)"Dark Fog Awakening v1.0.0 loaded.");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void OnGUI()
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
if (!ShowButton.Value || DarkFogAwakener.HasAwakened)
{
return;
}
UIRoot instance = UIRoot.instance;
if (instance == null)
{
return;
}
UIGame uiGame = instance.uiGame;
if (((uiGame != null) ? new bool?(((Component)uiGame).gameObject.activeSelf) : null).GetValueOrDefault())
{
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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
//IL_003e: Expected O, but got Unknown
GUILayout.Space(6f);
GUIStyle obj = _labelStyle;
if (obj == null)
{
GUIStyle val = new GUIStyle(GUI.skin.label)
{
wordWrap = true,
richText = true
};
GUIStyle val2 = val;
_labelStyle = val;
obj = val2;
}
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>", obj, 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.", 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();
}
}
internal static class PluginInfo
{
public const string GUID = "com.darkfogawakening.mod";
public const string NAME = "Dark Fog Awakening";
public const string VERSION = "1.0.0";
}
}