Decompiled source of AbilityRandomizer v1.0.2

AbilityRandomizer.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BoplFixedMath;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("AbilityRandomizer")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Randomizes ability slot after usage")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+5571565b44d78b4c922fdedc2700463defb099d9")]
[assembly: AssemblyProduct("AbilityRandomizer")]
[assembly: AssemblyTitle("AbilityRandomizer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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 AbilityRandomizer
{
	[BepInPlugin("com.almafa64.AbilityRandomizer", "AbilityRandomizer", "1.0.2")]
	[BepInProcess("BoplBattle.exe")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Harmony harmony;

		internal static ManualLogSource logger;

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			logger = ((BaseUnityPlugin)this).Logger;
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Ability), "ExitAbility", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "ExitAbility_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Teleport), "CastAbility", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Patches), "TeleportCastAbility_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(HookshotInstant), "FireHook", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "FireHook_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(RopeBody), "Dettach", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "Dettach_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Rope), "CheckIfDestroyed", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RopeCheckIfDestroyed_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Rope), "Initialize", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "RopeInitialize_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(GameSessionHandler), "SpawnPlayers", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "SpawnPlayers_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Invisibility), "OnInvisibiltyEnded", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Patches), "OnInvisibiltyEnded_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
	}
	internal class Patches
	{
		private static readonly Dictionary<RopeBody, HookshotInstant> ropeSlots = new Dictionary<RopeBody, HookshotInstant>();

		private static readonly Dictionary<Rope, RopeBody> ropeBodies = new Dictionary<Rope, RopeBody>();

		private static readonly FieldInfo invisAbilityField = MyGetField<Invisibility>("ia");

		private static readonly FieldInfo hookAbilityField = MyGetField<HookshotInstant>("instantAbility");

		private static readonly FieldInfo hookRopeBodyField = MyGetField<HookshotInstant>("ropeBody");

		private static readonly FieldInfo teleportAbilityField = MyGetField<Teleport>("instantAbility");

		private static readonly FieldInfo teleportIndicatorField = MyGetField<Teleport>("teleportIndicator");

		private static readonly FieldInfo abilityComponentsField = MyGetField<Ability>("abilityComponents");

		private static readonly FieldInfo abilityCooldownField = MyGetField<SlimeController>("abilityCooldownTimers");

		private static readonly FieldInfo placeObjectField = MyGetField<PlantObjectOnPlatform>("placeObject");

		private static readonly FieldInfo plantBufferField = MyGetField<PlaceSparkNode>("plantBuffer");

		private static FieldInfo MyGetField<T>(string name)
		{
			return typeof(T).GetField(name, AccessTools.all);
		}

		private static void ChangeAbility(InstantAbility instantAbility)
		{
			SlimeController slimeController = ((AbilityMonoBehaviour)instantAbility).GetSlimeController();
			int num = slimeController.abilities.IndexOf((AbilityMonoBehaviour)(object)instantAbility);
			if (num != -1)
			{
				ChangeAbility(slimeController, num);
			}
		}

		private static void ChangeAbility(SlimeController controller, int index)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			//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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			AbilityReadyIndicator val = controller.AbilityReadyIndicators[index];
			NamedSprite randomAbilityPrefab = RandomAbility.GetRandomAbilityPrefab(controller.abilityIconsFull, controller.abilityIconsDemo, val.GetPrimarySprite());
			GameObject associatedGameObject = randomAbilityPrefab.associatedGameObject;
			AbilityMonoBehaviour component = FixTransform.InstantiateFixed(associatedGameObject, Vec2.zero, Fix.Zero).GetComponent<AbilityMonoBehaviour>();
			controller.abilities[index] = component;
			PlayerHandler.Get().GetPlayer(controller.playerNumber).CurrentAbilities[index] = associatedGameObject;
			val.SetSprite(randomAbilityPrefab.sprite, true);
			val.ResetAnimation();
			(abilityCooldownField.GetValue(controller) as Fix[])[index] = (Fix)100000L;
			AudioManager.Get().Play("abilityPickup");
		}

		internal static void SpawnPlayers_Postfix()
		{
			ropeBodies.Clear();
			ropeSlots.Clear();
		}

		internal static void ExitAbility_Postfix(Ability __instance, AbilityExitInfo exitInfo)
		{
			SlimeController slimeController = ((AbilityMonoBehaviour)__instance).GetSlimeController();
			int num = slimeController.abilities.IndexOf((AbilityMonoBehaviour)(object)__instance);
			if (num == -1)
			{
				return;
			}
			IAbilityComponent[] array = abilityComponentsField.GetValue(__instance) as IAbilityComponent[];
			if (array.Length == 1)
			{
				IAbilityComponent obj = array[0];
				PlantObjectOnPlatform val = (PlantObjectOnPlatform)(object)((obj is PlantObjectOnPlatform) ? obj : null);
				if (val != null)
				{
					object? value = placeObjectField.GetValue(val);
					object? obj2 = ((value is IPlaceObject) ? value : null);
					PlaceSparkNode val2 = (PlaceSparkNode)((obj2 is PlaceSparkNode) ? obj2 : null);
					if (val2 != null && (Object)(object)(plantBufferField.GetValue(val2) as RingBuffer<SimpleSparkNode>)[1] == (Object)null)
					{
						return;
					}
				}
			}
			ChangeAbility(slimeController, num);
		}

		internal static void TeleportCastAbility_Prefix(Teleport __instance)
		{
			object? value = teleportIndicatorField.GetValue(__instance);
			TeleportIndicator val = (TeleportIndicator)((value is TeleportIndicator) ? value : null);
			if (!((Object)(object)val == (Object)null) && !((MonoUpdatable)val).IsDestroyed)
			{
				object? value2 = teleportAbilityField.GetValue(__instance);
				ChangeAbility((InstantAbility)((value2 is InstantAbility) ? value2 : null));
			}
		}

		internal static void FireHook_Postfix(HookshotInstant __instance)
		{
			Dictionary<RopeBody, HookshotInstant> dictionary = ropeSlots;
			object? value = hookRopeBodyField.GetValue(__instance);
			dictionary.Add((RopeBody)((value is RopeBody) ? value : null), __instance);
		}

		internal static void RopeCheckIfDestroyed_Postfix(Rope __instance)
		{
			if (!((Behaviour)__instance).enabled && ropeBodies.TryGetValue(__instance, out var value))
			{
				ropeBodies.Remove(__instance);
				Dettach_Postfix(value);
			}
		}

		internal static void Dettach_Postfix(RopeBody __instance)
		{
			if (ropeSlots.TryGetValue(__instance, out var value))
			{
				ropeSlots.Remove(__instance);
				object? value2 = hookAbilityField.GetValue(value);
				ChangeAbility((InstantAbility)((value2 is InstantAbility) ? value2 : null));
			}
		}

		internal static void RopeInitialize_Postfix(Rope __instance, ref RopeBody __result)
		{
			ropeBodies.Add(__instance, __result);
		}

		internal static void OnInvisibiltyEnded_Postfix(Invisibility __instance)
		{
			object? value = invisAbilityField.GetValue(__instance);
			ChangeAbility((InstantAbility)((value is InstantAbility) ? value : null));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "AbilityRandomizer";

		public const string PLUGIN_NAME = "AbilityRandomizer";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}