using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Zen.Config;
using Zen.Lib;
using Zen.Logging;
using ZenCombat.Section;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZenCombat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZenCombat")]
[assembly: AssemblyCopyright("Copyright \ufffd 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 ZenCombat
{
[BepInPlugin("ZenDragon.ZenCombat", "ZenCombat", "0.2.10")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[SynchronizationMode(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
internal class Plugin : ZenMod<Plugin>
{
public const string PluginName = "ZenCombat";
public const string PluginVersion = "0.2.10";
public const string PluginGUID = "ZenDragon.ZenCombat";
protected override void Setup()
{
((ZenMod)this).RequireGamepadRemap = RemapDodge.Configs.RemapDodgeButton.Value;
((ZenMod)this).RegisterInputs += RemapDodge.RemapDodgeGamepad;
((ZenMod)this).ConfigSync += Bows.SetupArrows;
}
protected override void TitleScene(bool isFirstBoot)
{
}
protected override void WorldStart()
{
}
protected override void Shutdown()
{
}
}
}
namespace ZenCombat.Section
{
[HarmonyPatch]
public static class Bows
{
private static class Configs
{
public static readonly ConfigEntry<bool> EnableWoodArrow;
public static readonly ConfigEntry<float> WoodArrowDamage;
public static readonly ConfigEntry<float> ProjectileLaunchAngle;
public static readonly ConfigEntry<float> BowDrawMovementSpeed;
static Configs()
{
EnableWoodArrow = Config.Define<bool>(true, "Bows", "Enable WoodArrow", false, "Allow wood arrows? They are a bit OP because they are so cheap and lethal.\r\nWhen enabled it does not make firing an arrow a risky proposition and they \r\nundermine any reason to invest in more expensive ammunition.\r\n[restart required]");
WoodArrowDamage = Config.Define<float>(true, "Bows", "WoodArrow Damage", 1f, Config.AcceptRange<float>(0.1f, 22f), "How much damage should wood arrows do if they are enabled?\r\nThey are very OP by default for being a basic crude arrow. (Vanilla: 22)\r\n[restart required]");
ProjectileLaunchAngle = Config.Define<float>(true, "Bows", "Projectile Launch Angle", -2f, Config.AcceptRange<float>(-10f, 10f), "Angle that the projectile is launched at. To offset the default undershot in Vanilla. (Vanilla: 0)");
BowDrawMovementSpeed = Config.Define<float>(true, "Bows", "Movement Speed", 0.5f, Config.AcceptRange<float>(0f, 1f), "Percent of normal movement speed when bow is drawn, 0.5 = 50%, move half speed when drawing bow. (Vanilla: 1)\r\nNOTE: If CombatOverhaulRewrite is installed it is recommended to set this to 1 otherwise the two mods will compound this value.");
}
}
internal static void SetupArrows()
{
Log.Info((object)"Setting up arrows", (ushort)0);
GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("ArrowWood");
ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
if ((Object)(object)val == (Object)null)
{
Log.Error((object)"Unable to find wood arrow in ObjectDB", (ushort)0);
return;
}
val.m_itemData.m_shared.m_damages.m_pierce = Configs.WoodArrowDamage.Value;
Recipe val2 = default(Recipe);
if (ItemDataExt.TryGetRecipe(val, ref val2))
{
val2.m_enabled = Configs.EnableWoodArrow.Value;
}
else
{
Log.Error((object)"Unable to find wood arrow recipe", (ushort)0);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Attack), "Start")]
private static void Attack_Start(Attack __instance)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Invalid comparison between Unknown and I4
Humanoid character = __instance.m_character;
Player val = (Player)(object)((character is Player) ? character : null);
if (val != null && PlayerExt.Is(val, (Character)(object)Player.m_localPlayer))
{
ItemData currentWeapon = ((Humanoid)val).GetCurrentWeapon();
if (currentWeapon != null && (int)currentWeapon.m_shared.m_skillType == 8)
{
Log.Info((object)$"Weapon: {ItemDataExt.GetName(currentWeapon)} LaunchAngle: {__instance.m_launchAngle}", (ushort)0);
__instance.m_launchAngle = Configs.ProjectileLaunchAngle.Value;
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "GetJogSpeedFactor")]
private static void Player_GetJogSpeedFactor(Player __instance, ref float __result)
{
__result *= ((((Humanoid)__instance).m_attackDrawTime > 0f) ? Configs.BowDrawMovementSpeed.Value : 1f);
}
}
[HarmonyPatch]
internal static class DamageUI
{
private static class Configs
{
public static readonly ConfigEntry<bool> SoftDamageScreenFlash;
public static readonly ConfigEntry<bool> HideDamageText0;
public static readonly ConfigEntry<DamageTextVisibilityMode> DamageTextVisibility;
static Configs()
{
SoftDamageScreenFlash = Config.Define<bool>(true, "UI", "Softer Damage Screen Flash", true, "Override the vanilla red screen damage flash with a softer less blinding style.");
HideDamageText0 = Config.Define<bool>(true, "UI", "Hide Damage Text 0", true, "Hide damage text when it is just 0 (Vanilla: false)");
DamageTextVisibility = Config.Define<DamageTextVisibilityMode>(true, "UI", "Damage Text Visibility", DamageTextVisibilityMode.Self, "In multiplayer, damage text visibility mode: (Vanilla: All)\r\nAll - View all damage numbers and info text from everyone.\r\nSelf - Only show your own damage numbers + Info texts.\r\nInfo - Only show info texts, no damage numbers.\r\nNone - Hide all texts, show nothing.");
}
}
private enum DamageTextVisibilityMode
{
All,
Self,
Info,
None
}
[HarmonyPatch]
private static class DamageTextDisplay
{
private static HitData? _hitData;
[HarmonyPrefix]
[HarmonyPatch(typeof(DamageText), "AddInworldText")]
private static void DamageText_AddInWorldText(ref bool __runOriginal, TextType type, bool mySelf)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Invalid comparison between Unknown and I4
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Invalid comparison between Unknown and I4
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Invalid comparison between Unknown and I4
HitData? hitData = _hitData;
Character val = ((hitData != null) ? hitData.GetAttacker() : null);
bool flag = (Object)(object)Player.m_localPlayer == (Object)(object)val;
bool flag2 = (int)type == 4;
bool num = mySelf && (int)type == 7;
bool flag3 = mySelf && (int)type <= 3;
bool flag4 = num || (flag && (int)type >= 3);
Log.Info((object)$"Attacker: {((val != null) ? val.GetHoverName() : null)} isAttacker:{flag}", (ushort)0);
__runOriginal = Configs.DamageTextVisibility.Value switch
{
DamageTextVisibilityMode.All => true,
DamageTextVisibilityMode.Self => flag || flag4 || flag2 || flag3,
DamageTextVisibilityMode.Info => flag4 || flag2,
DamageTextVisibilityMode.None => false,
_ => throw new ArgumentOutOfRangeException(),
};
_hitData = null;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(HitData), "SetAttacker")]
private static void HitData_SetAttacker(HitData __instance, Character? attacker)
{
_hitData = __instance;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(DamageText), "ShowText", new Type[]
{
typeof(TextType),
typeof(Vector3),
typeof(float),
typeof(bool)
})]
private static void DamageText_ShowText(TextType type, float dmg, ref bool __runOriginal)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if ((int)type == 0 && Configs.HideDamageText0.Value)
{
__runOriginal = dmg >= 0.1f;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(DamageText), "ShowText", new Type[]
{
typeof(TextType),
typeof(Vector3),
typeof(string),
typeof(bool)
})]
private static void DamageText_ShowText(TextType type, ref string text)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
if (float.TryParse(text, out var result) && result < 0.1f && (int)type == 3)
{
text = "$inventory_immune";
}
Log.Info((object)$"Damage text type: {type} text: {text}", (ushort)0);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Hud), "Awake")]
private static void Hud_Awake()
{
if (Configs.SoftDamageScreenFlash.Value)
{
Hud.instance.m_damageScreen.sprite = AssetIO.LoadSprite("damage_flash.png", (Assembly)null);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Hud), "DamageFlash")]
private static void Hud_DamageFlash(ref bool __runOriginal)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (Configs.SoftDamageScreenFlash.Value)
{
__runOriginal = false;
Image damageScreen = Hud.instance.m_damageScreen;
((Graphic)damageScreen).color = new Color(1f, 0f, 0f, 0.8f);
((Component)damageScreen).gameObject.SetActive(true);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Hud), "UpdateDamageFlash")]
private static void Hud_UpdateDamageFlash(ref bool __runOriginal, float dt)
{
//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_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
if (Configs.SoftDamageScreenFlash.Value)
{
__runOriginal = false;
Image damageScreen = Hud.instance.m_damageScreen;
Color color = ((Graphic)damageScreen).color;
color.a = Mathf.MoveTowards(color.a, 0f, dt * 0.5f);
((Graphic)damageScreen).color = color;
((Component)damageScreen).gameObject.SetActive(color.a > 0f);
}
}
}
[HarmonyPatch]
public static class Melee
{
private static class Configs
{
public static readonly ConfigEntry<bool> EnableSlopeCombat;
public static readonly ConfigEntry<bool> BlockTowardsLookDir;
public static readonly ConfigEntry<bool> NoStunParryRangedAttack;
public static readonly ConfigEntry<float> PushbackPercent;
static Configs()
{
NoStunParryRangedAttack = Config.Define<bool>(true, "Melee", "Parry Ranged Attacker - No Stun", true, "Parrying a ranged attack does not stun the attacker. That's just silly. (Vanilla : false)");
EnableSlopeCombat = Config.Define<bool>(true, "Melee", "Enable Slope Combat", true, "Attack targets on slopes above or below you.");
BlockTowardsLookDir = Config.Define<bool>(false, "Melee", "Block Towards Look Direction", true, "When the vanilla setting 'Attack towards look direction' is enabled this makes it also apply those rules for blocking. (Vanilla : false)");
PushbackPercent = Config.Define<float>(true, "Melee", "Pushback Force Percent", 0.4f, Config.AcceptRange<float>(0f, 1f), "The percent of vanilla pushback force to apply (Vanilla: 100%)\r\nBy default this is set to lower than 100% to make it feel weighty.\r\nOtherwise things get flinged around far to easily and feels weightless.");
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Character), "ApplyPushback", new Type[]
{
typeof(Vector3),
typeof(float)
})]
private static void Character_ApplyPushback(ref float pushForce)
{
pushForce *= Configs.PushbackPercent.Value;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Attack), "DoMeleeAttack")]
private static void Attack_DoMeleeAttack(Attack __instance)
{
Humanoid character = __instance.m_character;
Player val = (Player)(object)((character is Player) ? character : null);
if (val != null && PlayerExt.Is(val, (Character)(object)Player.m_localPlayer) && Configs.EnableSlopeCombat.Value)
{
__instance.m_maxYAngle = 180f;
__instance.m_attackOffset = 0f;
__instance.m_attackHeight = 1f;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "AlwaysRotateCamera")]
private static void Player_AlwaysRotateCamera(Character __instance, ref bool __result)
{
if (Configs.BlockTowardsLookDir.Value)
{
Player val = (Player)(object)((__instance is Player) ? __instance : null);
if (val != null && PlayerExt.Is(val, (Character)(object)Player.m_localPlayer) && ((Character)val).IsBlocking() && val.m_attackTowardsPlayerLookDir)
{
__result = false;
}
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
private static IEnumerable<CodeInstruction> Humanoid_BlockAttack(IEnumerable<CodeInstruction> instructions)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected O, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
FieldInfo fieldInfo = AccessTools.Field(typeof(Character), "m_staggerWhenBlocked");
return new CodeMatcher(instructions, (ILGenerator)null).MatchStartForward((CodeMatch[])(object)new CodeMatch[3]
{
new CodeMatch((OpCode?)OpCodes.Ldarg_2, (object)null, (string)null),
new CodeMatch((OpCode?)OpCodes.Ldfld, (object)fieldInfo, (string)null),
new CodeMatch((OpCode?)OpCodes.Brfalse, (object)null, (string)null)
}).ThrowIfInvalid("Unable to match IL for disabling stagger when parry ranged attack").Advance(1)
.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
{
new CodeInstruction(OpCodes.Ldarg_1, (object)null)
})
.SetInstruction(CodeInstruction.Call(typeof(Melee), "Humanoid_BlockAttack_StaggerIntercept", (Type[])null, (Type[])null))
.InstructionEnumeration();
}
private static bool Humanoid_BlockAttack_StaggerIntercept(Character attacker, HitData hitData)
{
if (!Configs.NoStunParryRangedAttack.Value)
{
return attacker.m_staggerWhenBlocked;
}
if (attacker.m_staggerWhenBlocked)
{
return !hitData.m_ranged;
}
return false;
}
}
[HarmonyPatch]
public static class AutoShield
{
public static class Configs
{
public static readonly ConfigEntry<bool> Autoequip;
static Configs()
{
Autoequip = Config.Define<bool>(false, "AutoShield", "Autoequip Recent Shield", true, "Automatically equip the recent shield when equipping main 1h weapon.\r\nPlus extra logic to make the torch behave nicely with auto shield.\r\nIntuitivly toggle weapons and shields and torches without needing to think about it to much.");
}
}
private const string CustomDataKey = "ZenDragon.ZenCombat|RecentShield";
private static ItemData? RecentShield
{
get
{
if (!Configs.Autoequip.Value)
{
return null;
}
Player localPlayer = Player.m_localPlayer;
string[] array = GeneralExtensions.GetValueSafe<string, string>(localPlayer.m_customData, "ZenDragon.ZenCombat|RecentShield")?.Split(new char[1] { '\t' });
(string Name, int Variant, int Quality) saved = ((array != null && array.Length == 3) ? (array[0], int.Parse(array[1]), int.Parse(array[2])) : default((string, int, int)));
return ((IEnumerable<ItemData>)((Humanoid)localPlayer).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => ItemDataExt.GetName(item) == saved.Name && item.m_variant == saved.Variant && item.m_quality == saved.Quality && item.m_worldLevel >= Game.m_worldLevel));
}
set
{
Dictionary<string, string> customData = Player.m_localPlayer.m_customData;
if (value == null)
{
customData.Remove("ZenDragon.ZenCombat|RecentShield");
}
else
{
customData["ZenDragon.ZenCombat|RecentShield"] = $"{ItemDataExt.GetName(value)}\t{value.m_variant}\t{value.m_quality}";
}
}
}
private static ItemData? GetBeltTorch(Humanoid humanoid)
{
if (!ItemDataExt.IsItemType(humanoid.m_hiddenLeftItem, (ItemType)15))
{
if (!ItemDataExt.IsItemType(humanoid.m_hiddenRightItem, (ItemType)15))
{
return null;
}
return humanoid.m_hiddenRightItem;
}
return humanoid.m_hiddenLeftItem;
}
private static void DebugItemPositions(Humanoid humanoid, ItemData item)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
if (Log.IsEnabled)
{
string value = new string('=', 73);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine(value);
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "POSITION", "TYPE", "NAME");
stringBuilder.AppendLine(value);
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "Equipping", ItemDataExt.GetItemType(item), ItemDataExt.GetName(item));
object arg = ItemDataExt.GetItemType(humanoid.LeftItem);
ItemData leftItem = humanoid.LeftItem;
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "Active Left", arg, (leftItem != null) ? ItemDataExt.GetName(leftItem) : null);
object arg2 = ItemDataExt.GetItemType(humanoid.m_hiddenLeftItem);
ItemData hiddenLeftItem = humanoid.m_hiddenLeftItem;
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "Hidden Left", arg2, (hiddenLeftItem != null) ? ItemDataExt.GetName(hiddenLeftItem) : null);
object arg3 = ItemDataExt.GetItemType(humanoid.RightItem);
ItemData rightItem = humanoid.RightItem;
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "Active Right", arg3, (rightItem != null) ? ItemDataExt.GetName(rightItem) : null);
object arg4 = ItemDataExt.GetItemType(humanoid.m_hiddenRightItem);
ItemData hiddenRightItem = humanoid.m_hiddenRightItem;
stringBuilder.AppendFormat("{0,15} | {1,25} | {2,25} |\n", "Hidden Right", arg4, (hiddenRightItem != null) ? ItemDataExt.GetName(hiddenRightItem) : null);
stringBuilder.AppendLine(value);
Log.Info((object)("\n" + stringBuilder), (ushort)0);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Humanoid), "EquipItem")]
private static void Humanoid_EquipItem_Prefix(Humanoid __instance, ItemData? item)
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Invalid comparison between Unknown and I4
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Invalid comparison between Unknown and I4
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Invalid comparison between Unknown and I4
Humanoid __instance2 = __instance;
if (!Configs.Autoequip.Value || item == null || (Object)(object)__instance2 != (Object)(object)Player.m_localPlayer || ((Character)__instance2).IsDead())
{
return;
}
DebugItemPositions(__instance2, item);
ItemData beltTorch = GetBeltTorch(__instance2);
ItemType itemType = ItemDataExt.GetItemType(item);
if ((int)itemType != 3)
{
if ((int)itemType != 5)
{
if ((int)itemType == 15 && ItemDataExt.IsItemType(__instance2.RightItem, (ItemType)3))
{
if (ItemDataExt.IsItemType(__instance2.LeftItem, (ItemType)5))
{
__instance2.UnequipItem(__instance2.LeftItem, false);
}
else if (ItemDataExt.IsItemType(__instance2.LeftItem, (ItemType)15) && __instance2.LeftItem != item)
{
__instance2.m_leftItem.m_equipped = false;
__instance2.m_leftItem = item;
__instance2.m_leftItem.m_equipped = true;
}
}
}
else if (beltTorch != null && IsHandAvail())
{
__instance2.m_rightItem = beltTorch;
__instance2.m_rightItem.m_equipped = true;
__instance2.m_hiddenLeftItem = null;
__instance2.m_hiddenRightItem = null;
}
}
else if (ItemDataExt.IsItemType(__instance2.RightItem, (ItemType)15))
{
__instance2.UnequipItem(__instance2.LeftItem, false);
}
else if (beltTorch != null && IsHandAvail())
{
__instance2.m_leftItem = beltTorch;
__instance2.m_leftItem.m_equipped = true;
__instance2.m_hiddenLeftItem = null;
__instance2.m_hiddenRightItem = null;
}
else if (ItemDataExt.IsItemType(__instance2.LeftItem, (ItemType)15))
{
if (__instance2.RightItem != null)
{
__instance2.m_rightItem.m_equipped = false;
}
__instance2.m_rightItem = __instance2.LeftItem;
__instance2.m_leftItem = null;
}
__instance2.SetupEquipment();
bool IsHandAvail()
{
if (__instance2.LeftItem != null)
{
return __instance2.RightItem == null;
}
return true;
}
}
private static void UpdateEquipped()
{
foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems())
{
allItem.m_equipped = ((Humanoid)Player.m_localPlayer).IsItemEquiped(allItem);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Humanoid), "EquipItem")]
private static void Humanoid_EquipItem_Postfix(Humanoid __instance, ItemData? item)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Invalid comparison between Unknown and I4
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Invalid comparison between Unknown and I4
if (!Configs.Autoequip.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsDead())
{
return;
}
ItemType? val = item?.m_shared.m_itemType;
if (val.HasValue)
{
ItemType valueOrDefault = val.GetValueOrDefault();
if ((int)valueOrDefault != 3)
{
if ((int)valueOrDefault == 5)
{
RecentShield = item;
}
}
else if (__instance.LeftItem == null)
{
__instance.EquipItem(RecentShield, false);
}
}
Timing.EndOfFrame((MonoBehaviour)(object)__instance, (Action)UpdateEquipped);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
private static void Humanoid_UnequipItem(Humanoid __instance, ItemData? item)
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
if (!Configs.Autoequip.Value || item == null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || ((Character)__instance).IsDead())
{
return;
}
ItemType itemType = item.m_shared.m_itemType;
if ((int)itemType != 3)
{
if ((int)itemType == 15 && ItemDataExt.IsItemType(__instance.RightItem, (ItemType)3))
{
__instance.EquipItem(RecentShield, false);
}
return;
}
if (ItemDataExt.IsItemType(__instance.LeftItem, (ItemType)15))
{
__instance.m_rightItem = __instance.m_leftItem;
__instance.m_leftItem = null;
__instance.SetupEquipment();
}
if (ItemDataExt.IsItemType(__instance.LeftItem, (ItemType)5) && !Object.op_Implicit((Object)(object)item.m_lastProjectile))
{
__instance.UnequipItem(__instance.LeftItem, false);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "UseHotbarItem")]
private static void Player_UseHotbarItem(int index)
{
if (Configs.Autoequip.Value && ((Humanoid)Player.m_localPlayer).GetInventory().GetItemAt(index - 1, 0) == RecentShield)
{
RecentShield = null;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
private static void InventoryGui_OnRightClickItem(InventoryGrid grid, ItemData item)
{
if (Configs.Autoequip.Value && grid.GetInventory() == ((Humanoid)Player.m_localPlayer).GetInventory() && item == RecentShield)
{
RecentShield = null;
}
}
}
[HarmonyPatch]
public static class RemapDodge
{
internal static class Configs
{
public static readonly ConfigEntry<bool> RemapDodgeButton;
public static readonly ConfigEntry<KeyCode> KeyboardDodgeButton;
static Configs()
{
RemapDodgeButton = Config.Define<bool>(false, "Input", "Separate Jump/Dodge Buttons", true, "Dodge becomes a separate button from jump, you no longer need to hold block to dodge.\r\nKeyboard: Define the custom key using the config option below.\r\nGamepad: Interact (Use) is moved to X on classic controller layout to make room.\r\nNote: When using gamepad you need to restart the game for all control mapping to take effect.");
RemapDodgeButton.SettingChanged += delegate
{
((ZenMod)ZenMod<Plugin>.Instance).RefreshInputs();
};
KeyboardDodgeButton = Config.Define<KeyCode>(false, "Input", "Keyboard Dodge Button", (KeyCode)308, "Keyboard: Dedicated dodge button for keyboard.");
}
}
[HarmonyPatch]
private static class HandleKeyboardDodgeButton
{
private static bool _isDodging;
[HarmonyPrefix]
[HarmonyPatch(typeof(Player), "SetControls")]
private static void SetControls_Prefix(Player __instance, ref bool jump)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
if (Configs.RemapDodgeButton.Value && !ZInput.IsGamepadActive() && !((Character)__instance).IsSitting() && !jump && ZInput.GetKey(Configs.KeyboardDodgeButton.Value, true))
{
jump = true;
_isDodging = true;
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Player), "SetControls")]
private static void SetControls_Postfix(ref bool jump)
{
_isDodging = false;
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Character), "Jump")]
private static void Character_Jump(Player __instance, ref bool __runOriginal)
{
if (Configs.RemapDodgeButton.Value && !ZInput.IsGamepadActive() && _isDodging)
{
__runOriginal = false;
InvokeDodge(__instance);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Player), "Dodge")]
private static void Player_Dodge(Player __instance, ref bool __runOriginal)
{
if (Configs.RemapDodgeButton.Value && !ZInput.IsGamepadActive() && !_isDodging)
{
__runOriginal = false;
((Character)__instance).Jump(false);
}
}
private static void InvokeDodge(Player player)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
Vector3 moveDir = ((Character)player).m_moveDir;
if (!(((Vector3)(ref moveDir)).magnitude < 0.1f))
{
player.Dodge(((Vector3)(ref moveDir)).normalized);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(KeyHints), "Awake")]
private static void KeyHints_Awake(KeyHints __instance)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
if (Configs.RemapDodgeButton.Value)
{
Transform obj = __instance.m_combatHints.transform.Find("Keyboard/Dodge");
TextMeshProUGUI component = ((Component)obj.Find("key_bkg/Key")).GetComponent<TextMeshProUGUI>();
KeyCode value = Configs.KeyboardDodgeButton.Value;
((TMP_Text)component).text = ((object)(KeyCode)(ref value)).ToString();
((Component)obj.GetChild(2)).gameObject.SetActive(false);
((Component)obj.GetChild(3)).gameObject.SetActive(false);
}
}
}
[CompilerGenerated]
private sealed class <Transpile_KeyHints_SetGamePadBindings>d__7 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
{
private int <>1__state;
private CodeInstruction <>2__current;
private int <>l__initialThreadId;
private IEnumerable<CodeInstruction> instructions;
public IEnumerable<CodeInstruction> <>3__instructions;
private IEnumerator<CodeInstruction> <>7__wrap1;
CodeInstruction IEnumerator<CodeInstruction>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Transpile_KeyHints_SetGamePadBindings>d__7(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = instructions.GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
break;
}
if (<>7__wrap1.MoveNext())
{
CodeInstruction current = <>7__wrap1.Current;
if (current.opcode == OpCodes.Ldstr && current.operand as string == "$hud_buildmenu <mspace=0.6em>$KEY_Use</mspace>")
{
current.operand = "$hud_buildmenu <mspace=0.6em>$KEY_BuildMenu</mspace>";
}
<>2__current = current;
<>1__state = 1;
return true;
}
<>m__Finally1();
<>7__wrap1 = null;
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
{
<Transpile_KeyHints_SetGamePadBindings>d__7 <Transpile_KeyHints_SetGamePadBindings>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<Transpile_KeyHints_SetGamePadBindings>d__ = this;
}
else
{
<Transpile_KeyHints_SetGamePadBindings>d__ = new <Transpile_KeyHints_SetGamePadBindings>d__7(0);
}
<Transpile_KeyHints_SetGamePadBindings>d__.instructions = <>3__instructions;
return <Transpile_KeyHints_SetGamePadBindings>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
}
}
[CompilerGenerated]
private sealed class <Transpile_Player_UpdateBuildGuiInput>d__6 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator
{
private int <>1__state;
private CodeInstruction <>2__current;
private int <>l__initialThreadId;
private IEnumerable<CodeInstruction> instructions;
public IEnumerable<CodeInstruction> <>3__instructions;
private IEnumerator<CodeInstruction> <>7__wrap1;
CodeInstruction IEnumerator<CodeInstruction>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <Transpile_Player_UpdateBuildGuiInput>d__6(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<>7__wrap1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>7__wrap1 = instructions.GetEnumerator();
<>1__state = -3;
break;
case 1:
<>1__state = -3;
break;
}
if (<>7__wrap1.MoveNext())
{
CodeInstruction current = <>7__wrap1.Current;
if (current.opcode == OpCodes.Ldstr && current.operand as string == "JoyUse")
{
current.operand = "JoyBuildMenu";
}
<>2__current = current;
<>1__state = 1;
return true;
}
<>m__Finally1();
<>7__wrap1 = null;
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
if (<>7__wrap1 != null)
{
<>7__wrap1.Dispose();
}
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
{
<Transpile_Player_UpdateBuildGuiInput>d__6 <Transpile_Player_UpdateBuildGuiInput>d__;
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
<Transpile_Player_UpdateBuildGuiInput>d__ = this;
}
else
{
<Transpile_Player_UpdateBuildGuiInput>d__ = new <Transpile_Player_UpdateBuildGuiInput>d__6(0);
}
<Transpile_Player_UpdateBuildGuiInput>d__.instructions = <>3__instructions;
return <Transpile_Player_UpdateBuildGuiInput>d__;
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
}
}
public static void RemapDodgeGamepad()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if (Configs.RemapDodgeButton.Value)
{
GamepadInput val;
if ((int)ZInput.InputLayout == 0)
{
val = (GamepadInput)5;
ZInputExt.RemapTo(ZInput.instance.GetButtonDef("JoyUse"), (GamepadInput)7, (bool?)null, (bool?)null, (bool?)null, (float?)null, (float?)null);
}
else
{
val = (GamepadInput)6;
}
ZInputExt.RemapTo(ZInput.instance.GetButtonDef("JoyDodge"), val, (bool?)false, (bool?)null, (bool?)null, (float?)null, (float?)null);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(KeyHints), "SetGamePadBindings")]
private static void KeyHints_SetGamePadBindings()
{
if (Configs.RemapDodgeButton.Value)
{
TextMeshProUGUI dodgeKey = KeyHints.instance.m_dodgeKey;
Localization.instance.RemoveTextFromCache((TMP_Text)(object)dodgeKey);
((TMP_Text)dodgeKey).text = "$settings_dodge <mspace=0.6em>$KEY_JoyDodge</mspace>";
Localization.instance.Localize(((TMP_Text)dodgeKey).transform);
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Player), "Update")]
private static void RemapDodge_CheckForInput_Player_Update(Player __instance)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!Configs.RemapDodgeButton.Value || !ZInput.IsGamepadActive() || !ZInput.GetButton("JoyDodge") || UI.IsOpen)
{
return;
}
if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !(__instance.m_queuedDodgeTimer > 0f))
{
Vector3 moveDir = ((Character)__instance).GetMoveDir();
if (!(((Vector3)(ref moveDir)).magnitude < 0.1f))
{
__instance.Dodge(moveDir);
}
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(Player), "Dodge")]
private static void RemapDodge_FixClassicJump_Player_Dodge(Player __instance, ref bool __runOriginal)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (Configs.RemapDodgeButton.Value && (int)ZInput.InputLayout == 0 && ZInput.IsGamepadActive() && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ZInput.GetButton("JoyButtonB"))
{
__runOriginal = false;
((Character)__instance).Jump(false);
}
}
[IteratorStateMachine(typeof(<Transpile_Player_UpdateBuildGuiInput>d__6))]
[HarmonyTranspiler]
[HarmonyPatch(typeof(Player), "UpdateBuildGuiInput")]
public static IEnumerable<CodeInstruction> Transpile_Player_UpdateBuildGuiInput(IEnumerable<CodeInstruction> instructions)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Transpile_Player_UpdateBuildGuiInput>d__6(-2)
{
<>3__instructions = instructions
};
}
[IteratorStateMachine(typeof(<Transpile_KeyHints_SetGamePadBindings>d__7))]
[HarmonyTranspiler]
[HarmonyPatch(typeof(KeyHints), "SetGamePadBindings")]
public static IEnumerable<CodeInstruction> Transpile_KeyHints_SetGamePadBindings(IEnumerable<CodeInstruction> instructions)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <Transpile_KeyHints_SetGamePadBindings>d__7(-2)
{
<>3__instructions = instructions
};
}
}
}