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<bool>(text, "Show Vanilla Debug Swing Hitbox", false, "Enables the base game debug melee swing hitbox visuals.").Value;
DrawDebugHitbox = config.Bind<bool>(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<float>(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 <DrawSpheres>d__2 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MeleeWeaponFirstPerson melee;
public MeleeData data;
object? IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object? IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DrawSpheres>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<MeleeWeaponFirstPerson>();
}
MeleeData data = MeleeDataManager.Current.GetData(melee);
_drawCoroutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(DrawSpheres(melee, data)), (Action)null);
}
[IteratorStateMachine(typeof(<DrawSpheres>d__2))]
private static IEnumerator DrawSpheres(MeleeWeaponFirstPerson melee, MeleeData? data)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DrawSpheres>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<MWS_AttackSwingBase>();
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<MeleeWeaponDamageData> 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<MeleeWeaponDamageData> hits)
{
DamageUtil.IncrementSearchID();
hits = new List<MeleeWeaponDamageData>();
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<MeleeWeaponDamageData> 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<iLG_WeakDoor_Destruction>();
if (componentInParent != null && !componentInParent.SkinnedDoorEnabled)
{
componentInParent.EnableSkinnedDoor();
}
}
IDamageable component = ((Component)((RaycastHit)(ref _rayHit)).collider).GetComponent<IDamageable>();
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<MeleeWeaponDamageData> 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<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapCapsule(item, item2, capsuleSize, LayerManager.MASK_MELEE_ATTACK_TARGETS));
}
else
{
float capsuleSize = attackOffset.GetEntitySize(archBlock, dotScale);
array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(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<IDamageable>();
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<T>(string json)
{
return JsonSerializer.Deserialize<T>(json, _setting);
}
public static T? Deserialize<T>(ref Utf8JsonReader reader)
{
return JsonSerializer.Deserialize<T>(ref reader, _setting);
}
public static object? Deserialize(Type type, string json)
{
return JsonSerializer.Deserialize(json, type, _setting);
}
public static string Serialize<T>(T value)
{
return JsonSerializer.Serialize(value, _setting);
}
public static void Serialize<T>(T value, Utf8JsonWriter writer)
{
JsonSerializer.Serialize(writer, value, _setting);
}
}
public sealed class OffsetDataConverter : JsonConverter<OffsetData>
{
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<Vector3?>
{
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<BasePlugin>)(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<string, List<MeleeData>> _fileData = new Dictionary<string, List<MeleeData>>();
private readonly Dictionary<uint, MeleeData> _idToData = new Dictionary<uint, MeleeData>();
private readonly Dictionary<uint, MeleeData> _cachedData = new Dictionary<uint, MeleeData>();
private readonly Dictionary<string, MeleeData> _prefabToCachedData = new Dictionary<string, MeleeData>();
private MeleeWeaponFirstPerson? _activeMelee;
private readonly Dictionary<string, MeleeData> _prefabToData = new Dictionary<string, MeleeData>();
private readonly Dictionary<string, List<MeleeDataAPI.TryGetMeleeData>> _prefabToDataInstance = new Dictionary<string, List<MeleeDataAPI.TryGetMeleeData>>();
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<string>)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<string>)delegate(string content)
{
ReadFileContent(e2.FullPath, content);
PrintCustomIDs();
});
}
private void ReadFileContent(string file, string content)
{
RemoveFile(file);
List<MeleeData> list = null;
try
{
list = MSCJson.Deserialize<List<MeleeData>>(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<MeleeData> 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<MeleeData>(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<MeleeArchetypeDataBlock>)(object)((ItemEquippable)melee).MeleeArchetypeData).persistentID, out MeleeData value))
{
List<string> 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<MeleeDataAPI.TryGetMeleeData> value))
{
_prefabToDataInstance.Add(prefab, value = new List<MeleeDataAPI.TryGetMeleeData>());
}
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<MeleeDataAPI.TryGetMeleeData> 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<MeleeArchetypeDataBlock>)(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<string> 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<MeleeArchetypeDataBlock>)(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<string> 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<eMeleeWeaponState, float>? 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<eMeleeWeaponState, float>();
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);
}
}
}