Decompiled source of SnatchinBrackin v1.0.0

SnatchingBracken.dll

Decompiled 2 years ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using SnatchinBracken.Patches;
using SnatchinBracken.Patches.data;
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("SnatchingBracken")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SnatchingBracken")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("afcd9203-dbdd-4b28-85a1-fb12890f0d98")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SnatchinBracken
{
	[BepInPlugin("Ovchinikov.SnatchingBracken", "SnatchingBracken", "1.0.0")]
	public class SnatchinBrackenBase : BaseUnityPlugin
	{
		private const string modGUID = "Ovchinikov.SnatchingBracken";

		private const string modName = "SnatchingBracken";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Ovchinikov.SnatchingBracken");

		private static SnatchinBrackenBase instance;

		internal ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)instance == (Object)null)
			{
				instance = this;
			}
			mls = Logger.CreateLogSource("Ovchinikov.SnatchingBracken");
			mls.LogInfo((object)"Enabling Snatching Bracken");
			harmony.PatchAll(typeof(SnatchinBrackenBase));
			harmony.PatchAll(typeof(BrackenAIPatch));
			harmony.PatchAll(typeof(EnemyAIPatch));
		}
	}
}
namespace SnatchinBracken.Patches
{
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyAIPatch
	{
		private const string modGUID = "Ovchinikov.SnatchinBracken";

		private static ManualLogSource mls;

		private static float maxWait;

		static EnemyAIPatch()
		{
			maxWait = 15000f;
			mls = Logger.CreateLogSource("Ovchinikov.SnatchinBracken");
		}

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		private static void UpdatePatcher(EnemyAI __instance)
		{
			FlowermanAI val = (FlowermanAI)(object)((__instance is FlowermanAI) ? __instance : null);
			if (val != null && SharedData.Instance.BindedDrags.ContainsKey(val))
			{
				PlayerControllerB valueSafe = GeneralExtensions.GetValueSafe<FlowermanAI, PlayerControllerB>(SharedData.Instance.BindedDrags, val);
				int valueSafe2 = GeneralExtensions.GetValueSafe<PlayerControllerB, int>(SharedData.Instance.PlayerIDs, valueSafe);
				UpdatePosition(val, valueSafe);
				float num = SharedData.Instance.LastGrabbedTimeStamp[val];
				if (Time.time - num >= maxWait)
				{
					FinishKillAnimationNormally(val, valueSafe, valueSafe2);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("PlayerIsTargetable")]
		private static bool PlayerIsTargetablePatch(EnemyAI __instance, PlayerControllerB playerScript, bool cannotBeInShip = false)
		{
			return !SharedData.Instance.BindedDrags.ContainsValue(playerScript);
		}

		private static void UpdatePosition(FlowermanAI __instance, PlayerControllerB player)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			((Component)player).transform.position = ((Component)__instance).transform.position;
		}

		private static void FinishKillAnimationNormally(FlowermanAI __instance, PlayerControllerB playerControllerB, int playerId)
		{
			mls.LogInfo((object)"Bracken found good spot to kill, killing player.");
			((EnemyAI)__instance).inSpecialAnimationWithPlayer = playerControllerB;
			playerControllerB.inSpecialInteractAnimation = true;
			__instance.KillPlayerAnimationClientRpc(playerId);
		}
	}
	[HarmonyPatch(typeof(FlowermanAI))]
	internal class BrackenAIPatch
	{
		private const string modGUID = "Ovchinikov.SnatchinBracken";

		private static ManualLogSource mls;

		static BrackenAIPatch()
		{
			mls = Logger.CreateLogSource("Ovchinikov.SnatchinBracken");
		}

		[HarmonyPrefix]
		[HarmonyPatch("KillPlayerAnimationServerRpc")]
		private static bool PrefixKillPlayerAnimationServerRpc(FlowermanAI __instance, int playerObjectId)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				mls.LogError((object)"FlowermanAI instance is null.");
				return true;
			}
			PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerObjectId];
			if ((Object)(object)val == (Object)null)
			{
				mls.LogError((object)"PlayerControllerB instance is null.");
				return true;
			}
			((EnemyAI)__instance).creatureAnimator.SetBool("killing", false);
			((EnemyAI)__instance).creatureAnimator.SetBool("carryingBody", true);
			__instance.carryingPlayerBody = true;
			val.inSpecialInteractAnimation = true;
			__instance.inKillAnimation = false;
			((EnemyAI)__instance).targetPlayer = null;
			SharedData.Instance.BindedDrags[__instance] = val;
			SharedData.Instance.PlayerIDs[val] = playerObjectId;
			SharedData.Instance.LastGrabbedTimeStamp[__instance] = Time.time;
			Transform favoriteSpot = ((EnemyAI)__instance).ChooseFarthestNodeFromPosition(RoundManager.FindMainEntrancePosition(false, false), false, 0, false);
			if ((Object)(object)((EnemyAI)__instance).favoriteSpot == (Object)null)
			{
				((EnemyAI)__instance).favoriteSpot = favoriteSpot;
			}
			((EnemyAI)__instance).SwitchToBehaviourState(1);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("HitEnemy")]
		private static void HitEnemyPatch(FlowermanAI __instance, int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			if (SharedData.Instance.BindedDrags.ContainsKey(__instance))
			{
				ManuallyDropPlayerOnHit(__instance, playerWhoHit);
				SharedData.Instance.BindedDrags.Remove(__instance);
			}
		}

		private static void ManuallyDropPlayerOnHit(FlowermanAI __instance, PlayerControllerB player)
		{
			player.inSpecialInteractAnimation = false;
			__instance.carryingPlayerBody = false;
			((EnemyAI)__instance).creatureAnimator.SetBool("killing", false);
			((EnemyAI)__instance).creatureAnimator.SetBool("carryingBody", false);
		}

		[HarmonyPrefix]
		[HarmonyPatch("DropPlayerBody")]
		private static bool DropBodyPatch(FlowermanAI __instance)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				mls.LogInfo((object)"FlowermanAI instance is null in DropBodyPatch.");
				return true;
			}
			if (!SharedData.Instance.BindedDrags.ContainsKey(__instance))
			{
				mls.LogInfo((object)"FlowermanAI instance not found in BindedDrags map.");
				return true;
			}
			PlayerControllerB valueSafe = GeneralExtensions.GetValueSafe<FlowermanAI, PlayerControllerB>(SharedData.Instance.BindedDrags, __instance);
			int valueSafe2 = GeneralExtensions.GetValueSafe<PlayerControllerB, int>(SharedData.Instance.PlayerIDs, valueSafe);
			if ((Object)(object)valueSafe == (Object)null)
			{
				mls.LogError((object)"PlayerControllerB instance is null in BindedDrags map.");
				SharedData.Instance.BindedDrags.Remove(__instance);
				return true;
			}
			valueSafe.inSpecialInteractAnimation = false;
			SharedData.Instance.BindedDrags.Remove(__instance);
			SharedData.Instance.LastGrabbedTimeStamp.Remove(__instance);
			__instance.carryingPlayerBody = false;
			__instance.bodyBeingCarried = null;
			((EnemyAI)__instance).creatureAnimator.SetBool("carryingBody", false);
			FinishKillAnimationNormally(__instance, valueSafe, valueSafe2);
			return false;
		}

		private static void FinishKillAnimationNormally(FlowermanAI __instance, PlayerControllerB playerControllerB, int playerId)
		{
			mls.LogInfo((object)"Bracken found good spot to kill, killing player.");
			((EnemyAI)__instance).inSpecialAnimationWithPlayer = playerControllerB;
			playerControllerB.inSpecialInteractAnimation = true;
			__instance.KillPlayerAnimationClientRpc(playerId);
		}
	}
}
namespace SnatchinBracken.Patches.data
{
	internal class SharedData
	{
		private static SharedData _instance;

		public static SharedData Instance => _instance ?? (_instance = new SharedData());

		public Dictionary<FlowermanAI, PlayerControllerB> BindedDrags { get; } = new Dictionary<FlowermanAI, PlayerControllerB>();


		public Dictionary<PlayerControllerB, int> PlayerIDs { get; } = new Dictionary<PlayerControllerB, int>();


		public Dictionary<FlowermanAI, float> LastGrabbedTimeStamp { get; } = new Dictionary<FlowermanAI, float>();

	}
}