Decompiled source of BetterMeleeHitbox v1.1.0

BetterMeleeHitbox.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BMH.MeleeChanges;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using MSC.API;
using MSC.CustomMeleeData;
using Microsoft.CodeAnalysis;
using ModifierAPI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BetterMeleeHitbox")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b1006088da94e093b4b851c27074f8f248721098")]
[assembly: AssemblyProduct("BetterMeleeHitbox")]
[assembly: AssemblyTitle("BetterMeleeHitbox")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace BMH
{
	internal static class DinoLogger
	{
		private static readonly ManualLogSource logger = Logger.CreateLogSource("BetterMeleeHitbox");

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)4, (object)str);
			}
		}

		public static void Error(string format, params object[] args)
		{
			Error(string.Format(format, args));
		}

		public static void Error(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	[BepInPlugin("Dinorush.BetterMeleeHitbox", "BetterMeleeHitbox", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public const string MODNAME = "BetterMeleeHitbox";

		public override void Load()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			new Harmony("BetterMeleeHitbox").PatchAll();
			foreach (var (text2, meleeChangeData2) in MeleeChangeData.ChangeDatas)
			{
				MeleeDataAPI.AddInstanceData(text2, new TryGetMeleeData(meleeChangeData2.HitboxData.TryGetMeleeData));
			}
			((BasePlugin)this).Log.LogMessage((object)"Loaded BetterMeleeHitbox");
		}
	}
}
namespace BMH.Patches
{
	[HarmonyPatch(typeof(MeleeWeaponFirstPerson))]
	internal static class MeleeSetupPatches
	{
		[HarmonyPatch("SetupMeleeAnimations")]
		[HarmonyAfter(new string[] { "Dinorush.MeleeSwingCustomization" })]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_MeleeSetup(MeleeWeaponFirstPerson __instance)
		{
			List<string> firstPersonPrefabs = ((Item)__instance).ItemDataBlock.FirstPersonPrefabs;
			if (firstPersonPrefabs != null && firstPersonPrefabs.Count != 0)
			{
				MeleeChangeData.ChangeDatas[firstPersonPrefabs[0]].Apply(__instance);
			}
		}
	}
}
namespace BMH.MeleeChanges
{
	public sealed class MeleeAnimData
	{
		private readonly float _attackLength;

		private readonly float _attackHitTime;

		private readonly float _damageStartTime;

		private readonly float _damageEndTime;

		private readonly float _attackCamFwdHitTime;

		private readonly float _comboEarlyTime;

		public MeleeAnimData(float attackLength = -1f, float attackHitTime = -1f, float damageStartTime = -1f, float damageEndTime = -1f, float attackCamFwdHitTime = -1f, float comboEarlyTime = -1f)
		{
			_attackLength = attackLength;
			_attackHitTime = attackHitTime;
			_damageStartTime = damageStartTime;
			_damageEndTime = damageEndTime;
			_attackCamFwdHitTime = attackCamFwdHitTime;
			_comboEarlyTime = comboEarlyTime;
		}

		public void Apply(MeleeAttackData data)
		{
			if (_attackLength >= 0f)
			{
				data.m_attackLength = _attackLength;
			}
			if (_attackHitTime >= 0f)
			{
				data.m_attackHitTime = _attackHitTime;
			}
			if (_damageStartTime >= 0f)
			{
				data.m_damageStartTime = _damageStartTime;
			}
			if (_damageEndTime >= 0f)
			{
				data.m_damageEndTime = _damageEndTime;
			}
			if (_attackCamFwdHitTime >= 0f)
			{
				data.m_attackCamFwdHitTime = _attackCamFwdHitTime;
			}
			if (_comboEarlyTime >= 0f)
			{
				data.m_comboEarlyTime = _comboEarlyTime;
			}
		}

		private bool Approximately(float a, float b)
		{
			return Math.Abs(a - b) <= 0.01f;
		}

