Decompiled source of SpearForwardThrust v1.0.2

BepInEx/plugins/SpearForwardThrust.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Daxtillion")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("SpearForwardThrust")]
[assembly: AssemblyTitle("SpearForwardThrust")]
[assembly: AssemblyVersion("1.0.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 SpearThrust
{
	[BepInPlugin("daxtillion.spearforwardthrust", "SpearForwardThrust", "1.0.2")]
	public sealed class SpearThrustPlugin : BaseUnityPlugin
	{
		private sealed class AttackSnapshot
		{
			internal string Animation;

			internal float Range;

			internal float Height;

			internal float Angle;

			internal float Width;

			internal AttackSnapshot(Attack attack)
			{
				Animation = attack.m_attackAnimation;
				Range = attack.m_attackRange;
				Height = attack.m_attackHeight;
				Angle = attack.m_attackAngle;
				Width = attack.m_attackRayWidth;
			}

			internal void Restore(Attack attack)
			{
				attack.m_attackAnimation = Animation;
				attack.m_attackRange = Range;
				attack.m_attackHeight = Height;
				attack.m_attackAngle = Angle;
				attack.m_attackRayWidth = Width;
			}
		}

		private Harmony harmony;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyboardShortcut> ToggleHotkey;

		internal static ConfigEntry<float> Speed;

		internal static ConfigEntry<float> Range;

		internal static ConfigEntry<float> HitHeight;

		internal static ConfigEntry<float> HitAngle;

		internal static ConfigEntry<float> RayWidth;

		internal static ConfigEntry<float> GripPitch;

		internal static ConfigEntry<float> GripYaw;

		internal static ConfigEntry<float> GripOffset;

		internal static readonly FieldRef<VisEquipment, GameObject> RightItem = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance");

		internal static readonly FieldRef<Humanoid, VisEquipment> Equipment = AccessTools.FieldRefAccess<Humanoid, VisEquipment>("m_visEquipment");

		internal static readonly FieldRef<Humanoid, Attack> CurrentAttack = AccessTools.FieldRefAccess<Humanoid, Attack>("m_currentAttack");

		internal static readonly FieldRef<Humanoid, bool> SecondaryAttack = AccessTools.FieldRefAccess<Humanoid, bool>("m_currentAttackIsSecondary");

		private static readonly Dictionary<Attack, AttackSnapshot> Originals = new Dictionary<Attack, AttackSnapshot>();

		private void Awake()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Expected O, but got Unknown
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn SpearForwardThrust on or off. Off restores the original attack and spear pose.");
			ToggleHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "Toggle hotkey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Press this key in game to toggle the mod. Can be changed in the mod configuration page.");
			Speed = ((BaseUnityPlugin)this).Config.Bind<float>("Attack", "Speed relative to vanilla", 0.8f, new ConfigDescription("0.8 is the default thrust speed. 1.0 targets the vanilla spear's attack-state duration. Raise it for a faster thrust or lower it for a slower one.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2f), Array.Empty<object>()));
			Range = ((BaseUnityPlugin)this).Config.Bind<float>("Attack", "Thrust range", 3.2f, new ConfigDescription("Forward reach in game units. Re-equip to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 4.5f), Array.Empty<object>()));
			HitHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Attack", "Hit height", 1f, new ConfigDescription("Height of the primary hit area. Re-equip to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			HitAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Attack", "Hit angle", 30f, new ConfigDescription("Width of the primary attack arc in degrees. Re-equip to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 90f), Array.Empty<object>()));
			RayWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Attack", "Hit ray width", 0.4f, new ConfigDescription("Thickness of the primary hit area. Re-equip to apply.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			GripPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Spear pitch", 180f, new ConfigDescription("Rotation that turns the spear point forward and upward.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 360f), Array.Empty<object>()));
			GripYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Spear yaw", 25f, new ConfigDescription("Additional sideways rotation of the held spear.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-90f, 90f), Array.Empty<object>()));
			GripOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Grip offset", -0.5f, new ConfigDescription("Position of the spear along its shaft.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-1.5f, 1.5f), Array.Empty<object>()));
			Enabled.SettingChanged += delegate
			{
				RefreshEnabledState();
			};
			harmony = new Harmony("daxtillion.spearforwardthrust");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SpearForwardThrust 1.0.2 by Daxtillion loaded");
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = ToggleHotkey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				Enabled.Value = !Enabled.Value;
			}
		}

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

		private static void RefreshEnabledState()
		{
			foreach (KeyValuePair<Attack, AttackSnapshot> original in Originals)
			{
				if (Enabled.Value)
				{
					ApplyAttack(original.Key);
				}
				else
				{
					original.Value.Restore(original.Key);
				}
			}
			SpearVisualState[] array = Resources.FindObjectsOfTypeAll<SpearVisualState>();
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Apply();
			}
		}

		private static void ApplyAttack(Attack attack)
		{
			attack.m_attackAnimation = "sword_secondary";
			attack.m_attackRange = Range.Value;
			attack.m_attackHeight = HitHeight.Value;
			attack.m_attackAngle = HitAngle.Value;
			attack.m_attackRayWidth = RayWidth.Value;
		}

		internal static bool IsOurSpear(ItemData item)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			SharedData val = item?.m_shared;
			if (val != null && (int)val.m_skillType == 5 && val.m_name != "$item_spear_chitin" && val.m_attack != null)
			{
				if (!(val.m_attack.m_attackAnimation == "spear_poke"))
				{
					return Originals.ContainsKey(val.m_attack);
				}
				return true;
			}
			return false;
		}

		internal static void ConfigureAttack(ItemData item)
		{
			if (IsOurSpear(item))
			{
				Attack attack = item.m_shared.m_attack;
				if (!Originals.ContainsKey(attack))
				{
					Originals.Add(attack, new AttackSnapshot(attack));
				}
				if (Enabled.Value)
				{
					ApplyAttack(attack);
				}
				else
				{
					Originals[attack].Restore(attack);
				}
			}
		}

		internal static bool IsSpearPrefab(int itemHash)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Invalid comparison between Unknown and I4
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return false;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return false;
			}
			SharedData val = itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared;
			if (val != null && (int)val.m_skillType == 5 && val.m_name != "$item_spear_chitin" && val.m_attack != null)
			{
				if (!(val.m_attack.m_attackAnimation == "spear_poke"))
				{
					return val.m_attack.m_attackAnimation == "sword_secondary";
				}
				return true;
			}
			return false;
		}
	}
	public sealed class SpearVisualState : MonoBehaviour
	{
		private Vector3 originalPosition;

		private Quaternion originalRotation;

		private bool initialized;

		private bool throwing;

		private bool sawThrowClip;

		private float throwStartedAt;

		private bool backAttach;

		internal void Initialize(bool isBackAttach)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized)
			{
				backAttach = isBackAttach;
				originalPosition = ((Component)this).transform.localPosition;
				originalRotation = ((Component)this).transform.localRotation;
				initialized = true;
				Apply();
			}
		}

		internal void SetThrowing(bool value)
		{
			if (initialized)
			{
				if (value && !throwing)
				{
					sawThrowClip = false;
					throwStartedAt = Time.time;
				}
				throwing = value;
				Apply();
			}
		}

		internal void UpdateThrowClip(bool active)
		{
			if (active)
			{
				if (!throwing)
				{
					SetThrowing(value: true);
				}
				sawThrowClip = true;
			}
			else if (throwing && (sawThrowClip || Time.time - throwStartedAt > 0.5f))
			{
				throwing = false;
			}
			Apply();
		}

		internal void Apply()
		{
			//IL_0010: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (initialized)
			{
				((Component)this).transform.localPosition = originalPosition;
				((Component)this).transform.localRotation = originalRotation;
				if (!throwing && !backAttach && SpearThrustPlugin.Enabled.Value)
				{
					((Component)this).transform.Rotate(SpearThrustPlugin.GripPitch.Value, SpearThrustPlugin.GripYaw.Value, 0f);
					float value = SpearThrustPlugin.GripOffset.Value;
					((Component)this).transform.Translate(Vector3.forward * value);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class EquipSpearPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ItemData item)
		{
			SpearThrustPlugin.ConfigureAttack(item);
		}
	}
	[HarmonyPatch(typeof(VisEquipment), "AttachItem")]
	internal static class AttachSpearPatch
	{
		[HarmonyPostfix]
		private static void Postfix(int itemHash, bool backAttach, GameObject __result)
		{
			if (!((Object)(object)__result == (Object)null) && SpearThrustPlugin.IsSpearPrefab(itemHash))
			{
				(__result.GetComponent<SpearVisualState>() ?? __result.AddComponent<SpearVisualState>()).Initialize(backAttach);
			}
		}
	}
	[HarmonyPatch(typeof(ZSyncAnimation), "RPC_SetTrigger")]
	internal static class ThrowSpearPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ZSyncAnimation __instance, string name)
		{
			if (!(name != "spear_throw") && SpearThrustPlugin.Enabled.Value)
			{
				Humanoid component = ((Component)__instance).GetComponent<Humanoid>();
				VisEquipment val = (((Object)(object)component == (Object)null) ? null : SpearThrustPlugin.Equipment.Invoke(component));
				object obj2;
				if (!((Object)(object)val == (Object)null))
				{
					GameObject obj = SpearThrustPlugin.RightItem.Invoke(val);
					obj2 = ((obj != null) ? obj.GetComponent<SpearVisualState>() : null);
				}
				else
				{
					obj2 = null;
				}
				((SpearVisualState)obj2)?.SetThrowing(value: true);
			}
		}
	}
	[HarmonyPatch(typeof(ZSyncAnimation), "SyncParameters")]
	internal static class SpearVisualUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(ZSyncAnimation __instance, Animator ___m_animator)
		{
			Humanoid component = ((Component)__instance).GetComponent<Humanoid>();
			VisEquipment val = (((Object)(object)component == (Object)null) ? null : SpearThrustPlugin.Equipment.Invoke(component));
			object obj2;
			if (!((Object)(object)val == (Object)null))
			{
				GameObject obj = SpearThrustPlugin.RightItem.Invoke(val);
				obj2 = ((obj != null) ? obj.GetComponent<SpearVisualState>() : null);
			}
			else
			{
				obj2 = null;
			}
			SpearVisualState spearVisualState = (SpearVisualState)obj2;
			if (!((Object)(object)spearVisualState == (Object)null))
			{
				spearVisualState.UpdateThrowClip(HasClip(___m_animator, "throw_spear"));
			}
		}

		internal static bool HasClip(Animator animator, string clipName)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)animator == (Object)null)
			{
				return false;
			}
			AnimatorClipInfo[] currentAnimatorClipInfo = animator.GetCurrentAnimatorClipInfo(0);
			for (int i = 0; i < currentAnimatorClipInfo.Length; i++)
			{
				AnimatorClipInfo val = currentAnimatorClipInfo[i];
				if ((Object)(object)((AnimatorClipInfo)(ref val)).clip != (Object)null && ((Object)((AnimatorClipInfo)(ref val)).clip).name == clipName)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterAnimEvent), "Speed")]
	internal static class SpearSpeedPatch
	{
		[HarmonyPrefix]
		private static void Prefix(Character ___m_character, ref float speedScale)
		{
			if (!SpearThrustPlugin.Enabled.Value || (Object)(object)___m_character == (Object)null)
			{
				return;
			}
			Humanoid val = (Humanoid)(object)((___m_character is Humanoid) ? ___m_character : null);
			if (!((Object)(object)val == (Object)null) && SpearThrustPlugin.IsOurSpear(val.GetCurrentWeapon()) && !SpearThrustPlugin.SecondaryAttack.Invoke(val))
			{
				Attack val2 = SpearThrustPlugin.CurrentAttack.Invoke(val);
				if (val2 != null && !(val2.m_attackAnimation != "sword_secondary"))
				{
					speedScale = 0.8f * SpearThrustPlugin.Speed.Value;
				}
			}
		}
	}
}