using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
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("EarlyWarp")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EarlyWarp")]
[assembly: AssemblyTitle("EarlyWarp")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace EarlyWarp;
[BepInPlugin("sinthome358.dsp.earlywarp", "Early Warp", "1.0.0")]
public sealed class EarlyWarpPlugin : BaseUnityPlugin
{
public const string PluginGuid = "sinthome358.dsp.earlywarp";
public const string PluginName = "Early Warp";
public const string PluginVersion = "1.0.0";
private const int GravitonRefractionTechId = 1704;
private const int LogisticsCarrierEngine4TechId = 3404;
private const int LogisticsVesselWarpDriveFunctionId = 17;
private const double LogisticsVesselWarpDriveFunctionValue = 1.0;
private const int MaxWarperCount = 50;
private static ManualLogSource _logger;
private static bool _techDefinitionsMigrated;
private Harmony _harmony;
private void Awake()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
_logger = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("sinthome358.dsp.earlywarp");
try
{
_harmony.PatchAll();
_logger.LogInfo((object)("Early Warp 1.0.0 loaded; warp slot migration target: " + 1704 + " <- function " + 17 + " from " + 3404 + "."));
}
catch (Exception ex)
{
_logger.LogError((object)("Failed to apply Harmony patches: " + ex));
}
}
private void OnDestroy()
{
if (_harmony != null)
{
_harmony.UnpatchSelf();
_harmony = null;
}
}
internal static void ApplyTechDefinitionMigration()
{
if (_techDefinitionsMigrated)
{
return;
}
try
{
if ((Object)(object)LDB.techs == (Object)null)
{
_logger.LogError((object)"TechProtoSet is unavailable; tech migration was not applied.");
return;
}
TechProto val = ((ProtoSet<TechProto>)(object)LDB.techs).Select(1704);
TechProto val2 = ((ProtoSet<TechProto>)(object)LDB.techs).Select(3404);
if (val == null || val2 == null)
{
_logger.LogError((object)("Could not find required tech protos: " + 1704 + "=" + (val != null) + ", " + 3404 + "=" + (val2 != null) + "."));
return;
}
string text = TechDefinitionMigration.DescribeFunctions(val2);
string text2 = TechDefinitionMigration.DescribeFunctions(val);
bool flag = TechDefinitionMigration.MoveWarpUnlock(val, val2, 17, 1.0);
if (flag)
{
((ProtoTable)LDB.techs).Signature = ProtoSignature_0_10_30_3100.CalculateSignature((ProtoTable)(object)LDB.techs);
}
_techDefinitionsMigrated = true;
_logger.LogInfo((object)("Tech migration complete; changed=" + flag + "; warp=" + text2 + " -> " + TechDefinitionMigration.DescribeFunctions(val) + "; engine4=" + text + " -> " + TechDefinitionMigration.DescribeFunctions(val2) + "."));
}
catch (Exception ex)
{
_logger.LogError((object)("Failed to migrate tech definitions: " + ex));
}
}
internal static void ApplyLoadedSaveCompatibility(GameData gameData)
{
try
{
if (gameData != null && gameData.history != null && gameData.history.TechUnlocked(1704))
{
bool flag = false;
if (!gameData.history.logisticShipWarpDrive)
{
gameData.history.logisticShipWarpDrive = true;
flag = true;
}
int num = EnsureExistingStationWarperSlots(gameData.galacticTransport);
if (flag || num > 0)
{
_logger.LogInfo((object)("Loaded save compatibility applied for tech " + 1704 + "; warp drive restored=" + flag + "; station slots repaired=" + num + "."));
}
}
}
catch (Exception ex)
{
_logger.LogError((object)("Failed to restore warp state for a loaded save: " + ex));
}
}
private static int EnsureExistingStationWarperSlots(GalacticTransport transport)
{
if (transport == null || transport.stationPool == null)
{
return 0;
}
int num = 0;
int num2 = Math.Min(transport.stationCursor, transport.stationPool.Length);
for (int i = 1; i < num2; i++)
{
StationComponent val = transport.stationPool[i];
if (val != null && val.gid == i && val.isStellar && !val.isCollector && !val.isVeinCollector && val.warperMaxCount < 50)
{
val.warperMaxCount = 50;
num++;
}
}
return num;
}
}
[HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
internal static class VFPreloadPatch
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix()
{
EarlyWarpPlugin.ApplyTechDefinitionMigration();
}
}
[HarmonyPatch(typeof(GameData), "Import")]
internal static class GameDataImportPatch
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix(GameData __instance)
{
EarlyWarpPlugin.ApplyLoadedSaveCompatibility(__instance);
}
}
internal static class TechDefinitionMigration
{
internal static bool MoveWarpUnlock(TechProto warpTech, TechProto engineTech, int functionId, double functionValue)
{
if (warpTech == null)
{
throw new ArgumentNullException("warpTech");
}
if (engineTech == null)
{
throw new ArgumentNullException("engineTech");
}
return RemoveUnlockFunction(engineTech, functionId) | AddOrUpdateUnlockFunction(warpTech, functionId, functionValue);
}
internal static bool ContainsUnlockFunction(TechProto tech, int functionId)
{
if (tech != null && tech.UnlockFunctions != null)
{
return Array.IndexOf(tech.UnlockFunctions, functionId) >= 0;
}
return false;
}
internal static string DescribeFunctions(TechProto tech)
{
if (tech == null || tech.UnlockFunctions == null || tech.UnlockFunctions.Length == 0)
{
return "<none>";
}
return string.Join(",", Array.ConvertAll(tech.UnlockFunctions, (int value) => value.ToString()));
}
private static bool RemoveUnlockFunction(TechProto tech, int functionId)
{
int[] array = tech.UnlockFunctions ?? Array.Empty<int>();
double[] array2 = tech.UnlockValues ?? Array.Empty<double>();
int num = 0;
for (int i = 0; i < array.Length; i++)
{
if (array[i] != functionId)
{
num++;
}
}
if (num == array.Length)
{
return false;
}
int[] array3 = new int[num];
double[] array4 = new double[num];
int num2 = 0;
for (int j = 0; j < array.Length; j++)
{
if (array[j] != functionId)
{
array3[num2] = array[j];
array4[num2] = ((j < array2.Length) ? array2[j] : 0.0);
num2++;
}
}
tech.UnlockFunctions = array3;
tech.UnlockValues = array4;
return true;
}
private static bool AddOrUpdateUnlockFunction(TechProto tech, int functionId, double value)
{
int[] array = tech.UnlockFunctions ?? Array.Empty<int>();
double[] array2 = tech.UnlockValues ?? Array.Empty<double>();
int num = Array.IndexOf(array, functionId);
if (num >= 0)
{
if (num < array2.Length && array2[num].Equals(value))
{
return false;
}
double[] array3 = new double[array.Length];
Array.Copy(array2, array3, Math.Min(array2.Length, array3.Length));
array3[num] = value;
tech.UnlockValues = array3;
return true;
}
int[] array4 = new int[array.Length + 1];
double[] array5 = new double[array.Length + 1];
Array.Copy(array, array4, array.Length);
Array.Copy(array2, array5, Math.Min(array2.Length, array5.Length));
array4[array.Length] = functionId;
array5[array.Length] = value;
tech.UnlockFunctions = array4;
tech.UnlockValues = array5;
return true;
}
}