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";
}
}