using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using ModRushOverhaul.Patches;
using ModRushOverhaul.enums;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ModRush_Overhaul-1.0.1")]
[assembly: AssemblyDescription("An Overhaul Mod for Lethal Company")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("By Rushki")]
[assembly: AssemblyProduct("ModRushPatcher")]
[assembly: AssemblyCopyright("Copyright © 2023 Rushki")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c6cc886c-71be-445a-8fd5-ab2c273ae675")]
[assembly: AssemblyFileVersion("1.0.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace ModRushOverhaul
{
[BepInPlugin("ModRush.Patcher", "Modrush Overhaul", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
private const string GUID = "ModRush.Patcher";
private const string NAME = "Modrush Overhaul";
private const string VERSION = "1.0.1";
private readonly Harmony harmony = new Harmony("ModRush.Patcher");
internal ManualLogSource mls;
public static PluginConfig cfg;
private static Plugin Instance;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
mls = Logger.CreateLogSource("ModRush.Patcher");
cfg = new PluginConfig(this);
harmony.PatchAll(typeof(Plugin));
mls.LogWarning((object)"The Company...");
if (cfg.usePremiumBatterys)
{
harmony.PatchAll(typeof(BatteryItemsPatch));
mls.LogWarning((object)"...bought better Batteries.");
}
if (cfg.keepItemsOnTeleport)
{
harmony.PatchAll(typeof(ShipTeleporterPatch));
mls.LogWarning((object)"...upgraded the Inverse Teleporter.");
}
if (cfg.useStaminaRework)
{
harmony.PatchAll(typeof(PlayerControllerBPatch));
mls.LogWarning((object)"...got you a Gym subscription.");
}
harmony.PatchAll(typeof(ItemDropshipPatch));
mls.LogWarning((object)"...now pays Amazon Premium.");
harmony.PatchAll(typeof(RoundManagerPatch));
if (cfg.dontLoseScrap)
{
mls.LogWarning((object)"...insured all found scrap");
}
if (cfg.longerDay)
{
harmony.PatchAll(typeof(TimeOfDayPatch));
mls.LogWarning((object)"God made the day longer");
}
if (cfg.openDoorsFaster)
{
harmony.PatchAll(typeof(DoorLockPatch));
mls.LogWarning((object)"You learned how to open doors quickly");
}
harmony.PatchAll(typeof(TerminalPatch));
mls.LogWarning((object)"New Terminal commands \"curval\" and \"quota\"");
}
}
public class PluginConfig
{
public readonly bool keepItemsOnTeleport;
public readonly bool usePremiumBatterys;
public readonly bool useStaminaRework;
public readonly bool dontLoseScrap;
public readonly bool longerDay;
public readonly bool openDoorsFaster;
public readonly float dropshipTimeToArrive;
public PluginConfig(Plugin BindingPlugin)
{
keepItemsOnTeleport = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroKeepItemsOnTeleport", true, "Do you want to keep your items when teleported?\ntrue = yes / false = no").Value;
usePremiumBatterys = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroUsePremiumBatterys", true, "Should the Company buy premium batteries?\ntrue = yes / false = no").Value;
useStaminaRework = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroUseStaminaRework", true, "You want to use a Gym subscription?\ntrue = yes / false = no").Value;
dontLoseScrap = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroDontLoseScrap", false, "Should the Company insure all found scrap?\ntrue = yes / false = no").Value;
longerDay = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroLongerDay", true, "Please God to make the day longer?\ntrue = yes / false = no").Value;
openDoorsFaster = ((BaseUnityPlugin)BindingPlugin).Config.Bind<bool>("ModRush Overhaul", "mroOpenDoorsFaster", false, "Do you want to learn how to open doors?\ntrue = yes / false = no").Value;
dropshipTimeToArrive = ((BaseUnityPlugin)BindingPlugin).Config.Bind<float>("ModRush Overhaul", "mroDropshipTimeToArrive", 8f, "Which type of Amazon Premium shoud the Company pay?\nHow fast will the Dropship arrive in seconds:").Value;
}
}
}
namespace ModRushOverhaul.Patches
{
internal class BatteryItemsPatch
{
[HarmonyPatch(typeof(FlashlightItem), "ItemActivate")]
[HarmonyPrefix]
private static void flashlightBattery(ref FlashlightItem __instance)
{
switch ((Flashlights)__instance.flashlightTypeID)
{
case Flashlights.ProFlashlight:
((GrabbableObject)__instance).itemProperties.batteryUsage = 450f;
break;
case Flashlights.Flashlight:
((GrabbableObject)__instance).itemProperties.batteryUsage = 210f;
break;
case Flashlights.LaserPointer:
((GrabbableObject)__instance).itemProperties.batteryUsage = 275f;
break;
}
}
[HarmonyPatch(typeof(WalkieTalkie), "ItemActivate")]
[HarmonyPostfix]
private static void walkieTalkieBattery(ref WalkieTalkie __instance)
{
((GrabbableObject)__instance).itemProperties.batteryUsage = 500f;
}
[HarmonyPatch(typeof(JetpackItem), "ItemActivate")]
[HarmonyPrefix]
private static void jetpackFuel(ref JetpackItem __instance)
{
((GrabbableObject)__instance).itemProperties.batteryUsage = 180f;
}
[HarmonyPatch(typeof(BoomboxItem), "ItemActivate")]
[HarmonyPrefix]
private static void hardbassLife(ref BoomboxItem __instance)
{
((GrabbableObject)__instance).itemProperties.batteryUsage = 250f;
}
}
[HarmonyPatch(typeof(DoorLock))]
internal class DoorLockPatch
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
private static void instantUse(ref InteractTrigger ___doorTrigger)
{
___doorTrigger.timeToHold = 0f;
}
}
[HarmonyPatch(typeof(ItemDropship))]
internal class ItemDropshipPatch
{
private static StartOfRound playersManager;
private static List<int> itemsToDeliver;
private static Terminal terminalScript;
private static List<int> orderedItemsFromTerminal;
private static float howFast = Plugin.cfg.dropshipTimeToArrive;
private static float willStay = 60f;
[HarmonyPatch("Start")]
[HarmonyPrefix]
public static void initializeDropship(ItemDropship __instance)
{
playersManager = Object.FindObjectOfType<StartOfRound>();
terminalScript = Object.FindObjectOfType<Terminal>();
itemsToDeliver = (List<int>)Traverse.Create((object)__instance).Field("itemsToDeliver").GetValue();
}
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static void dropshipUpdate(ItemDropship __instance)
{
if (((NetworkBehaviour)__instance).IsServer && !__instance.deliveringOrder && terminalScript.orderedItemsFromTerminal.Count > 0 && !playersManager.shipHasLanded)
{
__instance.shipTimer += Time.deltaTime;
}
}
[HarmonyPatch("Update")]
private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
List<CodeInstruction> list = new List<CodeInstruction>(instructions);
for (int i = 0; i < list.Count; i++)
{
if (list[i].opcode == OpCodes.Ldc_R4)
{
if ((float)list[i].operand == 20f)
{
list[i].operand = willStay;
}
else if ((float)list[i].operand == 40f)
{
list[i].operand = willStay + howFast;
}
else if ((float)list[i].operand == 30f)
{
list[i].operand = willStay;
break;
}
}
}
return list.AsEnumerable();
}
[HarmonyPatch("ShipLandedAnimationEvent")]
[HarmonyPrefix]
public static void addLateItemsServer(ItemDropship __instance)
{
if (((NetworkBehaviour)__instance).IsServer && __instance.shipLanded && !__instance.shipDoorsOpened)
{
while (orderedItemsFromTerminal.Count > 0 && itemsToDeliver.Count < 12)
{
itemsToDeliver.Add(orderedItemsFromTerminal[0]);
orderedItemsFromTerminal.RemoveAt(0);
}
}
}
[HarmonyPatch(typeof(Terminal), "Start")]
[HarmonyPrefix]
public static void initializeTerminal(Terminal __instance)
{
orderedItemsFromTerminal = __instance.orderedItemsFromTerminal;
}
}
[HarmonyPatch(typeof(PlayerControllerB))]
internal class PlayerControllerBPatch
{
private static float currentPlayerWeight;
private static float newWeight;
private static float playerSprintMeter;
private static float drianMultipier = 0.7f;
private static float regenMultipier = 1.2f;
private static float weightMultipier = 0.9f;
private static float jumpMultipier = 0.7f;
[HarmonyPatch("Update")]
[HarmonyPrefix]
public static void getStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
playerSprintMeter = __instance.sprintMeter;
currentPlayerWeight = __instance.carryWeight;
newWeight = Mathf.Max(__instance.carryWeight * weightMultipier, 1f);
__instance.carryWeight = newWeight;
}
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void setStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
float num = __instance.sprintMeter - playerSprintMeter;
if (num < 0f)
{
__instance.sprintMeter = Mathf.Max(playerSprintMeter + num * drianMultipier, 0f);
}
else if (num > 0f)
{
__instance.sprintMeter = Mathf.Min(playerSprintMeter + num * regenMultipier, 1f);
}
__instance.carryWeight = currentPlayerWeight + (__instance.carryWeight - newWeight);
}
}
[HarmonyPatch("LateUpdate")]
[HarmonyPrefix]
public static void getLateUpdateStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
playerSprintMeter = __instance.sprintMeter;
currentPlayerWeight = __instance.carryWeight;
newWeight = Mathf.Max(__instance.carryWeight * weightMultipier, 1f);
__instance.carryWeight = newWeight;
}
}
[HarmonyPatch("LateUpdate")]
[HarmonyPostfix]
public static void setLateUpdateStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
float num = __instance.sprintMeter - playerSprintMeter;
if (num < 0f)
{
__instance.sprintMeter = Mathf.Max(playerSprintMeter + num * drianMultipier, 0f);
}
else if (num > 0f)
{
__instance.sprintMeter = Mathf.Min(playerSprintMeter + num * regenMultipier, 1f);
}
__instance.carryWeight = currentPlayerWeight + (__instance.carryWeight - newWeight);
}
}
[HarmonyPatch("Jump_performed")]
[HarmonyPrefix]
public static void getJumpStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
playerSprintMeter = __instance.sprintMeter;
}
}
[HarmonyPatch("Jump_performed")]
[HarmonyPostfix]
public static void setJumpStamina(PlayerControllerB __instance)
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
float num = __instance.sprintMeter - playerSprintMeter;
if (num < 0f)
{
__instance.sprintMeter = Mathf.Max(new float[1] { playerSprintMeter + num * jumpMultipier });
}
}
}
}
[HarmonyPatch(typeof(ShipTeleporter))]
internal class ShipTeleporterPatch
{
private static AudioClip teleporterBeamUpSFX;
private static AudioSource shipTeleporterAudio;
[HarmonyPatch("TeleportPlayerOutWithInverseTeleporter")]
[HarmonyPrefix]
private static bool doNotLoseItemsInverse(ref int playerObj, ref Vector3 teleportPos)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Expected O, but got Unknown
//IL_0116: Expected O, but got Unknown
if (StartOfRound.Instance.allPlayerScripts[playerObj].isPlayerDead)
{
StartCoroutine(teleportBodyOut(playerObj, teleportPos));
return false;
}
PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerObj];
SetPlayerTeleporterId(val, -1);
if (Object.op_Implicit((Object)(object)Object.FindObjectOfType<AudioReverbPresets>()))
{
Object.FindObjectOfType<AudioReverbPresets>().audioPresets[2].ChangeAudioReverbForPlayer(val);
}
val.isInElevator = false;
val.isInHangarShipRoom = false;
val.isInsideFactory = true;
val.averageVelocity = 0f;
val.velocityLastFrame = Vector3.zero;
StartOfRound.Instance.allPlayerScripts[playerObj].TeleportPlayer(teleportPos, false, 0f, false, true);
StartOfRound.Instance.allPlayerScripts[playerObj].beamOutParticle.Play();
shipTeleporterAudio.PlayOneShot(teleporterBeamUpSFX);
StartOfRound.Instance.allPlayerScripts[playerObj].movementAudio.PlayOneShot(teleporterBeamUpSFX);
if ((Object)val == (Object)GameNetworkManager.Instance.localPlayerController)
{
Debug.Log((object)"Teleporter shaking camera");
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
}
return false;
}
private static void StartCoroutine(string routine)
{
}
private static void SetPlayerTeleporterId(PlayerControllerB playerScript, int teleporterId)
{
}
private static string teleportBodyOut(int playerObj, Vector3 teleportPosition)
{
return "Body Out";
}
[HarmonyPatch("Awake")]
[HarmonyPrefix]
private static void lowerCooldown(ref float ___cooldownAmount, ref bool ___isInverseTeleporter)
{
if (___isInverseTeleporter)
{
___cooldownAmount = 60f;
}
}
}
[HarmonyPatch(typeof(RoundManager))]
internal class RoundManagerPatch
{
private static List<GameObject> spawnedSyncedObjects = new List<GameObject>();
[HarmonyPatch("DespawnPropsAtEndOfRound")]
[HarmonyPrefix]
private static bool dontLoseScrapWhenAllDead(RoundManager __instance, ref bool despawnAllItems)
{
if (Plugin.cfg.dontLoseScrap)
{
if (!((NetworkBehaviour)__instance).IsServer)
{
return false;
}
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
for (int i = 0; i < array.Length; i++)
{
if (despawnAllItems || (!array[i].isHeld && !array[i].isInShipRoom))
{
if (array[i].isHeld && (Object)(object)array[i].playerHeldBy != (Object)null)
{
array[i].playerHeldBy.DropAllHeldItems(true, false);
}
((Component)array[i]).gameObject.GetComponent<NetworkObject>().Despawn(true);
}
else
{
array[i].scrapPersistedThroughRounds = true;
}
if (spawnedSyncedObjects.Contains(((Component)array[i]).gameObject))
{
spawnedSyncedObjects.Remove(((Component)array[i]).gameObject);
}
}
GameObject[] array2 = GameObject.FindGameObjectsWithTag("TemporaryEffect");
for (int j = 0; j < array2.Length; j++)
{
Object.Destroy((Object)(object)array2[j]);
}
return false;
}
return true;
}
[HarmonyPatch("PlotOutEnemiesForNextHour")]
[HarmonyPrefix]
private static void spawnEnemysFaster(RoundManager __instance)
{
if (Plugin.cfg.longerDay)
{
__instance.currentLevel.spawnProbabilityRange = 7f;
__instance.currentLevel.maxEnemyPowerCount = 12;
}
}
}
[HarmonyPatch(typeof(Terminal))]
internal class TerminalPatch
{
[HarmonyPostfix]
[HarmonyPatch("ParsePlayerSentence")]
private static void displayShipValue(ref Terminal __instance, ref TerminalNode __result)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Expected O, but got Unknown
string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded);
if (text.ToLower() == "curval")
{
List<GrabbableObject> shipItems = getShipItems();
int num = calculateScrapInShipValue(shipItems);
TerminalNode val = new TerminalNode();
val.displayText = $"Total scrap value inside the ship: ${num}\n";
val.clearPreviousText = true;
__result = val;
}
else
{
if (!(text.ToLower() == "quota"))
{
return;
}
List<GrabbableObject> shipItems2 = getShipItems();
int profitQuota = TimeOfDay.Instance.profitQuota;
int quotaFulfilled = TimeOfDay.Instance.quotaFulfilled;
int daysUntilDeadline = TimeOfDay.Instance.daysUntilDeadline;
float companyBuyingRate = StartOfRound.Instance.companyBuyingRate;
int num2 = (int)((float)calculateScrapInShipValue(shipItems2) * companyBuyingRate);
TerminalNode val2 = new TerminalNode();
if (num2 < profitQuota)
{
if (daysUntilDeadline <= 0)
{
val2.displayText = "You do not meet the profit quota.\n\nHappy disciplinary process! :)\n\n\n\nPS: I recommend restarting now\n";
}
else if (daysUntilDeadline > 0)
{
val2.displayText = $"Current quota: ${quotaFulfilled} / ${profitQuota}\n" + $"Buying at {Mathf.RoundToInt(companyBuyingRate * 100f)}%\n\n" + "You do not meet the profit quota.\n\n" + $"Your current scrap value at buying rate is ${num2}\n" + $"Difference: ${profitQuota - quotaFulfilled - num2}\n\n" + "I believe in you!\n";
}
}
else
{
val2.displayText = $"Current quota: ${quotaFulfilled} / ${profitQuota}\n" + $"Buying at {Mathf.RoundToInt(companyBuyingRate * 100f)}%\n\n" + "Note: All values calculated including the buying rate.\n\nTo meet the profit quota, sell the following items:\n\n";
GrabbableObject val3 = null;
float num3 = 0f;
foreach (GrabbableObject item in shipItems2.OrderByDescending((GrabbableObject item) => item.scrapValue))
{
int num4 = (int)((float)item.scrapValue * companyBuyingRate);
if (num4 == 0)
{
continue;
}
if ((float)(profitQuota - quotaFulfilled) - num3 >= (float)num4)
{
val2.displayText += $"- {item.itemProperties.itemName}: ${num4}\n";
num3 += (float)num4;
if (num3 >= (float)(profitQuota - quotaFulfilled))
{
break;
}
}
else
{
val3 = item;
}
}
string arg = "";
if (num3 != (float)(profitQuota - quotaFulfilled))
{
val2.displayText += $"\nThis item overshoots quota, but is the cheapest you own: {val3.itemProperties.itemName} (${(int)((float)val3.scrapValue * companyBuyingRate)})\n";
arg = $"(+ ${(int)((float)val3.scrapValue * companyBuyingRate)})";
}
val2.displayText += $"\nSelling value: ${num3} {arg}\n";
}
val2.clearPreviousText = true;
__result = val2;
}
}
private static int calculateScrapInShipValue(List<GrabbableObject> list)
{
return list.Sum((GrabbableObject item) => item.scrapValue);
}
private static List<GrabbableObject> getShipItems()
{
return (from sellableObject in GameObject.Find("/Environment/HangarShip").GetComponentsInChildren<GrabbableObject>()
where sellableObject.scrapValue != 0 && ((Object)sellableObject).name != "ClipboardManual" && ((Object)sellableObject).name != "StickyNoteItem"
select sellableObject).ToList();
}
}
[HarmonyPatch(typeof(TimeOfDay))]
internal class TimeOfDayPatch
{
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void longerDay(TimeOfDay __instance)
{
__instance.globalTimeSpeedMultiplier = 0.95f;
}
}
}
namespace ModRushOverhaul.enums
{
public enum Flashlights
{
ProFlashlight,
Flashlight,
LaserPointer
}
}