Decompiled source of Lethal Company Overhaul v1.0.1

BepInEx/plugins/ModRush_Overhaul-1.0.1.dll

Decompiled a year ago
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
	}
}