		public bool Equals(MeleeAttackData data)
		{
			if (_attackLength >= 0f && !Approximately(data.m_attackLength, _attackLength))
			{
				return false;
			}
			if (_attackHitTime >= 0f && !Approximately(data.m_attackHitTime, _attackHitTime))
			{
				return false;
			}
			if (_damageStartTime >= 0f && !Approximately(data.m_damageStartTime, _damageStartTime))
			{
				return false;
			}
			if (_damageEndTime >= 0f && !Approximately(data.m_damageEndTime, _damageEndTime))
			{
				return false;
			}
			if (_attackCamFwdHitTime >= 0f && !Approximately(data.m_attackCamFwdHitTime, _attackCamFwdHitTime))
			{
				return false;
			}
			if (_comboEarlyTime >= 0f && !Approximately(data.m_comboEarlyTime, _comboEarlyTime))
			{
				return false;
			}
			return true;
		}
	}
	public sealed class MeleeAnimTarget
	{
		public readonly eMeleeWeaponState State;

		public readonly MeleeAnimData Target;

		public MeleeAnimTarget(eMeleeWeaponState state, MeleeAnimData target)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			State = state;
			Target = target;
		}
	}
	public sealed class MeleeChangeData
	{
		private readonly List<(MeleeAnimTarget target, MeleeAnimData data)>? _animDatas;

		public readonly MeleeHitboxData HitboxData;

		public static readonly Dictionary<string, MeleeChangeData> ChangeDatas = new Dictionary<string, MeleeChangeData>
		{
			{
				"Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPerson.prefab",
				new MeleeChangeData(new MeleeHitboxData(1.8f, 0.3f, 1f, 0.05f, new MeleeData
				{
					AttackOffset = new OffsetData((Vector3?)new Vector3(0f, -0.12f, 0.2f), (Vector3?)new Vector3(0f, 0f, -0.3f), (Vector3?)null)
					{
						EntityRayLengthAdd = 0.9f,
						EntityOffset = new Vector3(0f, -0.12f, 0.6f),
						EntitySize = 0.3f,
						CapsuleSize = 0.05f,
						CapsuleUseCamFwd = true,
						CapsuleCamFwdAdd = -1.2f,
						CapsuleDelay = 0.1f
					},
					LightAttackSpeed = 1.3f,
					AttackSphereCenterMod = 1.5f
				}))
			},
			{
				"Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPersonKnife.prefab",
				new MeleeChangeData(new MeleeHitboxData(1.75f, 0.25f, 1f, 0.05f, new MeleeData
				{
					AttackOffset = new OffsetData((Vector3?)new Vector3(0f, -0.05f, 0.03f), (Vector3?)new Vector3(0f, -0.4f, 0f), (Vector3?)null)
					{
						EntityRayLengthAdd = 1f,
						EntityOffset = new Vector3(0f, 0.65f, 0.076f),
						EntitySize = 0.2f,
						CapsuleSize = 0.05f,
						CapsuleUseCamFwd = true,
						CapsuleCamFwdAdd = -1.2f,
						CapsuleStateDelay = new Dictionary<eMeleeWeaponState, float>
						{
							{
								(eMeleeWeaponState)8,
								0.05f
							},
							{
								(eMeleeWeaponState)10,
								0.05f
							}
						}
					},
					AttackSphereCenterMod = 1f
				}), new List<(MeleeAnimTarget, MeleeAnimData)>
				{
					(new MeleeAnimTarget((eMeleeWeaponState)4, new MeleeAnimData(1f, 0.1667f, 0.1f, 0.2667f, 0.1667f, 0.5f)), new MeleeAnimData(-1f, -1f, 0.1167f, -1f, 0.1167f, 0.4667f)),
					(new MeleeAnimTarget((eMeleeWeaponState)3, new MeleeAnimData(1f, 0.1667f, 0.1f, 0.2667f, 0.1667f, 0.5f)), new MeleeAnimData(-1f, -1f, 0.1167f, -1f, 0.1167f, 0.4667f)),
					(new MeleeAnimTarget((eMeleeWeaponState)6, new MeleeAnimData(1f, 0.1667f, -1f, -1f, -1f, 0.3f)), new MeleeAnimData(-1f, 0.1167f, -1f, -1f, -1f, 0.3333f)),
					(new MeleeAnimTarget((eMeleeWeaponState)5, new MeleeAnimData(1f, 0.1667f, -1f, -1f, -1f, 0.3f)), new MeleeAnimData(-1f, 0.1167f, -1f, -1f, -1f, 0.3333f)),
					(new MeleeAnimTarget((eMeleeWeaponState)10, new MeleeAnimData(1f, 0.1667f, 0f, 0.3667f, 0.1667f, 0.3f)), new MeleeAnimData(-1f, 0.1f, 0.08f, -1f, 0.1f)),
					(new MeleeAnimTarget((eMeleeWeaponState)8, new MeleeAnimData(1f, 0.1667f, 0f, 0.3667f, 0.1667f, 0.3f)), new MeleeAnimData(-1f, 0.1f, 0.0667f, -1f, 0.1f)),
					(new MeleeAnimTarget((eMeleeWeaponState)12, new MeleeAnimData(1f, 0.1334f, -1f, -1f, -1f, 0.3f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.3333f)),
					(new MeleeAnimTarget((eMeleeWeaponState)11, new MeleeAnimData(1f, 0.1334f, -1f, -1f, -1f, 0.3f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.3333f))
				})
			},
			{
				"Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPersonSpear.prefab",
				new MeleeChangeData(new MeleeHitboxData(3.2f, 0.15f, 1.3f, 0.05f, new MeleeData
				{
					AttackOffset = new OffsetData((Vector3?)new Vector3(0f, 0.6f, -0.002f), (Vector3?)new Vector3(0f, -0.3f, 0f), (Vector3?)null)
					{
						EntityRayLengthAdd = 1.9f,
						EntityOffset = new Vector3(0f, 1.4f, -0.002f),
						EntitySize = 0.15f,
						CapsuleSize = 0.05f,
						CapsuleUseCamFwd = true,
						CapsuleCamFwdAdd = -2f,
						CapsuleDelay = 0.1f
					}
				}))
			},
			{
				"Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPersonBat.prefab",
				new MeleeChangeData(new MeleeHitboxData(1.75f, 0.3f, 1f, 0.05f, new MeleeData
				{
					AttackOffset = new OffsetData((Vector3?)new Vector3(0f, 0.15f, 0f), (Vector3?)new Vector3(0f, -0.1f, -0.1f), (Vector3?)new Vector3(0f, 0.55f, -0.1f))
					{
						EntityRayLengthAdd = 0.85f,
						EntityOffset = new Vector3(0f, 0.6f, 0f),
						EntitySize = 0.3f,
						CapsuleSize = 0.05f,
						CapsuleUseCamFwd = true,
						CapsuleCamFwdAdd = -1.15f,
						CapsuleDelay = 0.05f
					},
					AttackSphereCenterMod = 1.5f
				}), new List<(MeleeAnimTarget, MeleeAnimData)>
				{
					(new MeleeAnimTarget((eMeleeWeaponState)4, new MeleeAnimData(1.3334f, 0.2334f, 0.1334f, 0.667f, -1f, 0.5f)), new MeleeAnimData(0.6667f, -1f, 0.2f, 0.6f, -1f, 0.45f)),
					(new MeleeAnimTarget((eMeleeWeaponState)3, new MeleeAnimData(1.3334f, 0.2334f, 0.1334f, 0.667f, -1f, 0.5f)), new MeleeAnimData(0.6667f, -1f, 0.2f, 0.6f, -1f, 0.45f)),
					(new MeleeAnimTarget((eMeleeWeaponState)6, new MeleeAnimData(1.3334f, 0.2334f, -1f, -1f, -1f, 0.4f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.33f)),
					(new MeleeAnimTarget((eMeleeWeaponState)5, new MeleeAnimData(1.3334f, 0.2334f, -1f, -1f, -1f, 0.4f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.33f)),
					(new MeleeAnimTarget((eMeleeWeaponState)13, new MeleeAnimData(1.1667f, 0.2334f, 0.2f, 0.2667f, 0.2334f, 0.667f)), new MeleeAnimData(-1f, -1f, 0.1667f, -1f, 0.1667f, 0.467f)),
					(new MeleeAnimTarget((eMeleeWeaponState)10, new MeleeAnimData(0.7f, 0.2334f, 0f, 0.3667f, 0.2334f, 0.3f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.4f)),
					(new MeleeAnimTarget((eMeleeWeaponState)8, new MeleeAnimData(0.7f, 0.2334f, 0f, 0.3667f, 0.2334f, 0.3f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.4f)),
					(new MeleeAnimTarget((eMeleeWeaponState)12, new MeleeAnimData(1.334f, 0.2334f, 0f, 0f, 0f, 0.4f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.3333f)),
					(new MeleeAnimTarget((eMeleeWeaponState)11, new MeleeAnimData(1.334f, 0.2334f, 0f, 0f, 0f, 0.4f)), new MeleeAnimData(-1f, -1f, -1f, -1f, -1f, 0.3333f))
				})
			}
		};

		public MeleeChangeData(MeleeHitboxData hitboxData, List<(MeleeAnimTarget target, MeleeAnimData anim)>? animDatas = null)
		{
			_animDatas = animDatas;
			HitboxData = hitboxData;
		}

		public void Apply(MeleeWeaponFirstPerson melee)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected I4, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected I4, but got Unknown
			if (_animDatas == null)
			{
				return;
			}
			Il2CppReferenceArray<MWS_Base> states = melee.m_states;
			foreach (var animData in _animDatas)
			{
				MeleeAnimTarget item = animData.target;
				MeleeAttackData data = ((Il2CppArrayBase<MWS_Base>)(object)states)[(int)item.State].m_data;
				if (!item.Target.Equals(data))
				{
					return;
				}
			}
			foreach (var animData2 in _animDatas)
			{
				MeleeAnimTarget item2 = animData2.target;
				MeleeAnimData item3 = animData2.data;
				MeleeAttackData data2 = ((Il2CppArrayBase<MWS_Base>)(object)states)[(int)item2.State].m_data;
				item3.Apply(data2);
			}
		}
	}
	public sealed class MeleeHitboxData
	{
		private readonly float _targetCameraDamageRayLength;

		private readonly float _targetAttackSphereRadius;

		private readonly float _cameraDamageRayLength;

		private readonly float _attackSphereRadius;

		private readonly MeleeData _baseData;

		private readonly Dictionary<uint, (float ray, float radius, MeleeData data)> _seenArchs;

		private static readonly List<PropertyInfo> s_offsetProps = new List<PropertyInfo>();

		private const float RayConversionMod = 0.75f;

		private const float CapsuleConversionMod = 0.33f;

		public MeleeHitboxData(float targetCameraDamageRayLength, float targetAttackSphereRadius, float cameraDamageRayLength, float attackSphereRadius, MeleeData hitboxData)
		{
			_targetCameraDamageRayLength = targetCameraDamageRayLength;
			_targetAttackSphereRadius = targetAttackSphereRadius;
			_cameraDamageRayLength = cameraDamageRayLength;
			_attackSphereRadius = attackSphereRadius;
			_baseData = hitboxData;
			_seenArchs = new Dictionary<uint, (float, float, MeleeData)>();
		}

		public bool TryGetMeleeData(MeleeWeaponFirstPerson melee, out MeleeData data)
		{
			MeleeArchetypeDataBlock meleeArchetypeData = ((ItemEquippable)melee).MeleeArchetypeData;
			if (_seenArchs.TryGetValue(((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)meleeArchetypeData).persistentID, out (float, float, MeleeData) value) && Approximately(meleeArchetypeData.CameraDamageRayLength, value.Item1) && Approximately(meleeArchetypeData.AttackSphereRadius, value.Item2))
			{
				data = value.Item3;
				return true;
			}
			float num = meleeArchetypeData.CameraDamageRayLength - _targetCameraDamageRayLength;
			float num2 = meleeArchetypeData.AttackSphereRadius - _targetAttackSphereRadius;
			if (Approximately(num, 0f) && Approximately(num2, 0f))
			{
				_seenArchs[((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)meleeArchetypeData).persistentID] = (_cameraDamageRayLength, _attackSphereRadius, _baseData);
				MeleeRangeAPI.SetBaseRange(_cameraDamageRayLength);
				meleeArchetypeData.AttackSphereRadius = _attackSphereRadius;
				data = _baseData;
				return true;
			}
			data = CreateCopyData();
			if (!Approximately(num, 0f))
			{
				data.AttackOffset.EntityRayLengthAdd = Math.Max(0f, data.AttackOffset.EntityRayLengthAdd + num * 0.75f);
				value.Item1 = Math.Max(0.2f, _cameraDamageRayLength + num * 0.25f);
			}
			else
			{
				value.Item1 = _cameraDamageRayLength;
			}
			if (!Approximately(num2, 0f))
			{
				data.AttackOffset.EntitySize = Math.Max(0f, data.AttackOffset.EntitySize + num2);
				data.AttackOffset.CapsuleSize = Math.Max(0f, data.AttackOffset.CapsuleSize + num2 * 0.33f);
				value.Item2 = Math.Max(0f, _attackSphereRadius + num2 * 0.33f);
			}
			else
			{
				value.Item2 = _attackSphereRadius;
			}
			_seenArchs[((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)meleeArchetypeData).persistentID] = (value.Item1, value.Item2, data);
			MeleeRangeAPI.SetBaseRange(value.Item1);
			meleeArchetypeData.AttackSphereRadius = value.Item2;
			return true;
		}

		private MeleeData CreateCopyData()
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			if (s_offsetProps.Count == 0)
			{
				PropertyInfo[] properties = typeof(OffsetData).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);
				s_offsetProps.EnsureCapacity(properties.Length);
				PropertyInfo[] array = properties;
				foreach (PropertyInfo propertyInfo in array)
				{
					MethodInfo? getMethod = propertyInfo.GetGetMethod(nonPublic: false);
					MethodInfo setMethod = propertyInfo.GetSetMethod(nonPublic: false);
					if (!(getMethod == null) && !(setMethod == null) && propertyInfo.CanWrite)
					{
						s_offsetProps.Add(propertyInfo);
					}
				}
				s_offsetProps.TrimExcess();
			}
			MeleeData val = new MeleeData
			{
				LightAttackSpeed = _baseData.LightAttackSpeed,
				ChargedAttackSpeed = _baseData.ChargedAttackSpeed,
				PushSpeed = _baseData.PushSpeed,
				PushOffset = _baseData.PushOffset,
				AttackSphereCenterMod = _baseData.AttackSphereCenterMod
			};
			foreach (PropertyInfo s_offsetProp in s_offsetProps)
			{
				s_offsetProp.SetValue(val.AttackOffset, s_offsetProp.GetValue(_baseData.AttackOffset));
			}
			return val;
		}

		private static bool Approximately(float a, float b)
		{
			return Math.Abs(a - b) <= 0.01f;
		}
	}
}
namespace BMH.Dependencies
{
	internal static class MSCWrapper
	{
		public const string GUID = "Dinorush.MeleeSwingCustomization";
	}
}