using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
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: AssemblyTitle("DistributeSpaceWarper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DistributeSpaceWarper")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("DD23704E-3C0C-4D6B-8EB1-F847CFB2BC2D")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace DistributeSpaceWarper
{
public static class Config
{
public static class General
{
public static ConfigEntry<bool> WarperRemoteMode;
public static ConfigEntry<bool> WarperTransportCost;
public static ConfigEntry<int> WarperRemoteTransportCost;
public static ConfigEntry<int> WarperTickCount;
public static ConfigEntry<int> WarperLocalTransportCost;
public static ConfigEntry<bool> WarpersRequiredToggleAutomation;
public static ConfigEntry<int> MinimumWarperCount;
public static ConfigEntry<int> MaximumWarperCount;
public static ConfigEntry<int> MinimumTransportAmount;
}
public static class Utility
{
public static ConfigEntry<bool> DisableMod;
public static ConfigEntry<bool> UninstallMod;
}
private static readonly string GENERAL_SECTION = "General";
private static readonly string UTILITY_SECTION = "Utility";
internal static void Init(ConfigFile config)
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Expected O, but got Unknown
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Expected O, but got Unknown
//IL_0159: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Expected O, but got Unknown
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Expected O, but got Unknown
General.WarperTickCount = config.Bind<int>(GENERAL_SECTION, "WarperTickCount", 60, new ConfigDescription("Default number of ticks before distributing warpers. Note: Maximum of 260, defaults to 60", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 275), new object[1]
{
new { }
}));
General.WarperRemoteMode = config.Bind<bool>(GENERAL_SECTION, "WarperRemoteMode", false, "By default only search local ILS/PLS for supplies. Enable this to get Warpers from different planets as well");
General.WarperTransportCost = config.Bind<bool>(GENERAL_SECTION, "WarperTransportCost", true, "If enabled, transporting Warpers costs 1 warper. Disable for moving Warpers at no costs.");
General.WarpersRequiredToggleAutomation = config.Bind<bool>(GENERAL_SECTION, "WarpersRequiredToggleAutomation", true, "If enabled, when `Warpers Required` toggle ticked on, this will auto fill the warper slot. When toggle is ticked off this will stop filling the wraper slot from suppliers");
General.WarperLocalTransportCost = config.Bind<int>(GENERAL_SECTION, "WarperLocalTransportCost", 1, new ConfigDescription("If enabled, transporting Warpers costs 1 warper. Disable for moving Warpers at no costs.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1]
{
new { }
}));
General.WarperRemoteTransportCost = config.Bind<int>(GENERAL_SECTION, "WarperRemoteTransportCost", 2, new ConfigDescription("Default cost of transporting Warpers from different planets. Note: Maximum of 10, defaults to 2", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1]
{
new { }
}));
General.MinimumWarperCount = config.Bind<int>(GENERAL_SECTION, "MinimumWarperCount", 10, new ConfigDescription("Minimum number of warpers required to distribute. Note: Maximum of 50, defaults to 1", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), new object[1]
{
new { }
}));
General.MaximumWarperCount = config.Bind<int>(GENERAL_SECTION, "MaximumWarperCount", 100, new ConfigDescription("Maximum number of warpers to distribute. Note: Maximum of 50, defaults to 50", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 200), new object[1]
{
new { }
}));
General.MinimumTransportAmount = config.Bind<int>(GENERAL_SECTION, "MinimumTransportAmount", 50, new ConfigDescription("Minimum amount of items to transport. Note: Maximum of 100, defaults to 50", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), new object[1]
{
new { }
}));
Utility.DisableMod = config.Bind<bool>(UTILITY_SECTION, "DisableMod", false, "While true this will disable all mod effects but will not remove additional slot from ILS. Useful if uninstalling mod failed for some reason.");
Utility.UninstallMod = config.Bind<bool>(UTILITY_SECTION, "UninstallMod", false, "WARNING!!! BACKUP YOUR SAVE BEFORE DOING THIS!!! This will not work if mod cannot load properly! If this is true, mod will remove additional slot from all current ILS. This will destroy any items in additional slot To correctly uninstall mod and get vanilla save please follow this steps. Step #1: Set UninstallMod to true. Step #2: Load your save. Step #3: Save your game. Step #4: Exit the game and remove this mod.");
}
}
public static class ModDebug
{
private static ManualLogSource Logger { get; set; }
public static void SetLogger(ManualLogSource logger)
{
Logger = logger;
}
public static void Assert(bool condition)
{
}
public static void Log(object message)
{
Logger.Log((LogLevel)16, message);
}
public static void Error(object message)
{
Logger.Log((LogLevel)2, message);
}
public static void Trace(object message)
{
Logger.Log((LogLevel)16, (object)("DISTR_SPACE_WARP-" + message));
}
public static void LogPlanetType(PlanetData planet)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected I4, but got Unknown
EPlanetType type = planet.type;
switch ((int)type)
{
case 5:
Log("Gas");
break;
case 3:
Log("Desert");
break;
case 4:
Log("Ice");
break;
case 2:
Log("Ocean");
break;
case 1:
Log("Vocano");
break;
case 0:
Log("None");
break;
}
}
public static void LogCmdMode(int mode)
{
switch (mode)
{
case -1:
Log("CmdMode: Destruct Mode");
break;
case -2:
Log("CmdMode: Upgrade Mode");
break;
case 1:
Log("CmdMode: Normal Build Mode");
break;
case 2:
Log("CmdMode: Build Mode - Belt");
break;
case 3:
Log("CmdMode: Build Mode - Inserter");
break;
case 4:
Log("CmdMode: Build Mode - Ground");
break;
case 0:
break;
}
}
}
internal static class Patch
{
private static List<StationComponent> supplierStations = new List<StationComponent>();
private static List<StationComponent> receiverStations = new List<StationComponent>();
private static bool ModDisabled
{
get
{
if (!Config.Utility.DisableMod.Value)
{
return Config.Utility.UninstallMod.Value;
}
return true;
}
}
private static bool RemoteTransfer => Config.General.WarperRemoteMode.Value;
public static int WarperTickCount => Config.General.WarperTickCount.Value;
public static bool WarperTransportCost => Config.General.WarperTransportCost.Value;
public static int WarperLocalTransportCost => Config.General.WarperLocalTransportCost.Value;
public static int WarperRemoteTransportCost => Config.General.WarperRemoteTransportCost.Value;
public static int MinimumWarperCount => Config.General.MinimumWarperCount.Value;
public static int MaximumWarperCount => Config.General.MaximumWarperCount.Value;
public static int MinimumTransportAmount => Config.General.MinimumTransportAmount.Value;
[HarmonyPatch(typeof(PlanetTransport), "GameTick", new Type[]
{
typeof(long),
typeof(bool),
typeof(bool)
})]
[HarmonyPostfix]
public static void PlanetTransport_GameTick_Postfix(PlanetTransport __instance)
{
try
{
if (ModDisabled)
{
Debug.Log((object)"Mod is disabled.");
return;
}
if (Time.frameCount % WarperTickCount != 0)
{
Debug.Log((object)"Skipping tick due to WarperTickCount.");
return;
}
int warperId = 1210;
if (Time.frameCount % (3 * WarperTickCount) == 0)
{
List<StationComponent> stations = CollectStations(__instance, warperId);
supplierStations.Clear();
receiverStations.Clear();
IdentifyStations(stations, supplierStations, receiverStations, warperId, MaximumWarperCount);
}
foreach (StationComponent receiverStation in receiverStations)
{
Debug.Log((object)$"Transferring warpers to receiver station {receiverStation.id}.");
Console.WriteLine($"[DistributeSpaceWarpers] Transferring warpers to receiver station {receiverStation.id}.");
TransferWarpersToReceiver(__instance, receiverStation, supplierStations, warperId, MaximumWarperCount);
}
}
catch (Exception ex)
{
Debug.LogError((object)("Error during GameTick Postfix: " + ex.Message));
Console.WriteLine("[DistributeSpaceWarpers] Error during GameTick Postfix: " + ex.Message);
}
}
private static List<StationComponent> CollectStations(PlanetTransport planetTransport, int warperId)
{
List<StationComponent> list = new List<StationComponent>(planetTransport.stationCursor);
StationComponent[] stationPool = planetTransport.stationPool;
for (int i = 1; i < planetTransport.stationCursor; i++)
{
StationComponent val = stationPool[i];
if (val != null && val.id == i && !val.isCollector && (val.isStellar || (RemoteTransfer && IsRemoteWarperSupplier(val, warperId)) || val.storage.Any((StationStore s) => s.itemId == warperId && ((int)s.localLogic == 1 || (int)s.remoteLogic == 1))))
{
list.Add(val);
}
}
if (RemoteTransfer)
{
StationComponent[] stationPool2 = UIRoot.instance.uiGame.gameData.galacticTransport.stationPool;
foreach (StationComponent val2 in stationPool2)
{
if (val2 != null && !val2.isCollector && val2.isStellar && val2.storage.Any((StationStore s) => s.itemId == warperId && (int)s.remoteLogic == 1))
{
list.Add(val2);
}
}
}
return list;
}
private static void IdentifyStations(List<StationComponent> stations, List<StationComponent> supplierStations, List<StationComponent> receiverStations, int warperId, int maxWarperCount)
{
foreach (StationComponent station in stations)
{
if (IsWarperSupplier(station, warperId))
{
Debug.Log((object)$"Station {station.id} is added to supplier stations.");
Console.WriteLine($"[DistributeSpaceWarpers] Station {station.id} is added to supplier stations.");
supplierStations.Add(station);
}
else if (NeedsWarpers(station, maxWarperCount))
{
Debug.Log((object)$"Station {station.id} needs warpers.");
Console.WriteLine($"[DistributeSpaceWarpers] Station {station.id} needs warpers.");
receiverStations.Add(station);
}
}
}
private static bool IsWarperSupplier(StationComponent station, int warperId)
{
int num;
if (station.warperCount > 0)
{
num = (station.storage.Any((StationStore s) => s.itemId == warperId && (int)s.localLogic == 1) ? 1 : 0);
if (num != 0)
{
Debug.Log((object)$"Station {station.id} is identified as a warper supplier.");
Console.WriteLine($"[DistributeSpaceWarpers] Station {station.id} is identified as a warper supplier.");
}
}
else
{
num = 0;
}
return (byte)num != 0;
}
private static bool IsRemoteWarperSupplier(StationComponent station, int warperId)
{
bool num = station.storage.Any((StationStore s) => s.itemId == warperId && (int)s.remoteLogic == 1);
if (num)
{
Debug.Log((object)$"Station {station.id} is identified as a remote warper supplier.");
Console.WriteLine($"[DistributeSpaceWarpers] Station {station.id} is identified as a remote warper supplier.");
}
return num;
}
private static bool NeedsWarpers(StationComponent station, int maxWarperCount)
{
int num;
if (station.warperCount < maxWarperCount)
{
num = (station.warperNecessary ? 1 : 0);
if (num != 0)
{
Debug.Log((object)$"Station {station.id} needs warpers (current: {station.warperCount}, max: {maxWarperCount}).");
Console.WriteLine($"[DistributeSpaceWarpers] Station {station.id} needs warpers (current: {station.warperCount}, max: {maxWarperCount}).");
}
}
else
{
num = 0;
}
return (byte)num != 0;
}
private static void TransferWarpersToReceiver(PlanetTransport planetTransport, StationComponent receiver, List<StationComponent> suppliers, int warperId, int maxWarperCount)
{
int num = maxWarperCount - receiver.warperCount;
Debug.Log((object)$"Receiver station {receiver.id} needs {num} warpers.");
if (num <= 0 || receiver.warperCount > MinimumWarperCount || num < MinimumTransportAmount)
{
Debug.Log((object)$"Receiver station {receiver.id} does not need more warpers or avaiable warpers are less than {MinimumTransportAmount}");
Console.WriteLine($"[DistributeSpaceWarpers] Receiver station {receiver.id} does not need more warpers or avaiable warpers are less than {MinimumTransportAmount}");
return;
}
int num7 = default(int);
foreach (StationComponent supplier in suppliers)
{
if (supplier.warperCount <= 0)
{
Debug.Log((object)$"Supplier station {supplier.id} has no warpers left to transfer.");
continue;
}
int num2 = CalculateTransportCost(supplier, receiver);
Debug.Log((object)$"Transport cost from supplier {supplier.id} to receiver {receiver.id} is {num2}.");
Console.WriteLine($"[DistributeSpaceWarpers] Transport cost from supplier {supplier.id} to receiver {receiver.id} is {num2}.");
int num3 = supplier.storage.Where((StationStore s) => s.itemId == warperId && ((int)s.localLogic == 1 || (int)s.remoteLogic == 1)).Sum((StationStore s) => s.count);
int num4 = num3 - num2;
int num5 = Mathf.Min(num, num4);
num5 = Mathf.Min(num5, num3 - num2);
if (num5 <= 0)
{
Debug.Log((object)$"No transferable warpers from supplier {supplier.id} to receiver {receiver.id}.");
Console.WriteLine($"[DistributeSpaceWarpers] No transferable warpers from supplier {supplier.id} to receiver {receiver.id}.");
continue;
}
int num6 = num5 + num2;
Debug.Log((object)$"Removing {num6} warpers from supplier station {supplier.id}.");
Console.WriteLine($"[DistributeSpaceWarpers] Removing {num6} warpers from supplier station {supplier.id}.");
supplier.TakeItem(ref warperId, ref num6, ref num7);
receiver.warperCount += num5;
Debug.Log((object)$"Added {num5} warpers to receiver station {receiver.id} (new count: {receiver.warperCount}).");
Console.WriteLine($"[DistributeSpaceWarpers] Added {num5} warpers to receiver station {receiver.id} (new count: {receiver.warperCount}).");
UpdateTraffic(planetTransport, receiver);
num -= num5;
if (num > 0)
{
continue;
}
Debug.Log((object)$"Receiver station {receiver.id} has received enough warpers.");
Console.WriteLine($"[DistributeSpaceWarpers] Receiver station {receiver.id} has received enough warpers.");
break;
}
}
private static int CalculateTransportCost(StationComponent supplier, StationComponent receiver)
{
if (!WarperTransportCost)
{
return 0;
}
if (supplier.planetId != receiver.planetId)
{
return WarperRemoteTransportCost;
}
return WarperLocalTransportCost;
}
private static void UpdateTraffic(PlanetTransport planetTransport, StationComponent receiver)
{
receiver.UpdateNeeds();
planetTransport.RefreshStationTraffic(0);
planetTransport.RefreshDispenserTraffic(0);
planetTransport.gameData.galacticTransport.RefreshTraffic(receiver.gid);
}
}
[BepInPlugin("BumpyClock.DSP.DistributeSpaceWarper", "Distribute Space Warper", "1.0.5")]
[BepInProcess("DSPGAME.exe")]
public class Plugin : BaseUnityPlugin
{
private static ManualLogSource _logger;
private const string PluginGuid = "BumpyClock.DSP.DistributeSpaceWarper";
private const string PluginName = "Distribute Space Warper";
private const string PluginVersion = "1.0.5";
public void Awake()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
Harmony val = new Harmony("BumpyClock.DSP.DistributeSpaceWarper");
Config.Init(((BaseUnityPlugin)this).Config);
val.PatchAll(typeof(Plugin));
val.PatchAll(typeof(Patch));
}
public void Start()
{
_logger = ((BaseUnityPlugin)this).Logger;
_logger.LogInfo((object)"Loaded!");
ModDebug.SetLogger(_logger);
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "DistributeSpaceWarper";
public const string PLUGIN_NAME = "DistributeSpaceWarper";
public const string PLUGIN_VERSION = "1.0.0";
}
}