Decompiled source of Weapon Loadouts v1.0.0

WeaponLoadouts.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using PluginConfig.API;
using PluginConfig.API.Fields;
using PluginConfig.API.Functionals;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("WeaponLoadouts")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WeaponLoadouts")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2cc71890-b5be-4854-ab1e-0e5f4dee4ce7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("winter.weaponloadouts", "Weapon Loadouts", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class WeaponLoadouts : BaseUnityPlugin
{
	public static WeaponLoadouts Instance;

	public static ManualLogSource Log;

	private static readonly string[] WeaponNames = new string[15]
	{
		"rev0", "rev1", "rev2", "sho0", "sho1", "sho2", "nai0", "nai1", "nai2", "rai0",
		"rai1", "rai2", "rock0", "rock1", "rock2"
	};

	private static readonly string[] ArmNames = new string[4] { "arm0", "arm1", "arm2", "arm3" };

	private static readonly string[] OrderKeys = new string[5] { "weapon.rev.order", "weapon.sho.order", "weapon.nai.order", "weapon.rai.order", "weapon.rock.order" };

	private static readonly string[] DefaultOrders = new string[5] { "1324", "1234", "1234", "1234", "1234" };

	private void Awake()
	{
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Expected O, but got Unknown
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Expected O, but got Unknown
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Expected O, but got Unknown
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Expected O, but got Unknown
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Expected O, but got Unknown
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Expected O, but got Unknown
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Expected O, but got Unknown
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		PluginConfigurator val = PluginConfigurator.Create("Weapon Loadouts", "winter.weaponloadouts");
		val.SetIconWithURL("https://raw.githubusercontent.com/Prospekt-18/ultrakill-mod-thumbnail/main/weaponloadoutsthumbnail.png");
		for (int i = 0; i < 5; i++)
		{
			int index = i;
			string text = ((i == 0) ? "Default" : ("Loadout " + (i + 1)));
			ConfigPanel val2 = new ConfigPanel(val.rootPanel, "Loadout " + (i + 1), "loadout" + i + "panel");
			StringField val3 = new StringField(val2, "Name", "wl.name." + i, text);
			ButtonField val4 = new ButtonField(val2, "Apply Loadout", "wl.apply." + i);
			ButtonField val5 = new ButtonField(val2, "Save Current Weapons", "wl.save." + i);
			ButtonField val6 = new ButtonField(val2, "Reset to Vanilla Default", "wl.reset." + i);
			val4.onClick += (OnClick)delegate
			{
				ApplyLoadout(index);
			};
			val5.onClick += (OnClick)delegate
			{
				SaveLoadout(index);
			};
			val6.onClick += (OnClick)delegate
			{
				ResetLoadout(index);
			};
		}
		new Harmony("winter.weaponloadouts").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Weapon Loadouts loaded.");
	}

	public void SaveLoadout(int index)
	{
		string[] orderKeys = OrderKeys;
		foreach (string text in orderKeys)
		{
			string @string = MonoSingleton<PrefsManager>.Instance.GetString(text, "1234");
			PlayerPrefs.SetString("wl." + index + "." + text, @string);
		}
		string[] weaponNames = WeaponNames;
		foreach (string text2 in weaponNames)
		{
			int @int = MonoSingleton<PrefsManager>.Instance.GetInt("weapon." + text2, 1);
			PlayerPrefs.SetInt("wl." + index + ".weapon." + text2, @int);
		}
		string[] armNames = ArmNames;
		foreach (string text3 in armNames)
		{
			int int2 = MonoSingleton<PrefsManager>.Instance.GetInt("weapon." + text3, 1);
			PlayerPrefs.SetInt("wl." + index + ".weapon." + text3, int2);
		}
		PlayerPrefs.SetInt("wl." + index + ".CurSlo", PlayerPrefs.GetInt("CurSlo", 1));
		PlayerPrefs.SetInt("wl." + index + ".CurVar", PlayerPrefs.GetInt("CurVar", 0));
		PlayerPrefs.SetInt("wl." + index + ".CurArm", PlayerPrefs.GetInt("CurArm", 0));
		for (int l = 0; l < 6; l++)
		{
			PlayerPrefs.SetInt("wl." + index + ".Slot" + l + "Var", PlayerPrefs.GetInt("Slot" + l + "Var", -1));
		}
		PlayerPrefs.Save();
		ManualLogSource log = Log;
		if (log != null)
		{
			log.LogInfo((object)("Saved loadout " + index));
		}
	}

	public void ApplyLoadout(int index)
	{
		if (!PlayerPrefs.HasKey("wl." + index + ".weapon.rev0"))
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("Loadout " + index + " is empty, nothing to apply."));
			}
			return;
		}
		GunControl instance = MonoSingleton<GunControl>.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		string text = (((Object)(object)instance.currentWeapon != (Object)null) ? ((Object)instance.currentWeapon).name : "");
		int @int = PlayerPrefs.GetInt("CurSlo", 1);
		ManualLogSource log2 = Log;
		if (log2 != null)
		{
			log2.LogInfo((object)("Current weapon before apply: " + text));
		}
		ManualLogSource log3 = Log;
		if (log3 != null)
		{
			log3.LogInfo((object)("Current slot before apply: " + @int));
		}
		string[] array = new string[OrderKeys.Length];
		for (int i = 0; i < OrderKeys.Length; i++)
		{
			array[i] = MonoSingleton<PrefsManager>.Instance.GetString(OrderKeys[i], DefaultOrders[i]);
		}
		int[] array2 = new int[WeaponNames.Length];
		for (int j = 0; j < WeaponNames.Length; j++)
		{
			array2[j] = MonoSingleton<PrefsManager>.Instance.GetInt("weapon." + WeaponNames[j], 1);
		}
		int[] array3 = new int[ArmNames.Length];
		for (int k = 0; k < ArmNames.Length; k++)
		{
			array3[k] = MonoSingleton<PrefsManager>.Instance.GetInt("weapon." + ArmNames[k], 1);
		}
		int int2 = PlayerPrefs.GetInt("CurArm", 0);
		for (int l = 0; l < OrderKeys.Length; l++)
		{
			string @string = PlayerPrefs.GetString("wl." + index + "." + OrderKeys[l], DefaultOrders[l]);
			MonoSingleton<PrefsManager>.Instance.SetString(OrderKeys[l], @string);
		}
		string[] weaponNames = WeaponNames;
		foreach (string text2 in weaponNames)
		{
			int int3 = PlayerPrefs.GetInt("wl." + index + ".weapon." + text2, 1);
			if (GameProgressSaver.CheckGear(text2) > 0 || int3 == 0)
			{
				MonoSingleton<PrefsManager>.Instance.SetInt("weapon." + text2, int3);
			}
		}
		string[] armNames = ArmNames;
		foreach (string text3 in armNames)
		{
			int int4 = PlayerPrefs.GetInt("wl." + index + ".weapon." + text3, 1);
			if (text3 == "arm0" || GameProgressSaver.CheckGear(text3) > 0 || int4 == 0)
			{
				MonoSingleton<PrefsManager>.Instance.SetInt("weapon." + text3, int4);
			}
		}
		PlayerPrefs.SetInt("CurArm", PlayerPrefs.GetInt("wl." + index + ".CurArm", 0));
		try
		{
			FistControl instance2 = MonoSingleton<FistControl>.Instance;
			if (instance2 != null)
			{
				instance2.ResetFists();
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log4 = Log;
			if (log4 != null)
			{
				log4.LogWarning((object)("ResetFists threw: " + ex.Message));
			}
		}
		GunSetter instance3 = MonoSingleton<GunSetter>.Instance;
		if (instance3 != null)
		{
			instance3.ResetWeapons(false);
		}
		ManualLogSource log5 = Log;
		if (log5 != null)
		{
			log5.LogInfo((object)"Slots after ResetWeapons:");
		}
		for (int num = 0; num < instance.slots.Count; num++)
		{
			for (int num2 = 0; num2 < instance.slots[num].Count; num2++)
			{
				ManualLogSource log6 = Log;
				if (log6 != null)
				{
					object arg = num;
					object arg2 = num2;
					GameObject obj = instance.slots[num][num2];
					log6.LogInfo((object)$"  Slot {arg} Var {arg2}: {((obj != null) ? ((Object)obj).name : null)}");
				}
			}
		}
		int num3 = 0;
		foreach (List<GameObject> slot in instance.slots)
		{
			num3 += slot.Count;
		}
		if (num3 == 0)
		{
			ManualLogSource log7 = Log;
			if (log7 != null)
			{
				log7.LogInfo((object)"Loadout left player with no weapons, rolling back.");
			}
			for (int num4 = 0; num4 < OrderKeys.Length; num4++)
			{
				MonoSingleton<PrefsManager>.Instance.SetString(OrderKeys[num4], array[num4]);
			}
			for (int num5 = 0; num5 < WeaponNames.Length; num5++)
			{
				MonoSingleton<PrefsManager>.Instance.SetInt("weapon." + WeaponNames[num5], array2[num5]);
			}
			for (int num6 = 0; num6 < ArmNames.Length; num6++)
			{
				MonoSingleton<PrefsManager>.Instance.SetInt("weapon." + ArmNames[num6], array3[num6]);
			}
			PlayerPrefs.SetInt("CurArm", int2);
			try
			{
				FistControl instance4 = MonoSingleton<FistControl>.Instance;
				if (instance4 != null)
				{
					instance4.ResetFists();
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource log8 = Log;
				if (log8 != null)
				{
					log8.LogWarning((object)("ResetFists threw on rollback: " + ex2.Message));
				}
			}
			GunSetter instance5 = MonoSingleton<GunSetter>.Instance;
			if (instance5 != null)
			{
				instance5.ResetWeapons(false);
			}
			EquipFirstAvailable(instance);
			return;
		}
		bool flag = false;
		for (int num7 = 0; num7 < instance.slots.Count; num7++)
		{
			for (int num8 = 0; num8 < instance.slots[num7].Count; num8++)
			{
				if ((Object)(object)instance.slots[num7][num8] != (Object)null && ((Object)instance.slots[num7][num8]).name == text)
				{
					PlayerPrefs.SetInt("CurSlo", num7 + 1);
					PlayerPrefs.SetInt("CurVar", num8);
					instance.ForceWeapon(instance.slots[num7][num8], true);
					flag = true;
					ManualLogSource log9 = Log;
					if (log9 != null)
					{
						log9.LogInfo((object)$"Found same weapon at slot {num7} var {num8}");
					}
					break;
				}
			}
			if (flag)
			{
				break;
			}
		}
		if (!flag)
		{
			int num9 = @int - 1;
			ManualLogSource log10 = Log;
			if (log10 != null)
			{
				log10.LogInfo((object)$"Same weapon not found, trying slot {num9}");
			}
			if (num9 >= 0 && num9 < instance.slots.Count && instance.slots[num9].Count > 0)
			{
				instance.ForceWeapon(instance.slots[num9][0], true);
				flag = true;
				ManualLogSource log11 = Log;
				if (log11 != null)
				{
					log11.LogInfo((object)$"Found weapon in same slot {num9}");
				}
			}
		}
		if (!flag)
		{
			ManualLogSource log12 = Log;
			if (log12 != null)
			{
				log12.LogInfo((object)"Falling back to first available weapon");
			}
			EquipFirstAvailable(instance);
		}
		for (int num10 = 0; num10 < 6; num10++)
		{
			int int5 = PlayerPrefs.GetInt("wl." + index + ".Slot" + num10 + "Var", -1);
			if (int5 >= 0)
			{
				PlayerPrefs.SetInt("Slot" + num10 + "Var", int5);
			}
		}
		PlayerPrefs.Save();
		ManualLogSource log13 = Log;
		if (log13 != null)
		{
			log13.LogInfo((object)("Applied loadout " + index));
		}
	}

	private void EquipFirstAvailable(GunControl gc)
	{
		for (int i = 0; i < gc.slots.Count; i++)
		{
			if (gc.slots[i].Count > 0 && (Object)(object)gc.slots[i][0] != (Object)null)
			{
				gc.ForceWeapon(gc.slots[i][0], true);
				break;
			}
		}
	}

	public void ResetLoadout(int index)
	{
		for (int i = 0; i < OrderKeys.Length; i++)
		{
			PlayerPrefs.SetString("wl." + index + "." + OrderKeys[i], DefaultOrders[i]);
		}
		string[] weaponNames = WeaponNames;
		foreach (string text in weaponNames)
		{
			PlayerPrefs.SetInt("wl." + index + ".weapon." + text, 1);
		}
		string[] armNames = ArmNames;
		foreach (string text2 in armNames)
		{
			PlayerPrefs.SetInt("wl." + index + ".weapon." + text2, 1);
		}
		PlayerPrefs.SetInt("wl." + index + ".CurSlo", 1);
		PlayerPrefs.SetInt("wl." + index + ".CurVar", 0);
		PlayerPrefs.SetInt("wl." + index + ".CurArm", 0);
		for (int l = 0; l < 6; l++)
		{
			PlayerPrefs.SetInt("wl." + index + ".Slot" + l + "Var", -1);
		}
		PlayerPrefs.Save();
		ManualLogSource log = Log;
		if (log != null)
		{
			log.LogInfo((object)("Reset loadout " + index + " to vanilla default"));
		}
	}
}
[HarmonyPatch(typeof(GunSetter), "Start")]
internal class Patch_GunSetterStart
{
	private static void Postfix()
	{
		if (!PlayerPrefs.HasKey("wl.initialized"))
		{
			WeaponLoadouts.Instance?.SaveLoadout(0);
			PlayerPrefs.SetInt("wl.initialized", 1);
			PlayerPrefs.Save();
			ManualLogSource log = WeaponLoadouts.Log;
			if (log != null)
			{
				log.LogInfo((object)"First time setup - saved default loadout");
			}
		}
	}
}