Decompiled source of MeleeSwingCustomization v1.0.1

MeleeSwingCustomization.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
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 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.Collections.Generic;
using MSC.CustomMeleeData;
using MSC.Dependencies;
using MSC.JSON;
using MSC.Utils;
using MTFO.API;
using Microsoft.CodeAnalysis;
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+b36c7a313655b92b84016dbe18396b07e6fe5f55")]
[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 ImproveBatHitbox;

		private static readonly ConfigFile configFile;

		static Configuration()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			ImproveBatHitbox = true;
			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 = "Base Settings";
			MeleeWeaponFirstPerson.DEBUG_TARGETING_ENABLED = (bool)configFile[text, "Improve Bat Hitbox"].BoxedValue;
			text = "Test Settings";
			MeleeWeaponFirstPerson.DEBUG_TARGETING_ENABLED = (bool)configFile[text, "Show Debug Targeting"].BoxedValue;
		}

		private static void BindAll(ConfigFile config)
		{
			string text = "Base Settings";
			ImproveBatHitbox = config.Bind<bool>(text, "Improve Bat Hitbox", ImproveBatHitbox, "Improves the hitbox position of bat melee weapons.").Value;
			text = "Test Settings";
			MeleeWeaponFirstPerson.DEBUG_TARGETING_ENABLED = config.Bind<bool>(text, "Show Debug Targeting", false, "Enables the base game debug melee hitbox visuals.").Value;
		}
	}
	[BepInPlugin("Dinorush.MeleeSwingCustomization", "MeleeSwingCustomization", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public const string MODNAME = "MeleeSwingCustomization";

		public override void Load()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			((BasePlugin)this).Log.LogMessage((object)"Loading MeleeSwingCustomization");
			Configuration.Init();
			MeleeDataManager.Current.Init();
			new Harmony("MeleeSwingCustomization").PatchAll();
			((BasePlugin)this).Log.LogMessage((object)"Loaded MeleeSwingCustomization");
		}
	}
}
namespace MSC.Utils
{
	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]
	internal static class MeleePatches
	{
		private const string BatPrefab = "Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPersonBat.prefab";

		private static readonly MeleeData ImprovedBatData = new MeleeData
		{
			AttackOffset = new Vector3
			{
				x = 0f,
				y = 0.55f,
				z = 0f
			}
		};

		private static MWS_AttackLight? _lightLeft;

		private static MWS_AttackLight? _lightRight;

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetupMeleeAnimations")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_MeleeSetup(MeleeWeaponFirstPerson __instance)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (!MeleeDataManager.Current.RegisterMelee(__instance) && Configuration.ImproveBatHitbox)
			{
				List<string> firstPersonPrefabs = ((Item)__instance).ItemDataBlock.FirstPersonPrefabs;
				if (firstPersonPrefabs != null && firstPersonPrefabs.Count > 0 && firstPersonPrefabs[0] == "Assets/AssetPrefabs/Items/Melee/MeleeWeaponFirstPersonBat.prefab")
				{
					__instance.ModelData.m_damageRefAttack.localPosition = ImprovedBatData.AttackOffset.Value;
				}
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "ChangeState")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_MeleeChangeState(MeleeWeaponFirstPerson __instance, eMeleeWeaponState newState)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected I4, but got Unknown
			MeleeData data = MeleeDataManager.Current.GetData(((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)((ItemEquippable)__instance).MeleeArchetypeData).persistentID);
			if (data == null)
			{
				return;
			}
			switch (newState - 3)
			{
			case 0:
				if (_lightLeft == null)
				{
					_lightLeft = ((Il2CppObjectBase)((Il2CppArrayBase<MWS_Base>)(object)__instance.m_states)[3]).TryCast<MWS_AttackLight>();
				}
				_lightLeft.m_wantedNormalSpeed = data.LightAttackSpeed;
				_lightLeft.m_wantedChargeSpeed = data.LightAttackSpeed * 0.3f;
				break;
			case 1:
				if (_lightRight == null)
				{
					_lightRight = ((Il2CppObjectBase)((Il2CppArrayBase<MWS_Base>)(object)__instance.m_states)[4]).TryCast<MWS_AttackLight>();
				}
				_lightRight.m_wantedNormalSpeed = data.LightAttackSpeed;
				_lightRight.m_wantedChargeSpeed = data.LightAttackSpeed * 0.3f;
				break;
			case 2:
			case 3:
				__instance.WeaponAnimator.speed = data.LightAttackSpeed;
				break;
			case 5:
			case 7:
				__instance.WeaponAnimator.speed = data.ChargedAttackSpeed;
				break;
			case 10:
			{
				Animator weaponAnimator = __instance.WeaponAnimator;
				weaponAnimator.speed *= data.PushSpeed;
				break;
			}
			case 4:
			case 6:
			case 8:
			case 9:
				break;
			}
		}
	}
}
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());
		}

		public static T? Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _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 sealed class Vector3Converter : JsonConverter<Vector3?>
	{
		public const string NullStr = "Unchanged";

		public const string NullStrLower = "unchanged";

		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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			if (input.ToLowerInvariant() == "unchanged")
			{
				vector = null;
				return true;
			}
			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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!value.HasValue)
			{
				writer.WriteStringValue("Unchanged");
			}
			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 uint ArchetypeID { get; set; }

		public string Name { get; set; } = string.Empty;


		public Vector3? AttackOffset { get; set; }

		public Vector3? PushOffset { get; set; }

		public float LightAttackSpeed { get; set; } = 1f;


		public float ChargedAttackSpeed { get; set; } = 1f;


		public float PushSpeed { get; set; } = 1f;

	}
	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 List<MeleeWeaponFirstPerson> _listeners = new List<MeleeWeaponFirstPerson>();

		private readonly LiveEditListener? _liveEditListener;

		private void FileChanged(LiveEditEventArgs e)
		{
			LiveEditEventArgs e2 = e;
			DinoLogger.Warning("LiveEdit File Changed: " + e2.FullPath);
			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.FullPath);
			RemoveFile(e.FullPath);
			PrintCustomIDs();
		}

		private void FileCreated(LiveEditEventArgs e)
		{
			LiveEditEventArgs e2 = e;
			DinoLogger.Warning("LiveEdit File Created: " + e2.FullPath);
			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 " + 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()
		{
			for (int num = _listeners.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_listeners[num] != (Object)null)
				{
					SetMeleeData(_listeners[num]);
				}
				else
				{
					_listeners.RemoveAt(num);
				}
			}
		}

		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_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Expected O, but got Unknown
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			if (!MTFOWrapper.HasCustomDatablocks)
			{
				DinoLogger.Log("No MTFO datablocks detected. Restricting to bat changes...");
				return;
			}
			string text = Path.Combine(MTFOWrapper.CustomPath, "MeleeSwingCustomization");
			if (!Directory.Exists(text))
			{
				DinoLogger.Log("No directory detected. Creating " + text + "/Template.json");
				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. " + text);
			}
			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);
		}

		internal void Init()
		{
		}

		public bool RegisterMelee(MeleeWeaponFirstPerson melee)
		{
			if (!MTFOWrapper.HasCustomDatablocks)
			{
				return false;
			}
			CacheData(melee);
			AddMeleeListener(melee);
			return SetMeleeData(melee);
		}

		public MeleeData? GetData(uint id)
		{
			return _idToData.GetValueOrDefault(id);
		}

		private void CacheData(MeleeWeaponFirstPerson melee)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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 value = new MeleeData
				{
					ArchetypeID = persistentID,
					AttackOffset = melee.ModelData.m_damageRefAttack.position,
					PushOffset = melee.ModelData.m_damageRefPush.position
				};
				_cachedData.Add(persistentID, value);
				FillDataWithCache(persistentID);
			}
		}

		private void FillDataWithCache(uint id)
		{
			if (_idToData.TryGetValue(id, out MeleeData value) && _cachedData.TryGetValue(id, out MeleeData value2))
			{
				if (!value.AttackOffset.HasValue)
				{
					value.AttackOffset = value2.AttackOffset;
				}
				if (!value.PushOffset.HasValue)
				{
					value.PushOffset = value2.PushOffset;
				}
			}
		}

		private void AddMeleeListener(MeleeWeaponFirstPerson melee)
		{
			MeleeWeaponFirstPerson melee2 = melee;
			if (!_listeners.Any((MeleeWeaponFirstPerson listener) => ((listener != null) ? new int?(((Object)listener).GetInstanceID()) : null) == ((Object)melee2).GetInstanceID()))
			{
				_listeners.Add(melee2);
			}
		}

		private bool SetMeleeData(MeleeWeaponFirstPerson melee)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_00ab: 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;
			}
			Transform damageRefAttack = melee.ModelData.m_damageRefAttack;
			Transform damageRefPush = melee.ModelData.m_damageRefPush;
			if (_idToData.TryGetValue(persistentID, out MeleeData value2))
			{
				damageRefAttack.localPosition = value2.AttackOffset.Value;
				damageRefPush.localPosition = value2.PushOffset.Value;
				SetMeleeAttackTimings(melee, value2);
				return true;
			}
			damageRefAttack.localPosition = value.AttackOffset.Value;
			damageRefPush.localPosition = value.PushOffset.Value;
			SetMeleeAttackTimings(melee, value);
			return false;
		}

		private void SetMeleeAttackTimings(MeleeWeaponFirstPerson melee, MeleeData data)
		{
			float mod = 1f / data.LightAttackSpeed;
			Il2CppReferenceArray<MWS_Base> states = melee.m_states;
			MeleeAnimationSetDataBlock meleeAnimationData = ((ItemEquippable)melee).MeleeAnimationData;
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[3].AttackData, meleeAnimationData.FPAttackMissLeft, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[4].AttackData, meleeAnimationData.FPAttackMissRight, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[5].AttackData, meleeAnimationData.FPAttackHitLeft, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[6].AttackData, meleeAnimationData.FPAttackHitRight, mod);
			mod = 1f / data.ChargedAttackSpeed;
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[8].AttackData, meleeAnimationData.FPAttackChargeUpReleaseLeft, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[10].AttackData, meleeAnimationData.FPAttackChargeUpReleaseRight, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[11].AttackData, meleeAnimationData.FPAttackChargeUpHitLeft, mod);
			CopyMeleeData(((Il2CppArrayBase<MWS_Base>)(object)states)[12].AttackData, meleeAnimationData.FPAttackChargeUpHitRight, mod);
			CopyMeleeData(mod: 1f / data.PushSpeed, data: ((Il2CppArrayBase<MWS_Base>)(object)states)[13].AttackData, animData: meleeAnimationData.FPAttackPush);
		}

		private static void CopyMeleeData(MeleeAttackData data, MeleeAttackData animData, float mod = 1f)
		{
			data.m_attackLength = animData.AttackLengthTime * mod;
			data.m_attackHitTime = animData.AttackHitTime * mod;
			data.m_damageStartTime = animData.DamageStartTime * mod;
			data.m_damageEndTime = animData.DamageEndTime * mod;
			data.m_attackCamFwdHitTime = animData.AttackCamFwdHitTime * mod;
			data.m_comboEarlyTime = animData.ComboEarlyTime * mod;
		}
	}
	internal static class MeleeDataTemplate
	{
		public static MeleeData[] Template = new MeleeData[5]
		{
			new MeleeData
			{
				ArchetypeID = 0u,
				Name = "Sledgehammer",
				AttackOffset = new Vector3
				{
					x = 0f,
					y = -0.111f,
					z = 0.483f
				},
				PushOffset = new Vector3
				{
					x = 0f,
					y = -0.005f,
					z = 0.041f
				}
			},
			new MeleeData
			{
				ArchetypeID = 0u,
				Name = "Knife",
				AttackOffset = new Vector3
				{
					x = 0f,
					y = 0.248f,
					z = 0.076f
				},
				PushOffset = new Vector3
				{
					x = 0f,
					y = 0.0228f,
					z = 1.061f
				}
			},
			new MeleeData
			{
				ArchetypeID = 0u,
				Name = "Spear",
				AttackOffset = new Vector3
				{
					x = 0f,
					y = 0.972f,
					z = -0.002f
				},
				PushOffset = new Vector3
				{
					x = 0f,
					y = -0.501f,
					z = 0.005f
				}
			},
			new MeleeData
			{
				ArchetypeID = 0u,
				Name = "Bat",
				AttackOffset = new Vector3
				{
					x = 0f,
					y = 0.4047f,
					z = 0f
				},
				PushOffset = new Vector3
				{
					x = 0f,
					y = -0.0817f,
					z = 0f
				}
			},
			new MeleeData
			{
				ArchetypeID = 0u,
				Name = "Improved Bat",
				AttackOffset = new Vector3
				{
					x = 0f,
					y = 0.55f,
					z = 0f
				},
				PushOffset = null
			}
		};
	}
}