Decompiled source of NuclearCruiser v1.3.0

Tomatobird.NuclearCruiser.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NuclearCruiser.MonoBehaviours;
using NuclearCruiser.Network;
using NuclearCruiser.Patches;
using Tomatobird.NuclearCruiser.NetcodePatcher;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Tomatobird.NuclearCruiser")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+7a227ff08ba3468540f0692706db6adb4ebbf988")]
[assembly: AssemblyProduct("NuclearCruiser")]
[assembly: AssemblyTitle("Tomatobird.NuclearCruiser")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 NuclearCruiser
{
	[BepInPlugin("Tomatobird.NuclearCruiser", "NuclearCruiser", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class NuclearCruiser : BaseUnityPlugin
	{
		internal enum Fragility
		{
			Default,
			Fragile,
			Extreme
		}

		internal static string IsNuclear = "isNuclear";

		internal static Texture2D? cruiserTexture;

		internal static Texture2D? destroyedCruiserTexture;

		internal static GameObject? nukeObject;

		internal static bool isFasterDropshipLoaded = false;

		internal static string cfgGeneral = "General";

		internal static string cfgCruiser = "Cruiser";

		internal static string cfgNuke = "Explosion";

		internal static string cfgCompat = "Compatibility";

		internal static ConfigEntry<float> nuclearCruiserChance = null;

		internal static bool nuclearCruiserWarning = true;

		internal static bool nuclearCruiserRadiationWarning = true;

		internal static float protectionTime = 3f;

		internal static bool infiniteBoosts = true;

		internal static Fragility cruiserFragility;

		internal static float minimumCrashVelocity = 4f;

		internal static int crashDamage = 4;

		internal static ConfigEntry<int> nuclearCruiserCompensation = null;

		internal static ConfigEntry<bool> compensationNotification = null;

		internal static float nukeScale = 0.5f;

		internal static ConfigEntry<float> nukeVolume = null;

		internal static ConfigEntry<float> nukeLightIntensity = null;

		internal static float decalVisibilityRange = 48f;

		internal static float decalScale = 2f;

		internal static ConfigEntry<bool> shakeCamera = null;

		internal static bool forcePatchCruiserStart = false;

		public static NuclearCruiser Instance { get; private set; } = null;

		internal static ManualLogSource Logger { get; private set; } = null;

		internal static Harmony? Harmony { get; set; }

		public void Awake()
		{
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			cruiserTexture = GetTexture(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "cruiser.png"));
			destroyedCruiserTexture = GetTexture(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "cruiser_blown.png"));
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "cruisernuke"));
			if ((Object)(object)val != (Object)null)
			{
				nukeObject = val.LoadAsset<GameObject>("Assets/LethalCompany/Mods/TomatoScrap/Prefabs/Miscallaneous/NuclearBombCruiser.prefab");
			}
			if ((Object)(object)cruiserTexture == (Object)null || (Object)(object)destroyedCruiserTexture == (Object)null || (Object)(object)nukeObject == (Object)null)
			{
				Logger.LogError((object)"Failed to load assets. Plugin loading aborted.");
				return;
			}
			nuclearCruiserChance = ((BaseUnityPlugin)this).Config.Bind<float>(cfgGeneral, "NuclearCruiserChance", 1f, new ConfigDescription("Chance of cruiser being a Nuclear Cruiser. 1 is always, 0 is never.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			nuclearCruiserWarning = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgGeneral, "NuclearCruiserWarning", true, "Should a warning pop up when a Nuclear Cruiser is spawned?").Value;
			nuclearCruiserRadiationWarning = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgGeneral, "NuclearCruiserRadiationWarning", true, "Should a radiation warning pop up when a Nuclear Cruiser is spawned?").Value;
			nukeScale = ((BaseUnityPlugin)this).Config.Bind<float>(cfgNuke, "NukeScale", 0.75f, "How large should the explosion be? 0.5 can already cover most of a moon's surface.").Value;
			nukeVolume = ((BaseUnityPlugin)this).Config.Bind<float>(cfgNuke, "NukeVolume", 0.67f, new ConfigDescription("Sound volume of the nuclear explosion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			nukeLightIntensity = ((BaseUnityPlugin)this).Config.Bind<float>(cfgNuke, "NukeLightIntensity", 1f, new ConfigDescription("Intensity of the light from the nuclear explosion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			decalVisibilityRange = ((BaseUnityPlugin)this).Config.Bind<float>(cfgNuke, "DecalVisibilityRange", 48f, "How far nuke explosion decals are visible.").Value;
			decalScale = ((BaseUnityPlugin)this).Config.Bind<float>(cfgNuke, "DecalScale", 4f, "How large are the nuke explosion decals.").Value;
			shakeCamera = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgNuke, "ShakeCamera", true, "Should camera shake upon explosion?");
			infiniteBoosts = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgCruiser, "InfiniteBoosts", true, "Should nuclear cruiser have infinite boosts?").Value;
			cruiserFragility = ((BaseUnityPlugin)this).Config.Bind<Fragility>(cfgCruiser, "CruiserFragility", Fragility.Fragile, "Fragility of the cruiser. Fragile makes cruiser take heavy damage from smaller impacts. Extreme makes cruiser on any impact past minimum crash velocity threshold and may explode upon landing on some moons if set too low.").Value;
			minimumCrashVelocity = ((BaseUnityPlugin)this).Config.Bind<float>(cfgCruiser, "MinimumCrashVelocity", 4f, "Damaging impact velocity threshold. Default threshold is reached at very low speeds.").Value;
			crashDamage = ((BaseUnityPlugin)this).Config.Bind<int>(cfgCruiser, "CrashDamage", 4, "Amount of damage cruiser takes on impact. Only used when CruiserFragility is set to Fragile.").Value;
			protectionTime = ((BaseUnityPlugin)this).Config.Bind<float>(cfgCruiser, "ProtectionTime", 3f, "Amount of time in seconds the cruiser stays more protected from damage when detached from dropship.").Value;
			nuclearCruiserCompensation = ((BaseUnityPlugin)this).Config.Bind<int>(cfgCruiser, "PurchaseCompensation", 0, "If set to more than 0, this amount of credits will be added to the terminal when a nuclear cruiser is spawned.");
			compensationNotification = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgCruiser, "CompensationNotification", true, "Should the added compensation be announced in chat?");
			forcePatchCruiserStart = ((BaseUnityPlugin)this).Config.Bind<bool>(cfgCompat, "ForcePatchCruiserStart", false, "This patch is automatically applied if FasterItemDropShip is installed. You can also manually force it here.").Value;
			Transform transform = nukeObject.transform;
			transform.localScale *= nukeScale;
			Transform child = nukeObject.transform.GetChild(0);
			child.rotation = Quaternion.Euler(90f, 0f, 0f);
			child.localScale *= decalScale;
			DecalProjector val2 = default(DecalProjector);
			((Component)child).TryGetComponent<DecalProjector>(ref val2);
			val2.drawDistance = decalVisibilityRange;
			AudioSource val3 = default(AudioSource);
			((Component)nukeObject.transform.GetChild(5)).TryGetComponent<AudioSource>(ref val3);
			AudioSource val4 = default(AudioSource);
			((Component)nukeObject.transform.GetChild(5).GetChild(0)).TryGetComponent<AudioSource>(ref val4);
			val3.volume = nukeVolume.Value;
			val4.volume = nukeVolume.Value;
			HDAdditionalLightData val5 = default(HDAdditionalLightData);
			((Component)nukeObject.transform.GetChild(1)).TryGetComponent<HDAdditionalLightData>(ref val5);
			HDAdditionalLightData val6 = default(HDAdditionalLightData);
			((Component)nukeObject.transform.GetChild(2)).TryGetComponent<HDAdditionalLightData>(ref val6);
			val5.color = new Color(nukeLightIntensity.Value, nukeLightIntensity.Value, nukeLightIntensity.Value, 1f);
			val6.color = new Color(nukeLightIntensity.Value, nukeLightIntensity.Value, nukeLightIntensity.Value, 1f);
			((Object)cruiserTexture).name = "nukeCruiserTexture";
			((Object)destroyedCruiserTexture).name = "blownNukeCruiserTexture";
			isFasterDropshipLoaded = Chainloader.PluginInfos.ContainsKey("FlipMods.FasterItemDropship");
			Patch();
			Logger.LogInfo((object)"Tomatobird.NuclearCruiser v1.3.0 has loaded!");
		}

		internal static Texture2D? GetTexture(string path)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (File.Exists(path))
			{
				Texture2D val = new Texture2D(2, 2);
				ImageConversion.LoadImage(val, File.ReadAllBytes(path));
				return val;
			}
			return null;
		}

		internal static void Patch()
		{
			//IL_000d: 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_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("Tomatobird.NuclearCruiser");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll(typeof(GameNetworkManagerPatch));
			Harmony.PatchAll(typeof(VehicleControllerPatch));
			Harmony.PatchAll(typeof(StartOfRoundPatch));
			if (isFasterDropshipLoaded || forcePatchCruiserStart)
			{
				Harmony.PatchAll(typeof(FasterDropshipCompatibilityPatch));
			}
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Tomatobird.NuclearCruiser";

		public const string PLUGIN_NAME = "NuclearCruiser";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace NuclearCruiser.Patches
{
	[HarmonyPatch(typeof(VehicleController))]
	public static class FasterDropshipCompatibilityPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Start_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(StartOfRound), "Instance"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(StartOfRound), "inShipPhase"), (string)null)
			};
			val.MatchForward(false, array).ThrowIfNotMatch("Couldn't find pattern in VehicleController.Start. Dropship that ships the cruiser while ship is still in orbit will cause issues.", Array.Empty<CodeMatch>()).SetAndAdvance(OpCodes.Call, (object)AccessTools.Method(typeof(FasterDropshipCompatibilityPatch), "InShipPhaseNotLoadingLevel", (Type[])null, (Type[])null))
				.RemoveInstruction();
			return val.InstructionEnumeration();
		}

		public static bool InShipPhaseNotLoadingLevel()
		{
			return StartOfRound.Instance.inShipPhase && !StartOfRound.Instance.beganLoadingNewLevel;
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	public static class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix()
		{
			NetworkHandler.CreateAndRegisterPrefab();
		}

		[HarmonyPatch("Disconnect")]
		[HarmonyPrefix]
		public static void Disconnect_Prefix()
		{
			NetworkHandler.DespawnNetworkHandler();
		}

		[HarmonyPatch("SaveItemsInShip")]
		[HarmonyPostfix]
		public static void SaveItemsInShip_Postfix(GameNetworkManager __instance)
		{
			try
			{
				VehicleController attachedVehicle = StartOfRound.Instance.attachedVehicle;
				CruiserNuker cruiserNuker = default(CruiserNuker);
				if (Object.op_Implicit((Object)(object)attachedVehicle) && attachedVehicle.vehicleID == 0 && ((Component)attachedVehicle).TryGetComponent<CruiserNuker>(ref cruiserNuker))
				{
					ES3.Save<bool>("NuclearCruiser" + NuclearCruiser.IsNuclear, true, GameNetworkManager.Instance.currentSaveFileName);
				}
				else
				{
					ES3.DeleteKey("NuclearCruiser" + NuclearCruiser.IsNuclear, GameNetworkManager.Instance.currentSaveFileName);
				}
			}
			catch (Exception arg)
			{
				NuclearCruiser.Logger.LogError((object)$"Failed to save nuclear cruiser data: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public static class StartOfRoundPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		public static void Awake_Prefix()
		{
			NetworkHandler.SpawnNetworkHandler();
		}

		[HarmonyPatch("SyncAlreadyHeldObjectsServerRpc")]
		[HarmonyPostfix]
		public static void SyncAlreadyHeldObjectsServerRpc_Postfix()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			VehicleController attachedVehicle = StartOfRound.Instance.attachedVehicle;
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (Object.op_Implicit((Object)(object)attachedVehicle) && ((Component)attachedVehicle).gameObject.TryGetComponent<CruiserNuker>(ref cruiserNuker))
			{
				NetworkHandler.Instance.AddCruiserNukerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)attachedVehicle));
			}
		}

		[HarmonyPatch("LoadAttachedVehicle")]
		[HarmonyPostfix]
		public static void LoadAttachedVehicle_Postfix(StartOfRound __instance)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance.attachedVehicle) || __instance.attachedVehicle.vehicleID != 0)
			{
				return;
			}
			try
			{
				if (ES3.KeyExists("NuclearCruiser" + NuclearCruiser.IsNuclear, GameNetworkManager.Instance.currentSaveFileName))
				{
					VehicleController attachedVehicle = __instance.attachedVehicle;
					CruiserNuker cruiserNuker = default(CruiserNuker);
					if (ES3.Load<bool>("NuclearCruiser" + NuclearCruiser.IsNuclear, GameNetworkManager.Instance.currentSaveFileName) && !((Component)attachedVehicle).gameObject.TryGetComponent<CruiserNuker>(ref cruiserNuker))
					{
						NetworkHandler.Instance.AddCruiserNukerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)attachedVehicle));
					}
				}
			}
			catch (Exception arg)
			{
				NuclearCruiser.Logger.LogError((object)$"Failed to load nuclear cruiser data: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(VehicleController))]
	public static class VehicleControllerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Start_Postfix(VehicleController __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.vehicleID != 0 || !((NetworkBehaviour)__instance).NetworkManager.IsServer || (StartOfRound.Instance.inShipPhase && !StartOfRound.Instance.beganLoadingNewLevel) || __instance.magnetedToShip)
			{
				return;
			}
			Random random = new Random();
			float num = (float)random.NextDouble();
			if (!(num < NuclearCruiser.nuclearCruiserChance.Value))
			{
				return;
			}
			NetworkHandler.Instance.AddCruiserNukerRpc(NetworkBehaviourReference.op_Implicit((NetworkBehaviour)(object)__instance));
			Terminal terminalScript = HUDManager.Instance.terminalScript;
			if (Object.op_Implicit((Object)(object)terminalScript) && NuclearCruiser.nuclearCruiserCompensation.Value > 0)
			{
				terminalScript.groupCredits += NuclearCruiser.nuclearCruiserCompensation.Value;
				terminalScript.SyncGroupCreditsClientRpc(terminalScript.groupCredits, terminalScript.numberOfItemsInDropship);
				if (NuclearCruiser.compensationNotification.Value)
				{
					HUDManager.Instance.AddTextToChatOnServer($"Nuclear cruiser compensation: ${NuclearCruiser.nuclearCruiserCompensation.Value}", -1);
				}
			}
		}

		[HarmonyPatch("UseTurboBoostLocalClient")]
		[HarmonyPostfix]
		public static void UseTurboBoostLocalClient_Postfix(VehicleController __instance)
		{
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (__instance.vehicleID == 0 && ((Component)__instance).TryGetComponent<CruiserNuker>(ref cruiserNuker) && NuclearCruiser.infiniteBoosts)
			{
				__instance.turboBoosts = 5;
			}
		}

		[HarmonyPatch("DestroyCar")]
		[HarmonyPrefix]
		public static void DestroyCar_Postfix(VehicleController __instance)
		{
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (__instance.vehicleID != 0 || __instance.carDestroyed || !((Component)__instance).TryGetComponent<CruiserNuker>(ref cruiserNuker))
			{
				return;
			}
			MeshRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<MeshRenderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (((Object)((Component)componentsInChildren[i]).transform).name.Contains("MainBody") || ((Object)((Component)componentsInChildren[i]).transform).name == "CarHoodMesh" || ((Object)((Component)componentsInChildren[i]).transform).name == "Door")
				{
					((Renderer)componentsInChildren[i]).materials[0].mainTexture = (Texture)(object)NuclearCruiser.destroyedCruiserTexture;
				}
			}
			cruiserNuker.Explode();
		}

		[HarmonyPatch("OnCollisionEnter")]
		[HarmonyPostfix]
		public static void OnCollisionEnter_Postfix(VehicleController __instance, Collision collision)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (__instance.vehicleID != 0 || !((Component)__instance).TryGetComponent<CruiserNuker>(ref cruiserNuker) || !((NetworkBehaviour)__instance).IsOwner || __instance.magnetedToShip || !__instance.hasBeenSpawned || ((Component)collision.collider).gameObject.layer != 8 || __instance.averageCount < 18 || NuclearCruiser.cruiserFragility == NuclearCruiser.Fragility.Default || ((Vector3)(ref __instance.averageVelocity)).magnitude < NuclearCruiser.minimumCrashVelocity || cruiserNuker.isProtected)
			{
				return;
			}
			float num = 0f;
			int contacts = collision.GetContacts(__instance.contacts);
			Vector3 val;
			for (int i = 0; i < contacts; i++)
			{
				val = ((ContactPoint)(ref __instance.contacts[i])).impulse;
				if (((Vector3)(ref val)).magnitude > num)
				{
					val = ((ContactPoint)(ref __instance.contacts[i])).impulse;
					num = ((Vector3)(ref val)).magnitude;
				}
			}
			num /= Time.fixedDeltaTime;
			if (num > __instance.mediumBumpForce)
			{
				int crashDamage = NuclearCruiser.crashDamage;
				val = default(Vector3);
				__instance.DealPermanentDamage(crashDamage, val);
			}
			if (num > __instance.maximumBumpForce && ((Vector3)(ref __instance.averageVelocity)).magnitude > NuclearCruiser.minimumCrashVelocity * 3f)
			{
				int num2 = NuclearCruiser.crashDamage * 2;
				val = default(Vector3);
				__instance.DealPermanentDamage(num2, val);
			}
		}

		[HarmonyPatch("CarReactToObstacle")]
		[HarmonyPrefix]
		public static bool CarReactToObstacle_Prefix(VehicleController __instance, bool __runOriginal)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			if (!__runOriginal)
			{
				return false;
			}
			if (__instance.vehicleID != 0)
			{
				return true;
			}
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (!((Component)__instance).TryGetComponent<CruiserNuker>(ref cruiserNuker))
			{
				return true;
			}
			if (!((NetworkBehaviour)__instance).IsOwner || __instance.magnetedToShip || __instance.carDestroyed || ((Vector3)(ref __instance.averageVelocity)).magnitude < NuclearCruiser.minimumCrashVelocity || cruiserNuker.isProtected)
			{
				return true;
			}
			if (NuclearCruiser.cruiserFragility == NuclearCruiser.Fragility.Extreme)
			{
				__instance.DestroyCarServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
				__instance.DestroyCar();
			}
			if (NuclearCruiser.cruiserFragility == NuclearCruiser.Fragility.Fragile)
			{
				__instance.DealPermanentDamage(NuclearCruiser.crashDamage, default(Vector3));
			}
			return false;
		}

		[HarmonyPatch("DealPermanentDamage")]
		[HarmonyPrefix]
		public static bool DealPermanentDamage_Prefix(VehicleController __instance, bool __runOriginal)
		{
			if (!__runOriginal)
			{
				return false;
			}
			if (__instance.vehicleID != 0)
			{
				return true;
			}
			CruiserNuker cruiserNuker = default(CruiserNuker);
			if (!((Component)__instance).TryGetComponent<CruiserNuker>(ref cruiserNuker))
			{
				return true;
			}
			if (cruiserNuker.isProtected)
			{
				return true;
			}
			if (!((NetworkBehaviour)__instance).IsOwner || __instance.magnetedToShip || __instance.carDestroyed || NuclearCruiser.cruiserFragility != NuclearCruiser.Fragility.Extreme)
			{
				return true;
			}
			__instance.DestroyCarServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId);
			__instance.DestroyCar();
			return false;
		}
	}
}
namespace NuclearCruiser.Network
{
	internal class NetworkHandler : NetworkBehaviour
	{
		private static GameObject? networkPrefab;

