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");
}
}
}
}