using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OpenShot.Core;
using OpenShot.UI;
using Shooterlatro.DebugTools;
using Shooterlatro.Game;
using Shooterlatro.Gameplay.RunSetup;
using Shooterlatro.Score;
using Shooterlatro.Shop;
using Shooterlatro.Upgrades;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("LuckyTest")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Sandbox build tester for Lucky Shot. Pick holos/bullets/charms/drinks, then jump into endless. Configure via OpenShot MODS hub.")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3+4135dd1490a61fe647f2a0e54287f36471f5cf7f")]
[assembly: AssemblyProduct("LuckyTest")]
[assembly: AssemblyTitle("LuckyTest")]
[assembly: AssemblyVersion("1.1.3.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 LuckyTest
{
internal sealed class CatalogEntry
{
public string Id;
public string Label;
public Object Asset;
}
internal static class CatalogCache
{
public static List<CatalogEntry> Holos { get; private set; } = new List<CatalogEntry>();
public static List<CatalogEntry> Bullets { get; private set; } = new List<CatalogEntry>();
public static List<CatalogEntry> Charms { get; private set; } = new List<CatalogEntry>();
public static List<CatalogEntry> Drinks { get; private set; } = new List<CatalogEntry>();
public static void Refresh()
{
//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: Expected O, but got Unknown
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
//IL_0020: Expected O, but got Unknown
UnityDeveloperConsoleRuntime val = new UnityDeveloperConsoleRuntime();
Holos = BuildHolos(val);
Bullets = BuildBullets(val);
Charms = BuildCharms(val);
Drinks = BuildDrinks();
}
private static List<CatalogEntry> BuildHolos(UnityDeveloperConsoleRuntime runtime)
{
List<CatalogEntry> list = new List<CatalogEntry>();
HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
IReadOnlyList<HoloItemData> readOnlyList = null;
try
{
readOnlyList = runtime.GetHolos();
}
catch
{
}
if (readOnlyList != null)
{
foreach (HoloItemData item in readOnlyList)
{
TryAddHolo(list, seen, runtime, item);
}
}
HoloItemData[] array = Resources.FindObjectsOfTypeAll<HoloItemData>();
foreach (HoloItemData holo in array)
{
TryAddHolo(list, seen, runtime, holo);
}
return list.OrderBy<CatalogEntry, string>((CatalogEntry e) => e.Id, StringComparer.OrdinalIgnoreCase).ToList();
}
private static void TryAddHolo(List<CatalogEntry> list, HashSet<string> seen, UnityDeveloperConsoleRuntime runtime, HoloItemData holo)
{
if ((Object)(object)holo == (Object)null)
{
return;
}
string text = ((!string.IsNullOrEmpty(holo.catalogId)) ? holo.catalogId : ((Object)holo).name);
if (!string.IsNullOrEmpty(text) && seen.Add(text))
{
string text2 = null;
try
{
text2 = runtime.GetHoloTitle(holo);
}
catch
{
}
if (string.IsNullOrWhiteSpace(text2))
{
text2 = ((Object)holo).name;
}
list.Add(new CatalogEntry
{
Id = text,
Label = text + " " + text2,
Asset = (Object)(object)holo
});
}
}
private static List<CatalogEntry> BuildBullets(UnityDeveloperConsoleRuntime runtime)
{
List<CatalogEntry> list = new List<CatalogEntry>();
HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
BulletItemData[] array = Resources.FindObjectsOfTypeAll<BulletItemData>();
foreach (BulletItemData val in array)
{
if (!((Object)(object)val == (Object)null) && !val.isNormalBullet)
{
string name = ((Object)val).name;
if (!string.IsNullOrEmpty(name) && hashSet.Add(name))
{
list.Add(new CatalogEntry
{
Id = name,
Label = name,
Asset = (Object)(object)val
});
}
}
}
return list.OrderBy<CatalogEntry, string>((CatalogEntry e) => e.Label, StringComparer.OrdinalIgnoreCase).ToList();
}
private static List<CatalogEntry> BuildCharms(UnityDeveloperConsoleRuntime runtime)
{
List<CatalogEntry> list = new List<CatalogEntry>();
HashSet<string> seen = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
IReadOnlyList<CharmItemData> readOnlyList = null;
try
{
readOnlyList = runtime.GetTrinkets();
}
catch
{
}
if (readOnlyList != null)
{
foreach (CharmItemData item in readOnlyList)
{
TryAddCharm(list, seen, runtime, item);
}
}
CharmItemData[] array = Resources.FindObjectsOfTypeAll<CharmItemData>();
foreach (CharmItemData charm in array)
{
TryAddCharm(list, seen, runtime, charm);
}
return list.OrderBy<CatalogEntry, string>((CatalogEntry e) => e.Label, StringComparer.OrdinalIgnoreCase).ToList();
}
private static void TryAddCharm(List<CatalogEntry> list, HashSet<string> seen, UnityDeveloperConsoleRuntime runtime, CharmItemData charm)
{
if ((Object)(object)charm == (Object)null)
{
return;
}
string name = ((Object)charm).name;
if (!string.IsNullOrEmpty(name) && seen.Add(name))
{
string text = null;
try
{
text = runtime.GetTrinketTitle(charm);
}
catch
{
}
if (string.IsNullOrWhiteSpace(text))
{
text = name;
}
list.Add(new CatalogEntry
{
Id = name,
Label = text,
Asset = (Object)(object)charm
});
}
}
private static List<CatalogEntry> BuildDrinks()
{
List<CatalogEntry> list = new List<CatalogEntry>();
HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
EnergyDrinkItemData[] array = Resources.FindObjectsOfTypeAll<EnergyDrinkItemData>();
foreach (EnergyDrinkItemData val in array)
{
if (!((Object)(object)val == (Object)null))
{
string name = ((Object)val).name;
if (!string.IsNullOrEmpty(name) && hashSet.Add(name))
{
list.Add(new CatalogEntry
{
Id = name,
Label = name,
Asset = (Object)(object)val
});
}
}
}
return list.OrderBy<CatalogEntry, string>((CatalogEntry e) => e.Label, StringComparer.OrdinalIgnoreCase).ToList();
}
}
internal static class LoadoutApplier
{
public static bool IsLaunching { get; private set; }
public static void BeginLaunch(MonoBehaviour host, HashSet<string> holoIds, HashSet<string> bulletNames, HashSet<string> charmNames, HashSet<string> drinkNames)
{
if (!((Object)(object)host == (Object)null) && !IsLaunching)
{
host.StartCoroutine(LaunchRoutine(holoIds, bulletNames, charmNames, drinkNames));
}
}
private static IEnumerator LaunchRoutine(HashSet<string> holoIds, HashSet<string> bulletNames, HashSet<string> charmNames, HashSet<string> drinkNames)
{
IsLaunching = true;
UnityDeveloperConsoleRuntime runtime = new UnityDeveloperConsoleRuntime();
try
{
PersistSelection(holoIds, bulletNames, charmNames, drinkNames);
GameManager gm = GameManager.Instance;
if ((Object)(object)gm == (Object)null)
{
LuckyTestPlugin.Log.LogError((object)"[LuckyTest] GameManager missing.");
yield break;
}
if ((int)gm.Phase == 7 || (int)gm.Phase == 8)
{
if ((int)gm.Phase == 7)
{
gm.ShowRunSetup();
}
yield return null;
yield return null;
RunSetupSelectionManager instance = RunSetupSelectionManager.Instance;
bool flag = false;
if ((Object)(object)instance != (Object)null)
{
flag = instance.TryCommitAndStartRun();
}
if (!flag)
{
gm.StartGameFromRunSetup();
}
float wait = 20f;
while (wait > 0f)
{
gm = GameManager.Instance;
if ((Object)(object)gm != (Object)null && ((int)gm.Phase == 3 || (int)gm.Phase == 5 || (int)gm.Phase == 1 || (int)gm.Phase == 0 || (int)gm.Phase == 2))
{
break;
}
wait -= Time.unscaledDeltaTime;
yield return null;
}
if (wait <= 0f)
{
LuckyTestPlugin.Log.LogWarning((object)"[LuckyTest] Timed out waiting for run start; applying loadout anyway.");
}
}
yield return null;
int num = 0;
int num2 = 0;
string text = default(string);
runtime.TryExpandHoloSlots(Mathf.Max(0, LuckyTestPlugin.ExtraHoloSlots.Value), ref num, ref num2, ref text);
HoloItemManager instance2 = HoloItemManager.Instance;
if ((Object)(object)instance2 != (Object)null)
{
instance2.ClearAllEquipped();
AccessTools.Method(typeof(HoloItemManager), "ClearAllGrantedNonPhysical", (Type[])null, (Type[])null)?.Invoke(instance2, null);
}
int equipped = 0;
foreach (string item in holoIds.OrderBy<string, string>((string s) => s, StringComparer.OrdinalIgnoreCase))
{
HoloItemData val = ResolveHolo(runtime, item);
if ((Object)(object)val == (Object)null)
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Holo not found: " + item));
}
else if (runtime.TryEquipHolo(val, ref text))
{
equipped++;
}
else
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Equip failed " + item + ": " + text));
}
}
int bulletsAdded = 0;
int num3 = Mathf.Max(1, LuckyTestPlugin.DefaultBulletAmount.Value);
foreach (string bulletName in bulletNames)
{
BulletItemData val2 = runtime.FindBullet(bulletName) ?? FindBulletByAssetName(bulletName);
if ((Object)(object)val2 == (Object)null)
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Bullet not found: " + bulletName));
}
else
{
bulletsAdded += runtime.AddBullets(val2, num3);
}
}
int charms = 0;
foreach (string charmName in charmNames)
{
CharmItemData val3 = runtime.FindTrinket(charmName) ?? FindCharmByAssetName(charmName);
if ((Object)(object)val3 == (Object)null)
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Charm not found: " + charmName));
}
else if (runtime.TryEquipTrinket(val3, ref text))
{
charms++;
}
else
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Charm failed " + charmName + ": " + text));
}
}
int drinks = 0;
string text2 = default(string);
foreach (string drinkName in drinkNames)
{
if (runtime.TryDrink(drinkName, ref text2, ref text))
{
drinks++;
}
else
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Drink failed " + drinkName + ": " + text));
}
}
int num4 = Mathf.Max(0, LuckyTestPlugin.StartingMoney.Value);
int num5 = default(int);
if (num4 > 0 && !runtime.TryAddMoney(num4, ref num5, ref text))
{
LuckyTestPlugin.Log.LogWarning((object)("[LuckyTest] Money failed: " + text));
}
yield return null;
int num6 = Mathf.Clamp(LuckyTestPlugin.StartingRound.Value, 1, 99);
if (!runtime.TryGoToLevel(num6, ref text))
{
LuckyTestPlugin.Log.LogWarning((object)$"[LuckyTest] TryGoToLevel({num6}) failed: {text}. Falling back to round index.");
ForceRoundIndex(num6);
}
gm = GameManager.Instance;
if ((Object)(object)gm != (Object)null)
{
try
{
gm.TryContinueAfterWinIntoEndless();
}
catch (Exception ex)
{
LuckyTestPlugin.Log.LogInfo((object)("[LuckyTest] TryContinueAfterWinIntoEndless: " + ex.Message));
}
}
runtime.MarkRunCheated("LuckyTest sandbox launch");
LuckyTestPlugin.Log.LogInfo((object)$"[LuckyTest] Ready — holos={equipped}, bullets={bulletsAdded}, charms={charms}, drinks={drinks}, level={num6}");
}
finally
{
IsLaunching = false;
}
}
private static void ForceRoundIndex(int oneBasedLevel)
{
ScoreManager instance = ScoreManager.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
int roundIndex = Mathf.Max(0, oneBasedLevel - 1);
instance.SetRoundIndex(roundIndex);
ShopManager instance2 = ShopManager.Instance;
if (!((Object)(object)instance2 != (Object)null))
{
return;
}
try
{
AccessTools.Method(typeof(ShopManager), "DebugSetAnteForDeveloperTools", (Type[])null, (Type[])null)?.Invoke(instance2, new object[1] { oneBasedLevel });
}
catch (Exception ex)
{
LuckyTestPlugin.Log.LogInfo((object)("[LuckyTest] DebugSetAnte: " + ex.Message));
}
}
private static HoloItemData ResolveHolo(UnityDeveloperConsoleRuntime runtime, string id)
{
if (string.IsNullOrEmpty(id))
{
return null;
}
HoloItemData val = runtime.FindHolo(id);
if ((Object)(object)val != (Object)null)
{
return val;
}
foreach (CatalogEntry holo in CatalogCache.Holos)
{
if (string.Equals(holo.Id, id, StringComparison.OrdinalIgnoreCase))
{
Object asset = holo.Asset;
HoloItemData val2 = (HoloItemData)(object)((asset is HoloItemData) ? asset : null);
if (val2 != null)
{
return val2;
}
}
}
HoloItemData[] array = Resources.FindObjectsOfTypeAll<HoloItemData>();
foreach (HoloItemData val3 in array)
{
if ((Object)(object)val3 != (Object)null && (string.Equals(val3.catalogId, id, StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val3).name, id, StringComparison.OrdinalIgnoreCase)))
{
return val3;
}
}
return null;
}
private static BulletItemData FindBulletByAssetName(string name)
{
BulletItemData[] array = Resources.FindObjectsOfTypeAll<BulletItemData>();
foreach (BulletItemData val in array)
{
if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase))
{
return val;
}
}
return null;
}
private static CharmItemData FindCharmByAssetName(string name)
{
CharmItemData[] array = Resources.FindObjectsOfTypeAll<CharmItemData>();
foreach (CharmItemData val in array)
{
if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase))
{
return val;
}
}
return null;
}
private static void PersistSelection(HashSet<string> holos, HashSet<string> bullets, HashSet<string> charms, HashSet<string> drinks)
{
LuckyTestPlugin.SavedHoloIds.Value = string.Join(",", holos.OrderBy((string s) => s));
LuckyTestPlugin.SavedBulletNames.Value = string.Join(",", bullets.OrderBy((string s) => s));
LuckyTestPlugin.SavedCharmNames.Value = string.Join(",", charms.OrderBy((string s) => s));
LuckyTestPlugin.SavedDrinkNames.Value = string.Join(",", drinks.OrderBy((string s) => s));
((BaseUnityPlugin)LuckyTestPlugin.Instance).Config.Save();
}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.liamgaming.luckytest", "LuckyTest", "1.1.3")]
public class LuckyTestPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.liamgaming.luckytest";
public const string PluginName = "LuckyTest";
public const string PluginVersion = "1.1.3";
private TesterPanel _panel;
private KeyCode _boundKey;
private static readonly KeyCode[] HotkeyCycle;
public static LuckyTestPlugin Instance { get; private set; }
public static ManualLogSource Log { get; private set; }
public static ConfigEntry<bool> Enabled { get; private set; }
public static ConfigEntry<int> StartingRound { get; private set; }
public static ConfigEntry<int> StartingMoney { get; private set; }
public static ConfigEntry<int> ExtraHoloSlots { get; private set; }
public static ConfigEntry<int> DefaultBulletAmount { get; private set; }
public static ConfigEntry<bool> OpenPanelOnMainMenu { get; private set; }
public static ConfigEntry<KeyCode> ToggleKey { get; private set; }
public static ConfigEntry<string> SavedHoloIds { get; private set; }
public static ConfigEntry<string> SavedBulletNames { get; private set; }
public static ConfigEntry<string> SavedCharmNames { get; private set; }
public static ConfigEntry<string> SavedDrinkNames { get; private set; }
private void Awake()
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Expected O, but got Unknown
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Expected O, but got Unknown
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Expected O, but got Unknown
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Expected O, but got Unknown
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_02b4: Expected O, but got Unknown
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
//IL_032c: Unknown result type (might be due to invalid IL or missing references)
//IL_0374: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch for LuckyTest.");
OpenPanelOnMainMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OpenPanelOnMainMenu", true, "When shooting the LUCKY TEST main-menu card, open the builder panel.");
StartingRound = ((BaseUnityPlugin)this).Config.Bind<int>("Launch", "StartingRound", 9, new ConfigDescription("1-based level/ante to jump to after applying the loadout (endless-friendly).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 99), Array.Empty<object>()));
StartingMoney = ((BaseUnityPlugin)this).Config.Bind<int>("Launch", "StartingMoney", 1000, new ConfigDescription("Money granted when launching a test run.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999999), Array.Empty<object>()));
ExtraHoloSlots = ((BaseUnityPlugin)this).Config.Bind<int>("Launch", "ExtraHoloSlots", 20, new ConfigDescription("Extra holo slots unlocked before equipping.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
DefaultBulletAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Launch", "DefaultBulletAmount", 8, new ConfigDescription("How many of each selected special bullet to grant.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 64), Array.Empty<object>()));
ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)288, "Keyboard key to open/close the LuckyTest panel.");
SavedHoloIds = ((BaseUnityPlugin)this).Config.Bind<string>("SavedLoadout", "HoloIds", "", "Comma-separated holo catalog IDs remembered between sessions.");
SavedBulletNames = ((BaseUnityPlugin)this).Config.Bind<string>("SavedLoadout", "BulletNames", "", "Comma-separated bullet asset names.");
SavedCharmNames = ((BaseUnityPlugin)this).Config.Bind<string>("SavedLoadout", "CharmNames", "", "Comma-separated charm/trinket asset names.");
SavedDrinkNames = ((BaseUnityPlugin)this).Config.Bind<string>("SavedLoadout", "DrinkNames", "", "Comma-separated energy drink asset names.");
ModMenu.Tab("LuckyTest").Toggle(Enabled).Info("— Launch —")
.Int("Start Round", StartingRound, 1)
.Int("Start Money", StartingMoney, 50)
.Int("Extra Holo Slots", ExtraHoloSlots, 1)
.Int("Bullet Amount", DefaultBulletAmount, 1)
.Info("— Panel —")
.Bool("Menu Card Opens Panel", OpenPanelOnMainMenu)
.Cycle("Hotkey", (Func<string>)(() => ((object)ToggleKey.Value/*cast due to .constrained prefix*/).ToString()), (Action)CycleToggleKey)
.Button("Open Panel", (Action)delegate
{
if ((Object)(object)_panel != (Object)null)
{
_panel.Toggle();
}
});
GameObject val = new GameObject("LuckyTest");
Object.DontDestroyOnLoad((Object)(object)val);
_panel = val.AddComponent<TesterPanel>();
_boundKey = ToggleKey.Value;
InputAPI.RegisterKeyCallback(_boundKey, (Action)OnHotkey);
ToggleKey.SettingChanged += delegate
{
};
MainMenu.WhenReady((Action)delegate
{
MainMenu.AddButton("LUCKY TEST", (Action)delegate
{
if (Enabled.Value && OpenPanelOnMainMenu.Value)
{
_panel?.Open();
}
});
});
new Harmony("com.liamgaming.luckytest").PatchAll(typeof(LuckyTestPlugin).Assembly);
Log.LogInfo((object)string.Format("{0} v{1} loaded (OpenShot {2}). Hotkey {3}.", "LuckyTest", "1.1.3", "2.0.3", ToggleKey.Value));
}
private void OnHotkey()
{
if (Enabled.Value && !((Object)(object)_panel == (Object)null))
{
_panel.Toggle();
}
}
private static void CycleToggleKey()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
int num = Array.IndexOf(HotkeyCycle, ToggleKey.Value);
if (num < 0)
{
num = 0;
}
ToggleKey.Value = HotkeyCycle[(num + 1) % HotkeyCycle.Length];
}
static LuckyTestPlugin()
{
KeyCode[] array = new KeyCode[7];
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
HotkeyCycle = (KeyCode[])(object)array;
}
}
internal sealed class TesterPanel : MonoBehaviour
{
private enum Tab
{
Holos,
Bullets,
Charms,
Drinks,
Launch
}
private bool _visible;
private Tab _tab;
private Vector2 _scroll;
private string _filter = "";
private string _status = "Pick a loadout, then Launch.";
private Rect _window = new Rect(80f, 60f, 820f, 560f);
private readonly HashSet<string> _holos = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _bullets = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _charms = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _drinks = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private CursorLockMode _prevLock;
private bool _prevCursor;
private bool _catalogReady;
public void Open()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
if (!_visible)
{
_prevLock = Cursor.lockState;
_prevCursor = Cursor.visible;
_visible = true;
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
EnsureCatalog();
LoadSavedSelection();
}
}
public void Close()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
if (_visible)
{
_visible = false;
Cursor.lockState = _prevLock;
Cursor.visible = _prevCursor;
}
}
public void Toggle()
{
if (_visible)
{
Close();
}
else
{
Open();
}
}
private void Update()
{
if (_visible && InputAPI.WasPressedThisFrame((KeyCode)27))
{
Close();
}
}
private void OnGUI()
{
//IL_001c: 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_0037: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
if (_visible && LuckyTestPlugin.Enabled.Value)
{
_window = GUI.Window(8742101, _window, new WindowFunction(DrawWindow), "LuckyTest — Build Sandbox");
}
}
private void DrawWindow(int id)
{
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
DrawTabButton(Tab.Holos, $"Holos ({_holos.Count})");
DrawTabButton(Tab.Bullets, $"Bullets ({_bullets.Count})");
DrawTabButton(Tab.Charms, $"Charms ({_charms.Count})");
DrawTabButton(Tab.Drinks, $"Drinks ({_drinks.Count})");
DrawTabButton(Tab.Launch, "Launch");
GUILayout.EndHorizontal();
GUILayout.Space(6f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Filter", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f) });
_filter = GUILayout.TextField(_filter ?? "", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (GUILayout.Button("Refresh", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }))
{
CatalogCache.Refresh();
_catalogReady = true;
_status = $"Catalog refreshed — holos={CatalogCache.Holos.Count}, bullets={CatalogCache.Bullets.Count}";
}
if (GUILayout.Button("Clear Tab", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
{
ClearCurrentTab();
}
GUILayout.EndHorizontal();
GUILayout.Space(4f);
_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
switch (_tab)
{
case Tab.Holos:
DrawPicker(CatalogCache.Holos, _holos);
break;
case Tab.Bullets:
DrawPicker(CatalogCache.Bullets, _bullets);
break;
case Tab.Charms:
DrawPicker(CatalogCache.Charms, _charms);
break;
case Tab.Drinks:
DrawPicker(CatalogCache.Drinks, _drinks);
break;
case Tab.Launch:
DrawLaunchTab();
break;
}
GUILayout.EndScrollView();
GUILayout.Space(4f);
GUILayout.Label(_status, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
{
Close();
}
GUI.enabled = !LoadoutApplier.IsLaunching;
if (GUILayout.Button(LoadoutApplier.IsLaunching ? "Launching…" : "START TEST RUN", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
{
StartTest();
}
GUI.enabled = true;
GUILayout.EndHorizontal();
GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
}
private void DrawTabButton(Tab tab, string label)
{
//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_001e: 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)
Color backgroundColor = GUI.backgroundColor;
if (_tab == tab)
{
GUI.backgroundColor = new Color(0.2f, 0.75f, 0.55f);
}
if (GUILayout.Button(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }))
{
_tab = tab;
}
GUI.backgroundColor = backgroundColor;
}
private void DrawPicker(List<CatalogEntry> entries, HashSet<string> selected)
{
if (entries == null || entries.Count == 0)
{
GUILayout.Label("No items found yet. Enter a run once, or hit Refresh after the game has loaded assets.", Array.Empty<GUILayoutOption>());
return;
}
string value = (_filter ?? "").Trim();
foreach (CatalogEntry entry in entries)
{
if (!string.IsNullOrEmpty(value) && entry.Label.IndexOf(value, StringComparison.OrdinalIgnoreCase) < 0 && entry.Id.IndexOf(value, StringComparison.OrdinalIgnoreCase) < 0)
{
continue;
}
bool flag = selected.Contains(entry.Id);
bool flag2 = GUILayout.Toggle(flag, entry.Label, Array.Empty<GUILayoutOption>());
if (flag2 != flag)
{
if (flag2)
{
selected.Add(entry.Id);
}
else
{
selected.Remove(entry.Id);
}
}
}
}
private void DrawLaunchTab()
{
GUILayout.Label("Launch jumps into a run (if needed), equips your picks, then GoToLevel(StartingRound).", Array.Empty<GUILayoutOption>());
GUILayout.Space(6f);
GUILayout.Label($"Starting round (1-based): {LuckyTestPlugin.StartingRound.Value}", Array.Empty<GUILayoutOption>());
LuckyTestPlugin.StartingRound.Value = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)LuckyTestPlugin.StartingRound.Value, 1f, 40f, Array.Empty<GUILayoutOption>()));
GUILayout.Label($"Starting money: {LuckyTestPlugin.StartingMoney.Value}", Array.Empty<GUILayoutOption>());
LuckyTestPlugin.StartingMoney.Value = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)LuckyTestPlugin.StartingMoney.Value, 0f, 5000f, Array.Empty<GUILayoutOption>()) / 50f) * 50;
GUILayout.Label($"Extra holo slots: {LuckyTestPlugin.ExtraHoloSlots.Value}", Array.Empty<GUILayoutOption>());
LuckyTestPlugin.ExtraHoloSlots.Value = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)LuckyTestPlugin.ExtraHoloSlots.Value, 0f, 40f, Array.Empty<GUILayoutOption>()));
GUILayout.Label($"Bullets per type: {LuckyTestPlugin.DefaultBulletAmount.Value}", Array.Empty<GUILayoutOption>());
LuckyTestPlugin.DefaultBulletAmount.Value = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)LuckyTestPlugin.DefaultBulletAmount.Value, 1f, 32f, Array.Empty<GUILayoutOption>()));
GUILayout.Space(8f);
GUILayout.Label($"Selected — Holos {_holos.Count} | Bullets {_bullets.Count} | Charms {_charms.Count} | Drinks {_drinks.Count}", Array.Empty<GUILayoutOption>());
GUILayout.Label("Tip: set Starting Round past the normal win ante (default 9) to land in endless scoring.", Array.Empty<GUILayoutOption>());
}
private void StartTest()
{
EnsureCatalog();
_status = "Launching test run…";
Close();
LoadoutApplier.BeginLaunch((MonoBehaviour)(object)this, Clone(_holos), Clone(_bullets), Clone(_charms), Clone(_drinks));
}
private static HashSet<string> Clone(HashSet<string> src)
{
return new HashSet<string>(src, StringComparer.OrdinalIgnoreCase);
}
private void ClearCurrentTab()
{
switch (_tab)
{
case Tab.Holos:
_holos.Clear();
break;
case Tab.Bullets:
_bullets.Clear();
break;
case Tab.Charms:
_charms.Clear();
break;
case Tab.Drinks:
_drinks.Clear();
break;
}
}
private void EnsureCatalog()
{
if (!_catalogReady || CatalogCache.Holos.Count <= 0)
{
CatalogCache.Refresh();
_catalogReady = true;
}
}
private void LoadSavedSelection()
{
Fill(_holos, LuckyTestPlugin.SavedHoloIds.Value);
Fill(_bullets, LuckyTestPlugin.SavedBulletNames.Value);
Fill(_charms, LuckyTestPlugin.SavedCharmNames.Value);
Fill(_drinks, LuckyTestPlugin.SavedDrinkNames.Value);
}
private static void Fill(HashSet<string> set, string csv)
{
set.Clear();
if (string.IsNullOrWhiteSpace(csv))
{
return;
}
string[] array = csv.Split(new char[3] { ',', ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < array.Length; i++)
{
string text = array[i].Trim();
if (text.Length > 0)
{
set.Add(text);
}
}
}
}
}