using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using GunTweaker;
using HarmonyLib;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppSLZ.Marrow.Data;
using Il2CppSLZ.Marrow.Pool;
using Il2CppSLZ.Marrow.Warehouse;
using Il2CppSystem.Collections.Generic;
using LabFusion.SDK.Gamemodes;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Tomlet;
using Tomlet.Models;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("GunTweaker")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany(null)]
[assembly: AssemblyProduct("GunTweaker")]
[assembly: AssemblyCopyright("Created by Adi")]
[assembly: AssemblyTrademark(null)]
[assembly: ComVisible(false)]
[assembly: AssemblyFileVersion("1.1.4")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: MelonInfo(typeof(global::GunTweaker.GunTweaker), "GunTweaker", "1.1.4", "Adi", null)]
[assembly: MelonOptionalDependencies(new string[] { "LabFusion" })]
[assembly: MelonGame(null, null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("1.1.4.0")]
namespace GunTweaker;
public static class FiremodeGarbage
{
public enum Firemode
{
Automatic,
SemiAutomatic,
BoltAction,
Burst,
BinaryTrigger
}
[HarmonyPatch(typeof(Gun), "OnFire")]
public static class GunPatch4000
{
public static void Prefix(Gun __instance)
{
if (GunTweaker.TryGetGunInfo(__instance, out var info))
{
info.ApplyTweaks(__instance);
}
}
public static void Postfix(Gun __instance)
{
if (!GunTweaker.TryGetGunInfo(__instance, out var info) || coroutines.ContainsKey(((Object)__instance).GetInstanceID()))
{
return;
}
if (info.AutoEject != null && (bool)info.AutoEject && info.SlideLockedOnEmpty != null && !info.SlideLockedOnEmpty && __instance.HasMagazine())
{
MagazineState magState = __instance._magState;
if (magState != null && magState.AmmoCount == 0)
{
AmmoSocket componentInChildren = ((Component)__instance).GetComponentInChildren<AmmoSocket>();
if (componentInChildren != null)
{
componentInChildren.EjectMagazine();
}
return;
}
}
if ((Firemode)info.FireMode == Firemode.Burst)
{
MelonCoroutines.Start(Burst(__instance, info));
}
if ((Firemode)info.FireMode == Firemode.BinaryTrigger)
{
MelonCoroutines.Start(BinaryTrigger(__instance));
}
}
}
[HarmonyPatch(typeof(Gun), "Fire")]
public static class GunPatch8000
{
public static bool Prefix(Gun __instance)
{
GunTweaker.isFiring = true;
int instanceID = ((Object)__instance).GetInstanceID();
if (!coroutines.TryGetValue(instanceID, out var value))
{
return true;
}
return value;
}
public static void Postfix()
{
GunTweaker.isFiring = false;
}
}
[HarmonyPatch(typeof(Gun), "PullCartridge")]
public static class InfiniteAmmoPatch
{
public static void Postfix(Gun __instance)
{
if (GunTweaker.TryGetGunInfo(__instance, out var info) && (bool)info.InfiniteAmmo)
{
MagazineState magState = __instance._magState;
if (magState != null)
{
magState.Refill();
}
}
}
}
public static Dictionary<int, bool> coroutines = new Dictionary<int, bool>();
public static FireMode GTFM2BLFM(this Firemode fm)
{
//IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
return (FireMode)(fm switch
{
Firemode.Automatic => 2,
Firemode.SemiAutomatic => 1,
Firemode.BoltAction => 0,
_ => 1,
});
}
public static void SetFiremode(this Gun gun, Firemode fm)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: 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_0014: Unknown result type (might be due to invalid IL or missing references)
gun.fireMode = (FireMode)(fm switch
{
Firemode.Automatic => 2,
Firemode.BoltAction => 0,
_ => 1,
});
}
public static IEnumerator Burst(Gun gun, GunInfo info)
{
int uuid = ((Object)gun).GetInstanceID();
coroutines.Add(uuid, value: false);
for (int i = 0; i < (int)info.BurstSize - 1; i++)
{
float timer = Time.time + 1f / gun.roundsPerSecond;
while (Time.time < timer)
{
yield return null;
}
yield return (object)new WaitForFixedUpdate();
if ((Object)(object)gun.chamberedCartridge == (Object)null && (!gun.HasMagazine() || !gun._hasMagState || gun.AmmoCount() == 0))
{
break;
}
gun.fireMode = (FireMode)2;
coroutines[uuid] = true;
gun.Fire();
coroutines[uuid] = false;
gun.fireMode = (FireMode)1;
}
gun.SetFiremode(info.FireMode);
coroutines.Remove(uuid);
}
private static IEnumerator BinaryTrigger(Gun gun)
{
int uuid = ((Object)gun).GetInstanceID();
coroutines.Add(uuid, value: false);
float timer = Time.time + 1.1f / gun.roundsPerSecond;
while (Time.time < timer || gun.isTriggerPulled)
{
yield return null;
}
gun.fireMode = (FireMode)2;
coroutines[uuid] = true;
gun.Fire();
coroutines[uuid] = false;
gun.fireMode = (FireMode)1;
yield return (object)new WaitForEndOfFrame();
coroutines.Remove(uuid);
}
}
public class GunInfo
{
public class OGGunInfo
{
public float FireRate { get; private set; }
public FireMode FireMode { get; private set; }
public FiremodeGarbage.Firemode FireModeGT { get; private set; }
public bool SlideLockedOnEmpty { get; private set; }
public bool SlideReleaseOnCollision { get; private set; }
public bool MagEjectOnEmpty { get; private set; }
public OGGunInfo(Gun gun)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected I4, but got Unknown
FireRate = gun.roundsPerMinute;
FireMode = gun.fireMode;
SlideReleaseOnCollision = gun.isSlideReleaseOnCollision;
SlideLockedOnEmpty = gun.isSlideLockedOnEmpty;
MagEjectOnEmpty = gun.isMagEjectOnEmpty;
FireMode fireMode = gun.fireMode;
FireModeGT = (int)fireMode switch
{
2 => FiremodeGarbage.Firemode.Automatic,
1 => FiremodeGarbage.Firemode.SemiAutomatic,
0 => FiremodeGarbage.Firemode.BoltAction,
_ => FiremodeGarbage.Firemode.SemiAutomatic,
};
}
}
public enum AmmoTypes
{
Normal,
Explosive
}
public static Dictionary<string, Preferences.GunPref> gunPrefs = new Dictionary<string, Preferences.GunPref>();
public Dictionary<string, float> rbWeights = new Dictionary<string, float>();
public float FireRate => Preferences.GlobalFirerateMultiplier.Value * (float)FireRateMult * OGInfo.FireRate;
public string Name { get; set; }
public float Damage => OGProjectileData.DamageMultiplier * Preferences.GlobalDamageMultiplier.Value * (float)DamageMult;
public bool IsShotgun { get; set; }
public bool IsPumpShotgun { get; private set; }
public bool IsModded { get; set; }
public bool WeirdGunTriggerShit { get; set; }
public bool HasInternalMagazine { get; private set; }
public bool HasBeenTweaked
{
get
{
if ((int)MagCapacity <= OGProjectileData.DefaultMagCapacity && !((float)FireRateMult > 1.01f) && !((float)DamageMult > 1.01f) && !((float)VelocityMult > 1.01f) && !((float)MassMult > 1.01f) && !InfiniteAmmo && ((FiremodeGarbage.Firemode)FireMode == OGInfo.FireModeGT || (FiremodeGarbage.Firemode)FireMode == FiremodeGarbage.Firemode.BoltAction) && (int)ProjCount <= OGProjectileData.Count)
{
return (float)RecoilMult <= 1.01f;
}
return true;
}
}
public AmmoInfo OGProjectileData { get; private set; }
public MagazineData Mag { get; set; }
public CartridgeData DefaultCart { get; set; }
public int CurrentProfile { get; set; }
public GunPref<float> FireRateMult { get; set; }
public GunPref<float> DamageMult { get; set; }
public GunPref<float> MassMult { get; set; }
public GunPref<float> VelocityMult { get; set; }
public GunPref<int> MagCapacity { get; set; }
public GunPref<FiremodeGarbage.Firemode> FireMode { get; set; }
public GunPref<int> BurstSize { get; set; }
public GunPref<bool> SlideReleaseOnCollision { get; set; }
public GunPref<bool> InfiniteAmmo { get; set; }
public GunPref<bool> PseudoShotgun { get; set; }
public GunPref<int> ProjCount { get; set; }
public GunPref<float> Spread { get; set; }
public GunPref<bool> SlideLockedOnEmpty { get; set; }
public GunPref<bool> MagEject { get; set; }
public GunPref<bool> AutoEject { get; set; }
public GunPref<bool> ScaleRecoil { get; set; }
public GunPref<float> RecoilMult { get; set; }
public GunPref<float> WeightMult { get; set; }
public OGGunInfo OGInfo { get; set; }
public HashSet<Gun> Instances { get; set; } = new HashSet<Gun>();
public Dictionary<GunTrigger, FireMode> GunTriggers { get; set; }
public HashSet<int> InstanceIds { get; set; } = new HashSet<int>();
public GunInfo(Gun gun, string pooleeName)
{
Name = pooleeName;
OGProjectileData = new AmmoInfo(gun.defaultCartridge.projectile, gun.internalMagazine ?? gun.defaultMagazine);
Mag = gun.internalMagazine ?? gun.defaultMagazine;
DefaultCart = gun.defaultCartridge;
OGInfo = new OGGunInfo(gun);
IsShotgun = ((Crate)((SpawnEvents)gun)._poolee.SpawnableCrate)._tags.Contains("Shotgun");
IsPumpShotgun = (Object)(object)((Component)gun).GetComponentInChildren<PumpShotgunVirtualController>() != (Object)null;
IsModded = !((Crate)((SpawnEvents)gun)._poolee.SpawnableCrate)._pallet.Internal;
WeirdGunTriggerShit = ((Component)gun).GetComponentsInChildren<GunTrigger>().Count > 1;
HasInternalMagazine = (Object)(object)gun.internalMagazine != (Object)null;
foreach (Rigidbody componentsInChild in ((Component)((Component)gun).transform.root).GetComponentsInChildren<Rigidbody>())
{
string cleanObjectName = HelperMethods.GetCleanObjectName(((Object)componentsInChild).name);
float mass = componentsInChild.mass;
if (!rbWeights.ContainsKey(cleanObjectName))
{
rbWeights.Add(cleanObjectName, mass);
}
}
CreatePrefs();
}
public void CreatePrefs()
{
//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_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected I4, but got Unknown
Preferences.GunPref value = null;
gunPrefs.TryGetValue(Name, out value);
int[] value2 = ((value == null) ? null : new int[1] { value.CurrentProfile });
CurrentProfile = new GunPref<int>(this, "CurrentProfile", 1, value2, multipleProfiles: false);
FireRateMult = new GunPref<float>(this, "FirerateMultiplier", 1f, value?.FirerateMultiplier);
DamageMult = new GunPref<float>(this, "DamageMultiplier", 1f, value?.DamageMultiplier);
MassMult = new GunPref<float>(this, "ProjectileMassMultiplier", 1f, value?.ProjectileMassMultiplier);
VelocityMult = new GunPref<float>(this, "ProjectileVelocityMultiplier", 1f, value?.ProjectileVelocityMultiplier);
BurstSize = new GunPref<int>(this, "RoundsPerBurst", 3, value?.RoundsPerBurst);
FireMode fireMode = OGInfo.FireMode;
FireMode = new GunPref<FiremodeGarbage.Firemode>(this, "Firemode", (int)fireMode switch
{
2 => FiremodeGarbage.Firemode.Automatic,
1 => FiremodeGarbage.Firemode.SemiAutomatic,
0 => FiremodeGarbage.Firemode.BoltAction,
_ => FiremodeGarbage.Firemode.SemiAutomatic,
}, value?.Firemode);
MagCapacity = new GunPref<int>(this, "MagazineCapacity", OGProjectileData.DefaultMagCapacity, value?.MagazineCapacity);
InfiniteAmmo = new GunPref<bool>(this, "InfiniteAmmo", defaultVal: false, value?.InfiniteAmmo);
if (!IsPumpShotgun)
{
SlideLockedOnEmpty = new GunPref<bool>(this, "SlideLock", OGInfo.SlideLockedOnEmpty, value?.SlideLock);
SlideReleaseOnCollision = new GunPref<bool>(this, "SlideReleaseOnCollision", OGInfo.SlideReleaseOnCollision, value?.SlideReleaseOnCollision);
}
if (!HasInternalMagazine)
{
MagEject = new GunPref<bool>(this, "MagEject", !OGInfo.MagEjectOnEmpty, value?.MagEject);
AutoEject = new GunPref<bool>(this, "AutoEject", OGInfo.MagEjectOnEmpty, value?.AutoEject);
}
if (!IsShotgun)
{
PseudoShotgun = new GunPref<bool>(this, "PseudoShotgun", defaultVal: false, value?.PseudoShotgun);
}
ProjCount = new GunPref<int>(this, "ProjectileCount", OGProjectileData.Count, value?.ProjectileCount);
Spread = new GunPref<float>(this, "Spread", OGProjectileData.Angle, value?.Spread);
RecoilMult = new GunPref<float>(this, "RecoilMult", 1f, value?.RecoilMult);
WeightMult = new GunPref<float>(this, "WeightMult", 1f, value?.WeightMult);
ScaleRecoil = new GunPref<bool>(this, "ScaleRecoil", defaultVal: false, value?.ScaleRecoil);
}
public void Reset(bool allProfiles = false)
{
FireRateMult?.Reset(allProfiles);
DamageMult?.Reset(allProfiles);
MassMult?.Reset(allProfiles);
VelocityMult?.Reset(allProfiles);
RecoilMult?.Reset(allProfiles);
BurstSize?.Reset(allProfiles);
InfiniteAmmo?.Reset(allProfiles);
WeightMult?.Reset(allProfiles);
if (!IsShotgun)
{
PseudoShotgun?.Reset(allProfiles);
}
Spread?.Reset(allProfiles);
ProjCount?.Reset(allProfiles);
if (!IsPumpShotgun)
{
SlideLockedOnEmpty?.Reset(allProfiles);
SlideReleaseOnCollision?.Reset(allProfiles);
}
if (!HasInternalMagazine)
{
MagEject?.Reset(allProfiles);
AutoEject?.Reset(allProfiles);
}
FireMode?.Reset(allProfiles);
MagCapacity?.Reset(allProfiles);
ScaleRecoil?.Reset(allProfiles);
}
public static bool CheckFusion()
{
if (Gamemode.IsGamemodeRunning)
{
if (!Gamemode.ActiveGamemode.DisableSpawnGun)
{
return Gamemode.ActiveGamemode.DisableDevTools;
}
return true;
}
return false;
}
public void ApplyTweaks(Gun spawnedGun = null)
{
if (GunTweaker.fusionInstalled && CheckFusion())
{
return;
}
foreach (Gun instance in Instances)
{
if ((Object)(object)spawnedGun != (Object)null && (Object)(object)instance != (Object)(object)spawnedGun)
{
continue;
}
Extensions.SetRpm(instance, FireRate);
instance.SetFiremode(FireMode);
instance.defaultCartridge.projectile.damageMultiplier = Damage;
instance.defaultCartridge.projectile.mass = OGProjectileData.Mass * (float)MassMult * Preferences.GlobalMassMultiplier.Value;
instance.defaultCartridge.projectile.startVelocity = OGProjectileData.StartVelocity * (float)VelocityMult * Preferences.GlobalVelocityMultiplier.Value;
instance.defaultCartridge.projectile.angle = ((IsShotgun || (bool)PseudoShotgun) ? ((float)Spread) : 0f);
instance.defaultCartridge.projectile.count = ((!IsShotgun && !PseudoShotgun) ? 1 : ((int)ProjCount));
instance.defaultCartridge.projectile.emissionType = (EmissionType)(((int)ProjCount != 1 || (float)Spread > 0.02f) ? 1 : 0);
if (instance._hasMagState)
{
instance._magState.magazineData.rounds = MagCapacity;
}
if (!IsPumpShotgun)
{
instance.isSlideLockedOnEmpty = SlideLockedOnEmpty;
instance.isSlideReleaseOnCollision = SlideReleaseOnCollision;
}
if (!HasInternalMagazine)
{
instance.isMagEjectOnEmpty = !MagEject;
}
foreach (Rigidbody componentsInChild in ((Component)((Component)instance).transform.root).GetComponentsInChildren<Rigidbody>())
{
string cleanObjectName = HelperMethods.GetCleanObjectName(((Object)componentsInChild).name);
if (rbWeights.ContainsKey(cleanObjectName))
{
componentsInChild.mass = rbWeights[cleanObjectName] * (float)WeightMult;
}
}
}
if ((Object)(object)GunTweaker.controller != (Object)null && !GunTweaker.controller.isDevToolSpawned && HasBeenTweaked)
{
GunTweaker.controller.isDevToolSpawned = true;
}
Mag.rounds = MagCapacity;
}
}
public class AmmoInfo
{
public float Angle { get; set; }
public int Count { get; set; }
public float DamageMultiplier { get; set; }
public float Mass { get; set; }
public float StartVelocity { get; set; }
public int DefaultMagCapacity { get; set; }
public AmmoInfo(ProjectileData projectile, MagazineData mag)
{
Angle = projectile.angle;
Count = projectile.count;
DamageMultiplier = projectile.damageMultiplier;
Mass = projectile.mass;
StartVelocity = projectile.startVelocity;
DefaultMagCapacity = mag.rounds;
}
}
public class GunPref<T>
{
public T[] profiles;
private readonly bool multipleProfiles;
private readonly GunInfo gunInfo;
private T defaultValue;
private T[] defaultArray;
public int CurrProfile
{
get
{
if (!multipleProfiles)
{
return 0;
}
return gunInfo.CurrentProfile - 1;
}
}
public GunPref(GunInfo gun, string name, T defaultVal, T[] value = null, bool multipleProfiles = true)
{
this.multipleProfiles = multipleProfiles;
gunInfo = gun;
T[] array = new T[(!this.multipleProfiles) ? 1 : 5];
for (int i = 0; i < array.Length; i++)
{
array[i] = defaultVal;
}
profiles = value ?? array;
defaultValue = defaultVal;
defaultArray = array;
}
public void SetValue(T val)
{
Preferences.SavePrefs();
profiles[CurrProfile] = val;
}
public T GetValue()
{
return profiles[CurrProfile];
}
public T GetDefaultValue()
{
return defaultValue;
}
public void Reset(bool allProfiles)
{
if (allProfiles)
{
profiles = defaultArray;
}
else
{
profiles[CurrProfile] = defaultValue;
}
}
public static implicit operator T(GunPref<T> pref)
{
return pref.profiles[pref.CurrProfile];
}
}
public static class BuildInfo
{
public const string Name = "GunTweaker";
public const string Author = "Adi";
public const string Company = null;
public const string Version = "1.1.4";
public const string DownloadLink = null;
}
public class GunTweaker : MelonMod
{
[HarmonyPatch(typeof(Gun), "Start")]
public static class GunPatch
{
public static void Postfix(Gun __instance)
{
OnSpawn(__instance);
}
}
[HarmonyPatch(typeof(Rigidbody), "AddForceAtPosition", new Type[]
{
typeof(Vector3),
typeof(Vector3),
typeof(ForceMode)
})]
public static class RecoilPatch
{
public static void Prefix(Rigidbody __instance, ref Vector3 force)
{
//IL_0072: 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_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
if (isFiring && instanceToPool.TryGetValue(HelperMethods.GetCleanObjectName(((Object)((Component)__instance).transform.root).name), out var value) && gunInfo.TryGetValue(value, out var value2))
{
if ((bool)value2.ScaleRecoil)
{
force /= (float)value2.MassMult * (float)value2.VelocityMult;
}
force *= (float)value2.RecoilMult * Preferences.GlobalRecoilMultiplier.Value;
}
}
}
[HarmonyPatch(typeof(GunSFX), "MagazineInsert")]
public static class MagPatchForModdedGunsBecauseTheyWorkDifferentlyForSomeFuckingReason_EVERYSINGLEVANILLAGUNJUSTUSESDEFAULTMAGAZINEWHYCANTMODDEDGUNSLIKEHOLYSHITDUDEWHYTHEFUCKDOIHAVETODOTHISSHITITMAKESZEROFUCKINGSENSEIALSOHAVETOPATCHGUNSFXMAGAZINEINSERTINSTEADOFGUNONMAGAZINEINSERTEDBECAUSEITDOESNTGETCALLEDCONSISTENTLYFORSOMEFUCKINGREASON_OKAPPARENTLYTHISISFORVANILLAGUNSASWELLNOWBECAUSETHEYBREAKINTHEARENAORSOMESHITIDONTEVENKNOWATTHISPOINTBRUH
{
public static void Postfix(GunSFX __instance)
{
if (SFXCache.TryGetValue(((Object)__instance).GetInstanceID(), out var value) && !((Object)(object)value == (Object)null) && value._hasMagState && TryGetGunInfo(value, out var info) && value._magState.magazineData.rounds != (int)info.MagCapacity)
{
value._magState.magazineData.rounds = info.MagCapacity;
value._magState.SetCartridge((int)info.MagCapacity);
value._magState.Refill();
}
}
}
[HarmonyPatch(typeof(Gun), "SlideLocked")]
public static class SlideLockedPatch
{
public static void Prefix(Gun __instance)
{
if (TryGetGunInfo(__instance, out var info) && !info.HasInternalMagazine)
{
__instance.isMagEjectOnEmpty = info.AutoEject;
}
}
public static void Postfix(Gun __instance)
{
if (TryGetGunInfo(__instance, out var info) && !info.HasInternalMagazine)
{
__instance.isMagEjectOnEmpty = !info.MagEject;
}
}
}
[HarmonyPatch(typeof(AmmoSocket), "UpdateProxyGripState")]
public static class ProxyGripPatch
{
public static void Prefix(AmmoSocket __instance)
{
if (TryGetGunInfo(__instance.gun, out var info) && !info.HasInternalMagazine)
{
__instance.gun.isMagEjectOnEmpty = info.OGInfo.MagEjectOnEmpty;
}
}
public static void Postfix(AmmoSocket __instance)
{
if (TryGetGunInfo(__instance.gun, out var info) && !info.HasInternalMagazine)
{
__instance.gun.isMagEjectOnEmpty = !info.MagEject;
}
}
}
public static Dictionary<string, string> instanceToPool = new Dictionary<string, string>();
public static Dictionary<string, GunInfo> gunInfo = new Dictionary<string, GunInfo>();
public static Page mainPage;
public const string purpleHex = "#960ACD";
public static BaseGameController controller;
public static HashSet<string> internalGunNames = new HashSet<string>();
public static bool fusionInstalled = false;
public static List<Element> elements = null;
public static Dictionary<int, Gun> SFXCache = new Dictionary<int, Gun>();
public static bool isFiring = false;
public static void AddToMenu(string gun)
{
if (elements == null)
{
elements = (List<Element>)typeof(Page).GetField("_elements", AccessTools.all).GetValue(mainPage);
}
int num = elements.FindIndex((Element i) => i.ElementName == gun);
Element val = null;
if (num != -1)
{
val = elements[num];
}
else if (elements.Count - 2 == 5)
{
elements.RemoveAt(elements.Count - 1);
}
if (val == null)
{
val = (Element)(object)CreateGunCategory(gun);
}
elements.Remove(val);
elements.Insert(1, val);
}
public override void OnDeinitializeMelon()
{
Preferences.SavePrefs();
}
public static Color HexToColor(string hex)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
Color result = default(Color);
ColorUtility.TryParseHtmlString("#960ACD", ref result);
return result;
}
public override void OnInitializeMelon()
{
//IL_002d: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: 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)
Preferences.LoadPrefs();
mainPage = Page.Root.CreatePage((Random.RandomRangeInt(1, 100001) == 100000) ? "Gun Twerker" : "Gun Tweaker", HexToColor("#960ACD"), 0, true);
((MelonBase)this).HarmonyInstance.Patch((MethodBase)typeof(BaseGameController).GetMethod("OnEnable", AccessTools.all), (HarmonyMethod)null, MelonUtils.ToNewHarmonyMethod(typeof(GunTweaker).GetMethod("ControllerPatch", AccessTools.all)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Page obj = mainPage.CreatePage("Global Modifiers", HexToColor("#960ACD"), 0, true);
obj.CreateFloat("Firerate Multiplier", Color.yellow, Preferences.GlobalFirerateMultiplier.Value, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
Preferences.GlobalFirerateMultiplier.Value = value;
foreach (GunInfo value in gunInfo.Values)
{
value.ApplyTweaks();
}
});
obj.CreateFloat("Damage Multiplier", Color.red, Preferences.GlobalDamageMultiplier.Value, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
Preferences.GlobalDamageMultiplier.Value = value;
foreach (GunInfo value2 in gunInfo.Values)
{
value2.ApplyTweaks();
}
});
obj.CreateFloat("Projectile Mass Multiplier", Color.magenta, Preferences.GlobalMassMultiplier.Value, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
Preferences.GlobalMassMultiplier.Value = value;
foreach (GunInfo value3 in gunInfo.Values)
{
value3.ApplyTweaks();
}
});
obj.CreateFloat("Projectile Velocity Multiplier", Color.cyan, Preferences.GlobalVelocityMultiplier.Value, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
Preferences.GlobalVelocityMultiplier.Value = value;
foreach (GunInfo value4 in gunInfo.Values)
{
value4.ApplyTweaks();
}
});
obj.CreateFloat("Recoil Multiplier", Color.white, Preferences.GlobalRecoilMultiplier.Value, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
Preferences.GlobalRecoilMultiplier.Value = value;
});
Hooking.OnMarrowGameStarted += delegate
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
Enumerator<Barcode, Scannable> enumerator2 = AssetWarehouse.Instance.InventoryRegistry.Values.GetEnumerator();
while (enumerator2.MoveNext())
{
Scannable current2 = enumerator2.Current;
SpawnableCrateReference val = new SpawnableCrateReference(current2.Barcode);
SpawnableCrate val2 = (((int)val != 0) ? ((CrateReferenceT<SpawnableCrate>)val).Crate : null);
if ((Object)(object)val2 != (Object)null && ((Crate)val2).Pallet.Internal && ((Crate)val2).Tags.Contains("Gun"))
{
internalGunNames.Add(current2.Title.Trim());
}
}
};
Hooking.OnGrabObject += OnGrabObject;
Hooking.OnLevelUnloaded += delegate
{
foreach (GunInfo value5 in gunInfo.Values)
{
value5.Instances.Clear();
value5.InstanceIds.Clear();
SFXCache.Clear();
}
};
}
public override void OnLateInitializeMelon()
{
fusionInstalled = MelonTypeBase<MelonMod>.RegisteredMelons.Any((MelonMod i) => ((MelonBase)i).Info.Name == "LabFusion");
}
public static void OnGrabObject(GameObject go, Hand hand)
{
string gunName = GetGunName(((Object)go.transform.root).name);
if (gunName != null)
{
AddToMenu(gunName);
}
}
public static PageLinkElement CreateGunCategory(string name)
{
//IL_0022: 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_0068: 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_0094: 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_0116: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
//IL_030c: Unknown result type (might be due to invalid IL or missing references)
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_038b: Unknown result type (might be due to invalid IL or missing references)
//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0426: Unknown result type (might be due to invalid IL or missing references)
//IL_0443: Unknown result type (might be due to invalid IL or missing references)
//IL_0482: Unknown result type (might be due to invalid IL or missing references)
//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0557: Unknown result type (might be due to invalid IL or missing references)
//IL_0598: Unknown result type (might be due to invalid IL or missing references)
//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
//IL_0647: Unknown result type (might be due to invalid IL or missing references)
//IL_0664: Unknown result type (might be due to invalid IL or missing references)
//IL_0675: Unknown result type (might be due to invalid IL or missing references)
//IL_067b: Expected O, but got Unknown
//IL_0528: Unknown result type (might be due to invalid IL or missing references)
if (!gunInfo.TryGetValue(name, out var info))
{
return null;
}
Page gunCat = mainPage.CreatePage(name, Color.white, 0, false);
IntElement profile = gunCat.CreateInt("Profile", Color.white, info.CurrentProfile, 1, 0, 6, (Action<int>)null);
Page val = gunCat.CreatePage("Modifiers", Color.yellow, 0, true);
Page val2 = gunCat.CreatePage("Miscellaneous Options", Color.green, 0, true);
FloatElement fr = val.CreateFloat("Firerate Multiplier", Color.yellow, (float)info.FireRateMult, 0.05f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
info.FireRateMult.SetValue(value);
info.ApplyTweaks();
});
FloatElement dmg = val.CreateFloat("Damage Multiplier", Color.red, (float)info.DamageMult, 0.05f, float.MinValue, float.MaxValue, (Action<float>)delegate(float value)
{
info.DamageMult.SetValue(value);
info.ApplyTweaks();
});
FloatElement mass = val.CreateFloat("Projectile Mass Multiplier", Color.magenta, (float)info.MassMult, 0.1f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
info.MassMult.SetValue(value);
info.ApplyTweaks();
});
FloatElement proj = val.CreateFloat("Projectile Velocity Multiplier", Color.cyan, (float)info.VelocityMult, 0.1f, 0f, float.MaxValue, (Action<float>)delegate(float value)
{
info.VelocityMult.SetValue(value);
info.ApplyTweaks();
});
IntElement burst = null;
IntElement mag = null;
Action action = null;
EnumElement fMode = null;
List<Element> _elements = (List<Element>)typeof(Page).GetField("_elements", AccessTools.all).GetValue(gunCat);
fMode = gunCat.CreateEnum("Firemode", Color.green, (Enum)info.FireMode.GetValue(), (Action<Enum>)delegate(Enum e)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
FiremodeGarbage.Firemode firemode = (FiremodeGarbage.Firemode)(object)e;
info.FireMode.SetValue(firemode);
info.ApplyTweaks();
if (firemode == FiremodeGarbage.Firemode.Burst)
{
burst = gunCat.CreateInt("Rounds Per Burst", HexToColor("#CC5500"), (int)info.BurstSize, 1, 2, int.MaxValue, (Action<int>)delegate(int value)
{
info.BurstSize.SetValue(value);
});
_elements.Remove((Element)(object)burst);
_elements.Insert(4, (Element)(object)burst);
}
else
{
_elements.Remove((Element)(object)burst);
}
Menu.OpenPage(gunCat);
});
burst = gunCat.CreateInt("Rounds Per Burst", HexToColor("#CC5500"), (int)info.BurstSize, 1, 2, int.MaxValue, (Action<int>)delegate(int value)
{
info.BurstSize.SetValue(value);
});
if ((FiremodeGarbage.Firemode)info.FireMode != FiremodeGarbage.Firemode.Burst)
{
gunCat.Remove((Element)(object)burst);
}
mag = gunCat.CreateInt("Magazine Capacity", Color.white, (int)info.MagCapacity, 1, 1, int.MaxValue, (Action<int>)delegate(int value)
{
info.MagCapacity.SetValue(value);
info.ApplyTweaks();
});
BoolElement inf = val2.CreateBool("Infinite Ammo", Color.magenta, (bool)info.InfiniteAmmo, (Action<bool>)delegate(bool value)
{
info.InfiniteAmmo.SetValue(value);
});
BoolElement slide = null;
BoolElement sLock = null;
if (!info.IsPumpShotgun)
{
slide = val2.CreateBool("Slide Release On Collision", Color.cyan, (bool)info.SlideReleaseOnCollision, (Action<bool>)delegate(bool value)
{
info.SlideReleaseOnCollision.SetValue(value);
info.ApplyTweaks();
});
sLock = val2.CreateBool("Slide Locked On Empty", Color.green, (bool)info.SlideLockedOnEmpty, (Action<bool>)delegate(bool value)
{
info.SlideLockedOnEmpty.SetValue(value);
info.ApplyTweaks();
});
}
BoolElement magEject = null;
BoolElement autoEject = null;
if (!info.HasInternalMagazine)
{
magEject = val2.CreateBool("Mag Eject", Color.white, (bool)info.MagEject, (Action<bool>)delegate(bool value)
{
info.MagEject.SetValue(value);
info.ApplyTweaks();
});
autoEject = val2.CreateBool("Auto Eject Mag", HexToColor("#CC5500"), (bool)info.AutoEject, (Action<bool>)delegate(bool value)
{
info.AutoEject.SetValue(value);
});
}
Page val3 = null;
BoolElement enabled = null;
Action<int> action2 = delegate(int value)
{
info.ProjCount.SetValue(value);
info.ApplyTweaks();
};
Action<float> action3 = delegate(float value)
{
info.Spread.SetValue(value);
info.ApplyTweaks();
};
if (!info.IsShotgun)
{
val3 = val2.CreatePage("Pseudo Shotgun", Color.red, 0, true);
}
enabled = ((val3 != null) ? val3.CreateBool("Enabled", Color.white, (bool)info.PseudoShotgun, (Action<bool>)delegate(bool value)
{
info.PseudoShotgun.SetValue(value);
info.ApplyTweaks();
}) : null);
FloatElement spread = ((val3 != null) ? val3.CreateFloat("Spread", HexToColor("#CC5500"), (float)info.Spread, 0.1f, 0f, float.MaxValue, action3) : null) ?? val.CreateFloat("Spread", HexToColor("#CC5500"), (float)info.Spread, 0.1f, 0f, float.MaxValue, action3);
IntElement projCount = ((val3 != null) ? val3.CreateInt("Pellets", Color.magenta, (int)info.ProjCount, 1, 0, int.MaxValue, action2) : null) ?? val.CreateInt("Pellets", Color.white, (int)info.ProjCount, 1, 0, int.MaxValue, action2);
FloatElement recoil = val.CreateFloat("Recoil Multiplier", Color.white, (float)info.RecoilMult, 0.05f, float.MinValue, float.MaxValue, (Action<float>)delegate(float value)
{
info.RecoilMult.SetValue(value);
});
FloatElement weight = val.CreateFloat("Weight Multiplier", Color.green, (float)info.WeightMult, 0.05f, float.MinValue, float.MaxValue, (Action<float>)delegate(float value)
{
info.WeightMult.SetValue(value);
info.ApplyTweaks();
});
val.CreateBool("Scale Recoil With Mass & Velocity", Color.red, (bool)info.ScaleRecoil, (Action<bool>)delegate(bool value)
{
info.ScaleRecoil.SetValue(value);
});
typeof(IntElement).GetField("_callback", AccessTools.all).SetValue(profile, (Action<int>)delegate(int value)
{
value = value switch
{
0 => 5,
6 => 1,
_ => value,
};
info.CurrentProfile = value;
profile.Value = value;
SetValues();
});
action = delegate
{
info.Reset();
SetValues();
};
gunCat.CreateFunction("Reset Profile", Color.red, action);
return new PageLinkElement(gunCat.Name, gunCat.Color, (Action)delegate
{
Menu.OpenPage(gunCat);
});
void SetValues()
{
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
fr.Value = info.FireRateMult;
dmg.Value = info.DamageMult;
mass.Value = info.MassMult;
proj.Value = info.VelocityMult;
fMode.Value = (FiremodeGarbage.Firemode)info.FireMode;
burst.Value = info.BurstSize;
mag.Value = info.MagCapacity;
if (slide != null)
{
slide.Value = info.SlideReleaseOnCollision;
}
inf.Value = info.InfiniteAmmo;
if (sLock != null)
{
sLock.Value = info.SlideLockedOnEmpty;
}
if (magEject != null)
{
magEject.Value = info.MagEject;
}
if (magEject != null)
{
autoEject.Value = info.AutoEject;
}
projCount.Value = info.ProjCount;
spread.Value = info.Spread;
if (enabled != null)
{
enabled.Value = info.PseudoShotgun;
}
recoil.Value = info.RecoilMult;
weight.Value = info.WeightMult;
gunCat.Remove((Element)(object)burst);
if ((FiremodeGarbage.Firemode)(object)fMode.Value == FiremodeGarbage.Firemode.Burst)
{
burst = gunCat.CreateInt("Rounds Per Burst", HexToColor("#CC5500"), (int)info.BurstSize, 1, 2, int.MaxValue, (Action<int>)delegate(int value)
{
info.BurstSize.SetValue(value);
});
_elements.Remove((Element)(object)burst);
_elements.Insert(4, (Element)(object)burst);
}
Menu.OpenPage(gunCat);
info.ApplyTweaks();
}
}
public static void ControllerPatch(BaseGameController __instance)
{
controller = __instance;
}
public static bool TryGetGunInfo(Gun gun, out GunInfo info)
{
info = null;
string gunName = GetGunName(gun);
if (string.IsNullOrEmpty(gunName))
{
return false;
}
return gunInfo.TryGetValue(gunName, out info);
}
public static bool TryGetGunInfo(string name, out GunInfo info)
{
info = null;
name = GetGunName(name);
if (string.IsNullOrEmpty(name))
{
return false;
}
return gunInfo.TryGetValue(name, out info);
}
public static string GetGunName(Gun gun)
{
string gunName = GetGunName(HelperMethods.GetCleanObjectName(((Object)((Component)gun).transform.root).name));
if (gunName != null)
{
return gunName;
}
object obj;
if (gun == null)
{
obj = null;
}
else
{
Poolee poolee = ((SpawnEvents)gun)._poolee;
obj = ((poolee != null) ? poolee.SpawnableCrate : null);
}
SpawnableCrate val = (SpawnableCrate)obj;
if ((Object)(object)val == (Object)null)
{
return null;
}
return (!((Crate)val).Pallet.Internal && internalGunNames.Contains(((Scannable)val).Title)) ? (((Crate)val).Pallet.Author + " - " + ((Scannable)val).Title) : ((Scannable)val).Title;
}
public static string GetGunName(string gun)
{
string cleanObjectName = HelperMethods.GetCleanObjectName(gun);
if (instanceToPool.TryGetValue(cleanObjectName, out var value))
{
return value;
}
return null;
}
public static void OnSpawn(Gun gun)
{
string cleanObjectName = HelperMethods.GetCleanObjectName(((Object)((Component)gun).transform.root).name);
if (cleanObjectName == "SPAWN_GUN")
{
return;
}
try
{
string gunName = GetGunName(gun);
if (!instanceToPool.ContainsKey(cleanObjectName) && gunName != null)
{
instanceToPool.Add(cleanObjectName, gunName);
}
if (gunName != null && !gunInfo.ContainsKey(gunName))
{
gunInfo.Add(gunName, new GunInfo(gun, gunName));
}
int instanceID = ((Object)gun).GetInstanceID();
if (gunInfo.TryGetValue(instanceToPool[cleanObjectName], out var value) && value.InstanceIds.Add(instanceID) && value.Instances.Add(gun))
{
SFXCache.Add(((Object)gun.gunSFX).GetInstanceID(), gun);
value.ApplyTweaks(gun);
}
}
catch (Exception ex)
{
object obj;
if (gun == null)
{
obj = null;
}
else
{
Poolee poolee = ((SpawnEvents)gun)._poolee;
obj = ((poolee != null) ? poolee.SpawnableCrate : null);
}
SpawnableCrate val = (SpawnableCrate)obj;
string text = (((Object)(object)val != (Object)null) ? (((Crate)val).Pallet.Author + " - " + ((Scannable)val).Title) : cleanObjectName);
MelonLogger.Msg(ConsoleColor.Red, text);
MelonLogger.Error((object)ex);
}
}
}
public static class Preferences
{
public class GunPref
{
public string Name;
public int CurrentProfile;
public float[] FirerateMultiplier;
public float[] DamageMultiplier;
public float[] ProjectileMassMultiplier;
public float[] ProjectileVelocityMultiplier;
public int[] RoundsPerBurst;
public FiremodeGarbage.Firemode[] Firemode;
public int[] MagazineCapacity;
public bool[] InfiniteAmmo;
public bool[] SlideLock;
public bool[] SlideReleaseOnCollision;
public bool[] MagEject;
public bool[] AutoEject;
public bool[] PseudoShotgun;
public int[] ProjectileCount;
public float[] Spread;
public float[] RecoilMult;
public float[] WeightMult;
public bool[] ScaleRecoil;
public GunPref()
{
}
public GunPref(GunInfo info)
{
Name = info.Name;
CurrentProfile = info.CurrentProfile;
FirerateMultiplier = info.FireRateMult?.profiles;
DamageMultiplier = info.DamageMult?.profiles;
ProjectileMassMultiplier = info.MassMult?.profiles;
ProjectileVelocityMultiplier = info.VelocityMult?.profiles;
MagazineCapacity = info.MagCapacity?.profiles;
Firemode = info.FireMode?.profiles;
RoundsPerBurst = info.BurstSize?.profiles;
SlideReleaseOnCollision = info.SlideReleaseOnCollision?.profiles;
InfiniteAmmo = info.InfiniteAmmo?.profiles;
PseudoShotgun = info.PseudoShotgun?.profiles;
ProjectileCount = info.ProjCount?.profiles;
Spread = info.Spread?.profiles;
SlideLock = info.SlideLockedOnEmpty?.profiles;
MagEject = info.MagEject?.profiles;
AutoEject = info.AutoEject?.profiles;
RecoilMult = info.RecoilMult?.profiles;
WeightMult = info.WeightMult?.profiles;
ScaleRecoil = info.ScaleRecoil?.profiles;
}
}
public static string path = Path.Combine(MelonEnvironment.UserDataDirectory, "GunTweakerPrefs.cfg");
public static MelonPreferences_Category cat = MelonPreferences.CreateCategory("GlobalModifiers");
public static MelonPreferences_Entry<float> GlobalFirerateMultiplier = cat.CreateEntry<float>("FirerateMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static MelonPreferences_Entry<float> GlobalDamageMultiplier = cat.CreateEntry<float>("DamageMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static MelonPreferences_Entry<float> GlobalMassMultiplier = cat.CreateEntry<float>("ProjectileMassMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static MelonPreferences_Entry<float> GlobalVelocityMultiplier = cat.CreateEntry<float>("ProjectileVelocityMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static MelonPreferences_Entry<float> GlobalRecoilMultiplier = cat.CreateEntry<float>("RecoilMultiplier", 1f, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static MelonPreferences_Entry<List<GunPref>> GunPrefs = cat.CreateEntry<List<GunPref>>("GunPrefs", new List<GunPref>(), (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
public static void LoadPrefs()
{
FixPrefs();
cat.SetFilePath(path, true, false);
cat.SaveToFile(false);
foreach (GunPref item in GunPrefs.Value)
{
GunInfo.gunPrefs.Add(item.Name, item);
}
}
public static void FixPrefs()
{
if (!File.Exists(path) || GunPrefs.Value.Count > 0)
{
return;
}
TomlDocument val = TomlParser.ParseFile(path);
Type[] array = new Type[6]
{
typeof(int),
typeof(bool[]),
typeof(int[]),
typeof(float[]),
typeof(float),
typeof(FiremodeGarbage.Firemode[])
};
foreach (KeyValuePair<string, TomlValue> entry in ((TomlTable)val).Entries)
{
if (entry.Key.Contains("GlobalModifiers"))
{
continue;
}
TomlTable subTable = ((TomlTable)val).GetSubTable(entry.Key);
GunPref gunPref = new GunPref
{
Name = entry.Key.Replace(" Config", "")
};
foreach (KeyValuePair<string, TomlValue> entry2 in subTable.Entries)
{
object obj = null;
Type[] array2 = array;
foreach (Type type in array2)
{
try
{
obj = TomletMain.To(type, entry2.Value, (TomlSerializerOptions)null);
}
catch (Exception)
{
continue;
}
break;
}
if (obj != null)
{
typeof(GunPref).GetField(entry2.Key)?.SetValue(gunPref, obj);
}
}
GunPrefs.Value.Add(gunPref);
}
}
public static void SavePrefs()
{
new List<GunPref>();
foreach (GunInfo value in GunTweaker.gunInfo.Values)
{
if (GunInfo.gunPrefs.ContainsKey(value.Name))
{
GunInfo.gunPrefs[value.Name] = new GunPref(value);
}
else
{
GunInfo.gunPrefs.Add(value.Name, new GunPref(value));
}
}
GunPrefs.Value = GunInfo.gunPrefs.Values.ToList();
}
}