using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using MagSlide;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "MagSlide", "1.2.0", "ElectroDynamic", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyCompany("MagSlide")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0")]
[assembly: AssemblyProduct("MagSlide")]
[assembly: AssemblyTitle("MagSlide")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MagSlide
{
public class Mod : MelonMod
{
private class Rec
{
public AmmoSocket Socket;
public float OrigInfluence;
public float OrigEndDistance;
public SphereCollider Trigger;
public float OrigTriggerRadius;
public float AppliedRadius = -1f;
public bool WasLocked;
public bool PlugCaptured;
public bool HasSeat;
public Rigidbody GunRb;
public Vector3 SeatMagPosL;
public Quaternion SeatMagRotL;
public Vector3 SocketPosL;
public Vector3 AxisL;
public float RailLen;
public Magazine LastMag;
public Rail Rail;
public float NoRelatchUntil;
public string Key;
public string Platform;
public WeaponClass Class;
public bool IdentityKnown;
}
private class Rail
{
public ConfigurableJoint Joint;
public Magazine Mag;
public Rigidbody MagRb;
public AmmoPlug Plug;
public Transform PlugT;
public Collider[] MagCols;
public Collider[] GunCols;
public Collider[] HandCols;
public List<Rigidbody> HandRbs;
public List<Collider> GunHandCols;
public bool Armed;
public float LatchTime;
public float NextTelem;
public float LastT;
public float NextBuzz;
public bool NearBuzzed;
}
private class SeatData
{
public Vector3 SocketPosL;
public Vector3 AxisL;
public Vector3 SeatMagPosL;
public Quaternion SeatMagRotL;
public float RailLen;
}
internal enum WeaponClass
{
Pistol,
Smg,
Rifle,
Other
}
private enum BuzzKind
{
Catch,
Slide,
Insert
}
private const float SnapRangeFraction = 0.25f;
private static MelonPreferences_Category _cat;
private static MelonPreferences_Entry<bool> _enabled;
private static MelonPreferences_Entry<bool> _magSlide;
private static MelonPreferences_Entry<float> _catch;
private static MelonPreferences_Entry<float> _depth;
private static readonly Dictionary<int, KeyValuePair<AmmoSocket, float>> _plugSockets = new Dictionary<int, KeyValuePair<AmmoSocket, float>>();
private static readonly HashSet<string> _blocked = new HashSet<string>();
private static readonly List<string> _seenGuns = new List<string>();
private static readonly HashSet<string> _listedGuns = new HashSet<string>();
private static Page _weaponListPage;
private static readonly string[] SmgWords = new string[16]
{
"smg", "uzi", "mp5", "mp7", "mp40", "vector", "pdrc", "pdw", "p90", "mac10",
"mac-10", "scorpion", "thompson", "tommy", "sten", "grease gun"
};
private static readonly string[] RifleWords = new string[26]
{
"rifle", "carbine", "akm", "ak47", "ak-47", "ak74", "m4", "m16", "mk18", "ar15",
"ar-15", "scar", "g36", "famas", "aug", "lmg", "m60", "saw", "sniper", "dmr",
"m14", "garand", "mosin", "fal", "g3", "bren"
};
private static readonly string[] PistolWords = new string[16]
{
"pistol", "eder", "m9", "1911", "p350", "glock", "deagle", "desert eagle", "revolver", "magnum",
"usp", "luger", "makarov", "beretta", "handgun", "sidearm"
};
private static readonly string[] JunkNames = new string[6] { "rigmanager", "asset spawner", "spawner", "player", "gamecontrol", "[bonelab]" };
private static readonly Dictionary<int, Rec> _known = new Dictionary<int, Rec>();
private static float _scanAccum;
private static int _lastCount = -1;
private static bool _patchesOk;
private static readonly List<AmmoPlug> _plugs = new List<AmmoPlug>();
private static readonly List<AmmoPlug> _candidates = new List<AmmoPlug>();
private static readonly HashSet<int> _railedPlugIds = new HashSet<int>();
private static float _scanInterval = 1f;
private static int _appliedCount = -1;
private static readonly Dictionary<string, SeatData> _seatLib = new Dictionary<string, SeatData>();
private static readonly List<KeyValuePair<Rail, float>> _dyingRails = new List<KeyValuePair<Rail, float>>();
public static Instance Log { get; private set; }
private static string BlockListPath => Path.Combine(MelonEnvironment.UserDataDirectory, "MagSlide_disabled_guns.txt");
private static string RailLibPath => Path.Combine(MelonEnvironment.UserDataDirectory, "MagSlide_rails.txt");
public override void OnInitializeMelon()
{
Log = ((MelonBase)this).LoggerInstance;
_cat = MelonPreferences.CreateCategory("MagSlide");
_enabled = _cat.CreateEntry<bool>("Enabled", true, "Realistic mag insertion: the mag only goes in when it is brought right up to the well", (string)null, false, false, (ValueValidator)null, (string)null);
_magSlide = _cat.CreateEntry<bool>("MagSlide", true, "Mag catches at the well mouth and has to be physically slid up into the gun", (string)null, false, false, (ValueValidator)null, (string)null);
_catch = _cat.CreateEntry<float>("CatchRange", 0.01f, "Capture bubble radius; the mag body adds ~7cm on top. Near zero = touch-the-well catch", (string)null, false, false, (ValueValidator)null, (string)null);
_depth = _cat.CreateEntry<float>("InsertDepth", 0.7f, "How far up the rail the mag must be pushed before it clicks in (fraction of the travel)", (string)null, false, false, (ValueValidator)null, (string)null);
if (_catch.Value > 0.08f || _catch.Value < 0.001f)
{
_catch.Value = 0.01f;
}
if (_depth.Value > 0.95f || _depth.Value < 0.4f)
{
_depth.Value = 0.7f;
}
_cat.SaveToFile(false);
LoadBlockList();
LoadSeatLib();
BuildMenu();
InstallHooks();
Hooking.OnLevelLoaded += delegate
{
CleanupForLevelChange();
};
Log.Msg("MagSlidingReimagined 1.5.0 loaded.");
}
public override void OnUpdate()
{
if (_enabled.Value || _magSlide.Value)
{
if (_magSlide.Value)
{
ManageTriggers();
}
ProcessDyingRails();
_scanAccum += Time.unscaledDeltaTime;
if (!(_scanAccum < _scanInterval))
{
_scanAccum = 0f;
ApplyToAll();
}
}
}
public override void OnFixedUpdate()
{
if (_magSlide.Value)
{
UpdateRails();
}
}
private static void CleanupForLevelChange()
{
foreach (Rec value in _known.Values)
{
try
{
if (value.Rail != null)
{
ReleaseRail(value, "level change");
}
}
catch
{
}
}
for (int num = _dyingRails.Count - 1; num >= 0; num--)
{
try
{
SetPairIgnores(_dyingRails[num].Key, ignore: false);
RestoreHandBodies(_dyingRails[num].Key);
}
catch
{
}
}
_dyingRails.Clear();
_plugSockets.Clear();
_known.Clear();
_candidates.Clear();
_railedPlugIds.Clear();
_scanInterval = 1f;
_appliedCount = -1;
_lastCount = -1;
}
private static void BuildMenu()
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
Page obj = Page.Root.CreatePage("MagSlidingReimagined", new Color(0.95f, 0.55f, 0.2f), 0, true);
BuildInfoMenu(obj);
BuildCatalogMenu(obj);
BuildSettingsMenu(obj);
obj.CreateFunction("MagSlidingReimagined 1.5.0 - by VRR", new Color(0.7f, 0.7f, 0.7f), (Action)delegate
{
Notify("MagSlidingReimagined 1.5.0 by VRR", (NotificationType)0);
});
}
private static void BuildInfoMenu(Page parent)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
parent.CreatePage("Info", new Color(1f, 0.85f, 0.3f), 0, true).CreateFunction("How This Mod Works", new Color(1f, 0.85f, 0.3f), (Action)delegate
{
Notify("Realistic Insert makes the mag only pull in when brought right up to the well. Mag Slide makes it catch at the well mouth and physically slide up until it clicks. Catalog lists every gun you've used - toggle one off to exempt it, or hit Recalibrate Slide if its insert feels off. Settings has Catch Range and Insert Depth for fine-tuning, plus Recalibrate All Guns to reset every gun's measurement at once.", (NotificationType)0, 15f);
});
}
private static void BuildCatalogMenu(Page parent)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
_weaponListPage = parent.CreatePage("Catalog", new Color(0.4f, 0.8f, 1f), 0, true);
_weaponListPage.CreateFunction("Scan For Guns", new Color(0.4f, 1f, 0.4f), (Action)delegate
{
int num = PopulateWeaponList();
Notify((num > 0) ? $"Added {num} gun(s) to the list." : "No new guns found - hold or fire the gun once, then scan again.", (NotificationType)3);
});
_weaponListPage.CreateFunction("What is 'Recalibrate Slide'?", new Color(0.7f, 0.7f, 0.7f), (Action)delegate
{
Notify("Every gun below has its own 'Recalibrate Slide' button. Use it if that gun's mag insert feels off - it wipes what was learned for just that gun so it re-measures next time you insert a mag. Not shotgun-specific, works for any gun.", (NotificationType)0);
});
PopulateWeaponList();
}
private static int PopulateWeaponList()
{
//IL_00e1: 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)
if (_weaponListPage == null)
{
return 0;
}
foreach (Rec value in _known.Values)
{
ResolveIdentity(value);
}
foreach (string key3 in _seatLib.Keys)
{
RememberGun(key3);
}
int num = 0;
for (int i = 0; i < _seenGuns.Count; i++)
{
string text = _seenGuns[i];
if (!_listedGuns.Contains(text))
{
_listedGuns.Add(text);
string key2 = text;
string text2 = text + " (" + ClassName(Classify(text)) + ")";
_weaponListPage.CreateBool(text2, Color.white, !_blocked.Contains(key2), (Action<bool>)delegate(bool v)
{
SetGunBlocked(key2, !v);
});
_weaponListPage.CreateFunction("Recalibrate Slide: " + text, new Color(1f, 0.8f, 0.3f), (Action)delegate
{
ClearLearnedRail(key2);
});
num++;
}
}
return num;
}
private static void BuildSettingsMenu(Page parent)
{
//IL_0015: 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_0061: 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_00e4: 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_015c: Unknown result type (might be due to invalid IL or missing references)
Page obj = parent.CreatePage("Settings", new Color(0.6f, 1f, 0.6f), 0, true);
obj.CreateBool("Realistic Insert", Color.green, _enabled.Value, (Action<bool>)delegate(bool v)
{
_enabled.Value = v;
_cat.SaveToFile(false);
Retune();
Notify(v ? "On - bring the mag right up to the well to insert it." : "Off - vanilla capture range restored.", (NotificationType)0);
});
obj.CreateBool("Mag Slide", Color.cyan, _magSlide.Value, (Action<bool>)delegate(bool v)
{
_magSlide.Value = v;
_cat.SaveToFile(false);
Retune();
Notify(v ? "On - the mag catches at the well mouth and slides up into the gun." : "Off - vanilla long-range mag capture restored.", (NotificationType)0);
});
obj.CreateFloat("Catch Range", Color.white, _catch.Value, 0.005f, 0.001f, 0.08f, (Action<float>)delegate(float v)
{
_catch.Value = v;
_cat.SaveToFile(false);
});
obj.CreateFloat("Insert Depth", Color.white, _depth.Value, 0.05f, 0.4f, 0.95f, (Action<float>)delegate(float v)
{
_depth.Value = Mathf.Clamp(v, 0.4f, 0.95f);
_cat.SaveToFile(false);
});
obj.CreateFunction("Reset Defaults", Color.red, (Action)delegate
{
_catch.Value = 0.01f;
_depth.Value = 0.7f;
_cat.SaveToFile(false);
Retune();
Notify("Settings reset to defaults.", (NotificationType)3);
});
obj.CreateFunction("Recalibrate All Guns", Color.red, (Action)delegate
{
ClearAllLearnedRails();
});
}
private static bool HasWord(string key, string[] words)
{
if (string.IsNullOrEmpty(key))
{
return false;
}
string text = key.ToLowerInvariant();
foreach (string text2 in words)
{
for (int num = text.IndexOf(text2, StringComparison.Ordinal); num >= 0; num = text.IndexOf(text2, num + 1, StringComparison.Ordinal))
{
bool num2 = num == 0 || !char.IsLetterOrDigit(text[num - 1]);
int num3 = num + text2.Length;
bool flag = num3 >= text.Length || !char.IsLetterOrDigit(text[num3]);
if (num2 && flag)
{
return true;
}
}
}
return false;
}
private static WeaponClass Classify(string key)
{
if (string.IsNullOrEmpty(key))
{
return WeaponClass.Other;
}
if (HasWord(key, SmgWords))
{
return WeaponClass.Smg;
}
if (HasWord(key, RifleWords))
{
return WeaponClass.Rifle;
}
if (HasWord(key, PistolWords))
{
return WeaponClass.Pistol;
}
return WeaponClass.Other;
}
private static string ClassName(WeaponClass c)
{
return c switch
{
WeaponClass.Pistol => "Pistols",
WeaponClass.Smg => "SMGs",
WeaponClass.Rifle => "Rifles",
_ => "Other",
};
}
private static void ResolveIdentity(Rec r)
{
if (r.IdentityKnown || (Object)(object)r.Socket == (Object)null)
{
return;
}
string text = GunModelKey((Component)(object)r.Socket);
if (!string.IsNullOrEmpty(text))
{
r.Key = text;
r.Platform = SocketPlatform(r.Socket);
r.Class = Classify(text);
if (r.Class == WeaponClass.Other && !string.IsNullOrEmpty(r.Platform))
{
r.Class = Classify(r.Platform);
}
r.IdentityKnown = true;
RememberGun(text);
}
}
private static void RememberGun(string key)
{
if (!string.IsNullOrEmpty(key) && !_seenGuns.Contains(key))
{
_seenGuns.Add(key);
}
}
private static bool IsAllowed(Rec r)
{
ResolveIdentity(r);
if (r.IdentityKnown)
{
return !_blocked.Contains(r.Key);
}
return true;
}
private static string CleanName(string name)
{
if (string.IsNullOrEmpty(name))
{
return null;
}
int num = name.LastIndexOf(" [", StringComparison.Ordinal);
if (num > 0)
{
name = name.Substring(0, num);
}
return name.Trim();
}
private static bool JunkName(string name)
{
if (string.IsNullOrEmpty(name))
{
return true;
}
string text = name.ToLowerInvariant();
for (int i = 0; i < JunkNames.Length; i++)
{
if (text.Contains(JunkNames[i]))
{
return true;
}
}
return false;
}
private static string GunModelKey(Component socketSide)
{
try
{
AmmoSocket val = ((Il2CppObjectBase)socketSide).TryCast<AmmoSocket>();
if ((Object)(object)val != (Object)null && (Object)(object)val.gun != (Object)null)
{
string text = CleanName(((Object)((Component)val.gun).gameObject).name);
if (!JunkName(text))
{
return text;
}
}
}
catch
{
}
try
{
Rigidbody componentInParent = socketSide.GetComponentInParent<Rigidbody>();
if ((Object)(object)componentInParent != (Object)null)
{
string text2 = CleanName(((Object)((Component)componentInParent).gameObject).name);
if (!JunkName(text2))
{
return text2;
}
}
}
catch
{
}
string text3 = null;
try
{
text3 = CleanName(((Object)socketSide.transform.root).name);
}
catch
{
}
if (!JunkName(text3))
{
return text3;
}
try
{
AmmoSocket val2 = ((Il2CppObjectBase)socketSide).TryCast<AmmoSocket>();
if ((Object)(object)val2 != (Object)null)
{
string text4 = SocketPlatform(val2);
if (!string.IsNullOrEmpty(text4))
{
return text4;
}
}
}
catch
{
}
return text3;
}
private static string SocketPlatform(AmmoSocket socket)
{
try
{
Gun gun = socket.gun;
if ((Object)(object)gun != (Object)null && (Object)(object)gun.defaultMagazine != (Object)null)
{
return gun.defaultMagazine.platform;
}
}
catch
{
}
return null;
}
private static void LoadBlockList()
{
try
{
if (!File.Exists(BlockListPath))
{
return;
}
string[] array = File.ReadAllLines(BlockListPath);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length > 0)
{
_blocked.Add(text);
RememberGun(text);
}
}
}
catch (Exception ex)
{
Log.Warning("disabled gun list load failed: " + ex.Message);
}
}
private static void SaveBlockList()
{
try
{
StringBuilder stringBuilder = new StringBuilder();
foreach (string item in _blocked)
{
stringBuilder.AppendLine(item);
}
File.WriteAllText(BlockListPath, stringBuilder.ToString());
}
catch
{
}
}
private static void SetGunBlocked(string key, bool blocked)
{
if (!string.IsNullOrEmpty(key))
{
if (blocked)
{
_blocked.Add(key);
}
else
{
_blocked.Remove(key);
}
SaveBlockList();
Retune();
}
}
private static string F(float v)
{
return v.ToString("R", CultureInfo.InvariantCulture);
}
private static float PF(string s)
{
return float.Parse(s, CultureInfo.InvariantCulture);
}
private static void LoadSeatLib()
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!File.Exists(RailLibPath))
{
return;
}
string[] array = File.ReadAllLines(RailLibPath);
foreach (string text in array)
{
try
{
string[] array2 = text.Split(new char[1] { '|' });
if (array2.Length == 15)
{
_seatLib[array2[0]] = new SeatData
{
SocketPosL = new Vector3(PF(array2[1]), PF(array2[2]), PF(array2[3])),
AxisL = new Vector3(PF(array2[4]), PF(array2[5]), PF(array2[6])),
RailLen = PF(array2[7]),
SeatMagPosL = new Vector3(PF(array2[8]), PF(array2[9]), PF(array2[10])),
SeatMagRotL = new Quaternion(PF(array2[11]), PF(array2[12]), PF(array2[13]), PF(array2[14]))
};
}
}
catch
{
}
}
if (_seatLib.Count > 0)
{
Log.Msg($"Loaded {_seatLib.Count} learned mag rail(s).");
}
}
catch (Exception ex)
{
Log.Warning("rail library load failed: " + ex.Message);
}
}
private static void SaveSeatLib()
{
try
{
StringBuilder stringBuilder = new StringBuilder();
foreach (KeyValuePair<string, SeatData> item in _seatLib)
{
SeatData value = item.Value;
stringBuilder.Append(item.Key).Append('|').Append(F(value.SocketPosL.x))
.Append('|')
.Append(F(value.SocketPosL.y))
.Append('|')
.Append(F(value.SocketPosL.z))
.Append('|')
.Append(F(value.AxisL.x))
.Append('|')
.Append(F(value.AxisL.y))
.Append('|')
.Append(F(value.AxisL.z))
.Append('|')
.Append(F(value.RailLen))
.Append('|')
.Append(F(value.SeatMagPosL.x))
.Append('|')
.Append(F(value.SeatMagPosL.y))
.Append('|')
.Append(F(value.SeatMagPosL.z))
.Append('|')
.Append(F(value.SeatMagRotL.x))
.Append('|')
.Append(F(value.SeatMagRotL.y))
.Append('|')
.Append(F(value.SeatMagRotL.z))
.Append('|')
.Append(F(value.SeatMagRotL.w))
.AppendLine();
}
File.WriteAllText(RailLibPath, stringBuilder.ToString());
}
catch
{
}
}
private static void TrySeatFromLibrary(Rec r)
{
//IL_0055: 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_0061: 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_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
try
{
if (r.HasSeat || (Object)(object)r.Socket == (Object)null)
{
return;
}
string text = GunModelKey((Component)(object)r.Socket);
if (text != null && _seatLib.TryGetValue(text, out var value))
{
Rigidbody componentInParent = ((Component)r.Socket).GetComponentInParent<Rigidbody>();
if (!((Object)(object)componentInParent == (Object)null))
{
r.GunRb = componentInParent;
r.SocketPosL = value.SocketPosL;
r.AxisL = value.AxisL;
r.RailLen = value.RailLen;
r.SeatMagPosL = value.SeatMagPosL;
r.SeatMagRotL = value.SeatMagRotL;
r.HasSeat = true;
}
}
}
catch
{
}
}
private static void ClearLearnedRail(string key)
{
if (string.IsNullOrEmpty(key))
{
return;
}
_seatLib.Remove(key);
foreach (Rec value in _known.Values)
{
if (value.Key == key)
{
value.HasSeat = false;
}
}
SaveSeatLib();
Notify(key + " will re-measure its slide next time you insert its mag.", (NotificationType)3);
}
private static void ClearAllLearnedRails()
{
_seatLib.Clear();
foreach (Rec value in _known.Values)
{
value.HasSeat = false;
}
SaveSeatLib();
Notify("Every gun will re-measure its slide as you insert its mag.", (NotificationType)3);
}
private static void Retune()
{
if (_enabled.Value || _magSlide.Value)
{
ApplyToAll();
}
else
{
RestoreAll();
}
}
private static float EngagedRadius(Rec r)
{
return Mathf.Min(r.OrigTriggerRadius, r.OrigEndDistance + 0.05f);
}
private static float EffectiveRailLen(Rec r)
{
return Mathf.Max(r.RailLen, 0.035f);
}
private static float CompleteAt(Rec r)
{
float num = Mathf.Clamp(_depth.Value, 0.4f, 0.95f);
float num2 = EffectiveRailLen(r);
return Mathf.Min(num2 - 0.01f, num2 * num);
}
private static float CatchRadius(Rec r)
{
return Mathf.Clamp(_catch.Value, 0.001f, 0.08f);
}
private static float LateralTolerance(Rec r)
{
return 0.02f;
}
private static float AngleGate(Rec r)
{
return 25f;
}
private static float CatchDepth(Rec r)
{
float num = CompleteAt(r);
return Mathf.Min(Mathf.Max(EffectiveRailLen(r) * 0.5f, 0.03f), num - 0.02f);
}
private static void SetTrigger(Rec r, bool on, float radius)
{
try
{
if (!((Object)(object)r.Trigger == (Object)null))
{
if (((Collider)r.Trigger).enabled != on)
{
((Collider)r.Trigger).enabled = on;
}
if (Mathf.Abs(radius - r.AppliedRadius) > 0.0001f)
{
r.Trigger.radius = radius;
r.AppliedRadius = radius;
}
}
}
catch
{
}
}
private static void ManageTriggers()
{
if (!_patchesOk)
{
return;
}
foreach (Rec value in _known.Values)
{
try
{
if ((Object)(object)value.Socket == (Object)null || (Object)(object)value.Trigger == (Object)null || !IsAllowed(value))
{
continue;
}
if (value.Rail != null)
{
value.WasLocked = false;
continue;
}
float num = CatchRadius(value);
bool flag = (Object)(object)((Socket)value.Socket).LockedPlug != (Object)null;
if (value.WasLocked && !flag)
{
value.WasLocked = false;
value.PlugCaptured = false;
SetTrigger(value, !value.HasSeat, Mathf.Min(value.OrigTriggerRadius, num));
TryRelatchEjected(value);
continue;
}
value.WasLocked = flag;
if (flag || value.PlugCaptured)
{
SetTrigger(value, on: true, EngagedRadius(value));
}
else if (value.HasSeat)
{
SetTrigger(value, on: false, Mathf.Min(value.OrigTriggerRadius, num));
}
else
{
SetTrigger(value, on: true, Mathf.Min(value.OrigTriggerRadius, num));
}
}
catch
{
}
}
}
private static void ApplyToAll()
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
try
{
Il2CppArrayBase<AmmoSocket> val = Resources.FindObjectsOfTypeAll<AmmoSocket>();
if (val == null)
{
if (_lastCount != 0)
{
Log.Warning("MagSlide: AmmoSocket search returned null.");
_lastCount = 0;
}
return;
}
int length = val.Length;
if (length != _lastCount)
{
Log.Msg($"MagSlide: {length} mag well(s) loaded in memory.");
_lastCount = length;
}
int num = 0;
for (int i = 0; i < length; i++)
{
AmmoSocket val2 = val[i];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
try
{
Scene scene = ((Component)val2).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
num++;
Register(val2);
ApplyOne(val2);
}
}
catch
{
}
}
RefreshPlugCache();
PruneCaches();
_scanInterval = ((num != _appliedCount) ? 1f : Mathf.Min(_scanInterval * 1.5f, 5f));
_appliedCount = num;
}
catch (Exception ex)
{
Log.Warning("Socket sweep failed: " + ex.Message);
}
}
private static void PruneCaches()
{
List<int> list = null;
foreach (KeyValuePair<int, Rec> item in _known)
{
if ((Object)(object)item.Value.Socket == (Object)null)
{
if (list == null)
{
list = new List<int>();
}
list.Add(item.Key);
}
}
if (list != null)
{
for (int i = 0; i < list.Count; i++)
{
if (_known.TryGetValue(list[i], out var _))
{
_known.Remove(list[i]);
}
}
}
float unscaledTime = Time.unscaledTime;
if (_plugSockets.Count <= 32)
{
return;
}
List<int> list2 = new List<int>();
foreach (KeyValuePair<int, KeyValuePair<AmmoSocket, float>> plugSocket in _plugSockets)
{
if (unscaledTime - plugSocket.Value.Value > 5f)
{
list2.Add(plugSocket.Key);
}
}
for (int j = 0; j < list2.Count; j++)
{
_plugSockets.Remove(list2[j]);
}
}
private static void Register(AmmoSocket s)
{
int instanceID = ((Object)s).GetInstanceID();
if (_known.ContainsKey(instanceID))
{
return;
}
Rec rec = new Rec
{
Socket = s
};
try
{
rec.OrigInfluence = ((Socket)s).influenceRadius;
}
catch
{
}
try
{
rec.OrigEndDistance = ((Socket)s).endDistance;
}
catch
{
}
try
{
Il2CppArrayBase<SphereCollider> components = ((Component)s).GetComponents<SphereCollider>();
if (components != null)
{
for (int i = 0; i < components.Length; i++)
{
SphereCollider val = components[i];
if (!((Object)(object)val == (Object)null) && ((Collider)val).isTrigger)
{
rec.Trigger = val;
rec.OrigTriggerRadius = val.radius;
break;
}
}
}
}
catch
{
}
_known[instanceID] = rec;
}
private static void ApplyOne(AmmoSocket s)
{
int instanceID = ((Object)s).GetInstanceID();
if (!_known.TryGetValue(instanceID, out var value))
{
return;
}
bool flag = IsAllowed(value);
bool num = _enabled.Value && flag;
bool flag2 = _magSlide.Value && flag;
if (num)
{
((Socket)s).influenceRadius = Mathf.Max(0.05f, value.OrigInfluence * 0.25f);
}
else
{
((Socket)s).influenceRadius = value.OrigInfluence;
}
((Socket)s).endDistance = value.OrigEndDistance;
if (flag2)
{
return;
}
if (value.Rail != null)
{
ReleaseRail(value, "mode off");
}
if (!((Object)(object)value.Trigger != (Object)null) || !(value.AppliedRadius >= 0f))
{
return;
}
try
{
value.Trigger.radius = value.OrigTriggerRadius;
((Collider)value.Trigger).enabled = true;
value.AppliedRadius = -1f;
}
catch
{
}
}
private static void RestoreAll()
{
foreach (Rec value in _known.Values)
{
try
{
if (value.Rail != null)
{
ReleaseRail(value, "restore");
}
if (!((Object)(object)value.Socket == (Object)null))
{
((Socket)value.Socket).influenceRadius = value.OrigInfluence;
((Socket)value.Socket).endDistance = value.OrigEndDistance;
if ((Object)(object)value.Trigger != (Object)null)
{
value.Trigger.radius = value.OrigTriggerRadius;
((Collider)value.Trigger).enabled = true;
value.AppliedRadius = -1f;
}
}
}
catch
{
}
}
}
private static void RefreshPlugCache()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
_plugs.Clear();
try
{
Il2CppArrayBase<AmmoPlug> val = Resources.FindObjectsOfTypeAll<AmmoPlug>();
if (val == null)
{
return;
}
for (int i = 0; i < val.Length; i++)
{
AmmoPlug val2 = val[i];
if ((Object)(object)val2 == (Object)null)
{
continue;
}
try
{
Scene scene = ((Component)val2).gameObject.scene;
if (((Scene)(ref scene)).IsValid())
{
_plugs.Add(val2);
}
}
catch
{
}
}
}
catch
{
}
}
private static bool PlatformMatches(Rec r, AmmoPlug plug)
{
try
{
Gun gun = r.Socket.gun;
if ((Object)(object)gun == (Object)null || (Object)(object)gun.defaultMagazine == (Object)null)
{
return true;
}
Magazine magazine = plug.magazine;
if ((Object)(object)magazine == (Object)null)
{
return true;
}
MagazineData magazineData = magazine.magazineState.magazineData;
if ((Object)(object)magazineData == (Object)null)
{
return true;
}
string platform = gun.defaultMagazine.platform;
string platform2 = magazineData.platform;
if (string.IsNullOrEmpty(platform) || string.IsNullOrEmpty(platform2))
{
return true;
}
return platform == platform2;
}
catch
{
return true;
}
}
private static bool IsHeld(AmmoPlug plug)
{
try
{
InteractableHost host = ((Plug)plug).host;
return (Object)(object)host != (Object)null && (Object)(object)host.GetHand(0) != (Object)null;
}
catch
{
return false;
}
}
private static bool RailedAnywhere(AmmoPlug plug)
{
try
{
return (Object)(object)plug != (Object)null && _railedPlugIds.Contains(((Object)plug).GetInstanceID());
}
catch
{
return false;
}
}
private static void Buzz(AmmoPlug plug, BuzzKind kind)
{
try
{
InteractableHost val = (((Object)(object)plug != (Object)null) ? ((Plug)plug).host : null);
Hand val2 = (((Object)(object)val != (Object)null) ? val.GetHand(0) : null);
if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Controller == (Object)null)
{
return;
}
Haptor haptor = val2.Controller.haptor;
if (!((Object)(object)haptor == (Object)null))
{
switch (kind)
{
case BuzzKind.Catch:
haptor.Haptic_Tap();
break;
case BuzzKind.Slide:
haptor.Haptic_SlideFriction();
break;
case BuzzKind.Insert:
haptor.Haptic_WepMagInsert();
break;
}
}
}
catch
{
}
}
private static List<Collider> CollectGunHandColliders(Rec r)
{
List<Collider> list = new List<Collider>();
try
{
Gun gun = r.Socket.gun;
if ((Object)(object)gun == (Object)null || (Object)(object)gun.triggerGrip == (Object)null)
{
return list;
}
Hand hand = gun.triggerGrip.GetHand();
if ((Object)(object)hand == (Object)null)
{
return list;
}
try
{
Il2CppArrayBase<Collider> componentsInChildren = ((Component)hand).GetComponentsInChildren<Collider>(true);
if (componentsInChildren != null)
{
foreach (Collider item in componentsInChildren)
{
if ((Object)(object)item != (Object)null)
{
list.Add(item);
}
}
}
}
catch
{
}
try
{
PhysHand physHand = hand.physHand;
if ((Object)(object)physHand != (Object)null)
{
if ((Object)(object)physHand.handCol != (Object)null && !list.Contains((Collider)(object)physHand.handCol))
{
list.Add((Collider)(object)physHand.handCol);
}
if ((Object)(object)physHand.fingersCol != (Object)null && !list.Contains((Collider)(object)physHand.fingersCol))
{
list.Add((Collider)(object)physHand.fingersCol);
}
if ((Object)(object)physHand.cUpper != (Object)null && !list.Contains((Collider)(object)physHand.cUpper))
{
list.Add((Collider)(object)physHand.cUpper);
}
if ((Object)(object)physHand.cLower != (Object)null && !list.Contains((Collider)(object)physHand.cLower))
{
list.Add((Collider)(object)physHand.cLower);
}
}
}
catch
{
}
}
catch
{
}
return list;
}
private static void SetPairIgnores(Rail rail, bool ignore)
{
if (rail == null)
{
return;
}
try
{
Collider[] gunCols;
if (rail.GunCols != null && rail.MagCols != null)
{
gunCols = rail.GunCols;
foreach (Collider val in gunCols)
{
if ((Object)(object)val == (Object)null || val.isTrigger)
{
continue;
}
Collider[] magCols = rail.MagCols;
foreach (Collider val2 in magCols)
{
if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger)
{
try
{
Physics.IgnoreCollision(val2, val, ignore);
}
catch
{
}
}
}
if (!ignore || rail.HandCols == null)
{
continue;
}
magCols = rail.HandCols;
foreach (Collider val3 in magCols)
{
if (!((Object)(object)val3 == (Object)null) && !val3.isTrigger)
{
try
{
Physics.IgnoreCollision(val3, val, true);
}
catch
{
}
}
}
}
}
if (rail.GunHandCols != null && rail.MagCols != null)
{
foreach (Collider gunHandCol in rail.GunHandCols)
{
if ((Object)(object)gunHandCol == (Object)null || gunHandCol.isTrigger)
{
continue;
}
gunCols = rail.MagCols;
foreach (Collider val4 in gunCols)
{
if (!((Object)(object)val4 == (Object)null) && !val4.isTrigger)
{
try
{
Physics.IgnoreCollision(val4, gunHandCol, ignore);
}
catch
{
}
}
}
}
}
if (ignore || rail.HandCols == null || rail.GunCols == null)
{
return;
}
gunCols = rail.GunCols;
foreach (Collider val5 in gunCols)
{
if ((Object)(object)val5 == (Object)null || val5.isTrigger)
{
continue;
}
Collider[] magCols = rail.HandCols;
foreach (Collider val6 in magCols)
{
if (!((Object)(object)val6 == (Object)null) && !val6.isTrigger)
{
try
{
Physics.IgnoreCollision(val6, val5, false);
}
catch
{
}
}
}
}
}
catch
{
}
}
private static void ProcessDyingRails()
{
if (_dyingRails.Count == 0)
{
return;
}
for (int num = _dyingRails.Count - 1; num >= 0; num--)
{
if (Time.unscaledTime >= _dyingRails[num].Value)
{
Rail key = _dyingRails[num].Key;
_dyingRails.RemoveAt(num);
SetPairIgnores(key, ignore: false);
RestoreHandBodies(key);
}
}
}
private static void RestoreHandBodies(Rail rail)
{
try
{
if (rail.HandRbs == null)
{
return;
}
foreach (Rigidbody handRb in rail.HandRbs)
{
try
{
if ((Object)(object)handRb != (Object)null)
{
handRb.detectCollisions = true;
}
}
catch
{
}
}
}
catch
{
}
}
private static void PurgeStrayJoints(Rail rail, Rigidbody magRb)
{
try
{
Il2CppArrayBase<ConfigurableJoint> components = ((Component)magRb).GetComponents<ConfigurableJoint>();
if (components == null)
{
return;
}
for (int i = 0; i < components.Length; i++)
{
ConfigurableJoint val = components[i];
if (!((Object)(object)val == (Object)null) && (rail == null || !((Object)(object)rail.Joint != (Object)null) || ((Object)val).GetInstanceID() != ((Object)rail.Joint).GetInstanceID()) && !((Object)(object)((Joint)val).connectedBody != (Object)null))
{
Object.Destroy((Object)(object)val);
}
}
}
catch
{
}
}
private static void CollectCandidates()
{
_candidates.Clear();
for (int i = 0; i < _plugs.Count; i++)
{
AmmoPlug val = _plugs[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
Magazine magazine = val.magazine;
if (!((Object)(object)magazine == (Object)null) && ((Component)magazine).gameObject.activeInHierarchy && !magazine.isMagazineInserted && IsHeld(val) && !RailedAnywhere(val))
{
_candidates.Add(val);
}
}
catch
{
}
}
}
private static void TryLatchCandidate(Rec r)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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_00be: 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_00c9: 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)
Transform transform = ((Component)r.GunRb).transform;
float num = CatchDepth(r);
float num2 = LateralTolerance(r);
float num3 = AngleGate(r);
for (int i = 0; i < _candidates.Count; i++)
{
AmmoPlug val = _candidates[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
Vector3 val2 = transform.InverseTransformPoint(((Component)val).transform.position) - r.SocketPosL;
float num4 = Vector3.Dot(val2, r.AxisL);
if (!(num4 >= -0.03f) || !(num4 <= num))
{
continue;
}
Vector3 val3 = val2 - r.AxisL * num4;
if (((Vector3)(ref val3)).magnitude <= num2)
{
Magazine magazine = val.magazine;
if (!((Object)(object)magazine == (Object)null) && PlatformMatches(r, val) && Quaternion.Angle(transform.rotation * r.SeatMagRotL, ((Component)magazine).transform.rotation) <= num3)
{
Latch(r, val);
_candidates.RemoveAt(i);
break;
}
}
}
catch
{
}
}
}
private static void UpdateRails()
{
if (!_patchesOk)
{
return;
}
CollectCandidates();
bool flag = _candidates.Count > 0;
float unscaledTime = Time.unscaledTime;
foreach (Rec value in _known.Values)
{
try
{
if (!IsAllowed(value))
{
if (value.Rail != null)
{
ReleaseRail(value, "weapon disabled");
}
}
else if (value.Rail != null)
{
TickRail(value);
}
else
{
if (!flag)
{
continue;
}
if (!value.HasSeat)
{
TrySeatFromLibrary(value);
}
if (value.HasSeat && !((Object)(object)value.Socket == (Object)null) && !((Object)(object)value.Trigger == (Object)null))
{
if ((Object)(object)value.GunRb == (Object)null)
{
value.HasSeat = false;
}
else if (unscaledTime >= value.NoRelatchUntil && (Object)(object)((Socket)value.Socket).LockedPlug == (Object)null && !value.PlugCaptured)
{
TryLatchCandidate(value);
}
}
continue;
}
}
catch
{
}
}
}
private static void Latch(Rec r, AmmoPlug plug)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//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_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01de: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
Magazine magazine = plug.magazine;
Transform transform = ((Component)magazine).transform;
Rigidbody component = ((Component)magazine).GetComponent<Rigidbody>();
if ((Object)(object)component == (Object)null)
{
return;
}
Transform transform2 = ((Component)r.GunRb).transform;
Transform transform3 = ((Component)plug).transform;
PurgeStrayJoints(null, component);
float num = Vector3.Dot(transform2.InverseTransformPoint(transform3.position) - r.SocketPosL, r.AxisL);
num = Mathf.Clamp(num, 0f, EffectiveRailLen(r));
Collider[] magCols = null;
Collider[] gunCols = null;
Collider[] handCols = null;
List<Rigidbody> list = null;
List<Collider> gunHandCols = null;
Hand val = null;
try
{
magCols = Il2CppArrayBase<Collider>.op_Implicit(((Component)magazine).GetComponentsInChildren<Collider>(true));
gunCols = Il2CppArrayBase<Collider>.op_Implicit(((Component)r.GunRb).GetComponentsInChildren<Collider>(true));
gunHandCols = CollectGunHandColliders(r);
try
{
val = (((Object)(object)((Plug)plug).host != (Object)null) ? ((Plug)plug).host.GetHand(0) : null);
if ((Object)(object)val != (Object)null)
{
handCols = Il2CppArrayBase<Collider>.op_Implicit(((Component)val).GetComponentsInChildren<Collider>(true));
list = new List<Rigidbody>();
Rigidbody componentInParent = ((Component)val).GetComponentInParent<Rigidbody>();
if ((Object)(object)componentInParent != (Object)null)
{
list.Add(componentInParent);
}
Il2CppArrayBase<Rigidbody> componentsInChildren = ((Component)val).GetComponentsInChildren<Rigidbody>(false);
if (componentsInChildren != null)
{
foreach (Rigidbody item in componentsInChildren)
{
if ((Object)(object)item != (Object)null && !list.Contains(item))
{
list.Add(item);
}
}
}
foreach (Rigidbody item2 in list)
{
try
{
item2.detectCollisions = false;
}
catch
{
}
}
}
}
catch
{
}
}
catch
{
}
ConfigurableJoint val2 = ((Component)component).gameObject.AddComponent<ConfigurableJoint>();
((Joint)val2).connectedBody = r.GunRb;
Vector3 val3 = (((Joint)val2).axis = transform.InverseTransformDirection(transform2.TransformDirection(r.AxisL)));
Vector3 val5 = Vector3.Cross(val3, Vector3.up);
if (((Vector3)(ref val5)).sqrMagnitude < 0.001f)
{
val5 = Vector3.Cross(val3, Vector3.right);
}
val2.secondaryAxis = ((Vector3)(ref val5)).normalized;
val2.xMotion = (ConfigurableJointMotion)2;
val2.yMotion = (ConfigurableJointMotion)0;
val2.zMotion = (ConfigurableJointMotion)0;
val2.angularXMotion = (ConfigurableJointMotion)0;
val2.angularYMotion = (ConfigurableJointMotion)0;
val2.angularZMotion = (ConfigurableJointMotion)0;
((Joint)val2).enableCollision = false;
((Joint)val2).enablePreprocessing = false;
((Joint)val2).autoConfigureConnectedAnchor = false;
try
{
((Collider)r.Trigger).enabled = false;
}
catch
{
}
float num2 = CompleteAt(r);
r.Rail = new Rail
{
Joint = val2,
Mag = magazine,
MagRb = component,
Plug = plug,
PlugT = transform3,
MagCols = magCols,
GunCols = gunCols,
HandCols = handCols,
HandRbs = list,
GunHandCols = gunHandCols,
Armed = (num < num2 - 0.015f),
LatchTime = Time.unscaledTime,
LastT = num
};
_railedPlugIds.Add(((Object)plug).GetInstanceID());
SetPairIgnores(r.Rail, ignore: true);
Buzz(plug, BuzzKind.Catch);
}
private static void TickRail(Rec r)
{
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0301: Unknown result type (might be due to invalid IL or missing references)
//IL_0345: Unknown result type (might be due to invalid IL or missing references)
//IL_034a: Unknown result type (might be due to invalid IL or missing references)
//IL_035a: Unknown result type (might be due to invalid IL or missing references)
//IL_035f: 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_007a: 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_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: 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_00d0: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: 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_0113: 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_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
Rail rail = r.Rail;
if ((Object)(object)rail.Joint == (Object)null || (Object)(object)rail.Mag == (Object)null || (Object)(object)rail.PlugT == (Object)null || (Object)(object)r.GunRb == (Object)null || !((Component)rail.Mag).gameObject.activeInHierarchy)
{
ReleaseRail(r, "stale");
return;
}
Transform transform = ((Component)r.GunRb).transform;
Vector3 val = transform.InverseTransformPoint(rail.PlugT.position) - r.SocketPosL;
float num = Vector3.Dot(val, r.AxisL);
float num2 = CompleteAt(r);
float num3 = EffectiveRailLen(r);
if (num > num3)
{
Vector3 val2 = transform.TransformDirection(r.AxisL);
try
{
Rigidbody magRb = rail.MagRb;
magRb.position -= val2 * (num - num3);
float num4 = Vector3.Dot(rail.MagRb.velocity - r.GunRb.velocity, val2);
if (num4 > 0f)
{
Rigidbody magRb2 = rail.MagRb;
magRb2.velocity -= val2 * num4;
}
}
catch
{
}
num = num3;
}
Vector3 val3 = val - r.AxisL * num;
float magnitude = ((Vector3)(ref val3)).magnitude;
if (magnitude > 0.0005f)
{
try
{
float num5 = Mathf.Min(magnitude, 0.06f * Time.deltaTime);
ConfigurableJoint joint = rail.Joint;
((Joint)joint).connectedAnchor = ((Joint)joint).connectedAnchor - val3 / magnitude * num5;
}
catch
{
}
}
float num6 = Mathf.Abs(num - rail.LastT);
if (num6 > 0.006f && Time.unscaledTime >= rail.NextBuzz)
{
float num7 = num6 / Mathf.Max(Time.deltaTime, 0.0001f);
rail.NextBuzz = Time.unscaledTime + Mathf.Lerp(0.09f, 0.035f, Mathf.Clamp01(num7 / 0.6f));
Buzz(rail.Plug, BuzzKind.Slide);
}
rail.LastT = num;
if (!rail.Armed && (num < num2 - 0.015f || Time.unscaledTime - rail.LatchTime > 0.35f))
{
rail.Armed = true;
}
if (Time.unscaledTime >= rail.NextTelem)
{
rail.NextTelem = Time.unscaledTime + 0.75f;
PurgeStrayJoints(rail, rail.MagRb);
SetPairIgnores(rail, ignore: true);
try
{
if (rail.HandRbs != null)
{
foreach (Rigidbody handRb in rail.HandRbs)
{
try
{
if ((Object)(object)handRb != (Object)null)
{
handRb.detectCollisions = false;
}
}
catch
{
}
}
}
}
catch
{
}
}
if (rail.Armed && num < num2)
{
float num8 = num2 - num;
float num9 = Mathf.Max(num3 * 0.12f, 0.01f);
if (num8 < num9)
{
try
{
Vector3 val4 = transform.TransformDirection(r.AxisL);
float num10 = Mathf.Clamp01(1f - num8 / num9);
float num11 = num10 * num10 * (3f - 2f * num10);
float num12 = Mathf.Lerp(0.01f, 0.05f, num11);
Rigidbody magRb3 = rail.MagRb;
magRb3.velocity += val4 * (num12 * Time.deltaTime * 60f);
}
catch
{
}
if (!rail.NearBuzzed && num8 < num9 * 0.5f)
{
rail.NearBuzzed = true;
Buzz(rail.Plug, BuzzKind.Catch);
}
}
}
if (rail.Armed && num >= num2)
{
AmmoPlug plug = rail.Plug;
AmmoSocket socket = r.Socket;
ReleaseRail(r, "top", 0.4f);
r.PlugCaptured = true;
SetTrigger(r, on: true, EngagedRadius(r));
try
{
((AlignPlug)plug).ForceInSocket((Socket)(object)socket);
}
catch
{
}
Buzz(plug, BuzzKind.Insert);
}
else if (num < -0.040000003f)
{
AmmoPlug plug2 = rail.Plug;
ReleaseRail(r, "pulled off");
r.NoRelatchUntil = Time.unscaledTime + 0.6f;
Buzz(plug2, BuzzKind.Catch);
}
}
private static void ReleaseRail(Rec r, string why, float deferRestore = 0f)
{
Rail rail = r.Rail;
r.Rail = null;
if (rail == null)
{
return;
}
try
{
if ((Object)(object)rail.Plug != (Object)null)
{
_railedPlugIds.Remove(((Object)rail.Plug).GetInstanceID());
}
}
catch
{
}
try
{
if ((Object)(object)rail.Joint != (Object)null)
{
Object.Destroy((Object)(object)rail.Joint);
}
}
catch
{
}
if (deferRestore > 0f)
{
_dyingRails.Add(new KeyValuePair<Rail, float>(rail, Time.unscaledTime + deferRestore));
return;
}
SetPairIgnores(rail, ignore: false);
RestoreHandBodies(rail);
}
private static void TryRelatchEjected(Rec r)
{
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: 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_00a1: 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_00ca: 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_00da: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!r.HasSeat || r.Rail != null || (Object)(object)r.LastMag == (Object)null || (Object)(object)r.GunRb == (Object)null)
{
return;
}
Magazine lastMag = r.LastMag;
if (!((Component)lastMag).gameObject.activeInHierarchy || lastMag.isMagazineInserted)
{
return;
}
AmmoPlug magazinePlug = lastMag.magazinePlug;
if (!((Object)(object)magazinePlug == (Object)null) && !RailedAnywhere(magazinePlug))
{
Transform transform = ((Component)r.GunRb).transform;
float num = Vector3.Dot(transform.InverseTransformPoint(((Component)magazinePlug).transform.position) - r.SocketPosL, r.AxisL);
if (num >= -0.045f && num <= EffectiveRailLen(r) + 0.03f && Quaternion.Angle(transform.rotation * r.SeatMagRotL, ((Component)lastMag).transform.rotation) <= AngleGate(r) + 10f)
{
Latch(r, magazinePlug);
}
}
}
catch
{
}
}
private static void RecordSeat(AmmoSocket socket, AmmoPlug plug)
{
//IL_001a: 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_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: 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_0135: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: 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_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_021d: Unknown result type (might be due to invalid IL or missing references)
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
//IL_023c: Unknown result type (might be due to invalid IL or missing references)
//IL_0241: Unknown result type (might be due to invalid IL or missing references)
//IL_01b7: 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_01c2: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!_known.TryGetValue(((Object)socket).GetInstanceID(), out var value))
{
try
{
Scene scene = ((Component)socket).gameObject.scene;
if (!((Scene)(ref scene)).IsValid())
{
return;
}
}
catch
{
return;
}
Register(socket);
if (!_known.TryGetValue(((Object)socket).GetInstanceID(), out value))
{
return;
}
}
Magazine magazine = plug.magazine;
if ((Object)(object)magazine == (Object)null)
{
return;
}
Rigidbody componentInParent = ((Component)socket).GetComponentInParent<Rigidbody>();
if ((Object)(object)componentInParent == (Object)null)
{
return;
}
Transform transform = ((Component)componentInParent).transform;
Vector3 val = transform.InverseTransformPoint(((Component)socket).transform.position);
Transform endTransform = ((Socket)socket).endTransform;
Vector3 val2 = transform.InverseTransformPoint(((Object)(object)endTransform != (Object)null) ? endTransform.position : ((Component)plug).transform.position) - val;
float magnitude = ((Vector3)(ref val2)).magnitude;
ResolveIdentity(value);
if (!IsAllowed(value) || !(magnitude >= 0.03f) || !(magnitude <= 0.4f))
{
return;
}
value.GunRb = componentInParent;
value.SocketPosL = val;
value.AxisL = val2 / magnitude;
value.RailLen = magnitude;
value.SeatMagPosL = transform.InverseTransformPoint(((Component)magazine).transform.position);
value.SeatMagRotL = Quaternion.Inverse(transform.rotation) * ((Component)magazine).transform.rotation;
value.LastMag = magazine;
value.HasSeat = true;
string text = value.Key ?? GunModelKey((Component)(object)socket);
if (text == null)
{
return;
}
bool flag = true;
int num;
if (_seatLib.TryGetValue(text, out var value2))
{
if (!(Mathf.Abs(value2.RailLen - value.RailLen) > 0.005f))
{
Vector3 val3 = value2.SocketPosL - value.SocketPosL;
if (!(((Vector3)(ref val3)).sqrMagnitude > 2.5E-05f))
{
val3 = value2.SeatMagPosL - value.SeatMagPosL;
num = ((((Vector3)(ref val3)).sqrMagnitude > 2.5E-05f) ? 1 : 0);
goto IL_01fc;
}
}
num = 1;
goto IL_01fc;
}
goto IL_01fe;
IL_01fe:
_seatLib[text] = new SeatData
{
SocketPosL = value.SocketPosL,
AxisL = value.AxisL,
RailLen = value.RailLen,
SeatMagPosL = value.SeatMagPosL,
SeatMagRotL = value.SeatMagRotL
};
if (flag)
{
SaveSeatLib();
}
return;
IL_01fc:
flag = (byte)num != 0;
goto IL_01fe;
}
catch
{
}
}
private static void InstallHooks()
{
bool num = TryPatch(typeof(AmmoSocket), "OnPlugEnter", "HookPlugEnter");
bool flag = TryPatch(typeof(AmmoSocket), "OnPlugExit", "HookPlugExit");
_patchesOk = num && flag;
if (!_patchesOk)
{
Log.Warning("capture hooks failed — Mag Slide trigger crush disabled (vanilla capture).");
}
TryPatch(typeof(AmmoSocket), "OnPlugLocked", "HookPlugLocked");
TryPatch(typeof(AlignPlug), "InsertPlug", "HookInsertPlug");
TryPatch(typeof(AmmoPlug), "OnPlugInsertComplete", "HookPlugSeated");
}
private static bool TryPatch(Type type, string method, string postfixName)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
try
{
MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
HarmonyMethod val = new HarmonyMethod(typeof(Mod), postfixName, (Type[])null);
((MelonBase)Melon<Mod>.Instance).HarmonyInstance.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
return true;
}
catch (Exception ex)
{
Log.Warning("hooks: couldn't patch " + type.Name + "." + method + ": " + ex.Message);
return false;
}
}
private static void RememberSocket(AmmoSocket socket, Plug plug)
{
try
{
AmmoPlug val = (((Object)(object)plug == (Object)null) ? null : ((Il2CppObjectBase)plug).TryCast<AmmoPlug>());
if ((Object)(object)val != (Object)null && (Object)(object)socket != (Object)null)
{
_plugSockets[((Object)val).GetInstanceID()] = new KeyValuePair<AmmoSocket, float>(socket, Time.unscaledTime);
}
}
catch
{
}
}
private static AmmoSocket SocketFor(AmmoPlug plug)
{
try
{
Socket lastSocket = ((AlignPlug)plug)._lastSocket;
if ((Object)(object)lastSocket != (Object)null)
{
AmmoSocket val = ((Il2CppObjectBase)lastSocket).TryCast<AmmoSocket>();
if ((Object)(object)val != (Object)null)
{
return val;
}
}
}
catch
{
}
try
{
if (_plugSockets.TryGetValue(((Object)plug).GetInstanceID(), out var value) && Time.unscaledTime - value.Value <= 2f && (Object)(object)value.Key != (Object)null)
{
return value.Key;
}
}
catch
{
}
return null;
}
public static void HookPlugEnter(AmmoSocket __instance, Plug plug)
{
try
{
RememberSocket(__instance, plug);
if (!_known.TryGetValue(((Object)__instance).GetInstanceID(), out var value) || !((Object)(object)value.Trigger != (Object)null) || value.Rail != null)
{
return;
}
value.PlugCaptured = true;
if (_magSlide.Value)
{
try
{
float num = EngagedRadius(value);
value.Trigger.radius = num;
value.AppliedRadius = num;
return;
}
catch
{
return;
}
}
}
catch
{
}
}
public static void HookPlugExit(AmmoSocket __instance, Plug plug)
{
try
{
if (_known.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
value.PlugCaptured = false;
}
}
catch
{
}
}
public static void HookPlugLocked(AmmoSocket __instance, Plug plug)
{
try
{
RememberSocket(__instance, plug);
AmmoPlug val = (((Object)(object)plug == (Object)null) ? null : ((Il2CppObjectBase)plug).TryCast<AmmoPlug>());
if ((Object)(object)val != (Object)null)
{
RecordSeat(__instance, val);
}
}
catch
{
}
}
public static void HookInsertPlug(AlignPlug __instance, Socket socket)
{
try
{
AmmoPlug val = (((Object)(object)__instance == (Object)null) ? null : ((Il2CppObjectBase)__instance).TryCast<AmmoPlug>());
if ((Object)(object)val != (Object)null)
{
AmmoSocket val2 = (((Object)(object)socket == (Object)null) ? null : ((Il2CppObjectBase)socket).TryCast<AmmoSocket>());
if ((Object)(object)val2 != (Object)null)
{
RememberSocket(val2, (Plug)(object)val);
}
}
}
catch
{
}
}
public static void HookPlugSeated(AmmoPlug __instance)
{
try
{
AmmoSocket val = SocketFor(__instance);
if ((Object)(object)val != (Object)null)
{
RecordSeat(val, __instance);
}
}
catch
{
}
}
internal static void Notify(string message, NotificationType type)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
Notify(message, type, 2.5f);
}
internal static void Notify(string message, NotificationType type, float seconds)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: 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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: 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_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
try
{
Notifier.Send(new Notification
{
Title = NotificationText.op_Implicit("MagSlidingReimagined"),
Message = NotificationText.op_Implicit(message),
PopupLength = seconds,
Type = type
});
}
catch
{
}
}
}
}