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