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}");
}
}
}
}
}