Decompiled source of TumbleAttackStun v1.0.0

TumbleAttackStun.dll

Decompiled 3 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("TumbleAttackStun")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TumbleAttackStun")]
[assembly: AssemblyTitle("TumbleAttackStun")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 TumbleAttackStun
{
	[HarmonyPatch]
	internal static class HurtCollider_EnemyHurt_Patch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(HurtCollider), "EnemyHurt", new Type[1] { typeof(Enemy) }, (Type[])null);
		}

		private static void Postfix(HurtCollider __instance, Enemy _enemy, bool __result)
		{
			if (!__result || (Object)(object)_enemy == (Object)null)
			{
				return;
			}
			try
			{
				PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>();
				if ((Object)(object)componentInParent == (Object)null || !ReflectionHelpers.TryGetIsTumbling(componentInParent))
				{
					return;
				}
				float num = 0f;
				num = ((TumbleAttackStunPlugin.StunSecondsConfig == null) ? 10f : Mathf.Max(0f, TumbleAttackStunPlugin.StunSecondsConfig.Value));
				if (!(num <= 0f) && ReflectionHelpers.TrySetEnemyStun(_enemy, num))
				{
					ManualLogSource logger = TumbleAttackStunPlugin.Logger;
					if (logger != null)
					{
						logger.LogInfo((object)$"Applied stun {num}s to enemy {((Object)_enemy).name}");
					}
				}
			}
			catch (Exception arg)
			{
				if (TumbleAttackStunPlugin.Logger != null)
				{
					TumbleAttackStunPlugin.Logger.LogError((object)$"TumbleAttackStun patch error: {arg}");
				}
			}
		}
	}
	internal static class ReflectionHelpers
	{
		private static readonly Type PlayerTumbleType;

		private static readonly PropertyInfo PT_IsTumbling_Property;

		private static readonly FieldInfo PT_IsTumbling_Field;

		private static readonly Type EnemyType;

		private static readonly PropertyInfo Enemy_HasStateStunned_Property;

		private static readonly FieldInfo Enemy_HasStateStunned_Field;

		private static readonly PropertyInfo Enemy_StateStunned_Property;

		private static readonly FieldInfo Enemy_StateStunned_Field;

		private static readonly MethodInfo StateStunned_Set_Method;

		static ReflectionHelpers()
		{
			PlayerTumbleType = typeof(PlayerTumble);
			EnemyType = typeof(Enemy);
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			PT_IsTumbling_Property = PlayerTumbleType.GetProperty("isTumbling", bindingAttr);
			PT_IsTumbling_Field = ((PT_IsTumbling_Property == null) ? PlayerTumbleType.GetField("isTumbling", bindingAttr) : null);
			Enemy_HasStateStunned_Property = EnemyType.GetProperty("HasStateStunned", bindingAttr);
			Enemy_HasStateStunned_Field = ((Enemy_HasStateStunned_Property == null) ? EnemyType.GetField("HasStateStunned", bindingAttr) : null);
			Enemy_StateStunned_Property = EnemyType.GetProperty("StateStunned", bindingAttr);
			Enemy_StateStunned_Field = ((Enemy_StateStunned_Property == null) ? EnemyType.GetField("StateStunned", bindingAttr) : null);
			Type type = null;
			if (Enemy_StateStunned_Property != null)
			{
				type = Enemy_StateStunned_Property.PropertyType;
			}
			else if (Enemy_StateStunned_Field != null)
			{
				type = Enemy_StateStunned_Field.FieldType;
			}
			if (type == null)
			{
				type = Type.GetType("EnemyStateStunned") ?? Type.GetType("EnemyStateStunned, Assembly-CSharp");
			}
			if (type != null)
			{
				StateStunned_Set_Method = type.GetMethod("Set", bindingAttr, null, new Type[1] { typeof(float) }, null);
			}
		}

		public static bool TryGetIsTumbling(PlayerTumble pt)
		{
			if ((Object)(object)pt == (Object)null)
			{
				return false;
			}
			try
			{
				if (PT_IsTumbling_Property != null)
				{
					object value = PT_IsTumbling_Property.GetValue(pt);
					if (value is bool)
					{
						bool result = (bool)value;
						if (true)
						{
							return result;
						}
					}
				}
				else if (PT_IsTumbling_Field != null)
				{
					object value2 = PT_IsTumbling_Field.GetValue(pt);
					if (value2 is bool)
					{
						bool result2 = (bool)value2;
						if (true)
						{
							return result2;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("ReflectionHelpers.TryGetIsTumbling error: " + ex.Message));
				}
			}
			return false;
		}

		public static bool TryGetHasStateStunned(Enemy enemy, out bool value)
		{
			value = false;
			if ((Object)(object)enemy == (Object)null)
			{
				return false;
			}
			try
			{
				if (Enemy_HasStateStunned_Property != null)
				{
					object value2 = Enemy_HasStateStunned_Property.GetValue(enemy);
					if (value2 is bool)
					{
						bool flag = (bool)value2;
						if (true)
						{
							value = flag;
							return true;
						}
					}
				}
				else
				{
					if (!(Enemy_HasStateStunned_Field != null))
					{
						object stateStunned = GetStateStunned(enemy);
						value = stateStunned != null;
						return true;
					}
					object value3 = Enemy_HasStateStunned_Field.GetValue(enemy);
					if (value3 is bool)
					{
						bool flag2 = (bool)value3;
						if (true)
						{
							value = flag2;
							return true;
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("ReflectionHelpers.TryGetHasStateStunned error: " + ex.Message));
				}
			}
			return false;
		}

		public static object GetStateStunned(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return null;
			}
			try
			{
				if (Enemy_StateStunned_Property != null)
				{
					return Enemy_StateStunned_Property.GetValue(enemy);
				}
				if (Enemy_StateStunned_Field != null)
				{
					return Enemy_StateStunned_Field.GetValue(enemy);
				}
				return ((Component)enemy).GetComponent("EnemyStateStunned");
			}
			catch (Exception ex)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("ReflectionHelpers.GetStateStunned error: " + ex.Message));
				}
				return null;
			}
		}

		public static bool TrySetStateStunned(object stateStunnedInstance, float time)
		{
			if (stateStunnedInstance == null)
			{
				return false;
			}
			try
			{
				if (StateStunned_Set_Method != null)
				{
					StateStunned_Set_Method.Invoke(stateStunnedInstance, new object[1] { time });
					return true;
				}
				MethodInfo method = stateStunnedInstance.GetType().GetMethod("Set", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(float) }, null);
				if (method != null)
				{
					method.Invoke(stateStunnedInstance, new object[1] { time });
					return true;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("ReflectionHelpers.TrySetStateStunned error: " + ex.Message));
				}
			}
			return false;
		}

		public static bool TrySetEnemyStun(Enemy enemy, float time)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return false;
			}
			try
			{
				object stateStunned = GetStateStunned(enemy);
				if (stateStunned == null)
				{
					return false;
				}
				return TrySetStateStunned(stateStunned, time);
			}
			catch (Exception ex)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogWarning((object)("ReflectionHelpers.TrySetEnemyStun error: " + ex.Message));
				}
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(EnemyDirector), "Start")]
	internal static class ReloadConfigOnLevelStart
	{
		private static void Postfix()
		{
			try
			{
				TumbleAttackStunPlugin.ReloadConfig();
			}
			catch (Exception arg)
			{
				ManualLogSource logger = TumbleAttackStunPlugin.Logger;
				if (logger != null)
				{
					logger.LogError((object)$"Failed reloading config on level start: {arg}");
				}
			}
		}
	}
	[BepInPlugin("osmarbriones.TumbleAttackStun", "TumbleAttackStun", "1.0.0")]
	public class TumbleAttackStunPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "osmarbriones.TumbleAttackStun";

		public const string PluginName = "TumbleAttackStun";

		public const string PluginVersion = "1.0.0";

		private Harmony harmony;

		internal static ManualLogSource Logger { get; private set; }

		internal static ConfigEntry<float> StunSecondsConfig { get; private set; }

		internal static TumbleAttackStunPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"TumbleAttackStun 1.0.0 loaded!");
			StunSecondsConfig = ((BaseUnityPlugin)this).Config.Bind<float>("General", "StunSeconds", 3f, new ConfigDescription("Stun duration (seconds) applied to enemies hit by a tumble attack. Range: 0 - 20", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
			Logger.LogInfo((object)string.Format("Configured {0} = {1}", "StunSecondsConfig", StunSecondsConfig.Value));
			harmony = new Harmony("osmarbriones.TumbleAttackStun");
			harmony.PatchAll();
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		internal static void ReloadConfig()
		{
			try
			{
				TumbleAttackStunPlugin instance = Instance;
				if (instance != null)
				{
					((BaseUnityPlugin)instance).Config.Reload();
				}
				ManualLogSource logger = Logger;
				if (logger != null)
				{
					logger.LogInfo((object)$"TumbleAttackStun config reloaded. StunTime={StunSecondsConfig?.Value}");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource logger2 = Logger;
				if (logger2 != null)
				{
					logger2.LogError((object)$"TumbleAttackStun ReloadConfig error: {arg}");
				}
			}
		}
	}
}