using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyCompany("Loki Moon Labs")]
[assembly: InternalsVisibleTo("IcarusBoost.Tests")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("Icarus Boost")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LokiMoonLabs.IcarusBoost;
[HarmonyPatch(typeof(MechaForge), "GameTick")]
internal static class CraftingProgress
{
internal static int Add(int current, float progress)
{
if (Plugin.Options == null || !Plugin.Options.Enabled.Value)
{
return current + (int)progress;
}
if (float.IsNaN(progress) || float.IsInfinity(progress) || progress < 0f)
{
return current;
}
return (int)Math.Max(-2147483648.0, Math.Min(2147483647.0, (double)current + Math.Truncate(progress)));
}
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> source)
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(source);
int num = 0;
for (int i = 0; i + 2 < list.Count; i++)
{
if (list[i].opcode == OpCodes.Conv_I4 && list[i + 1].opcode == OpCodes.Add && CodeInstructionExtensions.StoresField(list[i + 2], AccessTools.Field(typeof(ForgeTask), "tick")))
{
CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(CraftingProgress), "Add", (Type[])null, (Type[])null));
val.labels.AddRange(list[i].labels);
val.labels.AddRange(list[i + 1].labels);
val.blocks.AddRange(list[i].blocks);
val.blocks.AddRange(list[i + 1].blocks);
list[i] = val;
list.RemoveAt(i + 1);
num++;
}
}
if (num != 1)
{
throw new InvalidOperationException("Unsupported crafting progress IL: " + num);
}
return list;
}
}
[HarmonyPatch(typeof(PlayerController), "ApplyLocalForce")]
internal static class FlightAltitude
{
internal static bool Finite(double value)
{
if (!double.IsNaN(value))
{
return !double.IsInfinity(value);
}
return false;
}
internal static bool Eligible(bool enabled, EMovementState current, EMovementState next, double nativeWalk, double boostedWalk, double energy, bool gas)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Invalid comparison between Unknown and I4
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Invalid comparison between Unknown and I4
if (enabled && (int)current == 2 && (int)next == 2 && Finite(nativeWalk) && nativeWalk > 0.0 && Finite(boostedWalk) && boostedWalk > nativeWalk && Finite(energy))
{
return energy >= (double)(gas ? 120000000 : 10000);
}
return false;
}
internal static bool TryCorrection(double radius, double targetRadius, double horizontal, double radial, double force, double dt, out double correction)
{
correction = 0.0;
if (!Finite(radius) || !Finite(targetRadius) || !Finite(horizontal) || !Finite(radial) || !Finite(force) || !Finite(dt) || radius < 10.0 || targetRadius < 10.0 || horizontal < 0.0 || dt < 0.016666566666666667 || dt > 0.050001)
{
return false;
}
double num = Math.Max(-20.0, Math.Min(20.0, (targetRadius - radius) * 2.0));
double num2 = radius + num * dt;
double num3 = horizontal * dt;
double num4 = num2 * num2 - num3 * num3;
if (num4 <= 0.0 || !Finite(num4))
{
return false;
}
double num5 = (num2 - radius) / dt - num3 * num3 / (dt * (Math.Sqrt(num4) + num2));
double num6 = (num5 - radial) / dt - force;
if (!Finite(num6) || Math.Abs(num6) > 12000.0)
{
return false;
}
correction = num6;
return true;
}
[HarmonyPriority(0)]
[HarmonyPrefix]
internal static void Prefix(PlayerController __instance, ref VectorLF3 ____lForce)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Invalid comparison between Unknown and I4
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Invalid comparison between Unknown and I4
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
if (Plugin.Options == null || !Plugin.Options.Enabled.Value || (Object)(object)__instance == (Object)null)
{
return;
}
Player player = __instance.player;
if (player == null || !player.isAlive || (int)player.movementState != 2 || (int)__instance.movementStateInFrame != 2 || player.planetData == null)
{
return;
}
Mecha mecha = player.mecha;
PlayerMove_Fly actionFly = __instance.actionFly;
if (mecha == null || actionFly == null || !Eligible(enabled: true, player.movementState, __instance.movementStateInFrame, mecha.walkSpeed, Modifiers.FlightWalk(mecha.walkSpeed), mecha.coreEnergy, (int)player.planetData.type == 5))
{
return;
}
Vector3 position = player.position;
double num = ((Vector3)(ref position)).magnitude;
if (!Finite(num) || num < 10.0)
{
return;
}
Vector3 val = position / (float)num;
double num2 = Math.Max(1.0 / 60.0, Math.Min(0.05, Time.fixedDeltaTime));
Vector3 velocity = __instance.velocity;
double radial = Vector3.Dot(velocity, val);
Vector3 val2 = velocity + VectorLF3.op_Implicit(____lForce * num2);
double num3 = Vector3.Dot(val2, val);
Vector3 val3 = val2 - val * (float)num3;
double num4 = ((Vector3)(ref val3)).magnitude;
if (!(num4 <= (double)mecha.walkSpeed * 2.5) && !(num4 > 504.0))
{
double force = ____lForce.x * (double)val.x + ____lForce.y * (double)val.y + ____lForce.z * (double)val.z;
if (TryCorrection(num, player.planetData.realRadius + actionFly.targetAltitude, num4, radial, force, num2, out var correction))
{
____lForce += VectorLF3.op_Implicit(val * (float)correction);
}
}
}
}
internal static class LegacyCleanup
{
private static bool Valid(float value)
{
if (value > 0f && !float.IsNaN(value))
{
return !float.IsInfinity(value);
}
return false;
}
private static bool ValidCost(double value)
{
if (value >= 0.0 && !double.IsNaN(value))
{
return !double.IsInfinity(value);
}
return false;
}
private static bool Near(float actual, double expected)
{
return Math.Abs((double)actual - expected) <= Math.Max(1E-05, Math.Abs(expected) * 1E-05);
}
internal static bool Apply(Mecha mecha, ModeConfig baseline)
{
if (mecha == null || (Object)(object)baseline == (Object)null || !Valid(baseline.mechaMiningSpeed) || !Valid(baseline.mechaReplicateSpeed) || !Valid(baseline.mechaWalkSpeed) || !ValidCost(baseline.droneEjectEnergy) || !ValidCost(baseline.droneEnergyPerMeter))
{
return false;
}
if (!Valid(mecha.miningSpeed) || !Valid(mecha.replicateSpeed) || !Valid(mecha.walkSpeed) || !Near(mecha.miningSpeed, (double)baseline.mechaMiningSpeed * 10.0) || (double)mecha.replicateSpeed + 1E-05 < (double)baseline.mechaReplicateSpeed * 10.0 || (double)mecha.walkSpeed + 1E-05 < (double)baseline.mechaWalkSpeed * 2.0 || mecha.droneEjectEnergy != 0.0 || mecha.droneEnergyPerMeter != 0.0)
{
return false;
}
float num = (float)((double)mecha.replicateSpeed - (double)baseline.mechaReplicateSpeed * 9.0);
float num2 = mecha.walkSpeed - baseline.mechaWalkSpeed;
if (!Valid(num) || !Valid(num2))
{
return false;
}
mecha.miningSpeed = baseline.mechaMiningSpeed;
mecha.replicateSpeed = num;
mecha.walkSpeed = num2;
mecha.droneEjectEnergy = baseline.droneEjectEnergy;
mecha.droneEnergyPerMeter = baseline.droneEnergyPerMeter;
return true;
}
}
[HarmonyPatch(typeof(PlayerAction_Mine), "GameTick")]
internal static class MiningPerformance
{
[ThreadStatic]
private static int depth;
internal static bool Active
{
get
{
if (Plugin.Options != null)
{
return Plugin.Options.Enabled.Value;
}
return false;
}
}
internal static bool Muted => depth > 0;
[HarmonyPrefix]
internal static void Prefix(out bool __state)
{
__state = Active;
if (__state)
{
depth++;
}
}
[HarmonyFinalizer]
internal static void Finalizer(bool __state)
{
if (__state)
{
depth--;
}
}
internal static int BatchCount(int ticks, int miningTime, int amount, bool infinite)
{
long num = (long)miningTime * 10000L;
if (ticks <= 0 || num <= 0 || num > int.MaxValue || amount <= 0)
{
return 0;
}
long num2 = ticks / num;
if (!infinite)
{
num2 = Math.Min(num2, amount);
}
return (int)Math.Max(0L, num2 - 1);
}
internal static void BatchBeforeNative(PlayerAction_Mine action)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Invalid comparison between Unknown and I4
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Invalid comparison between Unknown and I4
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected I4, but got Unknown
if (!Active || action == null || ((PlayerAction)action).player == null || (int)action.miningType != 2)
{
return;
}
PlanetFactory factory = ((PlayerAction)action).player.factory;
int miningId = action.miningId;
if (factory == null || miningId <= 0 || miningId >= factory.veinPool.Length)
{
return;
}
VeinData val = factory.veinPool[miningId];
if (val.id != miningId || (int)val.type == 7)
{
return;
}
VeinProto val2 = ((ProtoSet<VeinProto>)(object)LDB.veins).Select((int)val.type);
if (val2 == null)
{
return;
}
bool isInfiniteResource = GameMain.data.gameDesc.isInfiniteResource;
int num = BatchCount(action.miningTick, val2.MiningTime, val.amount, isInfiniteResource);
if (num != 0)
{
int num2 = ((PlayerAction)action).player.TryAddItemToPackage(val2.MiningItem, num, 0, true, 0, false);
action.AddProductionStat(val2.MiningItem, num, factory);
((PlayerAction)action).controller.gameData.history.AddFeatureValue(2200000 + val2.MiningItem, num);
if (!isInfiniteResource)
{
ref VeinData reference = ref factory.veinPool[miningId];
reference.amount -= num;
ref VeinGroup reference2 = ref factory.veinGroups[val.groupIndex];
reference2.amount -= num;
}
action.miningTick -= (int)((long)num * (long)val2.MiningTime * 10000);
if (num2 > 0)
{
UIItemup.Up(val2.MiningItem, num2);
}
}
}
internal static void Effect(int id, Vector3 pos, Quaternion rot)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if (!Active)
{
VFEffectEmitter.Emit(id, pos, rot);
}
}
internal static void Popup(int item, int count, Vector3 pos, int index)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if (!Active)
{
UIRealtimeTip.PopupItemGet(item, count, pos, index);
}
}
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> source)
{
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Expected O, but got Unknown
//IL_016a: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>(source);
int num = 0;
int num2 = 0;
int num3 = 0;
for (int i = 0; i < list.Count; i++)
{
MethodInfo methodInfo = list[i].operand as MethodInfo;
if (methodInfo == null)
{
continue;
}
if (methodInfo.DeclaringType == typeof(PlayerAction_Mine) && methodInfo.Name == "set_percent" && i + 1 < list.Count && list[i + 1].opcode == OpCodes.Br)
{
bool flag = false;
for (int j = Math.Max(0, i - 10); j < i; j++)
{
FieldInfo fieldInfo = list[j].operand as FieldInfo;
if (fieldInfo != null && fieldInfo.DeclaringType == typeof(VeinProto) && fieldInfo.Name == "MiningTime")
{
flag = true;
}
}
if (flag)
{
CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null);
val.labels.AddRange(list[i + 1].labels);
list[i + 1].labels.Clear();
list.Insert(i + 1, val);
list.Insert(i + 2, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(MiningPerformance), "BatchBeforeNative", (Type[])null, (Type[])null)));
num++;
}
}
if (methodInfo.DeclaringType == typeof(VFEffectEmitter) && methodInfo.Name == "Emit" && methodInfo.GetParameters().Length == 3)
{
list[i].operand = AccessTools.Method(typeof(MiningPerformance), "Effect", (Type[])null, (Type[])null);
num2++;
}
if (methodInfo.DeclaringType == typeof(UIRealtimeTip) && methodInfo.Name == "PopupItemGet")
{
list[i].operand = AccessTools.Method(typeof(MiningPerformance), "Popup", (Type[])null, (Type[])null);
num3++;
}
}
if (num != 1 || num2 != 3 || num3 != 3)
{
throw new InvalidOperationException("Unsupported hand-mining IL: batch=" + num + ", effects=" + num2 + ", popups=" + num3);
}
return list;
}
}
[HarmonyPatch]
internal static class MiningAudio
{
[HarmonyTargetMethods]
internal static IEnumerable<MethodBase> Targets()
{
foreach (MethodInfo method in AccessTools.GetDeclaredMethods(typeof(VFAudio)))
{
ParameterInfo[] p = method.GetParameters();
if (method.Name == "Create" && method.IsStatic && method.ReturnType == typeof(VFAudio) && p.Length == 7 && (p[0].ParameterType == typeof(int) || p[0].ParameterType == typeof(string)))
{
yield return method;
}
}
}
[HarmonyPrefix]
internal static bool Prefix()
{
return !MiningPerformance.Muted;
}
}
[HarmonyPatch]
internal static class Consumers
{
internal static readonly Dictionary<string, string> Fields = new Dictionary<string, string>
{
{ "miningSpeed", "Mining" },
{ "replicateSpeed", "Crafting" },
{ "walkSpeed", "Walking" },
{ "jumpSpeed", "Jump" },
{ "droneEjectEnergy", "Launch" }
};
internal static IEnumerable<MethodBase> Targets()
{
string[] types = new string[13]
{
"PlayerAction_Mine", "PlayerMove_Drift", "PlayerMove_Drift", "PlayerMove_Fly", "PlayerMove_Fly", "PlayerMove_Walk", "PlayerMove_Walk", "PlayerController", "Mecha", "MechaForge",
"UITechTree", "PlayerMove_Walk", "PlayerAnimator"
};
string[] methods = new string[13]
{
"GameTick", "GameTick", "UseDriftEnergy", "GameTick", "UseFlyEnergy", "GameTick", "UseWalkEnergy", "HandleCollision", "CheckEjectConstructionDroneCondition", "GameTick",
"RefreshDataValueText", "Init", "CalculateJumpWeights"
};
for (int i = 0; i < types.Length; i++)
{
Type type = typeof(Mecha).Assembly.GetType(types[i]);
MethodInfo method = ((type == null) ? null : AccessTools.Method(type, methods[i], (Type[])null, (Type[])null));
if (method == null)
{
throw new MissingMethodException(types[i], methods[i]);
}
yield return method;
}
Type replacement = AccessTools.TypeByName("GalacticScale.PatchOnPlayerMove_Fly");
if (replacement != null)
{
MethodInfo method2 = AccessTools.Method(replacement, "GameTick", new Type[1] { typeof(PlayerMove_Fly).MakeByRefType() }, (Type[])null);
if (method2 == null || method2.ReturnType != typeof(bool))
{
throw new MissingMethodException(replacement.FullName, "GameTick(ref PlayerMove_Fly)");
}
yield return method2;
}
}
[HarmonyTargetMethods]
private static IEnumerable<MethodBase> TargetMethods()
{
return Targets();
}
[HarmonyTranspiler]
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> source, MethodBase __originalMethod)
{
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Expected O, but got Unknown
List<CodeInstruction> list = new List<CodeInstruction>();
int num = 0;
foreach (CodeInstruction item in source)
{
list.Add(item);
FieldInfo fieldInfo = item.operand as FieldInfo;
if (item.opcode == OpCodes.Ldfld && fieldInfo != null && fieldInfo.DeclaringType == typeof(Mecha) && Fields.TryGetValue(fieldInfo.Name, out var value))
{
if (fieldInfo.Name == "walkSpeed" && __originalMethod != null && (__originalMethod.DeclaringType == typeof(PlayerMove_Fly) || __originalMethod.DeclaringType.FullName == "GalacticScale.PatchOnPlayerMove_Fly"))
{
value = "FlightWalk";
}
list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Modifiers), value, (Type[])null, (Type[])null)));
num++;
}
}
if (num == 0)
{
throw new InvalidOperationException("No expected mecha stat reads in " + __originalMethod);
}
return list;
}
}
[HarmonyPatch(typeof(Mecha), "UseEnergy")]
internal static class EnergyUse
{
[HarmonyPriority(0)]
[HarmonyPrefix]
internal static void Prefix(ref double __0)
{
__0 = Modifiers.Energy(__0);
}
}
[HarmonyPatch]
internal static class DroneTravel
{
[HarmonyTargetMethod]
internal static MethodBase Target()
{
foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(DroneComponent)))
{
ParameterInfo[] parameters = declaredMethod.GetParameters();
if (declaredMethod.Name == "InternalUpdate" && parameters.Length == 10 && parameters[5].ParameterType == typeof(double).MakeByRefType() && parameters[6].ParameterType == typeof(double).MakeByRefType() && parameters[7].ParameterType == typeof(double) && parameters[9].ParameterType == typeof(float).MakeByRefType())
{
return declaredMethod;
}
}
throw new MissingMethodException("Icarus DroneComponent.InternalUpdate overload");
}
[HarmonyPrefix]
internal static void Prefix(ref DroneComponent __instance, ref double __7)
{
if (__instance.owner == 0)
{
__7 = Modifiers.Travel(__7);
}
}
}
[BepInIncompatibility("dsp.mechboost.btn")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("LokiMoonLabs.IcarusBoost", "Icarus Boost", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(GameMain), "Begin")]
private static class Loaded
{
[HarmonyPostfix]
[HarmonyPriority(0)]
private static void Postfix()
{
if (Options == null || !Options.Enabled.Value || GameMain.mainPlayer == null)
{
return;
}
Mecha mecha = GameMain.mainPlayer.mecha;
if (mecha == null)
{
return;
}
float miningSpeed = mecha.miningSpeed;
float replicateSpeed = mecha.replicateSpeed;
float walkSpeed = mecha.walkSpeed;
bool flag = LegacyCleanup.Apply(mecha, Configs.freeMode);
if (!((Object)(object)instance == (Object)null))
{
if (flag)
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)string.Format(CultureInfo.InvariantCulture, "Removed saved DSP MechBoost starting bonuses; research retained. Mining {0}->{1}; crafting {2}->{3}; walking {4}->{5}; native drone energy fields restored. Configured runtime multipliers now apply.", miningSpeed, mecha.miningSpeed, replicateSpeed, mecha.replicateSpeed, walkSpeed, mecha.walkSpeed));
}
else
{
((BaseUnityPlugin)instance).Logger.LogInfo((object)"No complete saved DSP MechBoost pattern found; current saved stats were retained. Configured runtime multipliers apply.");
}
}
}
}
public const string Guid = "LokiMoonLabs.IcarusBoost";
internal static Settings Options;
private static Plugin instance;
private Harmony harmony;
private void Awake()
{
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
Options = new Settings(((BaseUnityPlugin)this).Config);
((BaseUnityPlugin)this).Config.Save();
instance = this;
harmony = new Harmony("LokiMoonLabs.IcarusBoost");
try
{
harmony.PatchAll(typeof(Plugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)("Icarus Boost ready. Config: " + ((BaseUnityPlugin)this).Config.ConfigFilePath));
}
catch (Exception ex)
{
harmony.UnpatchSelf();
Options = null;
((BaseUnityPlugin)this).Logger.LogError((object)("Icarus Boost could not install its patches; all of its patches were removed. " + ex));
}
}
private void OnDestroy()
{
if (harmony != null)
{
harmony.UnpatchSelf();
}
if ((Object)(object)instance == (Object)(object)this)
{
instance = null;
Options = null;
}
}
}
internal sealed class Settings
{
internal const float MiningMaximum = 500f;
internal const float CraftingMaximum = 1000f;
internal const float WalkingMaximum = 20f;
internal const float JumpMaximum = 100f;
internal const float FlightMaximum = 20f;
internal const float EnergyMaximum = 5f;
internal const float MiningCeiling = 20000f;
internal const float CraftingCeiling = 10000f;
internal const float WalkingCeiling = 240f;
internal const float JumpCeiling = 120f;
internal const float FlightCeiling = 480f;
internal readonly ConfigEntry<bool> Enabled;
internal readonly ConfigEntry<float> Mining;
internal readonly ConfigEntry<float> Crafting;
internal readonly ConfigEntry<float> Walking;
internal readonly ConfigEntry<float> JumpHeight;
internal readonly ConfigEntry<float> Flight;
internal readonly ConfigEntry<float> Energy;
internal readonly ConfigEntry<float> Launch;
internal readonly ConfigEntry<float> Travel;
internal Settings(ConfigFile file)
{
Enabled = file.Bind<bool>("General", "Enabled", true, "Master switch for all boosts, quiet batched mining and flight altitude stabilization. Also enables one-time cleanup of recognizable saved DSP MechBoost bonuses while preserving research. Restart the game after changing this file.");
Mining = Number(file, "Speeds", "MiningSpeedMultiplier", 500f, 0.1f, 500f, "Icarus hand-mining speed. 1 = native speed; 500 = maximum multiplier. Does not affect mining machines. Ore extraction is batched; mining sounds, particle bursts and floating pickup popups are suppressed. Item-count feedback remains. Added speed is capped at 20000 native stat units.");
Crafting = Number(file, "Speeds", "CraftingSpeedMultiplier", 1000f, 0.1f, 1000f, "Icarus replicator speed, including researched crafting upgrades. 1 = native speed; 1000 = maximum multiplier. Keeps recipe ingredients, research and normal completion rules. Added speed is capped at 10000 native stat units; final queue progress is protected against integer overflow.");
Walking = Number(file, "Speeds", "WalkingSpeedMultiplier", 20f, 0.25f, 20f, "Icarus walking speed. 1 = native speed; 20 = maximum multiplier. Also affects native movement calculations that use walking speed. Added ground speed is capped at 240 m/s.");
JumpHeight = Number(file, "Movement", "JumpHeightMultiplier", 100f, 1f, 100f, "Approximate jump height. 1 = native height; 100 = maximum multiplier. Launch speed uses the square root of this value and is capped at 120 m/s for added boosts. Terrain, gravity and transitions into flight affect actual height.");
Flight = Number(file, "Movement", "FlightSpeedMultiplier", 20f, 0.25f, 20f, "Extra horizontal speed in planetary flight. 1 = no extra flight boost; 20 = maximum multiplier. Combines with WalkingSpeedMultiplier, up to 480 m/s added flight speed. Altitude stabilization follows the normal target height, including Galactic Scale flight. Manual ascent/descent, landing and space transitions remain available. Does not change sailing or warp speed.");
Energy = Number(file, "Energy", "MechaEnergyUseMultiplier", 0.5f, 0f, 5f, "Multiplier for costs routed through the native Mecha.UseEnergy method. 1 is normal, 0.5 is half and 0 is free. Other energy paths are not all routed through this method.");
Launch = Number(file, "Energy", "DroneLaunchEnergyMultiplier", 0f, 0f, 5f, "Icarus construction-drone launch energy requirement multiplier. 0 removes the requirement, 1 keeps the saved/native amount. Does not change battlefield-base drones.");
Travel = Number(file, "Energy", "DroneTravelEnergyMultiplier", 0f, 0f, 5f, "Icarus construction-drone travel energy multiplier. 0 is free travel and 1 is normal. Does not change battlefield-base drones or drone repair energy.");
}
private static ConfigEntry<float> Number(ConfigFile file, string section, string key, float fallback, float minimum, float maximum, string description)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
string text = ((section == "Energy") ? string.Empty : " Existing native/saved speeds above an added-speed cap are retained.");
ConfigEntry<float> val = file.Bind<float>(section, key, fallback, new ConfigDescription(description + text + " Restart after editing this file.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(minimum, maximum), new object[0]));
val.Value = Bound(val.Value, fallback, minimum, maximum);
return val;
}
internal static float Bound(float value, float fallback, float minimum, float maximum)
{
if (!float.IsNaN(value) && !float.IsInfinity(value))
{
return Math.Max(minimum, Math.Min(maximum, value));
}
return fallback;
}
}
internal static class Modifiers
{
private static bool Active
{
get
{
if (Plugin.Options != null)
{
return Plugin.Options.Enabled.Value;
}
return false;
}
}
internal static float Mining(float value)
{
if (!Active)
{
return value;
}
return LimitedSpeed(value, Settings.Bound(Plugin.Options.Mining.Value, 500f, 0.1f, 500f), 20000f);
}
internal static float Crafting(float value)
{
if (!Active)
{
return value;
}
return LimitedSpeed(value, Settings.Bound(Plugin.Options.Crafting.Value, 1000f, 0.1f, 1000f), 10000f);
}
internal static float Walking(float value)
{
if (!Active)
{
return value;
}
return LimitedSpeed(value, Settings.Bound(Plugin.Options.Walking.Value, 20f, 0.25f, 20f), 240f);
}
internal static float Jump(float value)
{
if (!Active)
{
return value;
}
return LimitedSpeed(value, (float)Math.Sqrt(Settings.Bound(Plugin.Options.JumpHeight.Value, 100f, 1f, 100f)), 120f);
}
internal static float FlightWalk(float value)
{
if (!Active)
{
return value;
}
float num = Walking(value);
float num2 = Settings.Bound(Plugin.Options.Flight.Value, 20f, 0.25f, 20f);
if (value <= 0f || float.IsNaN(value) || float.IsInfinity(value))
{
return value;
}
return (float)Math.Min(Math.Max(value, 192f), (double)num * (double)num2);
}
internal static double Launch(double value)
{
if (!Active)
{
return value;
}
return Cost(value, Settings.Bound(Plugin.Options.Launch.Value, 0f, 0f, 5f));
}
internal static double Travel(double value)
{
if (!Active)
{
return value;
}
return Cost(value, Settings.Bound(Plugin.Options.Travel.Value, 0f, 0f, 5f));
}
internal static double Energy(double value)
{
if (!Active)
{
return value;
}
return Cost(value, Settings.Bound(Plugin.Options.Energy.Value, 0.5f, 0f, 5f));
}
internal static float LimitedSpeed(float value, float multiplier, float ceiling)
{
return Math.Min(Speed(value, multiplier), Math.Max(value, ceiling));
}
internal static float Speed(float value, float multiplier)
{
if (value <= 0f || float.IsNaN(value) || float.IsInfinity(value) || float.IsNaN(multiplier) || float.IsInfinity(multiplier) || multiplier < 0f)
{
return value;
}
return (float)Math.Min(8.5070586659632215E+37, (double)value * (double)multiplier);
}
internal static double Cost(double value, float multiplier)
{
if (value <= 0.0 || double.IsNaN(value) || double.IsInfinity(value) || float.IsNaN(multiplier) || float.IsInfinity(multiplier) || multiplier < 0f)
{
return value;
}
return Math.Min(4.4942328371557893E+307, value * (double)multiplier);
}
}