using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using Microsoft.CodeAnalysis;
using NonStopHallsGauntlet;
using NonStopHallsGauntlet.Enemies;
using NonStopHallsGauntlet.Player;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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;
}
}
}
[HarmonyPatch]
public class Battle
{
public class EnemyDefinition
{
public Enemy Type;
public string DisplayName;
public string PrefabNameMatch;
public int Count;
public Vector3 SpawnMin;
public Vector3 SpawnMax;
}
public static BattleScene scene;
public static List<GameObject> enemyPool = new List<GameObject>();
public static int totalEnemies;
private static int maxEnemies;
public static int enemyHeal;
private static readonly Dictionary<Enemy, EnemyDefinition> Enemies = new Dictionary<Enemy, EnemyDefinition>
{
{
Enemy.Reed,
new EnemyDefinition
{
Type = Enemy.Reed,
DisplayName = "Reed",
PrefabNameMatch = "Song Reed"
}
},
{
Enemy.Bellringer,
new EnemyDefinition
{
Type = Enemy.Bellringer,
DisplayName = "Bellringer",
PrefabNameMatch = "Song Pilgrim 01"
}
},
{
Enemy.Choristor,
new EnemyDefinition
{
Type = Enemy.Choristor,
DisplayName = "Choristor",
PrefabNameMatch = "Song Pilgrim 03"
}
},
{
Enemy.Maiden,
new EnemyDefinition
{
Type = Enemy.Maiden,
DisplayName = "Clawmaiden",
PrefabNameMatch = "Song Handmaiden"
}
},
{
Enemy.Administrator,
new EnemyDefinition
{
Type = Enemy.Administrator,
DisplayName = "Admin",
PrefabNameMatch = "Song Administrator"
}
},
{
Enemy.Bellbearer,
new EnemyDefinition
{
Type = Enemy.Bellbearer,
DisplayName = "Bellbearer",
PrefabNameMatch = "Pilgrim 03 Song"
}
},
{
Enemy.Maestro,
new EnemyDefinition
{
Type = Enemy.Maestro,
DisplayName = "Maestro",
PrefabNameMatch = "Song Pilgrim Maestro"
}
},
{
Enemy.Sentry,
new EnemyDefinition
{
Type = Enemy.Sentry,
DisplayName = "Sentry",
PrefabNameMatch = "Song Heavy Sentry (2)"
}
}
};
private static bool IsHang04()
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
Scene activeScene = SceneManager.GetActiveScene();
return ((Scene)(ref activeScene)).name.Contains("Hang_04");
}
[HarmonyPatch(typeof(BattleScene), "DoStartBattle")]
[HarmonyPostfix]
public static void Postfix_DoStartBattle(BattleScene __instance)
{
if (!IsHang04())
{
return;
}
scene = __instance;
foreach (EnemyDefinition value in Enemies.Values)
{
value.Count = 0;
}
enemyPool = BuildEnemyPool(__instance);
foreach (BattleWave wave in __instance.waves)
{
((Component)wave).gameObject.SetActive(false);
}
maxEnemies = Plugin.numEnemies.Value;
enemyHeal = Plugin.enemyHeal.Value;
((MonoBehaviour)scene).StartCoroutine(InitOverlayAndStart());
PlayerDeathSave();
Plugin.Instance.replenishManagerGO.AddComponent<ReplenishManager>();
PlayerSkills.Skills();
}
[HarmonyPatch(typeof(BattleScene), "DecrementEnemy")]
[HarmonyPostfix]
private static void Postfix_EnemyDeath()
{
if (IsHang04())
{
totalEnemies--;
if (totalEnemies <= 0)
{
((MonoBehaviour)scene).StartCoroutine(SpawnEndlessWave(scene, enemyPool));
}
}
}
private static IEnumerator InitOverlayAndStart()
{
yield return (object)new WaitForSeconds(1f);
foreach (EnemyDefinition def2 in Enemies.Values)
{
OverlayEnemies.Instance.TriggerOverlay(def2.DisplayName);
yield return (object)new WaitForSeconds(0.1f);
}
yield return (object)new WaitForSeconds(0.1f);
foreach (EnemyDefinition def in Enemies.Values)
{
OverlayEnemies.Instance.SetOverlayText(def.DisplayName, def.Count.ToString());
}
((MonoBehaviour)scene).StartCoroutine(SpawnEndlessWave(scene, enemyPool));
}
public static List<GameObject> BuildEnemyPool(BattleScene scene)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
List<GameObject> list = new List<GameObject>();
foreach (BattleWave wave in scene.waves)
{
if (!Object.op_Implicit((Object)(object)wave))
{
continue;
}
foreach (Transform item in ((Component)wave).transform)
{
Transform child = item;
EnemyDefinition enemyDefinition = Enemies.Values.FirstOrDefault((EnemyDefinition e) => ((Object)child).name == e.PrefabNameMatch);
if (enemyDefinition != null && !list.Any((GameObject p) => ((Object)p).name == ((Object)child).name))
{
GameObject val = Object.Instantiate<GameObject>(((Component)child).gameObject);
((Object)val).name = ((Object)child).name;
val.SetActive(false);
val.AddComponent<EnemyHeal>();
val.AddComponent<EnemyTag>().Type = enemyDefinition.Type;
list.Add(val);
}
}
}
return list;
}
public static IEnumerator SpawnEndlessWave(BattleScene scene, List<GameObject> pool)
{
yield return (object)new WaitForSeconds(Random.Range(0.5f, 1f));
int countToSpawn = Random.Range(2, maxEnemies + 1);
float minX = 23f;
float maxX = 39f;
float spacing = (maxX - minX) / (float)(countToSpawn - 1);
totalEnemies = 0;
GameObject waveGO = new GameObject("Wave_Endless");
waveGO.transform.SetParent(((Component)scene).transform, false);
for (int i = 0; i < countToSpawn; i++)
{
GameObject prefab = Object.Instantiate<GameObject>(pool[Random.Range(0, pool.Count)], waveGO.transform);
EnemyTag tag = prefab.GetComponent<EnemyTag>();
_ = Enemies[tag.Type];
float x = minX + spacing * (float)i;
if (tag.Type == Enemy.Choristor)
{
prefab.transform.position = new Vector3(x + Random.Range(-1f, 1f), Random.Range(9f, 10f), 0f);
}
else if (tag.Type == Enemy.Bellringer)
{
prefab.transform.position = new Vector3(x + Random.Range(-1f, 1f), 7f, 0f);
}
else if (tag.Type == Enemy.Sentry)
{
prefab.transform.position = new Vector3(x + Random.Range(-1f, 1f), 25f, 0f);
}
else
{
prefab.transform.position = new Vector3(x + Random.Range(-1f, 1f), Random.Range(11f, 13f), 0f);
}
prefab.SetActive(true);
totalEnemies++;
float enemyX = Extensions.GetPositionX(prefab.transform);
if (enemyX < 20f)
{
Extensions.SetPositionX(prefab.transform, 20f);
}
if (enemyX > 42f)
{
Extensions.SetPositionX(prefab.transform, 40f);
}
float enemyY = Extensions.GetPositionY(prefab.transform);
if (enemyY < 5f)
{
Extensions.SetPositionY(prefab.transform, 9f);
}
}
yield return (object)new WaitForSeconds(Random.Range(1f, 1.5f));
BattleWave wave = waveGO.AddComponent<BattleWave>();
wave.startDelay = 0.1f;
wave.activateEnemiesOnStart = true;
wave.Init(scene);
scene.currentWave = 0;
int dummy = 0;
wave.WaveStarted(true, ref dummy);
}
public static void RegisterEnemyDeath(Enemy type)
{
if (Enemies.TryGetValue(type, out EnemyDefinition value))
{
value.Count++;
if ((Object)(object)OverlayEnemies.Instance != (Object)null)
{
OverlayEnemies.Instance.SetOverlayText(value.DisplayName, value.Count.ToString());
}
}
}
private static void PlayerDeathSave()
{
HeroController instance = HeroController.instance;
if (!((Object)(object)instance == (Object)null))
{
((Component)instance).gameObject.AddComponent<PlayerDeathSave>();
}
}
}
public class EnemyTag : MonoBehaviour
{
public Enemy Type;
}
public class OverlayEnemies : MonoBehaviour
{
public static OverlayEnemies Instance;
private Dictionary<string, Texture2D> overlayTextures = new Dictionary<string, Texture2D>();
private List<string> activeOverlays = new List<string>();
private Dictionary<string, string> overlayTexts = new Dictionary<string, string>();
private void Awake()
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
private void Start()
{
LoadOverlay("Reed", "NonStopHallsGauntlet/Reed.png");
LoadOverlay("Choristor", "NonStopHallsGauntlet/Choristor.png");
LoadOverlay("Bellringer", "NonStopHallsGauntlet/Bellringer.png");
LoadOverlay("Clawmaiden", "NonStopHallsGauntlet/Clawmaiden.png");
LoadOverlay("Bellbearer", "NonStopHallsGauntlet/Bellbearer.png");
LoadOverlay("Admin", "NonStopHallsGauntlet/Admin.png");
LoadOverlay("Maestro", "NonStopHallsGauntlet/Maestro.png");
LoadOverlay("Sentry", "NonStopHallsGauntlet/Sentry.png");
}
public void SetOverlayText(string key, string text)
{
if (overlayTextures.ContainsKey(key))
{
overlayTexts[key] = text;
}
}
public void LoadOverlay(string key, string relativePath)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Expected O, but got Unknown
string path = Path.Combine(Paths.PluginPath, relativePath);
if (File.Exists(path))
{
byte[] array = File.ReadAllBytes(path);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
ImageConversion.LoadImage(val, array);
overlayTextures[key] = val;
}
}
public void TriggerOverlay(string key)
{
if (overlayTextures.ContainsKey(key) && !activeOverlays.Contains(key))
{
activeOverlays.Add(key);
}
}
public void RemoveOverlay(string key)
{
activeOverlays.Remove(key);
}
public void ClearAllOverlays()
{
activeOverlays.Clear();
}
private void OnGUI()
{
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: Unknown result type (might be due to invalid IL or missing references)
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Expected O, but got Unknown
//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
if (activeOverlays.Count == 0)
{
return;
}
List<string> list = new List<string>(activeOverlays);
float num = 0f;
foreach (string item in list)
{
Texture2D val = overlayTextures[item];
num += (float)((Texture)val).width * Plugin.scale.Value;
}
num += (float)(Plugin.gap.Value * (list.Count - 1));
float num2 = ((float)Screen.width - num) / 2f + (float)Plugin.posX.Value;
float num3 = Plugin.posY.Value;
Rect val5 = default(Rect);
foreach (string item2 in list)
{
Texture2D val2 = overlayTextures[item2];
float num4 = (float)((Texture)val2).width * Plugin.scale.Value;
float num5 = (float)((Texture)val2).height * Plugin.scale.Value;
float num6 = num3 - num5;
GUI.DrawTexture(new Rect(num2, num6, num4, num5), (Texture)(object)val2);
if (overlayTexts.TryGetValue(item2, out string value))
{
int num7 = 30;
num7 = Mathf.RoundToInt((float)num7 * Plugin.scale.Value);
GUIStyle val3 = new GUIStyle(GUI.skin.label)
{
fontSize = num7,
alignment = (TextAnchor)1
};
val3.normal.textColor = Color.white;
GUIStyle val4 = val3;
((Rect)(ref val5))..ctor(num2, num6 + num5 + 2f, num4, (float)(num7 + Mathf.RoundToInt(20f * Plugin.scale.Value)));
GUI.Label(val5, value, val4);
}
num2 += num4 + (float)Plugin.gap.Value;
}
}
}
public static class RedToolNames
{
public static readonly HashSet<string> RedTools = new HashSet<string>
{
"Straight Pin", "Tri Pin", "Sting Shard", "Tack", "Harpoon", "Shakra Ring", "Pimpilo", "Curve Claws", "Curve Claws Upgraded", "Conch Drill",
"WebShot Forge", "WebShot Architect", "WebShot Weaver", "Cogwork Saw", "Cogwork Flier", "Screw Attack", "Flintstone"
};
}
public static class RedTools
{
private static MethodInfo _getEquippedTools;
private static MethodInfo GetEquippedToolsMethod()
{
if (_getEquippedTools == null)
{
_getEquippedTools = typeof(ToolItemManager).GetMethod("GetCurrentEquippedTools", BindingFlags.Static | BindingFlags.NonPublic);
}
return _getEquippedTools;
}
public static List<ToolItem> GetEquippedRedTools()
{
MethodInfo equippedToolsMethod = GetEquippedToolsMethod();
if (equippedToolsMethod == null)
{
return null;
}
if (!(equippedToolsMethod.Invoke(null, null) is List<ToolItem> list))
{
return null;
}
List<ToolItem> list2 = new List<ToolItem>();
foreach (ToolItem item in list)
{
if (!((Object)(object)item == (Object)null) && (Object)(object)item != (Object)null && RedToolNames.RedTools.Contains(item.name))
{
list2.Add(item);
}
}
return list2;
}
public static Sprite GetInventorySprite(ToolItem tool)
{
if ((Object)(object)tool == (Object)null)
{
return null;
}
return ((SavedItem)tool).GetPopupIcon();
}
public static bool ToolNeedsReplenish(ToolItem tool)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
Data toolData = PlayerData.instance.GetToolData(tool.name);
int toolStorageAmount = ToolItemManager.GetToolStorageAmount(tool);
return toolData.AmountLeft < toolStorageAmount;
}
public static void ReplenishTool(ToolItem tool)
{
//IL_0019: 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_0026: 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)
if (!((Object)(object)tool == (Object)null))
{
Data toolData = PlayerData.instance.GetToolData(tool.name);
int toolStorageAmount = ToolItemManager.GetToolStorageAmount(tool);
if (toolData.AmountLeft < toolStorageAmount)
{
toolData.AmountLeft++;
PlayerData.instance.SetToolData(tool.name, toolData);
}
ToolItemManager.ReportAllBoundAttackToolsUpdated();
ToolItemManager.SendEquippedChangedEvent(true);
}
}
}
public class ReplenishManager : MonoBehaviour
{
public float spawnInterval;
public Vector2 spawnXRange = new Vector2(20f, 40f);
public Vector2 spawnYRange = new Vector2(5f, 10f);
private float timer;
private List<ToolItem> redTools;
private void Awake()
{
spawnInterval = Plugin.toolSpawnInterval.Value + Random.Range(-2f, 2f);
timer = spawnInterval;
redTools = RedTools.GetEquippedRedTools();
if (redTools != null && redTools.Count != 0)
{
}
}
private void Update()
{
timer -= Time.deltaTime;
if (timer <= 0f)
{
SpawnRandomPickup();
timer = spawnInterval;
}
}
private void SpawnRandomPickup()
{
List<ToolItem> list = new List<ToolItem>();
foreach (ToolItem redTool in redTools)
{
if (RedTools.ToolNeedsReplenish(redTool))
{
list.Add(redTool);
}
}
if (list.Count != 0)
{
for (int i = 0; i < Random.Range(1, Plugin.numTools.Value + 1); i++)
{
ToolItem tool = list[Random.Range(0, list.Count)];
CreatePickup(tool);
}
}
}
private void CreatePickup(ToolItem tool)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Expected O, but got Unknown
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Expected O, but got Unknown
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(tool.name + "_Pickup");
SpriteRenderer val2 = val.AddComponent<SpriteRenderer>();
val2.sprite = RedTools.GetInventorySprite(tool);
((Renderer)val2).sortingOrder = 10;
Rigidbody2D val3 = val.AddComponent<Rigidbody2D>();
val3.gravityScale = 1f;
val3.linearDamping = 0.2f;
val3.angularDamping = 0.7f;
val3.linearVelocityX = Random.Range(-10f, 10f);
val3.angularVelocity = Random.Range(-200f, 200f);
val3.collisionDetectionMode = (CollisionDetectionMode2D)1;
CircleCollider2D val4 = val.AddComponent<CircleCollider2D>();
val4.radius = 0.2f;
GameObject val5 = new GameObject("PickupTrigger");
val5.transform.SetParent(val.transform, false);
CircleCollider2D val6 = val5.AddComponent<CircleCollider2D>();
((Collider2D)val6).isTrigger = true;
val6.radius = 0.5f;
PhysicsMaterial2D val7 = new PhysicsMaterial2D();
val7.bounciness = 0.8f;
val7.friction = 0.2f;
((Collider2D)val4).sharedMaterial = val7;
ToolPickup toolPickup = val5.AddComponent<ToolPickup>();
toolPickup.Tool = tool;
val.transform.position = new Vector3(Random.Range(spawnXRange.x, spawnXRange.y), Random.Range(spawnYRange.x, spawnYRange.y), 0f);
val.SetActive(true);
Fader fader = val.AddComponent<Fader>();
fader.lifetime = Plugin.toolDisappearTime.Value;
fader.fadeDuration = 0.25f;
}
}
public class ToolPickup : MonoBehaviour
{
public ToolItem Tool;
private void OnTriggerEnter2D(Collider2D collision)
{
if (((Component)collision).CompareTag("Player"))
{
if ((Object)(object)Tool != (Object)null)
{
RedTools.ReplenishTool(Tool);
}
Object.Destroy((Object)(object)((Component)((Component)this).transform.parent).gameObject);
}
}
}
public class Fader : MonoBehaviour
{
public float lifetime = 10f;
public float fadeDuration = 2f;
private SpriteRenderer[] renderers;
private float timer;
private void Awake()
{
renderers = ((Component)this).GetComponentsInChildren<SpriteRenderer>();
}
private void Start()
{
timer = lifetime;
}
private void Update()
{
timer -= Time.deltaTime;
if (timer <= fadeDuration)
{
float alpha = Mathf.Clamp01(timer / fadeDuration);
SetAlpha(alpha);
}
if (timer <= 0f)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
private void SetAlpha(float alpha)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
SpriteRenderer[] array = renderers;
foreach (SpriteRenderer val in array)
{
if (!((Object)(object)val == (Object)null))
{
Color color = val.color;
color.a = alpha;
val.color = color;
}
}
}
}
namespace NonStopHallsGauntlet
{
[BepInPlugin("com.lagerthon.NonStopHallsGauntlet", "High Halls Gauntlet", "1.2.0")]
public class Plugin : BaseUnityPlugin
{
private const string HARMONY_ID = "com.lagerthon.NonStopHallsGauntlet";
internal static ManualLogSource Log;
private static Harmony _rootHarmony;
internal static ConfigEntry<KeyboardShortcut> TeleportKey;
internal static ConfigEntry<KeyboardShortcut> CrestKey;
public static ConfigEntry<int> posX;
public static ConfigEntry<int> posY;
public static ConfigEntry<float> scale;
public static ConfigEntry<int> gap;
public static ConfigEntry<int> nailUpgrade;
public static ConfigEntry<int> numSilkHeart;
public static ConfigEntry<int> numEnemies;
public static ConfigEntry<int> enemyHeal;
public static ConfigEntry<int> numTools;
public static ConfigEntry<float> toolSpawnInterval;
public static ConfigEntry<float> toolDisappearTime;
public GameObject replenishManagerGO;
private bool CrestsToolsUnlock = false;
public static Plugin Instance { get; private set; }
internal static Harmony RootHarmony => _rootHarmony;
private void Awake()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Expected O, but got Unknown
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Expected O, but got Unknown
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Expected O, but got Unknown
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Expected O, but got Unknown
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Expected O, but got Unknown
//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Expected O, but got Unknown
//IL_021f: Unknown result type (might be due to invalid IL or missing references)
//IL_0229: Expected O, but got Unknown
//IL_0248: Unknown result type (might be due to invalid IL or missing references)
//IL_0276: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02aa: Expected O, but got Unknown
//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
//IL_02bc: Expected O, but got Unknown
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d3: Expected O, but got Unknown
_rootHarmony = new Harmony("com.lagerthon.NonStopHallsGauntlet");
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
posX = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy Images", "X Offset", 400, "Changes horizontal position of images");
posY = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy Images", "Y Offset", 220, "Changes vertical position of images");
scale = ((BaseUnityPlugin)this).Config.Bind<float>("Enemy Images", "Scale", 1f, "Changes the size of images and text");
gap = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy Images", "Gap", 10, "Changes gap between images (pixels)");
nailUpgrade = ((BaseUnityPlugin)this).Config.Bind<int>("Player Settings", "Nail Upgrade", 0, new ConfigDescription("Nail Upgrades", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
numSilkHeart = ((BaseUnityPlugin)this).Config.Bind<int>("Player Settings", "Number of Silk Hearts", 2, new ConfigDescription("Number of Silk Hearts", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
numEnemies = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy Settings", "Max Enemies", 3, new ConfigDescription("Maximum number of enemies per wave", (AcceptableValueBase)(object)new AcceptableValueRange<int>(3, 5), Array.Empty<object>()));
enemyHeal = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy Settings", "Enemy heal value", 10, new ConfigDescription("Enemy HP shoots up by this percent of their max HP everytime they heal", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[6] { 0, 10, 20, 30, 40, 50 }), Array.Empty<object>()));
numTools = ((BaseUnityPlugin)this).Config.Bind<int>("Red Tools Settings", "Number of tools", 1, new ConfigDescription("Number of tools that spawn at the same time", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), Array.Empty<object>()));
toolSpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Red Tools Settings", "Tool Spawn Interval (seconds)", 30f, new ConfigDescription("Upon usage, one of the equipped red tools will spawn after approximately this many seconds", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 60f), Array.Empty<object>()));
toolDisappearTime = ((BaseUnityPlugin)this).Config.Bind<float>("Red Tools Settings", "Tool Pickup Time (seconds)", 5f, new ConfigDescription("Once spawned, the tool will disappear after this time", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 10f), Array.Empty<object>()));
TeleportKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Teleport Key", "Teleport to the High Halls gauntlet", new KeyboardShortcut((KeyCode)303, Array.Empty<KeyCode>()), "Key to move to High Halls gauntlet and apply player skills");
CrestKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Tools and Crests Key", "Unlock all Crests and Tools", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "WARNING: This will unlock all Crests and Tools permanently in the save file");
_rootHarmony.PatchAll(typeof(Battle));
GameObject val = new GameObject("OverlayEnemies");
val.AddComponent<OverlayEnemies>();
GameObject val2 = new GameObject("MoveToHighHall");
val2.AddComponent<MoveToHighHall>();
replenishManagerGO = new GameObject("ReplenishManager");
Object.DontDestroyOnLoad((Object)(object)replenishManagerGO);
}
private void Update()
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
HeroController instance = HeroController.instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
KeyboardShortcut value = TeleportKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && (Object)(object)instance != (Object)null)
{
MoveToHighHall.Instance.StartHighHallTeleport();
OverlayEnemies.Instance.ClearAllOverlays();
ReplenishManager component = Instance.replenishManagerGO.GetComponent<ReplenishManager>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
}
if (!CrestsToolsUnlock)
{
value = CrestKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown() && (Object)(object)instance != (Object)null)
{
ToolItemManager.UnlockAllTools();
ToolItemManager.UnlockAllCrests();
CrestsToolsUnlock = true;
}
}
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name == "Quit_To_Menu")
{
OverlayEnemies.Instance.ClearAllOverlays();
ReplenishManager component2 = Instance.replenishManagerGO.GetComponent<ReplenishManager>();
if ((Object)(object)component2 != (Object)null)
{
Object.Destroy((Object)(object)component2);
}
}
}
}
}
namespace NonStopHallsGauntlet.Player
{
public class MoveToHighHall : MonoBehaviour
{
public static MoveToHighHall Instance;
private void Awake()
{
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
}
else
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
public void StartHighHallTeleport()
{
((MonoBehaviour)this).StartCoroutine(Teleport("Hang_04", "right1"));
}
private IEnumerator Teleport(string scene, string gate)
{
ScreenFaderUtils.Fade(ScreenFaderUtils.GetColour(), Color.black, 1f);
yield return (object)new WaitForSeconds(1f);
AudioSourceFadeControl[] sources = Object.FindObjectsByType<AudioSourceFadeControl>((FindObjectsInactive)1, (FindObjectsSortMode)0);
AudioSourceFadeControl[] array = sources;
foreach (AudioSourceFadeControl src in array)
{
src.FadeDown();
}
GameManager.instance.BeginSceneTransition(new SceneLoadInfo
{
SceneName = scene,
EntryGateName = gate,
Visualization = (SceneLoadVisualizations)0,
PreventCameraFadeOut = true
});
}
}
internal static class PlayerSkills
{
public static void Skills()
{
PlayerData instance = PlayerData.instance;
instance.hasDash = true;
instance.hasBrolly = true;
instance.hasWalljump = true;
instance.hasDoubleJump = true;
instance.hasHarpoonDash = true;
instance.hasSilkBossNeedle = true;
instance.hasThreadSphere = true;
instance.hasNeedleThrow = true;
instance.hasSilkCharge = true;
instance.hasSilkBomb = true;
instance.hasParry = true;
instance.nailUpgrades = Plugin.nailUpgrade.Value;
instance.silkRegenMax = Plugin.numSilkHeart.Value;
}
}
}
namespace NonStopHallsGauntlet.Enemies
{
public enum Enemy
{
Reed,
Bellringer,
Choristor,
Maiden,
Administrator,
Bellbearer,
Maestro,
Sentry,
Unknown
}
internal class EnemyHeal : MonoBehaviour
{
private HealthManager hm;
public int healAmount;
private EnemyTag tag;
private static readonly Dictionary<Enemy, string> HealStateByType = new Dictionary<Enemy, string>
{
{
Enemy.Reed,
"Alert"
},
{
Enemy.Bellringer,
"Walker"
},
{
Enemy.Choristor,
"Walker"
},
{
Enemy.Maiden,
"Fly"
},
{
Enemy.Administrator,
"Retreat?"
},
{
Enemy.Bellbearer,
"Out of Range"
},
{
Enemy.Maestro,
"Defending"
},
{
Enemy.Sentry,
"Walk"
}
};
private static readonly HashSet<Enemy> UsesWaitRandom = new HashSet<Enemy>
{
Enemy.Reed,
Enemy.Maiden,
Enemy.Administrator,
Enemy.Sentry
};
private void Awake()
{
hm = ((Component)this).GetComponent<HealthManager>();
healAmount = Mathf.CeilToInt((float)(Battle.enemyHeal * hm.hp) / 100f);
tag = ((Component)this).GetComponent<EnemyTag>();
if (!((Object)(object)tag == (Object)null))
{
HealingPatch();
HookDeath();
}
}
private void HealingPatch()
{
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Expected O, but got Unknown
if (healAmount == 0)
{
return;
}
PlayMakerFSM val = ((tag.Type == Enemy.Bellringer || tag.Type == Enemy.Choristor) ? FSMUtility.LocateMyFSM(((Component)this).gameObject, "Attack") : FSMUtility.LocateMyFSM(((Component)this).gameObject, "Control"));
if ((Object)(object)val == (Object)null || !HealStateByType.TryGetValue(tag.Type, out string value))
{
return;
}
FsmState state = val.Fsm.GetState(value);
if (state == null)
{
return;
}
FsmStateAction[] actions = state.Actions;
foreach (FsmStateAction val2 in actions)
{
if (UsesWaitRandom.Contains(tag.Type))
{
WaitRandom val3 = (WaitRandom)(object)((val2 is WaitRandom) ? val2 : null);
if (val3 != null)
{
val3.timeMin = FsmFloat.op_Implicit(2.1f);
val3.timeMax = FsmFloat.op_Implicit(2.2f);
continue;
}
}
if (!UsesWaitRandom.Contains(tag.Type))
{
Wait val4 = (Wait)(object)((val2 is Wait) ? val2 : null);
if (val4 != null)
{
val4.time.Value = 2.2f;
}
}
}
List<FsmStateAction> list = state.Actions.ToList();
list.Add((FsmStateAction)(object)new Healing.HealBurst
{
target = new FsmOwnerDefault
{
OwnerOption = (OwnerDefaultOption)0
},
maxHP = hm.hp,
healAmount = healAmount
});
state.Actions = list.ToArray();
}
private void HookDeath()
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
hm.OnDeath += new DeathEvent(OnDie);
}
private void OnDie()
{
if (!((Object)(object)tag == (Object)null))
{
Battle.RegisterEnemyDeath(tag.Type);
EnemyDeathEffects component = ((Component)this).GetComponent<EnemyDeathEffects>();
if ((Object)(object)component != (Object)null)
{
component.CorpseEmitted += OnCorpseEmitted;
}
}
}
private void OnCorpseEmitted(GameObject corpse)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
if ((Object)(object)corpse == (Object)null)
{
return;
}
Fader fader = corpse.AddComponent<Fader>();
fader.lifetime = Random.Range(5f, 6f);
fader.fadeDuration = 1f;
foreach (Transform item in corpse.transform)
{
Transform val = item;
if (!((Object)val).name.Contains("Silk"))
{
Fader fader2 = ((Component)val).gameObject.AddComponent<Fader>();
fader2.lifetime = Random.Range(5f, 6f);
fader2.fadeDuration = 1f;
}
}
}
}
public class Healing : MonoBehaviour
{
public class HealBurst : FsmStateAction
{
public FsmOwnerDefault target;
private HealthManager hm;
private GameObject go;
public int maxHP;
public int healAmount;
private Renderer rn;
private Color originalColor;
private float visualTimer;
private float flashTimer;
private float flashInterval;
private bool flashOn;
private bool doHeal;
private MaterialPropertyBlock block;
private int hpCheck;
public override void OnEnter()
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Expected O, but got Unknown
doHeal = false;
go = ((FsmStateAction)this).Fsm.GetOwnerDefaultTarget(target);
hm = go.GetComponent<HealthManager>();
hpCheck = hm.hp;
rn = go.GetComponentInChildren<Renderer>();
originalColor = rn.sharedMaterial.color;
block = new MaterialPropertyBlock();
float num = 1f - (float)hm.hp / (float)maxHP;
float value = Random.value;
if (value >= num)
{
((FsmStateAction)this).Finish();
return;
}
doHeal = true;
visualTimer = 1.5f;
flashInterval = 0.2f;
flashTimer = flashInterval;
flashOn = true;
}
public override void OnUpdate()
{
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_0172: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
if (!doHeal || (Object)(object)rn == (Object)null)
{
return;
}
if (hm.hp < hpCheck)
{
((FsmStateAction)this).Finish();
return;
}
hpCheck = hm.hp;
visualTimer -= Time.deltaTime;
if (visualTimer <= 0f)
{
hm.hp = Mathf.Min(hm.hp + healAmount, maxHP);
block.SetColor("_Color", originalColor);
rn.SetPropertyBlock(block);
((FsmStateAction)this).Finish();
}
flashTimer -= Time.deltaTime;
if (flashTimer <= 0f)
{
flashOn = !flashOn;
if (flashOn)
{
flashInterval = Mathf.Max(0.05f, flashInterval * 0.75f);
}
flashTimer = flashInterval;
}
block.SetColor("_Color", (Color)(flashOn ? new Color(0.1f, 0.1f, 0.1f, 1f) : originalColor));
rn.SetPropertyBlock(block);
}
public override void OnExit()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)rn != (Object)null)
{
block.SetColor("_Color", originalColor);
rn.SetPropertyBlock(block);
}
}
}
}
internal class PlayerDeathSave : MonoBehaviour
{
private HeroController heroController;
private void Awake()
{
heroController = ((Component)this).GetComponent<HeroController>();
PlayMakerFSM harpoonDashFSM = heroController.harpoonDashFSM;
if ((Object)(object)heroController != (Object)null)
{
heroController.OnDeath += HandleDeath;
}
}
private void HandleDeath()
{
((MonoBehaviour)this).StartCoroutine(OnDie());
}
private IEnumerator OnDie()
{
yield return (object)new WaitForSeconds(Random.Range(0.001f, 0.1f));
yield return (object)new WaitForEndOfFrame();
string folder = Path.Combine(Paths.PluginPath, "NonStopHallsGauntlet");
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
string timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
string path = Path.Combine(folder, "screenshot_" + timestamp + ".png");
int width = Screen.width;
int height = Screen.height;
Texture2D tex = new Texture2D(width, height, (TextureFormat)3, false);
tex.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
tex.Apply();
File.WriteAllBytes(path, ImageConversion.EncodeToPNG(tex));
Object.Destroy((Object)(object)tex);
yield return (object)new WaitForSeconds(2f);
yield return (object)new WaitForEndOfFrame();
OverlayEnemies.Instance.ClearAllOverlays();
ReplenishManager rm = Plugin.Instance.replenishManagerGO.GetComponent<ReplenishManager>();
if ((Object)(object)rm != (Object)null)
{
Object.Destroy((Object)(object)rm);
}
}
}
}