Decompiled source of LCTeleporterAnomaly v0.1.1

LCTeleporterAnomaly.dll

Decompiled 2 months ago
using System.Collections;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("LCTeleporterAnomaly")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("The company has cut costs by subcontracting the production of teleporters, but it seems that they are slightly defective. Can you survive or even profit from this anomaly?")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+d85d4233144ab55f3c76a3799adeb78a329f57ca")]
[assembly: AssemblyProduct("LCTeleporterAnomaly")]
[assembly: AssemblyTitle("LCTeleporterAnomaly")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
namespace LCTeleporterAnomaly
{
	[BepInPlugin("LCTeleporterAnomaly", "LCTeleporterAnomaly", "0.1.1")]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = null;

		internal static ManualLogSource Logger { get; private set; }

		protected Plugin()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("LCTeleporterAnomaly");
		}

		protected void Awake()
		{
			ManualLogSource logger = Logger;
			if (logger != null)
			{
				logger.LogInfo((object)"Plugin LCTeleporterAnomaly is loaded!");
			}
			ManualLogSource logger2 = Logger;
			if (logger2 != null)
			{
				logger2.LogDebug((object)"Patching harmony...");
			}
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LCTeleporterAnomaly";

		public const string PLUGIN_NAME = "LCTeleporterAnomaly";

		public const string PLUGIN_VERSION = "0.1.1";
	}
}
namespace LCTeleporterAnomaly.Patches
{
	[HarmonyPatch(typeof(BaboonBirdAI))]
	internal class BaboonBirdAIPatch : EnemyAIPatch<BaboonBirdAI>
	{
		protected override void TeleportToPosition(Vector3 targetPosition)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			_enemyAI.StopKillAnimation();
			base.TeleportToPosition(targetPosition);
			((EnemyAI)_enemyAI).SwitchToBehaviourState(0);
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(BaboonBirdAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<BaboonBirdAIPatch>();
		}

		[HarmonyPatch("killPlayerAnimation")]
		[HarmonyPostfix]
		private static void KillPlayerAnimationPostfix(BaboonBirdAI __instance, ref IEnumerator __result)
		{
			__result = KillPlayerAnimationEnumerator(__instance, __result);
			static IEnumerator KillPlayerAnimationEnumerator(BaboonBirdAI __instance, IEnumerator __result)
			{
				bool bRedirectedToEnemy = false;
				while (__result.MoveNext())
				{
					if (!bRedirectedToEnemy && (Object)(object)__instance.killAnimationBody != (Object)null)
					{
						ManualLogSource logger = Plugin.Logger;
						if (logger != null)
						{
							logger.LogDebug((object)("\"BaboonBirdAIPatch\" Redirecting player \"" + __instance.killAnimationBody.playerScript.playerUsername + "\" teleport to baboon hawk"));
						}
						__instance.killAnimationBody.playerScript.redirectToEnemy = (EnemyAI)(object)__instance;
						bRedirectedToEnemy = true;
					}
					yield return __result.Current;
				}
			}
		}

		[HarmonyPatch("StopKillAnimation")]
		[HarmonyPrefix]
		private static void StopKillAnimationPrefix(BaboonBirdAI __instance)
		{
			if ((Object)(object)__instance.killAnimationBody != (Object)null)
			{
				ManualLogSource logger = Plugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("\"BaboonBirdAIPatch\" Redirecting teleport from baboon hawk back to player \"" + __instance.killAnimationBody.playerScript.playerUsername + "\""));
				}
				__instance.killAnimationBody.playerScript.redirectToEnemy = null;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal static class EnemyAIPatch
	{
		[HarmonyPatch("ShipTeleportEnemy")]
		[HarmonyPostfix]
		private static void ShipTeleportEnemyPostfix(EnemyAI __instance)
		{
			IEnemyAIPatch enemyAIPatch = default(IEnemyAIPatch);
			if (!(__instance is MaskedPlayerEnemy) && ((Component)__instance).TryGetComponent<IEnemyAIPatch>(ref enemyAIPatch))
			{
				enemyAIPatch.StartTeleportSequence();
			}
		}
	}
	internal interface IEnemyAIPatch
	{
		void StartTeleportSequence(bool bInterruptOngoingTeleport = true);
	}
	[DisallowMultipleComponent]
	internal abstract class EnemyAIPatch<T> : MonoBehaviour, IEnemyAIPatch where T : EnemyAI
	{
		private Coroutine _teleportCoroutine = null;

		protected T _enemyAI = default(T);

		private static readonly DialogueSegment[] TeleporterAnomalyDialogue = (DialogueSegment[])(object)new DialogueSegment[1]
		{
			new DialogueSegment
			{
				speakerText = "PILOT COMPUTER",
				bodyText = "Alert! Anomaly detected with the teleporter.",
				waitTime = 4f
			}
		};

		protected void Start()
		{
			ManualLogSource logger = Plugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("\"" + typeof(T).Name + "\" applies \"" + ((object)this).GetType().Name + "\""));
			}
			_enemyAI = ((Component)this).gameObject.GetComponent<T>();
		}

