using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("QoLMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Quality of Life mod for Goblin Buster")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e02dd8764628d1e8f9c17ba1e5b12acaeb5789cf")]
[assembly: AssemblyProduct("QoLMod")]
[assembly: AssemblyTitle("QoLMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 QoLMod
{
[BepInPlugin("com.mod.goblinbuster.qolmod", "Goblin Buster QoL Mod", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
private Harmony _harmony;
private bool _showMenu;
private Rect _windowRect = new Rect(350f, 20f, 280f, 200f);
public static bool InstantSpawnEnabled;
public static bool AutoStartWaveEnabled;
public static bool SpeedControlEnabled;
private int _selectedSpeed;
private bool _showSpeedDropdown;
private Rect _speedButtonRect;
private readonly string[] _speedNames = new string[5] { "1x (Normal)", "2x", "3x", "5x", "10x" };
private readonly float[] _speedValues = new float[5] { 1f, 2f, 3f, 5f, 10f };
private Vector2 _speedScrollPos;
private Rect _speedDropdownRect;
private const float MIN_WIDTH = 250f;
private const float MIN_HEIGHT = 180f;
private bool _isResizing;
private void Awake()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin com.mod.goblinbuster.qolmod is loaded!");
_harmony = new Harmony("com.mod.goblinbuster.qolmod");
_harmony.PatchAll();
Logger.LogInfo((object)"Harmony patches applied!");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)287))
{
_showMenu = !_showMenu;
if (!_showMenu)
{
_showSpeedDropdown = false;
}
Logger.LogInfo((object)$"QoL menu toggled: {_showMenu}");
}
}
private void OnGUI()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Expected O, but got Unknown
//IL_0044: 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)
if (_showMenu)
{
GUI.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 0.95f);
_windowRect = GUI.Window(12346, _windowRect, new WindowFunction(DrawWindow), "QoL Mod Menu");
((Rect)(ref _windowRect)).width = Mathf.Max(((Rect)(ref _windowRect)).width, 250f);
((Rect)(ref _windowRect)).height = Mathf.Max(((Rect)(ref _windowRect)).height, 180f);
}
}
private void DrawWindow(int windowId)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0227: 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_013e: Invalid comparison between Unknown and I4
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 25f, 3f, 20f, 18f), "X"))
{
_showMenu = false;
_showSpeedDropdown = false;
}
GUILayout.Space(10f);
GUILayout.Label("=== Quality of Life ===", Array.Empty<GUILayoutOption>());
InstantSpawnEnabled = GUILayout.Toggle(InstantSpawnEnabled, " Instant Enemy Spawn (all at once)", Array.Empty<GUILayoutOption>());
AutoStartWaveEnabled = GUILayout.Toggle(AutoStartWaveEnabled, " Auto-Start Next Wave", Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
bool speedControlEnabled = SpeedControlEnabled;
SpeedControlEnabled = GUILayout.Toggle(SpeedControlEnabled, " Game Speed Control", Array.Empty<GUILayoutOption>());
if (speedControlEnabled && !SpeedControlEnabled)
{
Time.timeScale = 1f;
_selectedSpeed = 0;
}
if (SpeedControlEnabled)
{
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label("Speed:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) });
if (GUILayout.Button(_speedNames[_selectedSpeed], (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }))
{
_showSpeedDropdown = !_showSpeedDropdown;
}
if ((int)Event.current.type == 7)
{
_speedButtonRect = GUILayoutUtility.GetLastRect();
}
GUILayout.EndHorizontal();
LevelManager val = Object.FindObjectOfType<LevelManager>();
if ((Object)(object)val != (Object)null && !val.IsGameOver && IsWaveActive(val))
{
Time.timeScale = _speedValues[_selectedSpeed];
}
else
{
Time.timeScale = 1f;
}
}
GUILayout.FlexibleSpace();
GUILayout.Label("Drag edges to resize", GUI.skin.label, Array.Empty<GUILayoutOption>());
GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width - 30f, 20f));
Rect val2 = default(Rect);
((Rect)(ref val2))..ctor(((Rect)(ref _windowRect)).width - 20f, ((Rect)(ref _windowRect)).height - 20f, 20f, 20f);
GUI.Box(val2, "//");
if ((int)Event.current.type == 0 && ((Rect)(ref val2)).Contains(Event.current.mousePosition))
{
_isResizing = true;
}
DrawDropdownOverlay();
}
private void DrawDropdownOverlay()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
if (!_showSpeedDropdown)
{
return;
}
float num = 110f;
_speedDropdownRect = new Rect(((Rect)(ref _speedButtonRect)).x, ((Rect)(ref _speedButtonRect)).y + ((Rect)(ref _speedButtonRect)).height, ((Rect)(ref _speedButtonRect)).width, num);
GUI.Box(_speedDropdownRect, "");
GUILayout.BeginArea(_speedDropdownRect);
_speedScrollPos = GUILayout.BeginScrollView(_speedScrollPos, Array.Empty<GUILayoutOption>());
for (int i = 0; i < _speedNames.Length; i++)
{
if (GUILayout.Button(_speedNames[i], Array.Empty<GUILayoutOption>()))
{
_selectedSpeed = i;
_showSpeedDropdown = false;
}
}
GUILayout.EndScrollView();
GUILayout.EndArea();
if ((int)Event.current.type == 0 && !((Rect)(ref _speedDropdownRect)).Contains(Event.current.mousePosition) && !((Rect)(ref _speedButtonRect)).Contains(Event.current.mousePosition))
{
_showSpeedDropdown = false;
Event.current.Use();
}
}
private void LateUpdate()
{
//IL_0018: 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_0060: 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_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
if (_isResizing)
{
if (Input.GetMouseButton(0))
{
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y);
Vector2 val2 = default(Vector2);
((Vector2)(ref val2))..ctor(((Rect)(ref _windowRect)).x, ((Rect)(ref _windowRect)).y);
((Rect)(ref _windowRect)).width = Mathf.Max(250f, val.x - val2.x + 10f);
((Rect)(ref _windowRect)).height = Mathf.Max(180f, val.y - val2.y + 10f);
}
else
{
_isResizing = false;
}
}
}
private bool IsWaveActive(LevelManager levelManager)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(LevelManager), "isSpawning");
FieldInfo fieldInfo2 = AccessTools.Field(typeof(LevelManager), "aliveEnemies");
bool num = (bool)fieldInfo.GetValue(levelManager);
int num2 = (int)fieldInfo2.GetValue(levelManager);
if (!num)
{
return num2 > 0;
}
return true;
}
}
[HarmonyPatch(typeof(WaitForSeconds))]
[HarmonyPatch(/*Could not decode attribute arguments.*/)]
[HarmonyPatch(new Type[] { typeof(float) })]
public static class WaitForSecondsPatch
{
[HarmonyPrefix]
public static void Prefix(ref float seconds)
{
if (Plugin.InstantSpawnEnabled && seconds > 0f && seconds <= 2f)
{
seconds = 0.001f;
}
}
}
[HarmonyPatch(typeof(LevelManager), "EnemyKilled")]
public static class AutoStartWavePatch
{
[CompilerGenerated]
private sealed class <DelayedStartWave>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LevelManager levelManager;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedStartWave>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (!levelManager.IsGameOver && Plugin.AutoStartWaveEnabled)
{
levelManager.StartNextWave();
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPostfix]
public static void Postfix(LevelManager __instance)
{
if (Plugin.AutoStartWaveEnabled && (int)AccessTools.Field(typeof(LevelManager), "aliveEnemies").GetValue(__instance) <= 0 && !__instance.IsGameOver)
{
((MonoBehaviour)__instance).StartCoroutine(DelayedStartWave(__instance));
}
}
[IteratorStateMachine(typeof(<DelayedStartWave>d__1))]
private static IEnumerator DelayedStartWave(LevelManager levelManager)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedStartWave>d__1(0)
{
levelManager = levelManager
};
}
}
[HarmonyPatch(typeof(LevelManager), "EnemyBlewUp")]
public static class AutoStartWaveOnExplosionPatch
{
[CompilerGenerated]
private sealed class <DelayedStartWave>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public LevelManager levelManager;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedStartWave>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (!levelManager.IsGameOver && Plugin.AutoStartWaveEnabled)
{
levelManager.StartNextWave();
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPostfix]
public static void Postfix(LevelManager __instance)
{
if (Plugin.AutoStartWaveEnabled && (int)AccessTools.Field(typeof(LevelManager), "aliveEnemies").GetValue(__instance) <= 0 && !__instance.IsGameOver)
{
((MonoBehaviour)__instance).StartCoroutine(DelayedStartWave(__instance));
}
}
[IteratorStateMachine(typeof(<DelayedStartWave>d__1))]
private static IEnumerator DelayedStartWave(LevelManager levelManager)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedStartWave>d__1(0)
{
levelManager = levelManager
};
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.mod.goblinbuster.qolmod";
public const string PLUGIN_NAME = "Goblin Buster QoL Mod";
public const string PLUGIN_VERSION = "1.0.0";
}
}