using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: AssemblyProduct("AnyDirectionParry")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("AnyDirectionParry")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("1.1.1.0")]
namespace AnyDirectionParry;
public static class PluginInfo
{
public const string PLUGIN_GUID = "supidowagon.AnyDirectionParry";
public const string PLUGIN_NAME = "Any Direction Parry";
public const string PLUGIN_VERSION = "1.1.1";
}
[BepInPlugin("supidowagon.AnyDirectionParry", "Any Direction Parry", "1.1.1")]
public class Plugin : BaseUnityPlugin
{
[HarmonyPatch(typeof(EffectDealer), "FacingRuleCheck", new Type[]
{
typeof(DamageDealer),
typeof(Vector3),
typeof(Vector2)
})]
private static class Patch_EffectDealer_FacingRuleCheck
{
private static void Postfix(EffectDealer __instance, ref bool __result)
{
if (!__result && IgnoreParryDirection != null && IgnoreParryDirection.Value && (PlayerOnly == null || !PlayerOnly.Value || IsPlayerParryDealer(__instance)))
{
__result = true;
}
}
}
internal static ManualLogSource Logger;
internal static ConfigEntry<bool> IgnoreParryDirection;
internal static ConfigEntry<bool> PlayerOnly;
private static PropertyInfo playerInstanceProp;
private static FieldInfo playerHealthField;
private static FieldInfo parryDealerField;
private static bool reflectionReady;
private static bool reflectionFailed;
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
IgnoreParryDirection = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IgnoreParryDirection", true, "Parry attacks coming from any direction, whichever way Yi happens to be facing. Turn off to restore the stock behaviour without removing the mod.");
PlayerOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PlayerOnly", true, "Only lift the facing requirement for the player. Leave this on unless you also want enemies that parry to ignore facing.");
Logger.LogInfo((object)"Plugin supidowagon.AnyDirectionParry is loaded!");
Harmony val = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "supidowagon.AnyDirectionParry");
foreach (MethodBase patchedMethod in val.GetPatchedMethods())
{
Logger.LogInfo((object)("Patched method: " + patchedMethod.DeclaringType.FullName + "." + patchedMethod.Name));
}
if (val.GetPatchedMethods().Count() == 0)
{
Logger.LogError((object)"Failed to apply Harmony patches.");
}
}
private static void EnsureReflection()
{
if (reflectionReady || reflectionFailed)
{
return;
}
Type type = AccessTools.TypeByName("Player");
if (type != null)
{
playerInstanceProp = AccessTools.Property(type, "i");
playerHealthField = AccessTools.Field(type, "health");
if (playerHealthField != null)
{
parryDealerField = AccessTools.Field(playerHealthField.FieldType, "parryDealer");
}
}
if (playerInstanceProp == null || playerHealthField == null || parryDealerField == null)
{
reflectionFailed = true;
Logger.LogWarning((object)"Could not resolve Player.i.health.parryDealer; PlayerOnly cannot be enforced, so the facing rule is left untouched. Set PlayerOnly=false to apply it regardless.");
}
else
{
reflectionReady = true;
}
}
internal static bool IsPlayerParryDealer(EffectDealer dealer)
{
if ((Object)(object)dealer == (Object)null)
{
return false;
}
EnsureReflection();
if (!reflectionReady)
{
return false;
}
object value = playerInstanceProp.GetValue(null, null);
if (value == null)
{
return false;
}
object value2 = playerHealthField.GetValue(value);
if (value2 == null)
{
return false;
}
return object.ReferenceEquals(dealer, parryDealerField.GetValue(value2));
}
}