		public void StartTeleportSequence(bool bInterruptOngoingTeleport = true)
		{
			if ((Object)(object)_enemyAI == (Object)null)
			{
				return;
			}
			if (_teleportCoroutine != null)
			{
				if (!bInterruptOngoingTeleport)
				{
					return;
				}
				((MonoBehaviour)this).StopCoroutine(_teleportCoroutine);
			}
			_teleportCoroutine = ((MonoBehaviour)this).StartCoroutine(TeleportSequence());
		}

		private IEnumerator TeleportSequence()
		{
			if (!ShipTeleporter.hasBeenSpawnedThisSession)
			{
				ManualLogSource logger = Plugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("\"" + ((object)this).GetType().Name + "\" ignoring teleport sequence as no teleporter has been spawned this session"));
				}
				yield break;
			}
			ShipTeleporter teleporter = (from x in Object.FindObjectsOfType<ShipTeleporter>()
				where !x.isInverseTeleporter
				select x).First();
			if ((Object)(object)teleporter == (Object)null)
			{
				ManualLogSource logger2 = Plugin.Logger;
				if (logger2 != null)
				{
					logger2.LogWarning((object)("\"" + ((object)this).GetType().Name + "\" ignoring teleport sequence as no teleporter was found (inverse tp doesn't count)"));
				}
				yield break;
			}
			Vector3 cachedPosition = teleporter.teleporterPosition.position;
			yield return (object)new WaitForSeconds(3f);
			if (!GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				HUDManager.Instance.ReadDialogue(TeleporterAnomalyDialogue);
			}
			((EnemyAI)_enemyAI).creatureSFX.PlayOneShot(teleporter?.beamUpPlayerBodySFX);
			yield return (object)new WaitForSeconds(3f);
			if (StartOfRound.Instance.shipIsLeaving)
			{
				ManualLogSource logger3 = Plugin.Logger;
				if (logger3 != null)
				{
					logger3.LogDebug((object)("\"" + ((object)this).GetType().Name + "\" interrupting teleport sequence as the ship is leaving"));
				}
				yield break;
			}
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				ulong localClientId = GameNetworkManager.Instance.localPlayerController.actualClientId;
				if (((NetworkBehaviour)(object)_enemyAI).OwnerClientId != localClientId)
				{
					ManualLogSource logger4 = Plugin.Logger;
					if (logger4 != null)
					{
						logger4.LogDebug((object)("\"" + ((object)this).GetType().Name + "\" Changing OwnershipOfEnemy to prevent server/client desync (e.g. invisible enemy) after teleporting"));
					}
					((EnemyAI)_enemyAI).ChangeOwnershipOfEnemy(localClientId);
				}
			}
			SetOutside(outside: true);
			Vector3 targetPosition = ((teleporter != null) ? teleporter.teleporterPosition.position : cachedPosition) + Vector3.up * 0.5f;
			TeleportToPosition(targetPosition);
			((EnemyAI)_enemyAI).isInsidePlayerShip = true;
			ManualLogSource logger5 = Plugin.Logger;
			if (logger5 != null)
			{
				logger5.LogDebug((object)$"\"{((object)this).GetType().Name}\" Agent speed={((EnemyAI)_enemyAI).agent.speed}; Agent behaviour[{((EnemyAI)_enemyAI).currentBehaviourStateIndex}]={((EnemyAI)_enemyAI).currentBehaviourState.name}");
			}
		}

		protected virtual bool SetOutside(bool outside)
		{
			if (((EnemyAI)_enemyAI).isOutside == outside)
			{
				return false;
			}
			ManualLogSource logger = Plugin.Logger;
			if (logger != null)
			{
				logger.LogInfo((object)$"Changing \"{typeof(T).Name}\" isOutside=({((EnemyAI)_enemyAI).isOutside} => {outside})");
			}
			((EnemyAI)_enemyAI).isOutside = outside;
			((EnemyAI)_enemyAI).allAINodes = (outside ? RoundManager.Instance.outsideAINodes : RoundManager.Instance.insideAINodes);
			float num = RoundManager.Instance.currentOutsideEnemyPower + ((EnemyAI)_enemyAI).enemyType.PowerLevel * (float)(outside ? 1 : (-1));
			float num2 = RoundManager.Instance.currentEnemyPower + ((EnemyAI)_enemyAI).enemyType.PowerLevel * (float)((!outside) ? 1 : (-1));
			RoundManager.Instance.currentOutsideEnemyPower = Mathf.Max(num, 0f);
			RoundManager.Instance.currentEnemyPower = Mathf.Max(num2, 0f);
			return true;
		}

		protected virtual void TeleportToPosition(Vector3 targetPosition)
		{
			//IL_0028: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)_enemyAI).StopSearch(((EnemyAI)_enemyAI).currentSearch, true);
			targetPosition = RoundManager.Instance.GetNavMeshPosition(targetPosition, RoundManager.Instance.navHit, 5f, -1);
			ManualLogSource logger = Plugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)$"Teleporting \"{typeof(T).Name}\" to {targetPosition}");
			}
			if (((Behaviour)((EnemyAI)_enemyAI).agent).enabled)
			{
				((Behaviour)((EnemyAI)_enemyAI).agent).enabled = false;
				((Component)(object)_enemyAI).transform.position = targetPosition;
				((Behaviour)((EnemyAI)_enemyAI).agent).enabled = true;
				((EnemyAI)_enemyAI).agent.ResetPath();
			}
			else
			{
				((Component)(object)_enemyAI).transform.position = targetPosition;
			}
			((EnemyAI)_enemyAI).moveTowardsDestination = false;
			((EnemyAI)_enemyAI).movingTowardsTargetPlayer = false;
			((EnemyAI)_enemyAI).serverPosition = targetPosition;
		}
	}
	[HarmonyPatch(typeof(FlowermanAI))]
	internal class FlowermanAIPatch : EnemyAIPatch<FlowermanAI>
	{
		protected override bool SetOutside(bool outside)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!base.SetOutside(outside))
			{
				return false;
			}
			_enemyAI.mainEntrancePosition = RoundManager.FindMainEntrancePosition(false, outside);
			return true;
		}

		protected override void TeleportToPosition(Vector3 targetPosition)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			_enemyAI.DropPlayerBody();
			base.TeleportToPosition(targetPosition);
			((EnemyAI)_enemyAI).SwitchToBehaviourState(0);
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(FlowermanAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<FlowermanAIPatch>();
		}

		[HarmonyPatch("FinishKillAnimation")]
		[HarmonyPostfix]
		private static void FinishKillAnimationPostfix(FlowermanAI __instance)
		{
			if ((Object)(object)__instance.bodyBeingCarried != (Object)null)
			{
				ManualLogSource logger = Plugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("\"FlowermanAIPatch\" Redirecting player \"" + __instance.bodyBeingCarried.playerScript.playerUsername + "\" teleport to bracken"));
				}
				__instance.bodyBeingCarried.playerScript.redirectToEnemy = (EnemyAI)(object)__instance;
			}
		}

		[HarmonyPatch("DropPlayerBody")]
		[HarmonyPrefix]
		private static void DropPlayerBodyPrefix(FlowermanAI __instance)
		{
			if ((Object)(object)__instance.bodyBeingCarried != (Object)null)
			{
				ManualLogSource logger = Plugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("\"FlowermanAIPatch\" Redirecting teleport from bracken back to player \"" + __instance.bodyBeingCarried.playerScript.playerUsername + "\""));
				}
				__instance.bodyBeingCarried.playerScript.redirectToEnemy = null;
			}
		}
	}
	[HarmonyPatch(typeof(MouthDogAI))]
	internal class MouthDogAIPatch : EnemyAIPatch<MouthDogAI>
	{
		private void SwitchToSlightSuspicion(Vector3 heardNoisePosition)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)_enemyAI).SwitchToBehaviourState(1);
			_enemyAI.lastHeardNoisePosition = heardNoisePosition;
			_enemyAI.lastHeardNoiseDistanceWhenHeard = Vector3.Distance(((Component)_enemyAI).transform.position, heardNoisePosition);
			_enemyAI.noisePositionGuess = _enemyAI.roundManager.GetRandomNavMeshPositionInRadius(heardNoisePosition, _enemyAI.lastHeardNoiseDistanceWhenHeard / _enemyAI.noiseApproximation, default(NavMeshHit));
			_enemyAI.AITimer = 3f;
			_enemyAI.hearNoiseCooldown = 1f;
			_enemyAI.suspicionLevel = 2;
		}

		protected override void TeleportToPosition(Vector3 targetPosition)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			_enemyAI.DropCarriedBody();
			SwitchToSlightSuspicion(targetPosition);
			base.TeleportToPosition(targetPosition);
			_enemyAI.previousPosition = ((Component)_enemyAI).transform.position;
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(MouthDogAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<MouthDogAIPatch>();
		}

		[HarmonyPatch("TakeBodyInMouth")]
		[HarmonyPostfix]
		private static void TakeBodyInMouthPostfix(MouthDogAI __instance, DeadBodyInfo body)
		{
			ManualLogSource logger = Plugin.Logger;
			if (logger != null)
			{
				logger.LogDebug((object)("\"MouthDogAIPatch\" Redirecting player \"" + body.playerScript.playerUsername + "\" teleport to eyeless dog"));
			}
			body.playerScript.redirectToEnemy = (EnemyAI)(object)__instance;
		}

		[HarmonyPatch("DropCarriedBody")]
		[HarmonyPrefix]
		private static void DropCarriedBodyPrefix(MouthDogAI __instance)
		{
			if ((Object)(object)__instance.carryingBody != (Object)null)
			{
				ManualLogSource logger = Plugin.Logger;
				if (logger != null)
				{
					logger.LogDebug((object)("\"MouthDogAIPatch\" Redirecting teleport from eyeless dog back to player \"" + __instance.carryingBody.playerScript.playerUsername + "\""));
				}
				__instance.carryingBody.playerScript.redirectToEnemy = null;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}