		public static NetworkHandler Instance { get; private set; }

		public static void CreateAndRegisterPrefab()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				networkPrefab = new GameObject("Tomatobird.NuclearCruiser NetworkPrefab");
				GameObject? obj = networkPrefab;
				((Object)obj).hideFlags = (HideFlags)(((Object)obj).hideFlags | 0x3D);
				NetworkObject obj2 = networkPrefab.AddComponent<NetworkObject>();
				FieldInfo field = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic);
				field.SetValue(obj2, GetHash("Tomatobird.NuclearCruiser NetworkPrefab"));
				networkPrefab.AddComponent<NetworkHandler>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
				NuclearCruiser.Logger.LogInfo((object)"Nuclear Cruiser network Network-Prefab added.");
			}
		}

		public static void SpawnNetworkHandler()
		{
			if (NetworkManager.Singleton.IsServer)
			{
				GameObject obj = Object.Instantiate<GameObject>(networkPrefab);
				if (obj != null)
				{
					obj.GetComponent<NetworkObject>().Spawn(false);
				}
				NuclearCruiser.Logger.LogInfo((object)"Spawned network handler.");
			}
		}

		public static void DespawnNetworkHandler()
		{
			NetworkObject val = default(NetworkObject);
			if (!((Object)(object)Instance == (Object)null) && NetworkManager.Singleton.IsServer && ((Component)Instance).gameObject.TryGetComponent<NetworkObject>(ref val) && val.IsSpawned)
			{
				val.Despawn(true);
				NuclearCruiser.Logger.LogInfo((object)"Despawned network handler.");
			}
		}

		protected internal static uint GetHash(string value)
		{
			return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0;
		}

		private void Awake()
		{
			Instance = this;
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		public void AddCruiserNukerRpc(NetworkBehaviourReference vehicleNetObjRef)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_0043: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1)
			{
				RpcAttributeParams val = default(RpcAttributeParams);
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(2834407357u, val3, val, (SendTo)6, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkBehaviourReference>(ref vehicleNetObjRef, default(ForNetworkSerializable));
				((NetworkBehaviour)this).__endSendRpc(ref val2, 2834407357u, val3, val, (SendTo)6, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1)
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			VehicleController val4 = default(VehicleController);
			if (!((NetworkBehaviourReference)(ref vehicleNetObjRef)).TryGet<VehicleController>(ref val4, (NetworkManager)null))
			{
				NuclearCruiser.Logger.LogError((object)$"Couldn't find a VehicleController component for {vehicleNetObjRef}");
			}
			else if (val4.vehicleID == 0)
			{
				CruiserNuker cruiserNuker = default(CruiserNuker);
				if (((Component)val4).TryGetComponent<CruiserNuker>(ref cruiserNuker))
				{
					NuclearCruiser.Logger.LogDebug((object)"VehicleController already contains a CruiserNuker component, skipping");
				}
				else
				{
					((Component)((NetworkBehaviour)val4).NetworkObject).gameObject.AddComponent<CruiserNuker>();
				}
			}
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(2834407357u, new RpcReceiveHandler(__rpc_handler_2834407357), "AddCruiserNukerRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_2834407357(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				NetworkBehaviourReference vehicleNetObjRef = default(NetworkBehaviourReference);
				((FastBufferReader)(ref reader)).ReadValueSafe<NetworkBehaviourReference>(ref vehicleNetObjRef, default(ForNetworkSerializable));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((NetworkHandler)(object)target).AddCruiserNukerRpc(vehicleNetObjRef);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "NetworkHandler";
		}
	}
}
namespace NuclearCruiser.MonoBehaviours
{
	public class CruiserNuker : MonoBehaviour
	{
		public bool isProtected = true;

