using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using MSC.API; using MSC.CustomMeleeData; using MSC.Dependencies; using MSC.JSON; using MSC.Utils; using MTFO.API; using Microsoft.CodeAnalysis; using ModifierAPI; using Player; 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("MeleeSwingCustomization")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+8440da57820d04eebcedd7a09b0b5a985ad5a893")] [assembly: AssemblyProduct("MeleeSwingCustomization")] [assembly: AssemblyTitle("MeleeSwingCustomization")] [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 MSC { internal static class Configuration { public static bool DrawDebugHitbox; public static float DebugSphereSize; private static readonly ConfigFile configFile; static Configuration() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown DrawDebugHitbox = false; DebugSphereSize = 0.1f; configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "MeleeSwingCustomization.cfg"), true); BindAll(configFile); } internal static void Init() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown LiveEdit.CreateListener(Paths.ConfigPath, "MeleeSwingCustomization.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged); } private static void OnFileChanged(LiveEditEventArgs _) { configFile.Reload(); string text = "Test Settings"; MeleeWeaponFirstPerson.DEBUG_TARGETING_ENABLED = (bool)configFile[text, "Show Vanilla Debug Swing Hitbox"].BoxedValue; DrawDebugHitbox = (bool)configFile[text, "Show Debug Hitbox Positions"].BoxedValue; DebugSphereSize = (float)configFile[text, "Debug Hitbox Size"].BoxedValue; DebugUtil.DrawDebugSpheres(); } private static void BindAll(ConfigFile config) { string text = "Test Settings"; MeleeWeaponFirstPerson.DEBUG_TARGETING_ENABLED = config.Bind(text, "Show Vanilla Debug Swing Hitbox", false, "Enables the base game debug melee swing hitbox visuals.").Value; DrawDebugHitbox = config.Bind(text, "Show Debug Hitbox Positions", DrawDebugHitbox, "Shows visuals of the held melee weapon's attack offset.\nAlso shows the capsule endpoint if it exists").Value; DebugSphereSize = config.Bind(text, "Debug Hitbox Size", DebugSphereSize, "Size of the rendered Hitbox Positions.").Value; } } [BepInPlugin("Dinorush.MeleeSwingCustomization", "MeleeSwingCustomization", "1.4.3")] [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 = "MeleeSwingCustomization"; public override void Load() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) Configuration.Init(); MeleeDataManager.Current.Init(); new Harmony("MeleeSwingCustomization").PatchAll(); ((BasePlugin)this).Log.LogMessage((object)"Loaded MeleeSwingCustomization"); } } } namespace MSC.Utils { internal static class DebugUtil { [CompilerGenerated] private sealed class d__2 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public MeleeWeaponFirstPerson melee; public MeleeData data; object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: { <>1__state = -1; PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); object obj; if (localPlayerAgent == null) { obj = null; } else { FirstPersonItemHolder fPItemHolder = localPlayerAgent.FPItemHolder; obj = ((fPItemHolder != null) ? fPItemHolder.WieldedItem : null); } if ((Object)obj != (Object)(object)melee) { break; } Vector3 position = melee.ModelData.m_damageRefAttack.position; MeleeData meleeData = data; if (meleeData != null && meleeData.AttackOffset.HasCapsule) { var (val, val2) = data.AttackOffset.GetCapsuleOffsets(melee.ModelData.m_damageRefAttack, ((ItemEquippable)melee).MeleeArchetypeData); DebugDraw3D.DrawSphere(val, Configuration.DebugSphereSize, (val == position) ? ColorExt.Orange(0.4f) : ColorExt.Yellow(0.4f), ""); DebugDraw3D.DrawSphere(val2, Configuration.DebugSphereSize, (val2 == position) ? ColorExt.Orange(0.4f) : ColorExt.Yellow(0.4f), ""); if (val != position && val2 != position) { DebugDraw3D.DrawSphere(position, Configuration.DebugSphereSize, ColorExt.Red(0.4f), ""); } } else { DebugDraw3D.DrawSphere(position, Configuration.DebugSphereSize, ColorExt.Red(0.4f), ""); } MeleeData meleeData2 = data; if (meleeData2 != null && meleeData2.AttackOffset.HasEntity) { DebugDraw3D.DrawSphere(data.AttackOffset.GetEntityOffset(melee.ModelData.m_damageRefAttack), Configuration.DebugSphereSize, ColorExt.Blue(0.4f), ""); } break; } } if ((Object)(object)melee != (Object)null) { <>2__current = null; <>1__state = 1; return true; } _drawCoroutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Coroutine? _drawCoroutine; public static void DrawDebugSpheres(MeleeWeaponFirstPerson? melee = null) { if (_drawCoroutine != null) { CoroutineManager.StopCoroutine(_drawCoroutine); _drawCoroutine = null; } if (!Configuration.DrawDebugHitbox) { return; } if ((Object)(object)melee == (Object)null) { BackpackItem val = default(BackpackItem); if (!PlayerBackpackManager.LocalBackpack.TryGetBackpackItem((InventorySlot)10, ref val)) { return; } melee = ((Il2CppObjectBase)val.Instance).Cast(); } MeleeData data = MeleeDataManager.Current.GetData(melee); _drawCoroutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DrawSpheres(melee, data)), (Action)null); } [IteratorStateMachine(typeof(d__2))] private static IEnumerator DrawSpheres(MeleeWeaponFirstPerson melee, MeleeData? data) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0) { melee = melee, data = data }; } } internal static class DinoLogger { private static readonly ManualLogSource logger = Logger.CreateLogSource("MeleeSwingCustomization"); 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); } } } public static class RegexUtil { private static readonly Regex _vectorRegex = new Regex("-?[0-9.]+"); public static bool TryParseVectorString(string input, out float[] vectorArray) { try { MatchCollection matchCollection = _vectorRegex.Matches(input); int count = matchCollection.Count; if (count < 1) { throw new Exception(); } vectorArray = new float[count]; for (int i = 0; i < count; i++) { Match match = matchCollection[i]; vectorArray[i] = float.Parse(match.Value, CultureInfo.InvariantCulture); } return true; } catch { vectorArray = null; return false; } } } } namespace MSC.Patches { [HarmonyPatch(typeof(MeleeWeaponFirstPerson))] internal static class MeleeSetupPatches { [HarmonyPatch("SetupMeleeAnimations")] [HarmonyWrapSafe] [HarmonyPostfix] private static void Post_MeleeSetup(MeleeWeaponFirstPerson __instance) { MeleeDataManager.Current.RegisterMelee(__instance); DebugUtil.DrawDebugSpheres(__instance); } } [HarmonyPatch] internal static class MeleeSwingPatches { private static RaycastHit _rayHit; private static float _lastCrosshairCheckTime = 0f; private static bool _lastCrosshairCheck = false; private static float _lastWallCheckTime = 0f; private static float _lastWallDist = float.PositiveInfinity; private const float CameraUpdateInterval = 0.033f; [HarmonyPatch(typeof(MeleeWeaponFirstPerson), "UpdateLocal")] [HarmonyWrapSafe] [HarmonyPrefix] private static bool Pre_Update(MeleeWeaponFirstPerson __instance) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Invalid comparison between Unknown and I4 MeleeData activeData = MeleeDataManager.Current.ActiveData; if (activeData == null) { return true; } if (Clock.Time - _lastWallCheckTime > 0.033f) { float entityRayLen = activeData.AttackOffset.GetEntityRayLen(((ItemEquippable)__instance).MeleeArchetypeData); _lastWallCheckTime = Clock.Time; _lastWallDist = (Physics.Raycast(((Item)__instance).Owner.FPSCamera.m_camRay, ref _rayHit, entityRayLen, LayerManager.MASK_WORLD) ? ((RaycastHit)(ref _rayHit)).distance : float.PositiveInfinity); } __instance.UpdateInput(); __instance.CurrentState.Update(); eMeleeWeaponState currentStateName = __instance.CurrentStateName; if (currentStateName - 3 <= 1 || (int)currentStateName == 8 || (int)currentStateName == 10) { MWS_AttackSwingBase mws = ((Il2CppObjectBase)__instance.CurrentState).Cast(); CustomHitDetection(__instance, mws, activeData); } CrosshairUpdate(__instance, activeData); return false; } private static void CrosshairUpdate(MeleeWeaponFirstPerson melee, MeleeData data) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) FPSCamera fPSCamera = ((Item)melee).Owner.FPSCamera; bool flag = (Object)(object)fPSCamera.CameraRayObject != (Object)null && fPSCamera.CameraRayDist <= ((ItemEquippable)melee).MeleeArchetypeData.CameraDamageRayLength && fPSCamera.CameraRayObject.layer == LayerManager.LAYER_ENEMY_DAMAGABLE; if (!flag) { if (Clock.Time - _lastCrosshairCheckTime > 0.033f) { float entityRayLen = data.AttackOffset.GetEntityRayLen(((ItemEquippable)melee).MeleeArchetypeData, _lastWallDist); _lastCrosshairCheckTime = Clock.Time; _lastCrosshairCheck = Physics.Raycast(fPSCamera.m_camRay, ref _rayHit, entityRayLen, LayerManager.MASK_ENEMY_DAMAGABLE); } flag = _lastCrosshairCheck; } if (flag) { if (!melee.m_lookAtEnemy) { GuiManager.CrosshairLayer.ScaleToSize(((ItemEquippable)melee).HipFireCrosshairSize * 0.6f); GuiManager.CrosshairLayer.TriggerBlink(Color.white); melee.m_lookAtEnemy = true; } } else if (melee.m_lookAtEnemy) { GuiManager.CrosshairLayer.ScaleToSize(((ItemEquippable)melee).HipFireCrosshairSize); GuiManager.CrosshairLayer.ResetChargeUpColor(); melee.m_lookAtEnemy = false; } } private static void CustomHitDetection(MeleeWeaponFirstPerson melee, MWS_AttackSwingBase mws, MeleeData data) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) MeleeAttackData attackData = ((MWS_Base)mws).AttackData; float damageStartTime = attackData.m_damageStartTime; float elapsed = mws.m_elapsed; if (!(elapsed <= damageStartTime) && !(elapsed > attackData.m_damageEndTime) && !mws.m_targetsFound) { MeleeArchetypeDataBlock meleeArchetypeData = ((ItemEquippable)melee).MeleeArchetypeData; bool hasEntityRay = data.AttackOffset.HasEntityRay; bool hasCapsule = data.AttackOffset.HasCapsule; bool hasEntity = data.AttackOffset.HasEntity; float num = (hasCapsule ? (damageStartTime + data.AttackOffset.GetCapsuleDelay(melee.CurrentStateName)) : 0f); float attackCamFwdHitTime = attackData.m_attackCamFwdHitTime; FPSCamera fPSCamera = ((Item)melee).Owner.FPSCamera; if ((meleeArchetypeData.CanHitMultipleEnemies || !Physics.Raycast(fPSCamera.Position, fPSCamera.Forward, ref _rayHit, meleeArchetypeData.CameraDamageRayLength, LayerManager.MASK_MELEE_ATTACK_TARGETS_WITH_STATIC)) && CheckForHits(hasEntityRay, elapsed >= attackCamFwdHitTime, hasEntity, hasCapsule && elapsed >= num, fPSCamera, meleeArchetypeData, attackData, data, out List hits)) { mws.m_targetsFound = true; melee.HitsForDamage = hits; mws.OnAttackHit(); } } } private static bool CheckForHits(bool checkRay, bool canRayHit, bool checkEntity, bool checkCapsule, FPSCamera camera, MeleeArchetypeDataBlock archBlock, MeleeAttackData attackData, MeleeData data, [MaybeNullWhen(false)] out List hits) { DamageUtil.IncrementSearchID(); hits = new List(); bool flag = !archBlock.CanHitMultipleEnemies; bool flag2 = checkRay && CheckForRaycastHit(camera, archBlock, data, hits); if (flag2 && flag) { return canRayHit; } if (checkEntity && CheckForHits_Inner(capsule: false, camera, archBlock, attackData, data, hits) && flag) { return true; } if (checkCapsule && CheckForHits_Inner(capsule: true, camera, archBlock, attackData, data, hits) && flag) { return true; } return hits.Count > ((flag2 && !canRayHit) ? 1 : 0); } private static bool CheckForRaycastHit(FPSCamera camera, MeleeArchetypeDataBlock archBlock, MeleeData data, List hits) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown float entityRayLen = data.AttackOffset.GetEntityRayLen(archBlock, _lastWallDist + 0.05f); if (Physics.Raycast(camera.Position, camera.Forward, ref _rayHit, entityRayLen, LayerManager.MASK_MELEE_ATTACK_TARGETS)) { if (((Component)((RaycastHit)(ref _rayHit)).collider).gameObject.layer == LayerManager.LAYER_DYNAMIC) { iLG_WeakDoor_Destruction componentInParent = ((Component)((RaycastHit)(ref _rayHit)).collider).GetComponentInParent(); if (componentInParent != null && !componentInParent.SkinnedDoorEnabled) { componentInParent.EnableSkinnedDoor(); } } IDamageable component = ((Component)((RaycastHit)(ref _rayHit)).collider).GetComponent(); if (component == null) { return false; } IDamageable baseDamagable = component.GetBaseDamagable(); if (baseDamagable != null) { baseDamagable.TempSearchID = DamageUtil.SearchID; } hits.Add(new MeleeWeaponDamageData { damageGO = ((Component)((RaycastHit)(ref _rayHit)).collider).gameObject, damageComp = component, hitPos = ((RaycastHit)(ref _rayHit)).point, hitNormal = ((RaycastHit)(ref _rayHit)).normal, sourcePos = camera.Position }); return true; } return false; } private static bool CheckForHits_Inner(bool capsule, FPSCamera camera, MeleeArchetypeDataBlock archBlock, MeleeAttackData attackData, MeleeData data, List hits) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) //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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Expected O, but got Unknown Transform transform = ((Component)attackData.m_damageRef).transform; Vector3 position = transform.position; Vector3 position2 = camera.Position; Vector3 forward = camera.Forward; Vector3 val = position - position2; float num = Vector3.Dot(forward, ((Vector3)(ref val)).normalized); if (num <= 0f && !archBlock.CanHitMultipleEnemies) { return false; } float dotScale = ((num > 0.5f) ? (1f + num * (data.AttackSphereCenterMod - 1f)) : 1f); OffsetData attackOffset = data.AttackOffset; Collider[] array; if (capsule) { float capsuleSize = attackOffset.GetCapsuleSize(archBlock, dotScale); (Vector3 start, Vector3 end) capsuleOffsets = attackOffset.GetCapsuleOffsets(transform, archBlock, _lastWallDist); Vector3 item = capsuleOffsets.start; Vector3 item2 = capsuleOffsets.end; array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapCapsule(item, item2, capsuleSize, LayerManager.MASK_MELEE_ATTACK_TARGETS)); } else { float capsuleSize = attackOffset.GetEntitySize(archBlock, dotScale); array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)Physics.OverlapSphere(attackOffset.GetEntityOffset(transform, _lastWallDist), capsuleSize, LayerManager.MASK_MELEE_ATTACK_TARGETS)); } if (array.Length == 0) { return false; } uint searchID = DamageUtil.SearchID; List<(Collider, float)> list = new List<(Collider, float)>(); Collider[] array2 = array; foreach (Collider val2 in array2) { val = ((Component)val2).transform.position - position2; list.Add((val2, ((Vector3)(ref val)).sqrMagnitude)); } list.Sort(SqrMagnitudeCompare); bool result = false; foreach (var item4 in list) { Collider item3 = item4.Item1; IDamageable component = ((Component)item3).GetComponent(); if (component != null && component.GetBaseDamagable().TempSearchID != searchID) { component.GetBaseDamagable().TempSearchID = searchID; MeleeWeaponDamageData val3 = new MeleeWeaponDamageData { damageGO = ((Component)item3).gameObject, hitPos = ((Component)item3).transform.position }; val = position - ((Component)item3).transform.position; val3.hitNormal = ((Vector3)(ref val)).normalized; val3.sourcePos = position2; val3.damageTargetFound = true; MeleeWeaponDamageData val4 = val3; hits.Add(val4); result = true; } } return result; } private static int SqrMagnitudeCompare((Collider, float sqrMagnitude) x, (Collider, float sqrMagnitude) y) { if (x.sqrMagnitude == y.sqrMagnitude) { return 0; } if (!(x.sqrMagnitude < y.sqrMagnitude)) { return 1; } return -1; } } } namespace MSC.JSON { public static class MSCJson { private static readonly JsonSerializerOptions _setting; static MSCJson() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown _setting = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, IncludeFields = true, PropertyNameCaseInsensitive = true, WriteIndented = true, IgnoreReadOnlyProperties = true }; _setting.Converters.Add(new JsonStringEnumConverter()); _setting.Converters.Add((JsonConverter)new LocalizedTextConverter()); _setting.Converters.Add(new Vector3Converter()); _setting.Converters.Add(new OffsetDataConverter()); } public static T? Deserialize(string json) { return JsonSerializer.Deserialize(json, _setting); } public static T? Deserialize(ref Utf8JsonReader reader) { return JsonSerializer.Deserialize(ref reader, _setting); } public static object? Deserialize(Type type, string json) { return JsonSerializer.Deserialize(json, type, _setting); } public static string Serialize(T value) { return JsonSerializer.Serialize(value, _setting); } public static void Serialize(T value, Utf8JsonWriter writer) { JsonSerializer.Serialize(writer, value, _setting); } } public sealed class OffsetDataConverter : JsonConverter { public override OffsetData Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { OffsetData offsetData = new OffsetData(); switch (reader.TokenType) { case JsonTokenType.Null: return offsetData; case JsonTokenType.StartObject: while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return offsetData; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string @string = reader.GetString(); reader.Read(); if (reader.TokenType != JsonTokenType.Null) { offsetData.DeserializeProperty(@string.ToLowerInvariant().Replace(" ", null), ref reader); } } throw new JsonException("Expected EndObject token"); case JsonTokenType.String: { string text = reader.GetString().Trim(); if (offsetData.ParseOffsetTriplet(text)) { return offsetData; } throw new JsonException("Bad vector formats detected for OffsetData: " + text); } default: throw new JsonException($"OffsetData Json type: {reader.TokenType} is not implemented!"); } } public override void Write(Utf8JsonWriter writer, OffsetData value, JsonSerializerOptions options) { value.Serialize(writer); } } public sealed class Vector3Converter : JsonConverter { public override bool HandleNull => false; public override Vector3? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 value = default(Vector3); switch (reader.TokenType) { case JsonTokenType.StartObject: while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return value; } if (reader.TokenType != JsonTokenType.PropertyName) { throw new JsonException("Expected PropertyName token"); } string? @string = reader.GetString(); reader.Read(); switch (@string.ToLowerInvariant()) { case "x": value.x = reader.GetSingle(); break; case "y": value.y = reader.GetSingle(); break; case "z": value.z = reader.GetSingle(); break; } } throw new JsonException("Expected EndObject token"); case JsonTokenType.String: { string text = reader.GetString().Trim(); if (TryParseVector3(text, out var vector)) { return vector; } throw new JsonException("Vector3 format is not right: " + text); } default: throw new JsonException($"Vector3Json type: {reader.TokenType} is not implemented!"); } } private static bool TryParseVector3(string input, out Vector3? vector) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) if (!RegexUtil.TryParseVectorString(input, out float[] vectorArray)) { vector = Vector3.zero; return false; } if (vectorArray.Length < 3) { vector = Vector3.zero; return false; } vector = new Vector3(vectorArray[0], vectorArray[1], vectorArray[2]); return true; } public override void Write(Utf8JsonWriter writer, Vector3? value, JsonSerializerOptions options) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!value.HasValue) { writer.WriteNullValue(); } else { writer.WriteStringValue($"({value.Value.x} {value.Value.y} {value.Value.z})"); } } } } namespace MSC.Dependencies { internal static class MTFOWrapper { public const string GUID = "com.dak.MTFO"; public static string GameDataPath => MTFOPathAPI.RundownPath; public static string CustomPath => MTFOPathAPI.CustomPath; public static bool HasCustomDatablocks { get { if (HasMTFO) { return UnsafeHasCustomDatablocks; } return false; } } private static bool UnsafeHasCustomDatablocks => MTFOPathAPI.HasRundownPath; public static bool HasMTFO { get; private set; } static MTFOWrapper() { HasMTFO = ((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.dak.MTFO"); } } } namespace MSC.CustomMeleeData { public sealed class MeleeData { public static readonly MeleeData Empty = new MeleeData(); public uint ArchetypeID { get; set; } public string Name { get; set; } = string.Empty; public OffsetData AttackOffset { get; set; } = new OffsetData(); public Vector3? PushOffset { get; set; } public float LightAttackSpeed { get; set; } = 1f; public float ChargedAttackSpeed { get; set; } = 1f; public float PushSpeed { get; set; } = 1f; public float AttackSphereCenterMod { get; set; } = 1.9f; } public sealed class MeleeDataManager { public static readonly MeleeDataManager Current = new MeleeDataManager(); private readonly Dictionary> _fileData = new Dictionary>(); private readonly Dictionary _idToData = new Dictionary(); private readonly Dictionary _cachedData = new Dictionary(); private readonly Dictionary _prefabToCachedData = new Dictionary(); private MeleeWeaponFirstPerson? _activeMelee; private readonly Dictionary _prefabToData = new Dictionary(); private readonly Dictionary> _prefabToDataInstance = new Dictionary>(); private readonly (IStatModifier light, IStatModifier charged, IStatModifier push) _speedModifiers = (MeleeAttackSpeedAPI.AddLightModifier(1f, (StackLayer)0, "MSC"), MeleeAttackSpeedAPI.AddChargedAnimationModifier(1f, (StackLayer)0, "MSC"), MeleeAttackSpeedAPI.AddPushModifier(1f, (StackLayer)0, "MSC")); private readonly LiveEditListener? _liveEditListener; public MeleeData? ActiveData { get; private set; } public float CurrentRangeMod { get; private set; } = 1f; private void FileChanged(LiveEditEventArgs e) { LiveEditEventArgs e2 = e; DinoLogger.Warning("LiveEdit File Changed: " + e2.FileName); LiveEdit.TryReadFileContent(e2.FullPath, (Action)delegate(string content) { ReadFileContent(e2.FullPath, content); PrintCustomIDs(); }); } private void FileDeleted(LiveEditEventArgs e) { DinoLogger.Warning("LiveEdit File Removed: " + e.FileName); RemoveFile(e.FullPath); PrintCustomIDs(); } private void FileCreated(LiveEditEventArgs e) { LiveEditEventArgs e2 = e; DinoLogger.Warning("LiveEdit File Created: " + e2.FileName); LiveEdit.TryReadFileContent(e2.FullPath, (Action)delegate(string content) { ReadFileContent(e2.FullPath, content); PrintCustomIDs(); }); } private void ReadFileContent(string file, string content) { RemoveFile(file); List list = null; try { list = MSCJson.Deserialize>(content); } catch (JsonException ex) { DinoLogger.Error("Error parsing json " + Path.GetFileName(file)); DinoLogger.Error(ex.Message); } if (list != null) { AddFile(file, list); } } private void RemoveFile(string file) { if (!_fileData.ContainsKey(file)) { return; } foreach (MeleeData item in _fileData[file]) { _idToData.Remove(item.ArchetypeID); } _fileData.Remove(file); ResetListeners(); } private void AddFile(string file, List dataList) { _fileData.Add(file, dataList); foreach (MeleeData data in dataList) { if (data.ArchetypeID != 0) { if (_idToData.ContainsKey(data.ArchetypeID)) { DinoLogger.Warning($"Duplicate archetype ID {data.ArchetypeID} detected. Previous name: {_idToData[data.ArchetypeID].Name}, new name: {data.Name}"); } _idToData[data.ArchetypeID] = data; FillDataWithCache(data.ArchetypeID); } } ResetListeners(); } private void ResetListeners() { if (!((Object)(object)_activeMelee == (Object)null)) { SetActiveMelee(_activeMelee); DebugUtil.DrawDebugSpheres(_activeMelee); } } private void PrintCustomIDs() { if (_idToData.Count > 0) { StringBuilder stringBuilder = new StringBuilder("Found custom blocks for archetype IDs: "); stringBuilder.AppendJoin(", ", _idToData.Keys.ToImmutableSortedSet()); DinoLogger.Log(stringBuilder.ToString()); } } private MeleeDataManager() { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown if (!MTFOWrapper.HasCustomDatablocks) { DinoLogger.Log("No MTFO datablocks detected. Restricting to API..."); return; } string text = Path.Combine(MTFOWrapper.CustomPath, "MeleeSwingCustomization"); if (!Directory.Exists(text)) { DinoLogger.Log("No directory detected. Creating template."); Directory.CreateDirectory(text); StreamWriter streamWriter = File.CreateText(Path.Combine(text, "Template.json")); streamWriter.WriteLine(MSCJson.Serialize(new List(MeleeDataTemplate.Template))); streamWriter.Flush(); streamWriter.Close(); } else { DinoLogger.Log("Directory detected."); } foreach (string item in Directory.EnumerateFiles(text, "*.json", SearchOption.AllDirectories)) { string content = File.ReadAllText(item); ReadFileContent(item, content); } PrintCustomIDs(); _liveEditListener = LiveEdit.CreateListener(text, "*.json", true); _liveEditListener.FileCreated += new LiveEditEventHandler(FileCreated); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); _liveEditListener.FileDeleted += new LiveEditEventHandler(FileDeleted); MeleeRangeAPI.SetRangeOverride((RangeOverrideFunc)delegate(float baseRange, float mod) { CurrentRangeMod = mod; return ActiveData == null || !ActiveData.AttackOffset.HasEntityRay; }); } internal void Init() { } public bool RegisterMelee(MeleeWeaponFirstPerson melee) { CacheData(melee); return SetActiveMelee(melee); } private bool SetActiveMelee(MeleeWeaponFirstPerson melee) { _activeMelee = melee; if (SetMeleeData(melee)) { ActiveData = GetData(melee); MeleeRangeAPI.RefreshRange(); return true; } ActiveData = null; MeleeRangeAPI.RefreshRange(); return false; } public bool HasData(uint id) { return _idToData.ContainsKey(id); } public MeleeData? GetData(MeleeWeaponFirstPerson melee) { if (!_idToData.TryGetValue(((GameDataBlockBase)(object)((ItemEquippable)melee).MeleeArchetypeData).persistentID, out MeleeData value)) { List firstPersonPrefabs = ((Item)melee).ItemDataBlock.FirstPersonPrefabs; if (firstPersonPrefabs != null && firstPersonPrefabs.Count > 0) { TryGetPrefabData(melee, firstPersonPrefabs[0], out value); return value; } } return value; } public void AddDataForPrefab(string prefab, MeleeData data) { if (_prefabToData.ContainsKey(prefab)) { DinoLogger.Warning($"Duplicate prefab data {prefab} detected. Previous name: {_prefabToData[prefab].Name}, new name: {data.Name}"); } _prefabToData[prefab] = data; if (_prefabToCachedData.TryGetValue(prefab, out MeleeData value)) { FillDataWithCache(data, value); } } public void AddInstanceDataForPrefab(string prefab, MeleeDataAPI.TryGetMeleeData callback) { if (!_prefabToDataInstance.TryGetValue(prefab, out List value)) { _prefabToDataInstance.Add(prefab, value = new List()); } value.Add(callback); } private bool TryGetPrefabData(MeleeWeaponFirstPerson melee, string prefab, [MaybeNullWhen(false)] out MeleeData data) { if (_prefabToData.TryGetValue(prefab, out data)) { return true; } if (!_prefabToDataInstance.TryGetValue(prefab, out List value)) { return false; } foreach (MeleeDataAPI.TryGetMeleeData item in value) { if (item(melee, out data)) { if (_prefabToCachedData.TryGetValue(prefab, out MeleeData value2)) { FillDataWithCache(data, value2); } return true; } } return false; } private void CacheData(MeleeWeaponFirstPerson melee) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) uint persistentID = ((GameDataBlockBase)(object)((ItemEquippable)melee).MeleeArchetypeData).persistentID; if (!_cachedData.ContainsKey(persistentID)) { MeleeData meleeData = new MeleeData { ArchetypeID = persistentID, AttackOffset = new OffsetData(melee.ModelData.m_damageRefAttack.localPosition), PushOffset = melee.ModelData.m_damageRefPush.localPosition }; _cachedData.Add(persistentID, meleeData); FillDataWithCache(persistentID); List firstPersonPrefabs = ((Item)melee).ItemDataBlock.FirstPersonPrefabs; if (firstPersonPrefabs != null && firstPersonPrefabs.Count > 0) { _prefabToCachedData.TryAdd(firstPersonPrefabs[0], meleeData); FillDataWithCache(firstPersonPrefabs[0], meleeData); } } } private void FillDataWithCache(string prefab, MeleeData cachedData) { if (_prefabToData.TryGetValue(prefab, out MeleeData value)) { FillDataWithCache(value, cachedData); } } private void FillDataWithCache(uint id) { if (_idToData.TryGetValue(id, out MeleeData value) && _cachedData.TryGetValue(id, out MeleeData value2)) { FillDataWithCache(value, value2); } } private void FillDataWithCache(MeleeData customData, MeleeData cachedData) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!customData.AttackOffset.HasOffset) { customData.AttackOffset.Offset = cachedData.AttackOffset.Offset; } if (!customData.PushOffset.HasValue) { customData.PushOffset = cachedData.PushOffset; } } private bool SetMeleeData(MeleeWeaponFirstPerson melee) { //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) uint persistentID = ((GameDataBlockBase)(object)((ItemEquippable)melee).MeleeArchetypeData).persistentID; if (!_cachedData.TryGetValue(persistentID, out MeleeData value)) { DinoLogger.Error($"Unable to get original data for melee {((Object)melee).name}, archetype ID {persistentID}"); return false; } if (!_idToData.TryGetValue(persistentID, out MeleeData value2)) { List firstPersonPrefabs = ((Item)melee).ItemDataBlock.FirstPersonPrefabs; if (firstPersonPrefabs.Count > 0) { TryGetPrefabData(melee, firstPersonPrefabs[0], out value2); } } Transform damageRefAttack = melee.ModelData.m_damageRefAttack; Transform damageRefPush = melee.ModelData.m_damageRefPush; if (value2 != null) { damageRefAttack.localPosition = value2.AttackOffset.Offset; damageRefPush.localPosition = value2.PushOffset.Value; melee.m_attackDamageSphereDotScale = value2.AttackSphereCenterMod - 1f; _speedModifiers.light.Enable(value2.LightAttackSpeed); _speedModifiers.charged.Enable(value2.ChargedAttackSpeed); _speedModifiers.push.Enable(value2.PushSpeed); return true; } damageRefAttack.localPosition = value.AttackOffset.Offset; damageRefPush.localPosition = value.PushOffset.Value; melee.m_attackDamageSphereDotScale = value.AttackSphereCenterMod - 1f; _speedModifiers.light.Disable(); _speedModifiers.charged.Disable(); _speedModifiers.push.Disable(); return false; } } internal static class MeleeDataTemplate { public static MeleeData[] Template = new MeleeData[5] { new MeleeData { ArchetypeID = 0u, Name = "Sledgehammer", AttackOffset = new OffsetData(0f, -0.111f, 0.483f), PushOffset = new Vector3(0f, -0.005f, 0.041f) }, new MeleeData { ArchetypeID = 0u, Name = "Knife", AttackOffset = new OffsetData(0f, 0.248f, 0.076f), PushOffset = new Vector3(0f, 0.0228f, 1.061f) }, new MeleeData { ArchetypeID = 0u, Name = "Spear", AttackOffset = new OffsetData(0f, 0.972f, -0.002f), PushOffset = new Vector3(0f, -0.501f, 0.005f) }, new MeleeData { ArchetypeID = 0u, Name = "Bat", AttackOffset = new OffsetData(0f, 0.4047f, 0f), PushOffset = new Vector3(0f, -0.0817f, 0f) }, new MeleeData { ArchetypeID = 0u, Name = "Improved Bat", AttackOffset = new OffsetData((Vector3?)new Vector3(0f, 0.6f, 0f), (Vector3?)new Vector3(0f, -0.2f, -0.1f), (Vector3?)new Vector3(0f, 0.55f, -0.1f)) { CapsuleSize = 0.05f, CapsuleUseCamFwd = true, CapsuleCamFwdAdd = -1.2f, CapsuleDelay = 0.05f }, AttackSphereCenterMod = 1f } }; } public sealed class OffsetData { private Vector3? _offset; public Vector3 Offset { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return _offset.Value; } set { //IL_0001: Unknown result type (might be due to invalid IL or missing references) _offset = value; } } public float EntityRayLengthAdd { get; set; } public Vector3? EntityOffset { get; set; } public float EntitySize { get; set; } public bool EntityUseCenterMod { get; set; } = true; public Vector3? CapsuleOffset { get; set; } public Vector3? CapsuleOffsetEnd { get; set; } public bool CapsuleUseCamFwd { get; set; } public float CapsuleCamFwdAdd { get; set; } public float CapsuleSize { get; set; } public bool CapsuleUseCenterMod { get; set; } public float CapsuleDelay { get; set; } public Dictionary? CapsuleStateDelay { get; set; } public bool HasOffset => _offset.HasValue; public bool HasCapsule { get { if (!CapsuleUseCamFwd) { return CapsuleOffset.HasValue; } return true; } } public bool HasEntity => EntityOffset.HasValue; public bool HasEntityRay => EntityRayLengthAdd != 0f; public bool HasCustomHitbox { get { if (!HasCapsule && !HasEntity) { return HasEntityRay; } return true; } } public OffsetData(Vector3? offset = null, Vector3? capsuleOffset = null, Vector3? capsuleOffsetEnd = null) { _offset = offset; CapsuleOffset = capsuleOffset; CapsuleOffsetEnd = capsuleOffsetEnd; } public OffsetData(float x, float y, float z) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) _offset = new Vector3(x, y, z); } public float GetCapsuleDelay(eMeleeWeaponState state) { //IL_0015: 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) float result = CapsuleDelay; if (CapsuleStateDelay != null && CapsuleStateDelay.ContainsKey(state)) { result = CapsuleStateDelay[state]; } return result; } public float GetCapsuleSize(MeleeArchetypeDataBlock data, float dotScale = 1f) { float num = ((CapsuleSize > 0f) ? CapsuleSize : data.AttackSphereRadius); if (!CapsuleUseCenterMod) { return num; } return num * dotScale; } public float GetEntitySize(MeleeArchetypeDataBlock data, float dotScale = 1f) { float num = ((EntitySize > 0f) ? EntitySize : data.AttackSphereRadius); if (!EntityUseCenterMod) { return num; } return num * dotScale; } public float GetEntityRayLen(MeleeArchetypeDataBlock data, float wallDist = float.PositiveInfinity) { return Math.Min(data.CameraDamageRayLength + EntityRayLengthAdd * MeleeDataManager.Current.CurrentRangeMod, wallDist); } public (Vector3 start, Vector3 end) GetCapsuleOffsets(Transform transform, MeleeArchetypeDataBlock data, float wallDist = float.PositiveInfinity) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = transform.localPosition; Vector3 position = transform.parent.position; Quaternion rotation = transform.parent.rotation; if (CapsuleUseCamFwd) { float num = Math.Min(CapsuleCamFwdAdd + data.CameraDamageRayLength + EntityRayLengthAdd * MeleeDataManager.Current.CurrentRangeMod, wallDist); if (!CapsuleOffset.HasValue) { return (position, position + rotation * ((Vector3)(ref localPosition)).normalized * num); } Vector3 val; if (!CapsuleOffsetEnd.HasValue) { Vector3 item = position + rotation * CapsuleOffset.Value; val = localPosition - CapsuleOffset.Value; return (item, position + rotation * ((Vector3)(ref val)).normalized * num); } Vector3 item2 = position + rotation * CapsuleOffset.Value; val = CapsuleOffsetEnd.Value - CapsuleOffset.Value; return (item2, position + rotation * ((Vector3)(ref val)).normalized * num); } return (position + rotation * CapsuleOffset.Value, CapsuleOffsetEnd.HasValue ? (position + rotation * CapsuleOffsetEnd.Value) : transform.position); } public Vector3 GetEntityOffset(Transform transform, float wallDist = float.PositiveInfinity) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector3 position = transform.parent.position; Vector3 val = transform.parent.rotation * EntityOffset.Value; Vector3 normalized = ((Vector3)(ref val)).normalized; val = EntityOffset.Value; return position + normalized * Math.Min(wallDist, ((Vector3)(ref val)).magnitude); } public void Serialize(Utf8JsonWriter writer) { if (!_offset.HasValue) { writer.WriteNullValue(); return; } if (!CapsuleOffset.HasValue) { MSCJson.Serialize(_offset, writer); return; } writer.WriteStartObject(); writer.WritePropertyName("Offset"); if (_offset.HasValue) { string text = MSCJson.Serialize(_offset); StringBuilder stringBuilder = new StringBuilder(text.Substring(1, text.Length - 1 - 1)); if (CapsuleOffset.HasValue) { text = MSCJson.Serialize(CapsuleOffset); stringBuilder.Append(" " + text.Substring(1, text.Length - 1 - 1)); } if (CapsuleOffsetEnd.HasValue) { text = MSCJson.Serialize(CapsuleOffsetEnd); stringBuilder.Append(" " + text.Substring(1, text.Length - 1 - 1)); } writer.WriteStringValue(stringBuilder.ToString()); } else { writer.WriteNullValue(); } writer.WriteNumber("EntityRayLengthAdd", EntityRayLengthAdd); writer.WritePropertyName("EntityOffset"); if (EntityOffset.HasValue) { string text = MSCJson.Serialize(EntityOffset); writer.WriteStringValue(text.Substring(1, text.Length - 1 - 1)); } else { writer.WriteNullValue(); } writer.WriteNumber("EntitySize", EntitySize); writer.WriteBoolean("EntityUseCenterMod", EntityUseCenterMod); writer.WritePropertyName("CapsuleOffset"); if (CapsuleOffset.HasValue && !_offset.HasValue) { string text = MSCJson.Serialize(CapsuleOffset); StringBuilder stringBuilder2 = new StringBuilder(text.Substring(1, text.Length - 1 - 1)); if (CapsuleOffsetEnd.HasValue) { text = MSCJson.Serialize(CapsuleOffsetEnd); stringBuilder2.Append(" " + text.Substring(1, text.Length - 1 - 1)); } writer.WriteStringValue(stringBuilder2.ToString()); } else { writer.WriteNullValue(); } writer.WriteBoolean("CapsuleUseCamFwd", CapsuleUseCamFwd); writer.WriteNumber("CapsuleCamFwdAdd", CapsuleCamFwdAdd); writer.WriteNumber("CapsuleSize", CapsuleSize); writer.WriteBoolean("CapsuleUseCenterMod", CapsuleUseCenterMod); writer.WriteNumber("CapsuleDelay", CapsuleDelay); writer.WriteEndObject(); } public void DeserializeProperty(string propertyName, ref Utf8JsonReader reader) { if (propertyName == null) { return; } switch (propertyName.Length) { case 18: switch (propertyName[6]) { case 'r': if (propertyName == "entityraylengthadd") { EntityRayLengthAdd = Math.Max(0f, reader.GetSingle()); } break; case 'u': if (propertyName == "entityusecentermod") { EntityUseCenterMod = reader.GetBoolean(); } break; } break; case 12: switch (propertyName[0]) { case 'e': if (propertyName == "entityoffset") { ParseEntityOffset(reader.GetString().Trim()); } break; case 'c': if (propertyName == "capsuledelay") { ParseDamageDelays(ref reader); } break; } break; case 16: switch (propertyName[7]) { case 'u': if (propertyName == "capsuleusecamfwd") { CapsuleUseCamFwd = reader.GetBoolean(); } break; case 'c': if (propertyName == "capsulecamfwdadd") { CapsuleCamFwdAdd = reader.GetSingle(); } break; } break; case 7: if (!(propertyName == "offsets")) { break; } goto IL_0159; case 6: if (!(propertyName == "offset")) { break; } goto IL_0159; case 10: if (propertyName == "entitysize") { EntitySize = reader.GetSingle(); } break; case 13: if (propertyName == "capsuleoffset") { ParseCapsuleOffset(reader.GetString().Trim()); } break; case 11: if (propertyName == "capsulesize") { CapsuleSize = reader.GetSingle(); } break; case 19: if (propertyName == "capsuleusecentermod") { CapsuleUseCenterMod = reader.GetBoolean(); } break; case 8: case 9: case 14: case 15: case 17: break; IL_0159: ParseOffsetTriplet(reader.GetString().Trim()); break; } } public bool ParseOffsetTriplet(string text) { if (TryParseVector3OffsetTriplet(text, out var vectors)) { (_offset, CapsuleOffset, CapsuleOffsetEnd) = vectors; return true; } return false; } private bool ParseCapsuleOffset(string text) { if (TryParseVector3OffsetTriplet(text, out var vectors)) { (CapsuleOffset, CapsuleOffsetEnd, _) = vectors; return true; } return false; } private bool ParseEntityOffset(string text) { if (TryParseVector3OffsetTriplet(text, out var vectors)) { (EntityOffset, _, _) = vectors; return true; } return false; } public static bool TryParseVector3OffsetTriplet(string input, out (Vector3?, Vector3?, Vector3?) vectors) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!RegexUtil.TryParseVectorString(input, out float[] vectorArray)) { vectors = (null, null, null); return false; } if (vectorArray.Length < 3) { vectors = (null, null, null); return false; } vectors.Item1 = new Vector3(vectorArray[0], vectorArray[1], vectorArray[2]); vectors.Item2 = ((vectorArray.Length >= 6) ? new Vector3?(new Vector3(vectorArray[3], vectorArray[4], vectorArray[5])) : null); vectors.Item3 = ((vectorArray.Length >= 9) ? new Vector3?(new Vector3(vectorArray[6], vectorArray[7], vectorArray[8])) : null); return true; } public bool ParseDamageDelays(ref Utf8JsonReader reader) { if (reader.TokenType == JsonTokenType.Number) { CapsuleDelay = reader.GetSingle(); return false; } if (reader.TokenType == JsonTokenType.StartObject) { CapsuleStateDelay = new Dictionary(); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndObject) { return true; } if (reader.TokenType != JsonTokenType.PropertyName) { return false; } string text = reader.GetString().ToLowerInvariant().Replace(" ", null); reader.Read(); if (reader.TokenType != JsonTokenType.Number) { return false; } float single = reader.GetSingle(); switch (text) { case "light": CapsuleStateDelay[(eMeleeWeaponState)3] = single; CapsuleStateDelay[(eMeleeWeaponState)4] = single; break; case "charged": CapsuleStateDelay[(eMeleeWeaponState)8] = single; CapsuleStateDelay[(eMeleeWeaponState)10] = single; break; case "lightleft": case "attackmissleft": CapsuleStateDelay[(eMeleeWeaponState)3] = single; break; case "lightright": case "attackmissright": CapsuleStateDelay[(eMeleeWeaponState)4] = single; break; case "chargedleft": case "attackchargereleaseleft": CapsuleStateDelay[(eMeleeWeaponState)8] = single; break; case "chargedright": case "attackchargereleaseright": CapsuleStateDelay[(eMeleeWeaponState)10] = single; break; } } } return false; } } } namespace MSC.API { public static class MeleeDataAPI { public delegate bool TryGetMeleeData(MeleeWeaponFirstPerson melee, out MeleeData data); public static void AddData(string prefab, MeleeData data) { MeleeDataManager.Current.AddDataForPrefab(prefab, data); } public static void AddInstanceData(string prefab, TryGetMeleeData callback) { MeleeDataManager.Current.AddInstanceDataForPrefab(prefab, callback); } } }