using System;
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 PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ULTRAKILLME")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("fucking kill yourself")]
[assembly: AssemblyTitle("ULTRAKILLME")]
[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 ULTRAKILLME
{
[BepInPlugin("ULTRAKILLME", "fucking kill yourself", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
internal static PluginConfigurator Config;
internal static BoolField ConfigMasterEnable;
internal static BoolField ConfigRandomEnemies;
internal static BoolField ConfigRandomLevels;
internal static BoolField ConfigRandomGuns;
internal static BoolField ConfigRandomHp;
internal static BoolField ConfigRandomDifficulty;
internal static BoolField ConfigRandomProjectiles;
internal static int SceneLoadCount;
internal static bool ModEnabled => ConfigMasterEnable == null || ConfigMasterEnable.value;
internal static bool WarmupDone => SceneLoadCount >= 2;
internal static bool RandomEnemiesEnabled => ModEnabled && WarmupDone && (ConfigRandomEnemies == null || ConfigRandomEnemies.value);
internal static bool RandomLevelsEnabled => ModEnabled && WarmupDone && (ConfigRandomLevels == null || ConfigRandomLevels.value);
internal static bool RandomGunsEnabled => ModEnabled && WarmupDone && (ConfigRandomGuns == null || ConfigRandomGuns.value);
internal static bool RandomHpEnabled => ModEnabled && WarmupDone && (ConfigRandomHp == null || ConfigRandomHp.value);
internal static bool RandomDifficultyEnabled => ModEnabled && WarmupDone && (ConfigRandomDifficulty == null || ConfigRandomDifficulty.value);
internal static bool RandomProjectilesEnabled => ModEnabled && WarmupDone && (ConfigRandomProjectiles == null || ConfigRandomProjectiles.value);
private void Awake()
{
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Expected O, but got Unknown
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected O, but got Unknown
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Expected O, but got Unknown
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Expected O, but got Unknown
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin ULTRAKILLME is loaded!");
try
{
Config = PluginConfigurator.Create("ULTRAKILLME", "ULTRAKILLME");
ConfigPanel rootPanel = Config.rootPanel;
ConfigMasterEnable = new BoolField(rootPanel, "Enable ULTRAKILLME", "ultrakillme.master_enable", true);
ConfigRandomEnemies = new BoolField(rootPanel, "Random Enemies", "ultrakillme.random_enemies", true);
ConfigRandomLevels = new BoolField(rootPanel, "Random Levels", "ultrakillme.random_levels", true);
ConfigRandomGuns = new BoolField(rootPanel, "Random Guns", "ultrakillme.random_guns", true);
ConfigRandomHp = new BoolField(rootPanel, "Random HP", "ultrakillme.random_hp", true);
ConfigRandomDifficulty = new BoolField(rootPanel, "Random Difficulty", "ultrakillme.random_difficulty", true);
ConfigRandomProjectiles = new BoolField(rootPanel, "Random Projectiles", "ultrakillme.random_projectiles", true);
}
catch (Exception arg)
{
Logger.LogWarning((object)$"ULTRAKILLME: UKPluginConfigurator not found or failed to init config: {arg}");
}
try
{
Harmony val = new Harmony("ULTRAKILLME");
val.PatchAll();
Logger.LogInfo((object)"ULTRAKILLME: Harmony patches applied.");
}
catch (Exception arg2)
{
Logger.LogError((object)$"ULTRAKILLME: Failed to apply Harmony patches: {arg2}");
}
}
internal static bool IsMainMenuSceneName(string name)
{
if (string.IsNullOrEmpty(name))
{
return false;
}
string text = name.ToLowerInvariant();
return text.Contains("main menu") || text.Contains("mainmenu");
}
}
internal static class WeaponRandomizerUtil
{
public static void RandomizeWeapons(GunControl gc)
{
try
{
if (!Plugin.RandomGunsEnabled || (Object)(object)gc == (Object)null)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(GunControl), "slots");
if (fieldInfo == null || !(fieldInfo.GetValue(gc) is List<List<GameObject>> list) || list.Count == 0)
{
return;
}
bool flag = false;
for (int i = 0; i < list.Count; i++)
{
List<GameObject> list2 = list[i];
if (list2 == null || list2.Count == 0)
{
continue;
}
int count = list2.Count;
int num = Random.Range(0, count + 1);
if (num == count)
{
flag = true;
continue;
}
int[] array = new int[count];
for (int j = 0; j < count; j++)
{
array[j] = j;
}
for (int k = 0; k < count; k++)
{
int num2 = Random.Range(k, count);
int num3 = array[k];
array[k] = array[num2];
array[num2] = num3;
}
if (num <= 0)
{
list2.Clear();
continue;
}
List<GameObject> list3 = new List<GameObject>();
for (int l = 0; l < num; l++)
{
int num4 = array[l];
if (num4 >= 0 && num4 < count && (Object)(object)list2[num4] != (Object)null)
{
list3.Add(list2[num4]);
}
}
list2.Clear();
if (list3.Count > 0)
{
list2.AddRange(list3);
flag = true;
}
}
FieldInfo fieldInfo2 = AccessTools.Field(typeof(GunControl), "noWeapons");
if (fieldInfo2 != null)
{
fieldInfo2.SetValue(gc, !flag);
}
if (!flag)
{
return;
}
List<int> list4 = new List<int>();
for (int m = 0; m < list.Count; m++)
{
List<GameObject> list5 = list[m];
if (list5 != null && list5.Count > 0)
{
list4.Add(m);
}
}
if (list4.Count != 0)
{
int num5 = list4[Random.Range(0, list4.Count)];
List<GameObject> list6 = list[num5];
int num6 = Random.Range(0, list6.Count);
GameObject value = list6[num6];
FieldInfo fieldInfo3 = AccessTools.Field(typeof(GunControl), "currentSlotIndex");
FieldInfo fieldInfo4 = AccessTools.Field(typeof(GunControl), "currentVariationIndex");
FieldInfo fieldInfo5 = AccessTools.Field(typeof(GunControl), "currentWeapon");
if (fieldInfo3 != null)
{
fieldInfo3.SetValue(gc, num5 + 1);
}
if (fieldInfo4 != null)
{
fieldInfo4.SetValue(gc, num6);
}
if (fieldInfo5 != null)
{
fieldInfo5.SetValue(gc, value);
}
MethodInfo methodInfo = AccessTools.Method(typeof(GunControl), "UpdateWeaponList", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(gc, new object[1] { false });
}
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing weapons: {arg}");
}
}
}
}
[HarmonyPatch(typeof(GunControl), "Start")]
internal static class GunControl_Start_Patch
{
private static void Postfix(GunControl __instance)
{
if (Plugin.RandomGunsEnabled)
{
WeaponRandomizerUtil.RandomizeWeapons(__instance);
}
}
}
[HarmonyPatch(typeof(GunSetter), "ResetWeapons")]
internal static class GunSetter_ResetWeapons_Patch
{
private static void Postfix()
{
try
{
if (Plugin.RandomGunsEnabled)
{
GunControl instance = MonoSingleton<GunControl>.Instance;
WeaponRandomizerUtil.RandomizeWeapons(instance);
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error re-randomizing weapons after ResetWeapons: {arg}");
}
}
}
}
[HarmonyPatch(typeof(StatsManager), "Restart")]
internal static class StatsManager_Restart_Patch
{
private static bool Prefix(StatsManager __instance)
{
if (!Plugin.RandomLevelsEnabled)
{
return true;
}
try
{
MonoSingleton<MusicManager>.Instance.ArenaMusicEnd();
__instance.timer = true;
string text = null;
for (int i = 0; i < 10; i++)
{
int num = Random.Range(0, 50);
string sceneName = GetMissionName.GetSceneName(num);
if (!string.IsNullOrEmpty(sceneName) && !Plugin.IsMainMenuSceneName(sceneName))
{
text = sceneName;
break;
}
}
if (!string.IsNullOrEmpty(text))
{
SceneHelper.LoadScene(text, false);
}
else
{
SceneHelper.RestartScene();
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing death restart: {arg}");
}
return true;
}
return false;
}
}
[HarmonyPatch(typeof(NewMovement), "Start")]
internal static class NewMovement_Start_Patch
{
private static void Postfix(NewMovement __instance)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
if (Plugin.RandomHpEnabled)
{
int num = Random.Range(1, 201);
FieldInfo fieldInfo = AccessTools.Field(typeof(NewMovement), "hp");
if (fieldInfo != null)
{
fieldInfo.SetValue(__instance, num);
}
FieldInfo fieldInfo2 = AccessTools.Field(typeof(NewMovement), "maxHp");
if (fieldInfo2 != null)
{
fieldInfo2.SetValue(__instance, num);
}
}
if (!Plugin.RandomDifficultyEnabled)
{
return;
}
PrefsManager instance = MonoSingleton<PrefsManager>.Instance;
if (!((Object)(object)instance != (Object)null))
{
return;
}
int num2 = Random.Range(0, 5);
instance.SetInt("difficulty", num2);
FieldInfo fieldInfo3 = AccessTools.Field(typeof(NewMovement), "difficulty");
if (fieldInfo3 != null)
{
fieldInfo3.SetValue(__instance, num2);
}
try
{
HudMessageReceiver instance2 = MonoSingleton<HudMessageReceiver>.Instance;
if ((Object)(object)instance2 != (Object)null)
{
string text = "Difficulty Selected: " + num2 switch
{
0 => "HARMLESS",
1 => "LENIENT",
2 => "STANDARD",
3 => "VIOLENT",
4 => "BRUTAL",
_ => num2.ToString(),
};
instance2.SendHudMessage(text, "", "", 0, false, true, true);
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error sending difficulty HUD message: {arg}");
}
}
}
catch (Exception arg2)
{
ManualLogSource logger2 = Plugin.Logger;
if (logger2 != null)
{
logger2.LogError((object)$"ULTRAKILLME: Error randomizing player HP: {arg2}");
}
}
}
}
internal static class EnemyRandomizerUtil
{
private static GameObject[] _cachedPool;
public static GameObject[] GetRandomEnemyPool()
{
if (_cachedPool == null || _cachedPool.Length == 0)
{
try
{
SpawnableObjectsDatabase[] array = Resources.FindObjectsOfTypeAll<SpawnableObjectsDatabase>();
if (array != null && array.Length != 0)
{
SpawnableObjectsDatabase val = array[0];
if (val.enemies != null && val.enemies.Length != 0)
{
_cachedPool = (GameObject[])(object)new GameObject[val.enemies.Length];
for (int i = 0; i < val.enemies.Length; i++)
{
SpawnableObject val2 = val.enemies[i];
_cachedPool[i] = (((Object)(object)val2 != (Object)null) ? val2.gameObject : null);
}
_cachedPool = Array.FindAll(_cachedPool, (GameObject go) => (Object)(object)go != (Object)null);
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogInfo((object)$"ULTRAKILLME: Built enemy pool from SpawnableObjectsDatabase with {_cachedPool.Length} entries.");
}
}
}
}
catch (Exception arg)
{
ManualLogSource logger2 = Plugin.Logger;
if (logger2 != null)
{
logger2.LogError((object)$"ULTRAKILLME: Failed building enemy pool: {arg}");
}
_cachedPool = Array.Empty<GameObject>();
}
}
return _cachedPool ?? Array.Empty<GameObject>();
}
public static GameObject GetRandomEnemyTemplate()
{
GameObject[] randomEnemyPool = GetRandomEnemyPool();
if (randomEnemyPool.Length == 0)
{
return null;
}
for (int i = 0; i < 10; i++)
{
int num = Random.Range(0, randomEnemyPool.Length);
GameObject val = randomEnemyPool[num];
if (!((Object)(object)val == (Object)null))
{
string name = ((Object)val).name;
if (name.IndexOf("Minos", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("Sisyphus", StringComparison.OrdinalIgnoreCase) < 0)
{
return val;
}
if (Random.value < 0.1f)
{
return val;
}
}
}
return randomEnemyPool[Random.Range(0, randomEnemyPool.Length)];
}
}
[HarmonyPatch(typeof(ActivateArena), "SpawnEnemy")]
internal static class ActivateArena_SpawnEnemy_Patch
{
private static void Prefix(ActivateArena __instance)
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: 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_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!Plugin.RandomEnemiesEnabled || (Object)(object)__instance == (Object)null || __instance.enemies == null || __instance.enemies.Length == 0)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(ActivateArena), "currentEnemy");
if (fieldInfo == null)
{
return;
}
int num = (int)fieldInfo.GetValue(__instance);
if (num < 0 || num >= __instance.enemies.Length)
{
return;
}
GameObject val = __instance.enemies[num];
if (!((Object)(object)val == (Object)null))
{
GameObject randomEnemyTemplate = EnemyRandomizerUtil.GetRandomEnemyTemplate();
if (!((Object)(object)randomEnemyTemplate == (Object)null))
{
Vector3 position = val.transform.position;
Quaternion rotation = val.transform.rotation;
Transform parent = val.transform.parent;
val.SetActive(false);
GameObject val2 = Object.Instantiate<GameObject>(randomEnemyTemplate, position, rotation, parent);
val2.SetActive(true);
}
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing arena spawn: {arg}");
}
}
}
}
[HarmonyPatch(typeof(ActivateNextWave), "SpawnEnemy")]
internal static class ActivateNextWave_SpawnEnemy_Patch
{
private static void Prefix(ActivateNextWave __instance)
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: 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_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!Plugin.RandomEnemiesEnabled || (Object)(object)__instance == (Object)null || __instance.nextEnemies == null || __instance.nextEnemies.Length == 0)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(typeof(ActivateNextWave), "currentEnemy");
if (fieldInfo == null)
{
return;
}
int num = (int)fieldInfo.GetValue(__instance);
if (num < 0 || num >= __instance.nextEnemies.Length)
{
return;
}
GameObject val = __instance.nextEnemies[num];
if (!((Object)(object)val == (Object)null))
{
GameObject randomEnemyTemplate = EnemyRandomizerUtil.GetRandomEnemyTemplate();
if (!((Object)(object)randomEnemyTemplate == (Object)null))
{
Vector3 position = val.transform.position;
Quaternion rotation = val.transform.rotation;
Transform parent = val.transform.parent;
val.SetActive(false);
GameObject val2 = Object.Instantiate<GameObject>(randomEnemyTemplate, position, rotation, parent);
val2.SetActive(true);
}
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing wave spawn: {arg}");
}
}
}
}
[HarmonyPatch(typeof(SceneHelper), "LoadScene")]
internal static class SceneHelper_LoadScene_Patch
{
private static void Prefix(ref string sceneName)
{
try
{
Plugin.SceneLoadCount++;
if (!Plugin.RandomLevelsEnabled || Plugin.IsMainMenuSceneName(sceneName))
{
return;
}
for (int i = 0; i < 10; i++)
{
int num = Random.Range(0, 50);
string sceneName2 = GetMissionName.GetSceneName(num);
if (!string.IsNullOrEmpty(sceneName2) && !Plugin.IsMainMenuSceneName(sceneName2))
{
sceneName = sceneName2;
break;
}
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing scene load: {arg}");
}
}
}
}
[HarmonyPatch(typeof(Projectile), "Start")]
internal static class Projectile_Start_Patch
{
private static void Postfix(Projectile __instance)
{
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
try
{
if (!((Object)(object)__instance == (Object)null) && Plugin.RandomProjectilesEnabled)
{
__instance.speed *= Random.Range(0.5f, 2f);
__instance.damage *= Random.Range(0.5f, 3f);
HomingType[] array = (HomingType[])Enum.GetValues(typeof(HomingType));
if (array.Length != 0)
{
__instance.homingType = array[Random.Range(0, array.Length)];
}
if (Random.value < 0.3f)
{
__instance.explosive = true;
}
if (Random.value < 0.2f)
{
__instance.bigExplosion = true;
}
}
}
catch (Exception arg)
{
ManualLogSource logger = Plugin.Logger;
if (logger != null)
{
logger.LogError((object)$"ULTRAKILLME: Error randomizing projectile: {arg}");
}
}
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "ULTRAKILLME";
public const string PLUGIN_NAME = "fucking kill yourself";
public const string PLUGIN_VERSION = "1.0.0";
}
}