Decompiled source of JetpackFixes v1.5.0

JetpackFixes.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("JetpackFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Fixes some (lethal) bugs with the jetpack")]
[assembly: AssemblyFileVersion("1.5.0.0")]
[assembly: AssemblyInformationalVersion("1.5.0+f92ab859f14b326c1104a207f0f0ec70ac9c3a18")]
[assembly: AssemblyProduct("JetpackFixes")]
[assembly: AssemblyTitle("JetpackFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.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 JetpackFixes
{
	internal enum MidAirExplosions
	{
		Off = -1,
		OnlyTooHigh,
		Always
	}
	[BepInPlugin("butterystancakes.lethalcompany.jetpackfixes", "Jetpack Fixes", "1.5.0")]
	public class Plugin : BaseUnityPlugin
	{
		private const string PLUGIN_GUID = "butterystancakes.lethalcompany.jetpackfixes";

		private const string PLUGIN_NAME = "Jetpack Fixes";

		private const string PLUGIN_VERSION = "1.5.0";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<MidAirExplosions> configMidAirExplosions;

		internal static ConfigEntry<bool> configTransferMomentum;

		private void Awake()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			configMidAirExplosions = ((BaseUnityPlugin)this).Config.Bind<MidAirExplosions>("Misc", "MidAirExplosions", MidAirExplosions.OnlyTooHigh, "When should high speeds (exceeding 50u/s, vanilla's \"speed limit\") explode the jetpack?\n\"Off\" will only explode when you crash into something solid.\n\"OnlyTooHigh\" will explode if you are flying too fast, while you are also *extremely* high above the terrain.\n\"Always\" will explode any time you are flying too fast. (Most similar to vanilla's behavior)");
			configTransferMomentum = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "TransferMomentum", false, "When dropping the jetpack, instead of immediately coming to a stop, you will maintain the same direction and speed.");
			if (configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh)
			{
				if (!((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "BecomeFirework", true, "Legacy setting, use \"MidAirExplosions\" instead").Value)
				{
					configMidAirExplosions.Value = MidAirExplosions.Off;
				}
				((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "BecomeFirework"].Definition);
				((BaseUnityPlugin)this).Config.Save();
			}
			new Harmony("butterystancakes.lethalcompany.jetpackfixes").PatchAll();
			Logger.LogInfo((object)"Jetpack Fixes v1.5.0 loaded");
		}
	}
	[HarmonyPatch]
	internal class JetpackFixesPatches
	{
		private const float SAFE_HEIGHT = 110.55537f;

		private const float MIN_DEATH_SPEED = 50f;

		private const float MAX_DEATH_SPEED = 54f;

		private static EnemyType flowerSnakeEnemy;

		private static readonly FieldInfo JETPACK_ACTIVATED = AccessTools.Field(typeof(JetpackItem), "jetpackActivated");

		[HarmonyPatch(typeof(JetpackItem), "Update")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TransJetpackUpdate(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			List<CodeInstruction> list = instructions.ToList();
			LayerMask val = LayerMask.op_Implicit(-1111789641);
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) & ~(1 << LayerMask.NameToLayer("PlaceableShipObjects")));
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) | (1 << LayerMask.NameToLayer("Terrain")));
			val = LayerMask.op_Implicit(LayerMask.op_Implicit(val) & ~(1 << LayerMask.NameToLayer("InteractableObject")));
			for (int i = 1; i < list.Count - 3; i++)
			{
				if (list[i].opcode == OpCodes.Ldc_R4 && (float)list[i].operand == 10f && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == typeof(JetpackItem).GetField("jetpackPower", BindingFlags.Instance | BindingFlags.NonPublic))
				{
					list[i + 1].opcode = OpCodes.Bgt_Un;
					Plugin.Logger.LogDebug((object)"Transpiler: Reverse jetpackPower comparison on isGrounded check (allows for sliding)");
				}
				else if (list[i].opcode == OpCodes.Ldflda && (FieldInfo)list[i].operand == typeof(JetpackItem).GetField("rayHit", BindingFlags.Instance | BindingFlags.NonPublic))
				{
					if (list[i + 1].opcode == OpCodes.Ldc_R4 && (float)list[i + 1].operand == 25f)
					{
						list[i + 1].operand = 4f;
						Plugin.Logger.LogDebug((object)"Transpiler: Reduce raycast range from 25 to 4");
					}
					else if (list[i + 2].opcode == OpCodes.Ldc_R4 && (float)list[i + 2].operand == 4f)
					{
						for (int num = i + 3; num >= i - 1; num--)
						{
							list.RemoveAt(num);
						}
						Plugin.Logger.LogDebug((object)"Transpiler: Remove 4 unit distance check (redundant)");
					}
				}
				else if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == typeof(StartOfRound).GetField("allPlayersCollideWithMask", BindingFlags.Instance | BindingFlags.Public))
				{
					list[i].opcode = OpCodes.Ldc_I4;
					list[i].operand = LayerMask.op_Implicit(val);
					list.RemoveAt(i - 1);
					Plugin.Logger.LogDebug((object)"Transpiler: Replace layer mask with custom");
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(JetpackItem), "Update")]
		[HarmonyPostfix]
		private static void PostJetpackUpdate(JetpackItem __instance, Vector3 ___forces, bool ___jetpackActivated, float ___jetpackPower)
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00fb: 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)
			if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
			{
				return;
			}
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController && !((GrabbableObject)__instance).playerHeldBy.isPlayerDead && ___jetpackActivated && ((GrabbableObject)__instance).playerHeldBy.jetpackControls)
			{
				if (___jetpackPower > 10f)
				{
					float magnitude = ((Vector3)(ref ___forces)).magnitude;
					if (magnitude > 50f)
					{
						if (magnitude > 54f && (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always || (Plugin.configMidAirExplosions.Value == MidAirExplosions.OnlyTooHigh && ((Component)__instance).transform.position.y > 110.55537f)))
						{
							((GrabbableObject)__instance).playerHeldBy.KillPlayer(___forces, true, (CauseOfDeath)2, 0, default(Vector3));
							if (Plugin.configMidAirExplosions.Value == MidAirExplosions.Always)
							{
								Plugin.Logger.LogInfo((object)"Player killed from flying too fast");
							}
							else
							{
								Plugin.Logger.LogInfo((object)$"Player killed from flying too high too fast (Altitude: {((Component)__instance).transform.position.y} > {110.55537f})");
							}
						}
						else if (((GrabbableObject)__instance).playerHeldBy.thisController.isGrounded)
						{
							((GrabbableObject)__instance).playerHeldBy.KillPlayer(___forces, true, (CauseOfDeath)2, 0, default(Vector3));
							Plugin.Logger.LogInfo((object)"Player killed from touching ground while flying too fast");
						}
					}
				}
				if ((Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null && ((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle >= 0f && ((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle < 360f)
				{
					((GrabbableObject)__instance).playerHeldBy.maxJetpackAngle = float.MaxValue;
					((GrabbableObject)__instance).playerHeldBy.jetpackRandomIntensity = 60f;
					Plugin.Logger.LogInfo((object)"Uncap player rotation (using jetpack while tulip snakes riding)");
				}
			}
			((GrabbableObject)__instance).isBeingUsed = ___jetpackActivated;
		}

		[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
		[HarmonyPrefix]
		private static void PrePlayerDamaged(PlayerControllerB __instance, ref int damageNumber, CauseOfDeath causeOfDeath)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)causeOfDeath == 2 && (Object)(object)__instance == (Object)(object)GameNetworkManager.Instance.localPlayerController && __instance.jetpackControls && __instance.averageVelocity >= 50f)
			{
				Plugin.Logger.LogInfo((object)$"Player took {damageNumber} \"Gravity\" damage while flying too fast; should be instant death");
				damageNumber = Mathf.Max(100, __instance.health);
			}
		}

		[HarmonyPatch(typeof(JetpackItem), "EquipItem")]
		[HarmonyPostfix]
		private static void PostEquipJetpack(JetpackItem __instance)
		{
			if ((Object)(object)((GrabbableObject)__instance).playerHeldBy == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				__instance.jetpackAudio.dopplerLevel = 0f;
				__instance.jetpackBeepsAudio.dopplerLevel = 0f;
				Plugin.Logger.LogInfo((object)"Jetpack held by you, disable doppler effect");
			}
			else
			{
				__instance.jetpackAudio.dopplerLevel = 1f;
				__instance.jetpackBeepsAudio.dopplerLevel = 1f;
				Plugin.Logger.LogInfo((object)"Jetpack held by other player, enable doppler effect");
			}
			((GrabbableObject)__instance).useCooldown = 0f;
		}

		[HarmonyPatch(typeof(JetpackItem), "DeactivateJetpack")]
		[HarmonyPostfix]
		private static void PostDeactivateJetpack(PlayerControllerB ___previousPlayerHeldBy)
		{
			if ((Object)(object)___previousPlayerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController || !___previousPlayerHeldBy.disablingJetpackControls || !((Object)(object)flowerSnakeEnemy != (Object)null) || flowerSnakeEnemy.numberSpawned <= 0)
			{
				return;
			}
			int num = flowerSnakeEnemy.numberSpawned;
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				FlowerSnakeEnemy val = (FlowerSnakeEnemy)(object)((spawnedEnemy is FlowerSnakeEnemy) ? spawnedEnemy : null);
				if ((Object)(object)val != (Object)null)
				{
					num--;
					if (!((EnemyAI)val).isEnemyDead && (Object)(object)val.clingingToPlayer == (Object)(object)___previousPlayerHeldBy && val.flightPower > 0f)
					{
						val.clingingToPlayer.disablingJetpackControls = false;
						val.clingingToPlayer.maxJetpackAngle = float.MaxValue;
						val.clingingToPlayer.jetpackRandomIntensity = 60f;
						Plugin.Logger.LogInfo((object)"Jetpack disabled, but tulip snake is still carrying");
						break;
					}
					if (num <= 0)
					{
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(FlowerSnakeEnemy), "SetFlappingLocalClient")]
		[HarmonyPostfix]
		private static void PostSetFlappingLocalClient(FlowerSnakeEnemy __instance, bool isMainSnake)
		{
			if (!isMainSnake || (Object)(object)__instance.clingingToPlayer != (Object)(object)GameNetworkManager.Instance.localPlayerController || !__instance.clingingToPlayer.disablingJetpackControls)
			{
				return;
			}
			for (int i = 0; i < __instance.clingingToPlayer.ItemSlots.Length; i++)
			{
				if (!((Object)(object)__instance.clingingToPlayer.ItemSlots[i] == (Object)null) && !__instance.clingingToPlayer.ItemSlots[i].isPocketed)
				{
					GrabbableObject obj = __instance.clingingToPlayer.ItemSlots[i];
					JetpackItem val = (JetpackItem)(object)((obj is JetpackItem) ? obj : null);
					if ((Object)(object)val != (Object)null && (bool)JETPACK_ACTIVATED.GetValue(val))
					{
						__instance.clingingToPlayer.disablingJetpackControls = false;
						__instance.clingingToPlayer.maxJetpackAngle = -1f;
						__instance.clingingToPlayer.jetpackRandomIntensity = 0f;
						Plugin.Logger.LogInfo((object)"Player still using jetpack when tulip snake dropped; re-enable flight controls");
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(FlowerSnakeEnemy), "Start")]
		[HarmonyPostfix]
		private static void PostTulipSnakeStart(FlowerSnakeEnemy __instance)
		{
			if ((Object)(object)flowerSnakeEnemy == (Object)null)
			{
				flowerSnakeEnemy = ((EnemyAI)__instance).enemyType;
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void GameNetworkManagerPostDisconnect()
		{
			flowerSnakeEnemy = null;
		}

		[HarmonyPatch(typeof(JetpackItem), "DiscardItem")]
		[HarmonyPostfix]
		private static void PostDropJetpack(JetpackItem __instance, PlayerControllerB ___previousPlayerHeldBy, ref Vector3 ___forces)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (Plugin.configTransferMomentum.Value && !___previousPlayerHeldBy.isPlayerDead && ___previousPlayerHeldBy.jetpackControls && ((Vector3)(ref ___forces)).magnitude > 0f)
			{
				___previousPlayerHeldBy.externalForceAutoFade += new Vector3(___forces.x, ___forces.y * __instance.verticalMultiplier, ___forces.z);
				Plugin.Logger.LogInfo((object)"Player dropped jetpack while flying, fling them!");
			}
			___forces = Vector3.zero;
		}

		[HarmonyPatch(typeof(JetpackItem), "SetJetpackAudios")]
		[HarmonyPrefix]
		private static bool NewJetpackAudio(JetpackItem __instance, ref bool ___jetpackActivated, ref float ___noiseInterval)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (___jetpackActivated)
			{
				if (___noiseInterval >= 0.5f)
				{
					___noiseInterval = 0f;
					RoundManager.Instance.PlayAudibleNoise(((Component)__instance).transform.position, 25f, 0.85f, 0, ((GrabbableObject)__instance).playerHeldBy.isInHangarShipRoom && StartOfRound.Instance.hangarDoorsClosed, 41);
				}
				else
				{
					___noiseInterval += Time.deltaTime;
				}
				if (((GrabbableObject)__instance).insertedBattery.charge < 0.15f)
				{
					if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackLowBatteriesSFX)
					{
						__instance.jetpackBeepsAudio.Stop();
						__instance.jetpackBeepsAudio.clip = __instance.jetpackLowBatteriesSFX;
					}
					if (!__instance.jetpackBeepsAudio.isPlaying)
					{
						__instance.jetpackBeepsAudio.Play();
					}
				}
				else
				{
					if ((Object)(object)__instance.jetpackBeepsAudio.clip != (Object)(object)__instance.jetpackWarningBeepSFX)
					{
						__instance.jetpackBeepsAudio.Stop();
						__instance.jetpackBeepsAudio.clip = __instance.jetpackWarningBeepSFX;
					}
					if (Physics.CheckSphere(((Component)__instance).transform.position, 6f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
					{
						if (!__instance.jetpackBeepsAudio.isPlaying)
						{
							__instance.jetpackBeepsAudio.Play();
						}
					}
					else
					{
						__instance.jetpackBeepsAudio.Stop();
					}
				}
			}
			else
			{
				__instance.jetpackBeepsAudio.Stop();
			}
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "JetpackFixes";

		public const string PLUGIN_NAME = "JetpackFixes";

		public const string PLUGIN_VERSION = "1.5.0";
	}
}