		public void Explode()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(NuclearCruiser.nukeObject);
			if (!((Object)(object)val == (Object)null))
			{
				val.transform.position = ((Component)this).gameObject.transform.position;
				Vector3 position = ((Component)StartOfRound.Instance.activeCamera).transform.position;
				if (Vector3.Distance(val.transform.position, position) < 100f * NuclearCruiser.nukeScale)
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)3);
				}
				else
				{
					HUDManager.Instance.ShakeCamera((ScreenShakeType)2);
				}
			}
		}

		public void Start()
		{
			VehicleController val = default(VehicleController);
			if (!((Component)this).TryGetComponent<VehicleController>(ref val) || val.vehicleID != 0)
			{
				return;
			}
			if (NuclearCruiser.infiniteBoosts)
			{
				val.turboBoosts = 5;
			}
			MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (((Object)((Component)componentsInChildren[i]).transform).name.Contains("MainBody") || ((Object)((Component)componentsInChildren[i]).transform).name == "CarHoodMesh" || ((Object)((Component)componentsInChildren[i]).transform).name == "Door")
				{
					((Renderer)componentsInChildren[i]).materials[0].mainTexture = (Texture)(object)NuclearCruiser.cruiserTexture;
				}
			}
			MeshRenderer val2 = default(MeshRenderer);
			if (val.destroyedTruckMesh.TryGetComponent<MeshRenderer>(ref val2))
			{
				((Renderer)val2).materials[0].mainTexture = (Texture)(object)NuclearCruiser.destroyedCruiserTexture;
			}
			ItemDropship val3 = Object.FindAnyObjectByType<ItemDropship>((FindObjectsInactive)0);
			if (NuclearCruiser.protectionTime <= 0f)
			{
				isProtected = false;
			}
			if ((Object)(object)val3 != (Object)null && val3.deliveringVehicle)
			{
				((MonoBehaviour)this).StartCoroutine(InvulnerabilityCountdown(val3));
				if (NuclearCruiser.nuclearCruiserRadiationWarning)
				{
					HUDManager.Instance.RadiationWarningHUD();
				}
				if (NuclearCruiser.nuclearCruiserWarning)
				{
					if (NuclearCruiser.infiniteBoosts)
					{
						HUDManager.Instance.DisplayTip("NUCLEAR CRUISER SPAWNED", "Using nuclear power, the cruiser can boost infinitely. Handle with extreme care.", true, false, "LC_Tip1");
					}
					else
					{
						HUDManager.Instance.DisplayTip("NUCLEAR CRUISER SPAWNED", "Handle with extreme care.", true, false, "LC_Tip1");
					}
				}
			}
			else
			{
				isProtected = false;
			}
		}

		private IEnumerator InvulnerabilityCountdown(ItemDropship ship)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => ship.untetheredVehicle));
			yield return (object)new WaitForSeconds(NuclearCruiser.protectionTime);
			isProtected = false;
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace Tomatobird.NuclearCruiser.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}