using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using ExtraRecoilData.CustomRecoil;
using ExtraRecoilData.JSON;
using ExtraRecoilData.Patches;
using ExtraRecoilData.Utils;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using MTFO.API;
using Microsoft.CodeAnalysis;
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("ExtraRecoilData")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+77dc485c38981c602f3027ed08e8cd9f29f618b3")]
[assembly: AssemblyProduct("ExtraRecoilData")]
[assembly: AssemblyTitle("ExtraRecoilData")]
[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 ExtraRecoilData
{
[BepInPlugin("Dinorush.ExtraRecoilData", "ExtraRecoilData", "1.3.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 = "ExtraRecoilData";
public override void Load()
{
//IL_000f: 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)
ERDLogger.Log("Loading ExtraRecoilData");
Harmony val = new Harmony("ExtraRecoilData");
val.PatchAll(typeof(WeaponSetupPatches));
val.PatchAll(typeof(RecoilPatches));
ClassInjector.RegisterTypeInIl2Cpp<CustomRecoilComponent>();
ERDLogger.Log("Loaded ExtraRecoilData");
}
}
}
namespace ExtraRecoilData.Utils
{
internal static class ERDLogger
{
private static ManualLogSource logger = Logger.CreateLogSource("ExtraRecoilData");
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);
}
}
}
internal static class FloatExtensions
{
public static float Map(this float orig, float fromMin, float fromMax, float toMin, float toMax)
{
if (fromMin == fromMax)
{
if (!(orig < fromMin))
{
return toMax;
}
return toMin;
}
orig = Mathf.Clamp(orig, fromMin, fromMax);
return (orig - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin;
}
}
}
namespace ExtraRecoilData.Patches
{
internal static class RecoilPatches
{
private static BulletWeapon? cachedWeapon;
private static CustomRecoilComponent? cachedManager;
internal static void RefreshCache(BulletWeapon weapon)
{
if ((Object)(object)cachedWeapon != (Object)null && ((Object)weapon).GetInstanceID() == ((Object)cachedWeapon).GetInstanceID())
{
cachedManager = ((Component)cachedWeapon).GetComponent<CustomRecoilComponent>();
}
}
private static CustomRecoilComponent? GetCustomRecoilManager(BulletWeapon? newWeapon = null)
{
if ((Object)(object)newWeapon == (Object)null)
{
return cachedManager;
}
PlayerAgent owner = ((Item)newWeapon).Owner;
if (owner == null || !((Agent)owner).IsLocallyOwned)
{
return null;
}
if ((Object)(object)cachedWeapon == (Object)null || ((Object)newWeapon).GetInstanceID() != ((Object)cachedWeapon).GetInstanceID())
{
cachedWeapon = newWeapon;
cachedManager = ((Component)newWeapon).GetComponent<CustomRecoilComponent>();
}
return cachedManager;
}
[HarmonyPatch(typeof(BulletWeapon), "OnWield")]
[HarmonyWrapSafe]
[HarmonyPostfix]
private static void UpdateCurrentWeapon(BulletWeapon __instance)
{
GetCustomRecoilManager(__instance);
}
[HarmonyPatch(typeof(BulletWeapon), "OnUnWield")]
[HarmonyWrapSafe]
[HarmonyPostfix]
private static void RemoveCurrentWeapon(BulletWeapon __instance)
{
PlayerAgent owner = ((Item)__instance).Owner;
if (owner == null || ((Agent)owner).IsLocallyOwned)
{
cachedWeapon = null;
cachedManager = null;
}
}
[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
[HarmonyWrapSafe]
[HarmonyPostfix]
private static void UpdateCustomRecoil(BulletWeaponArchetype __instance)
{
CustomRecoilComponent customRecoilManager = GetCustomRecoilManager(__instance.m_weapon);
if (!((Object)(object)customRecoilManager == (Object)null))
{
customRecoilManager.FireTriggered(Math.Max(0f, Math.Max(__instance.m_nextShotTimer, __instance.m_nextBurstTimer)));
}
}
[HarmonyPatch(typeof(FPS_RecoilSystem), "ApplyRecoil")]
[HarmonyWrapSafe]
[HarmonyPostfix]
private static void CustomApplyRecoilAfter(FPS_RecoilSystem __instance, bool resetSimilarity, RecoilDataBlock recoilData)
{
//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_001e: 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_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)cachedManager == (Object)null))
{
Vector2 modifiedRecoil = cachedManager.GetModifiedRecoil(__instance.recoilDir);
Vector2 currentRecoilForce = __instance.currentRecoilForce;
currentRecoilForce.x += (__instance.recoilDir.x - modifiedRecoil.x) * (1f - recoilData.worldToViewSpaceBlendVertical);
currentRecoilForce.y += (__instance.recoilDir.y - modifiedRecoil.y) * (1f - recoilData.worldToViewSpaceBlendHorizontal);
Vector2 currentRecoilForceVP = __instance.currentRecoilForceVP;
currentRecoilForceVP.x += (__instance.recoilDir.x - modifiedRecoil.x) * recoilData.worldToViewSpaceBlendVertical;
currentRecoilForceVP.y += (__instance.recoilDir.y - modifiedRecoil.y) * recoilData.worldToViewSpaceBlendHorizontal;
__instance.recoilDir = modifiedRecoil;
__instance.currentRecoilForce = currentRecoilForce;
__instance.currentRecoilForceVP = currentRecoilForceVP;
}
}
}
internal static class WeaponSetupPatches
{
[HarmonyPatch(typeof(BulletWeaponArchetype), "SetOwner")]
[HarmonyWrapSafe]
[HarmonyPostfix]
private static void SetupCallback(BulletWeaponArchetype __instance, PlayerAgent owner)
{
if (!((Object)(object)owner == (Object)null))
{
CustomRecoilData customRecoilData = CustomRecoilManager.Current.GetCustomRecoilData(((GameDataBlockBase<ArchetypeDataBlock>)(object)__instance.m_archetypeData).persistentID);
if (customRecoilData != null && !((Object)(object)((Component)__instance.m_weapon).gameObject.GetComponent<CustomRecoilComponent>() != (Object)null))
{
((Component)__instance.m_weapon).gameObject.AddComponent<CustomRecoilComponent>().Data = customRecoilData;
}
}
}
}
}
namespace ExtraRecoilData.JSON
{
public static class ERDJson
{
private static readonly JsonSerializerOptions _setting;
static ERDJson()
{
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: 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(new MinMaxConverter());
if (MTFOPartialDataUtil.IsLoaded)
{
_setting.Converters.Add(MTFOPartialDataUtil.PersistentIDConverter);
_setting.Converters.Add(MTFOPartialDataUtil.LocalizedTextConverter);
ERDLogger.Log("PartialData support found!");
}
else
{
_setting.Converters.Add((JsonConverter)new LocalizedTextConverter());
}
}
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 MinMaxConverter : JsonConverter<MinMaxValue>
{
public override MinMaxValue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException("Missing { for MinMaxValue object");
}
MinMaxValue val = new MinMaxValue();
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return val;
}
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException("Expected PropertyName token");
}
string? @string = reader.GetString();
reader.Read();
string text = @string.ToLowerInvariant();
if (!(text == "min"))
{
if (!(text == "max"))
{
throw new JsonException("Expected Min or Max property");
}
val.Max = reader.GetSingle();
}
else
{
val.Min = reader.GetSingle();
}
}
throw new JsonException("Expected EndObject token");
}
public override void Write(Utf8JsonWriter writer, MinMaxValue value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("Min");
writer.WriteNumberValue(value.Min);
writer.WritePropertyName("Max");
writer.WriteNumberValue(value.Max);
writer.WriteEndObject();
}
}
internal static class MTFOPartialDataUtil
{
public const string PLUGIN_GUID = "MTFO.Extension.PartialBlocks";
public static JsonConverter PersistentIDConverter { get; private set; }
public static JsonConverter LocalizedTextConverter { get; private set; }
public static bool IsLoaded { get; private set; }
public static bool Initialized { get; private set; }
public static string PartialDataPath { get; private set; }
public static string ConfigPath { get; private set; }
static MTFOPartialDataUtil()
{
PersistentIDConverter = null;
LocalizedTextConverter = null;
IsLoaded = false;
Initialized = false;
PartialDataPath = string.Empty;
ConfigPath = string.Empty;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value))
{
return;
}
try
{
Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type[] types = obj.GetTypes();
Type type = types.First((Type t) => t.Name == "PersistentIDConverter");
if ((object)type == null)
{
throw new Exception("Unable to Find PersistentIDConverter Class");
}
Type type2 = types.First((Type t) => t.Name == "PartialDataManager");
if ((object)type2 == null)
{
throw new Exception("Unable to Find PartialDataManager Class");
}
Type type3 = types.First((Type t) => t.Name == "LocalizedTextConverter") ?? throw new Exception("Unable to Find LocalizedTextConverter Class");
PropertyInfo property = type2.GetProperty("Initialized", BindingFlags.Static | BindingFlags.Public);
PropertyInfo property2 = type2.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public);
PropertyInfo? property3 = type2.GetProperty("ConfigPath", BindingFlags.Static | BindingFlags.Public);
if ((object)property == null)
{
throw new Exception("Unable to Find Property: Initialized");
}
if ((object)property2 == null)
{
throw new Exception("Unable to Find Property: PartialDataPath");
}
if ((object)property3 == null)
{
throw new Exception("Unable to Find Field: ConfigPath");
}
Initialized = (bool)property.GetValue(null);
PartialDataPath = (string)property2.GetValue(null);
ConfigPath = (string)property3.GetValue(null);
PersistentIDConverter = (JsonConverter)Activator.CreateInstance(type);
LocalizedTextConverter = (JsonConverter)Activator.CreateInstance(type3);
IsLoaded = true;
}
catch (Exception value2)
{
ERDLogger.Error($"Exception thrown while reading data from MTFO_Extension_PartialData:\n{value2}");
}
}
}
internal static class MTFOUtil
{
public const string PLUGIN_GUID = "com.dak.MTFO";
public const BindingFlags PUBLIC_STATIC = BindingFlags.Static | BindingFlags.Public;
public static string GameDataPath { get; private set; }
public static string CustomPath { get; private set; }
public static bool HasCustomContent { get; private set; }
public static bool IsLoaded { get; private set; }
static MTFOUtil()
{
GameDataPath = string.Empty;
CustomPath = string.Empty;
HasCustomContent = false;
IsLoaded = false;
if (!((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("com.dak.MTFO", out var value))
{
return;
}
try
{
Assembly obj = ((value == null) ? null : value.Instance?.GetType()?.Assembly) ?? null;
if ((object)obj == null)
{
throw new Exception("Assembly is Missing!");
}
Type obj2 = obj.GetTypes().First((Type t) => t.Name == "ConfigManager") ?? throw new Exception("Unable to Find ConfigManager Class");
FieldInfo field = obj2.GetField("GameDataPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo field2 = obj2.GetField("CustomPath", BindingFlags.Static | BindingFlags.Public);
FieldInfo? field3 = obj2.GetField("HasCustomContent", BindingFlags.Static | BindingFlags.Public);
if ((object)field == null)
{
throw new Exception("Unable to Find Field: GameDataPath");
}
if ((object)field2 == null)
{
throw new Exception("Unable to Find Field: CustomPath");
}
if ((object)field3 == null)
{
throw new Exception("Unable to Find Field: HasCustomContent");
}
GameDataPath = (string)field.GetValue(null);
CustomPath = (string)field2.GetValue(null);
HasCustomContent = (bool)field3.GetValue(null);
IsLoaded = true;
}
catch (Exception value2)
{
ERDLogger.Log($"Exception thrown while reading path from DataDumper (MTFO): \n{value2}");
}
}
}
}
namespace ExtraRecoilData.CustomRecoil
{
public class CustomRecoilComponent : MonoBehaviour
{
protected CustomRecoilData data = new CustomRecoilData();
protected List<Vector2> recoilPattern = new List<Vector2>();
protected int recoilPatternIndex;
protected List<Vector2> recoilPatternFirst = new List<Vector2>();
protected int recoilPatternFirstIndex;
protected float recoilScaleProgress;
protected float lastUpdateTime;
protected float nextShotTime;
public CustomRecoilData Data
{
get
{
return data;
}
set
{
data = value;
data.RecoilScaleCap = ((data.RecoilScaleCap >= 0f) ? data.RecoilScaleCap : 0f);
data.RecoilScaleThreshold = Mathf.Clamp(data.RecoilScaleThreshold, 0f, data.RecoilScaleCap);
SetRecoilPattern(ref recoilPattern, data.RecoilPattern);
SetRecoilPattern(ref recoilPatternFirst, data.RecoilPatternFirst);
}
}
public CustomRecoilComponent(IntPtr value)
: base(value)
{
}
protected static void SetRecoilPattern(ref List<Vector2> localPattern, List<float> pattern)
{
localPattern.Clear();
if (pattern.Any((float val) => Math.Abs(val) > 1f))
{
localPattern = CreatePatternFromPolar(pattern);
}
else
{
localPattern = CreatePatternFromEuclidean(pattern);
}
}
protected static List<Vector2> CreatePatternFromPolar(List<float> pattern)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
List<Vector2> list = new List<Vector2>(pattern.Count);
for (int i = 0; i < pattern.Count; i++)
{
float num = (0f - pattern[i] + 90f) * ((float)Math.PI / 180f);
list.Add(new Vector2((float)Math.Sin(num), (float)(0.0 - Math.Cos(num))));
}
return list;
}
protected static List<Vector2> CreatePatternFromEuclidean(List<float> pattern)
{
//IL_0048: 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_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
List<Vector2> list = new List<Vector2>(pattern.Count / 2);
for (int i = 0; i < pattern.Count - 1; i += 2)
{
Vector2 item = (Vector2)((pattern[i] != 0f || pattern[i + 1] != 0f) ? new Vector2(pattern[i + 1], 0f - pattern[i]) : Vector2.right);
((Vector2)(ref item)).Normalize();
list.Add(item);
}
return list;
}
protected void UpdateToPresent()
{
if (lastUpdateTime != Clock.Time)
{
float num = Clock.Time - nextShotTime;
float num2 = Clock.Time - lastUpdateTime;
if (num > data.RecoilScaleDecayDelay)
{
float num3 = num2 - Math.Max(0f, data.RecoilScaleDecayDelay + nextShotTime - lastUpdateTime);
recoilScaleProgress = Math.Max(0f, Math.Min(data.RecoilScaleCap, recoilScaleProgress - data.RecoilScaleDecay * num3));
}
if (num > data.RecoilPatternResetDelay)
{
recoilPatternIndex = 0;
recoilPatternFirstIndex = 0;
}
lastUpdateTime = Clock.Time;
}
}
public Vector2 GetModifiedRecoil(Vector2 recoilDir)
{
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_0114: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: 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)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
UpdateToPresent();
float num = recoilScaleProgress.Map(data.RecoilScaleThreshold, data.RecoilScaleCap, data.RecoilScaleMin, data.RecoilScaleMax);
float num2 = recoilScaleProgress.Map(data.RecoilScaleThreshold, data.RecoilScaleCap, data.RecoilPatternScaleMin, data.RecoilPatternScaleMax);
Vector2 val = Vector2.right;
if (recoilPatternFirstIndex < recoilPatternFirst.Count)
{
val = recoilPatternFirst[recoilPatternFirstIndex];
}
else if (recoilPattern.Count > 0)
{
val = recoilPattern[recoilPatternIndex];
}
if (data.RecoilPatternAlign == RecoilPatternAlign.ALIGN)
{
((Vector2)(ref recoilDir)).Set(recoilDir.x * val.x - recoilDir.y * val.y, recoilDir.y * val.x + recoilDir.x * val.y);
}
return recoilDir * num + val * data.RecoilPatternPower.GetRandom() * num2;
}
public void FireTriggered(float newShotTime)
{
UpdateToPresent();
nextShotTime = (data.RecoilDelayStartOnFire ? Clock.Time : newShotTime);
recoilScaleProgress = Math.Min(recoilScaleProgress + 1f, data.RecoilScaleCap);
if (recoilPatternFirstIndex < recoilPatternFirst.Count)
{
recoilPatternFirstIndex++;
}
else if (recoilPattern.Count > 0)
{
recoilPatternIndex = (recoilPatternIndex + 1) % recoilPattern.Count;
}
}
}
public class CustomRecoilData
{
public bool RecoilDelayStartOnFire;
public uint ArchetypeID { get; set; }
public string Name { get; set; } = string.Empty;
public float RecoilScaleCap { get; set; } = 1f;
public float RecoilScaleThreshold { get; set; }
public float RecoilScaleDecay { get; set; } = 1f;
public float RecoilScaleDecayDelay { get; set; } = 0.016f;
public float RecoilScaleMin { get; set; } = 1f;
public float RecoilScaleMax { get; set; } = 1f;
public float RecoilPatternScaleMin { get; set; } = 1f;
public float RecoilPatternScaleMax { get; set; } = 1f;
public List<float> RecoilPattern { get; set; } = new List<float>();
public List<float> RecoilPatternFirst { get; set; } = new List<float>();
public RecoilPatternAlign RecoilPatternAlign { get; set; }
public MinMaxValue RecoilPatternPower { get; set; } = new MinMaxValue
{
Min = 0f,
Max = 0f
};
public float RecoilPatternResetDelay { get; set; } = 0.016f;
}
public class CustomRecoilManager
{
private readonly Dictionary<uint, CustomRecoilData> customData = new Dictionary<uint, CustomRecoilData>();
private readonly LiveEditListener liveEditListener;
public static CustomRecoilManager Current { get; private set; }
public string DEFINITION_PATH { get; private set; }
public override string ToString()
{
return "Printing manager: " + customData.ToString();
}
protected virtual void AddCustomRecoilData(CustomRecoilData? data)
{
if (data != null)
{
if (customData.ContainsKey(data.ArchetypeID))
{
ERDLogger.Warning("Replaced custom recoil for ArchetypeID " + data.ArchetypeID);
}
customData[data.ArchetypeID] = data;
}
}
protected virtual void FileChanged(LiveEditEventArgs e)
{
ERDLogger.Warning("LiveEdit File Changed: " + e.FullPath);
LiveEdit.TryReadFileContent(e.FullPath, (Action<string>)delegate(string content)
{
List<CustomRecoilData> list = ERDJson.Deserialize<List<CustomRecoilData>>(content);
if (list == null)
{
return;
}
foreach (CustomRecoilData item in list)
{
AddCustomRecoilData(item);
}
});
}
public CustomRecoilData? GetCustomRecoilData(uint ArchetypeID)
{
if (!customData.ContainsKey(ArchetypeID))
{
return null;
}
return customData[ArchetypeID];
}
private CustomRecoilManager()
{
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
DEFINITION_PATH = Path.Combine(MTFOPathAPI.CustomPath, "ExtraRecoilData");
if (!Directory.Exists(DEFINITION_PATH))
{
Directory.CreateDirectory(DEFINITION_PATH);
StreamWriter streamWriter = File.CreateText(Path.Combine(DEFINITION_PATH, "Template.json"));
streamWriter.WriteLine(ERDJson.Serialize(new List<CustomRecoilData>
{
new CustomRecoilData()
}));
streamWriter.Flush();
streamWriter.Close();
}
foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories))
{
List<CustomRecoilData> list = ERDJson.Deserialize<List<CustomRecoilData>>(File.ReadAllText(item));
if (list == null)
{
continue;
}
foreach (CustomRecoilData item2 in list)
{
AddCustomRecoilData(item2);
}
}
liveEditListener = LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true);
liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged);
}
static CustomRecoilManager()
{
Current = new CustomRecoilManager();
}
}
public enum RecoilPatternAlign
{
ALIGN,
ABSOLUTE
}
}
namespace ExtraRecoilData.API
{
public static class ChangeAPI
{
public static void ChangeERDComponent(uint archetypeID, BulletWeapon weapon)
{
CustomRecoilComponent component = ((Component)weapon).GetComponent<CustomRecoilComponent>();
CustomRecoilData customRecoilData = CustomRecoilManager.Current.GetCustomRecoilData(archetypeID);
if ((Object)(object)component != (Object)null)
{
component.Data = customRecoilData ?? new CustomRecoilData();
}
else if (customRecoilData != null)
{
component = ((Component)weapon).gameObject.AddComponent<CustomRecoilComponent>();
component.Data = customRecoilData;
}
RecoilPatches.RefreshCache(weapon);
}
}
}