Decompiled source of RealerBulwarksHaunt v1.1.5

BulwarksHaunt.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BulwarksHaunt.Items;
using EntityStates;
using EntityStates.GameOver;
using EntityStates.Interactables.MSObelisk;
using HG;
using IL.RoR2;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MysticsRisky2Utils;
using MysticsRisky2Utils.BaseAssetTypes;
using MysticsRisky2Utils.ContentManagement;
using MysticsRisky2Utils.SoftDependencies;
using Newtonsoft.Json;
using On.EntityStates.Interactables.MSObelisk;
using On.RoR2;
using On.RoR2.Navigation;
using On.RoR2.UI;
using On.RoR2.UI.LogBook;
using ProperSave;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.Achievements;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using RoR2.Navigation;
using RoR2.Skills;
using RoR2.UI;
using RoR2.UI.LogBook;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering.PostProcessing;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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: AssemblyCompany("BulwarksHaunt")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e3de36572a33a316f4e2508607ae58c637413eeb")]
[assembly: AssemblyProduct("BulwarksHaunt")]
[assembly: AssemblyTitle("BulwarksHaunt")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace BulwarksHaunt
{
	[BepInPlugin("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", "1.1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class BulwarksHauntPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static CollectContentPackProvidersDelegate <>9__11_0;

			internal void <Awake>b__11_0(AddContentPackProviderDelegate addContentPackProvider)
			{
				addContentPackProvider.Invoke((IContentPackProvider)(object)new BulwarksHauntContent());
			}
		}

		public const string PluginGUID = "com.themysticsword.bulwarkshaunt";

		public const string PluginName = "Bulwark's Haunt";

		public const string PluginVersion = "1.1.4";

		public static Assembly executingAssembly;

		internal static Type declaringType;

		internal static PluginInfo pluginInfo;

		internal static ManualLogSource logger;

		internal static ConfigFile config;

		private static AssetBundle _assetBundle;

		public static AssetBundle AssetBundle
		{
			get
			{
				if ((Object)(object)_assetBundle == (Object)null)
				{
					_assetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(pluginInfo.Location), "bulwarkshauntassetbundle"));
				}
				return _assetBundle;
			}
		}

		public void Awake()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			pluginInfo = ((BaseUnityPlugin)this).Info;
			logger = ((BaseUnityPlugin)this).Logger;
			config = ((BaseUnityPlugin)this).Config;
			executingAssembly = Assembly.GetExecutingAssembly();
			declaringType = MethodBase.GetCurrentMethod().DeclaringType;
			TMProEffects.Init();
			GhostWaveSkins.Init();
			NetworkingAPI.RegisterMessageType<BulwarksHauntWaveModifier.SyncWaveModifierActive>();
			ContentLoadHelper.PluginAwakeLoad<BaseItem>(executingAssembly);
			ContentLoadHelper.PluginAwakeLoad<BaseEquipment>(executingAssembly);
			ContentLoadHelper.PluginAwakeLoad<BaseBuff>(executingAssembly);
			ContentLoadHelper.PluginAwakeLoad<BaseInteractable>(executingAssembly);
			ContentLoadHelper.PluginAwakeLoad<GhostWave>(executingAssembly);
			object obj = <>c.<>9__11_0;
			if (obj == null)
			{
				CollectContentPackProvidersDelegate val = delegate(AddContentPackProviderDelegate addContentPackProvider)
				{
					addContentPackProvider.Invoke((IContentPackProvider)(object)new BulwarksHauntContent());
				};
				<>c.<>9__11_0 = val;
				obj = (object)val;
			}
			ContentManager.collectContentPackProviders += (CollectContentPackProvidersDelegate)obj;
			Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
			if (pluginInfos.ContainsKey("com.KingEnderBrine.ProperSave"))
			{
				ProperSaveSupport.Init();
			}
			if (RiskOfOptionsDependency.enabled)
			{
				Texture2D val2 = new Texture2D(2, 2);
				ImageConversion.LoadImage(val2, File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "icon.png")));
				Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0f, 0f), 100f);
				RiskOfOptionsDependency.RegisterModInfo("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", "Adds a new Obelisk ending", val3);
			}
		}
	}
	public class BulwarksHauntContent : IContentPackProvider
	{
		public static class Resources
		{
			public static List<GameObject> bodyPrefabs = new List<GameObject>();

			public static List<GameObject> masterPrefabs = new List<GameObject>();

			public static List<GameObject> projectilePrefabs = new List<GameObject>();

			public static List<GameObject> effectPrefabs = new List<GameObject>();

			public static List<NetworkSoundEventDef> networkSoundEventDefs = new List<NetworkSoundEventDef>();

			public static List<UnlockableDef> unlockableDefs = new List<UnlockableDef>();

			public static List<Type> entityStateTypes = new List<Type>();

			public static List<SkillDef> skillDefs = new List<SkillDef>();

			public static List<SkillFamily> skillFamilies = new List<SkillFamily>();

			public static List<SceneDef> sceneDefs = new List<SceneDef>();

			public static List<GameEndingDef> gameEndingDefs = new List<GameEndingDef>();
		}

		public static class Items
		{
			public static ItemDef BulwarksHaunt_Sword;

			public static ItemDef BulwarksHaunt_SwordUnleashed;

			public static ItemDef BulwarksHaunt_GhostFury;

			public static ItemDef BulwarksHaunt_RecruitedMonster;
		}

		public static class GameEndings
		{
			public static GameEndingDef BulwarksHaunt_HauntedEnding;
		}

		public static class Achievements
		{
			public static AchievementDef BulwarksHaunt_WinGhostWave;
		}

		private ContentPack contentPack = new ContentPack();

		public string identifier => "Bulwark's Haunt";

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			contentPack.identifier = identifier;
			ContentLoadHelper contentLoadHelper = new ContentLoadHelper();
			Action[] loadDispatchers = new Action[5]
			{
				delegate
				{
					contentLoadHelper.DispatchLoad<ItemDef>(BulwarksHauntPlugin.executingAssembly, typeof(BaseItem), (Action<ItemDef[]>)delegate(ItemDef[] x)
					{
						contentPack.itemDefs.Add(x);
					});
				},
				delegate
				{
					contentLoadHelper.DispatchLoad<EquipmentDef>(BulwarksHauntPlugin.executingAssembly, typeof(BaseEquipment), (Action<EquipmentDef[]>)delegate(EquipmentDef[] x)
					{
						contentPack.equipmentDefs.Add(x);
					});
				},
				delegate
				{
					contentLoadHelper.DispatchLoad<BuffDef>(BulwarksHauntPlugin.executingAssembly, typeof(BaseBuff), (Action<BuffDef[]>)delegate(BuffDef[] x)
					{
						contentPack.buffDefs.Add(x);
					});
				},
				delegate
				{
					contentLoadHelper.DispatchLoad<GameObject>(BulwarksHauntPlugin.executingAssembly, typeof(BaseInteractable), (Action<GameObject[]>)null);
				},
				delegate
				{
					contentLoadHelper.DispatchLoad<SceneDef>(BulwarksHauntPlugin.executingAssembly, typeof(GhostWave), (Action<SceneDef[]>)null);
				}
			};
			int i = 0;
			while (i < loadDispatchers.Length)
			{
				loadDispatchers[i]();
				args.ReportProgress(Util.Remap((float)(i + 1), 0f, (float)loadDispatchers.Length, 0f, 0.05f));
				yield return null;
				int num = i + 1;
				i = num;
			}
			while (contentLoadHelper.coroutine.MoveNext())
			{
				args.ReportProgress(Util.Remap(contentLoadHelper.progress.value, 0f, 1f, 0.05f, 0.9f));
				yield return contentLoadHelper.coroutine.Current;
			}
			loadDispatchers = new Action[12]
			{
				delegate
				{
					ContentLoadHelper.PopulateTypeFields<ItemDef>(typeof(Items), contentPack.itemDefs, (Func<string, string>)null);
				},
				delegate
				{
					contentPack.bodyPrefabs.Add(Resources.bodyPrefabs.ToArray());
				},
				delegate
				{
					contentPack.masterPrefabs.Add(Resources.masterPrefabs.ToArray());
				},
				delegate
				{
					contentPack.projectilePrefabs.Add(Resources.projectilePrefabs.ToArray());
				},
				delegate
				{
					contentPack.effectDefs.Add(Resources.effectPrefabs.ConvertAll((Converter<GameObject, EffectDef>)((GameObject x) => new EffectDef(x))).ToArray());
				},
				delegate
				{
					contentPack.networkSoundEventDefs.Add(Resources.networkSoundEventDefs.ToArray());
				},
				delegate
				{
					contentPack.unlockableDefs.Add(Resources.unlockableDefs.ToArray());
				},
				delegate
				{
					contentPack.entityStateTypes.Add(Resources.entityStateTypes.ToArray());
				},
				delegate
				{
					contentPack.skillDefs.Add(Resources.skillDefs.ToArray());
				},
				delegate
				{
					contentPack.skillFamilies.Add(Resources.skillFamilies.ToArray());
				},
				delegate
				{
					contentPack.sceneDefs.Add(Resources.sceneDefs.ToArray());
				},
				delegate
				{
					contentPack.gameEndingDefs.Add(Resources.gameEndingDefs.ToArray());
				}
			};
			int j = 0;
			while (j < loadDispatchers.Length)
			{
				loadDispatchers[j]();
				args.ReportProgress(Util.Remap((float)(j + 1), 0f, (float)loadDispatchers.Length, 0.9f, 0.95f));
				yield return null;
				int num = j + 1;
				j = num;
			}
			loadDispatchers = new Action[4]
			{
				delegate
				{
					ContentLoadHelper.InvokeAfterContentPackLoaded<BaseItem>(BulwarksHauntPlugin.executingAssembly);
				},
				delegate
				{
					ContentLoadHelper.InvokeAfterContentPackLoaded<BaseEquipment>(BulwarksHauntPlugin.executingAssembly);
				},
				delegate
				{
					ContentLoadHelper.InvokeAfterContentPackLoaded<BaseBuff>(BulwarksHauntPlugin.executingAssembly);
				},
				delegate
				{
					ContentLoadHelper.InvokeAfterContentPackLoaded<BaseInteractable>(BulwarksHauntPlugin.executingAssembly);
				}
			};
			int k = 0;
			while (k < loadDispatchers.Length)
			{
				loadDispatchers[k]();
				args.ReportProgress(Util.Remap((float)(k + 1), 0f, (float)loadDispatchers.Length, 0.95f, 0.99f));
				yield return null;
				int num = k + 1;
				k = num;
			}
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}
	}
	[CreateAssetMenu(fileName = "NewWaveModifier.asset", menuName = "Bulwark's Haunt/Wave Modifier")]
	public class BulwarksHauntWaveModifier : ScriptableObject
	{
		public delegate void WaveModifierEventHandler(GhostWave.GhostWaveControllerBaseState.MonsterWaves waveState = null);

		public class SyncWaveModifierActive : INetMessage, ISerializableObject
		{
			private int modifierIndex;

			private bool active;

			public SyncWaveModifierActive()
			{
			}

			public SyncWaveModifierActive(int modifierIndex, bool active)
			{
				this.modifierIndex = modifierIndex;
				this.active = active;
			}

			public void Deserialize(NetworkReader reader)
			{
				modifierIndex = reader.ReadInt32();
				active = reader.ReadBoolean();
			}

			public void OnReceived()
			{
				if (NetworkServer.active)
				{
					return;
				}
				BulwarksHauntWaveModifier waveModifier = GhostWave.WaveModifierCatalog.GetWaveModifier(modifierIndex);
				if (Object.op_Implicit((Object)(object)waveModifier) && active != waveModifier.active)
				{
					if (active)
					{
						waveModifier.Activate();
					}
					else
					{
						waveModifier.Deactivate();
					}
				}
			}

			public void Serialize(NetworkWriter writer)
			{
				writer.Write(modifierIndex);
				writer.Write(active);
			}
		}

		private string _cachedName;

		public string nameToken;

		public string popupToken;

		public string descriptionToken;

		[Header("Auto-assigned at runtime")]
		public bool active = false;

		public int index = -1;

		public WaveModifierEventHandler onActivated;

		public WaveModifierEventHandler onUpdate;

		public WaveModifierEventHandler onFixedUpdate;

		public WaveModifierEventHandler onDeactivated;

		public string cachedName
		{
			get
			{
				return _cachedName;
			}
			set
			{
				_cachedName = value;
				((Object)this).name = value;
			}
		}

		[ContextMenu("Auto Populate Tokens")]
		public void AutoPopulateTokens()
		{
			nameToken = "BULWARKSHAUNT_GHOSTWAVE_MODIFIER_" + ((Object)this).name.ToUpperInvariant() + "_NAME";
			popupToken = "BULWARKSHAUNT_GHOSTWAVE_MODIFIER_" + ((Object)this).name.ToUpperInvariant() + "_POPUP";
			descriptionToken = "BULWARKSHAUNT_GHOSTWAVE_MODIFIER_" + ((Object)this).name.ToUpperInvariant() + "_DESCRIPTION";
		}

		public void Activate(GhostWave.GhostWaveControllerBaseState.MonsterWaves waveState = null)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			if (active)
			{
				return;
			}
			active = true;
			GhostWave.WaveModifierCatalog.activeWaveModifiers.Add(cachedName);
			if (Object.op_Implicit((Object)(object)Run.instance))
			{
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if (Object.op_Implicit((Object)(object)instance.master))
					{
						CharacterMasterNotificationQueue notificationQueueForMaster = CharacterMasterNotificationQueue.GetNotificationQueueForMaster(instance.master);
						if (Object.op_Implicit((Object)(object)notificationQueueForMaster))
						{
							NotificationInfo val = new NotificationInfo((object)this, (TransformationInfo)null);
							notificationQueueForMaster.PushNotification(val, 10f);
						}
					}
				}
			}
			SimpleChatMessage val2 = new SimpleChatMessage();
			val2.baseToken = "BULWARKSHAUNT_GHOSTWAVE_SYSTEM_WAVEMODIFIER";
			val2.paramTokens = new string[1] { Language.currentLanguage.GetLocalizedStringByToken(nameToken) };
			Chat.AddMessage((ChatMessageBase)(object)val2);
			if (NetworkServer.active)
			{
				NetMessageExtensions.Send((INetMessage)(object)new SyncWaveModifierActive(index, active: true), (NetworkDestination)1);
			}
			if (onActivated != null)
			{
				onActivated(waveState);
			}
		}

		public void Deactivate(GhostWave.GhostWaveControllerBaseState.MonsterWaves waveState = null)
		{
			if (active)
			{
				active = false;
				GhostWave.WaveModifierCatalog.activeWaveModifiers.Remove(cachedName);
				if (NetworkServer.active)
				{
					NetMessageExtensions.Send((INetMessage)(object)new SyncWaveModifierActive(index, active: false), (NetworkDestination)1);
				}
				if (onDeactivated != null)
				{
					onDeactivated(waveState);
				}
			}
		}
	}
	public class GhostWave : BaseLoadableAsset
	{
		public struct BakedNodes
		{
			public NodeSerialized[] nodes;

			public Link[] links;

			public List<string> gateNames;
		}

		public struct NodeSerialized
		{
			public float x;

			public float y;

			public float z;

			public LinkListIndex linkListIndex;

			public HullMask forbiddenHulls;

			public byte[] lineOfSightMaskBytes;

			public int lineOfSightMaskLength;

			public byte gateIndex;

			public NodeFlags flags;
		}

		public struct KilledEnemyData
		{
			public BodyIndex bodyIndex;

			public List<ItemCountPair> inventory;

			public EquipmentDef equipment;
		}

		public class BulwarksHauntGhostWaveController : MonoBehaviour
		{
			public class ClearGhostWavesObjectiveController : ObjectiveTracker
			{
				public int wave = -1;

				public override string GenerateString()
				{
					BulwarksHauntGhostWaveController bulwarksHauntGhostWaveController = (BulwarksHauntGhostWaveController)(object)base.sourceDescriptor.source;
					wave = bulwarksHauntGhostWaveController.wave;
					if (wave == maxWaves)
					{
						return Language.GetString("OBJECTIVE_BULWARKSHAUNT_GHOSTWAVE_CLEARWAVES_FINAL");
					}
					return string.Format(Language.GetString("OBJECTIVE_BULWARKSHAUNT_GHOSTWAVE_CLEARWAVES"), wave);
				}

				public override bool IsDirty()
				{
					return ((BulwarksHauntGhostWaveController)(object)base.sourceDescriptor.source).wave != wave;
				}
			}

			public static BulwarksHauntGhostWaveController instance;

			public int wave = 1;

			public int currentSpeechVariant = 1;

			public float oobCheckTimer = 0f;

			public float oobCheckInterval = 5f;

			public float oobRadius = 350f;

			public float oobRadiusShrinkAmount = 100f;

			public float oobShrinkDuration = 300f;

			public float oobShrinkTimer = 0f;

			public float oobHealthLoss = 0.34f;

			public Vector3 oobCenter = Vector3.zero;

			public float oobBottomY = -400f;

			public static event Action onGhostWaveComplete;

			public void Start()
			{
				instance = this;
			}

			public void FixedUpdate()
			{
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Invalid comparison between Unknown and I4
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Invalid comparison between Unknown and I4
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Invalid comparison between Unknown and I4
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Invalid comparison between Unknown and I4
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Invalid comparison between Unknown and I4
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0162: 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)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Unknown result type (might be due to invalid IL or missing references)
				if (!NetworkServer.active)
				{
					return;
				}
				oobCheckTimer -= Time.fixedDeltaTime;
				while (oobCheckTimer <= 0f)
				{
					oobCheckTimer += oobCheckInterval;
					float num = oobRadius - oobRadiusShrinkAmount * Mathf.Min(oobShrinkTimer / oobShrinkDuration, 1f);
					TeamIndex val = (TeamIndex)0;
					while ((int)val < 5)
					{
						if ((int)val != 1 && (int)val != -1 && (int)val > 0)
						{
							foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers(val))
							{
								CharacterBody body = teamMember.body;
								if (Vector3.Distance(((Component)teamMember).transform.position, oobCenter) >= num)
								{
									HandleBodyOutOfBounds(body);
								}
							}
						}
						else if ((int)val == 1)
						{
							foreach (TeamComponent teamMember2 in TeamComponent.GetTeamMembers(val))
							{
								CharacterBody body2 = teamMember2.body;
								if (((Component)teamMember2).transform.position.y <= oobBottomY)
								{
									HandleBodyOutOfBounds(body2);
								}
							}
						}
						val = (TeamIndex)(sbyte)(val + 1);
					}
				}
			}

			public void HandleBodyOutOfBounds(CharacterBody body)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Invalid comparison between Unknown and I4
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Expected O, but got Unknown
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				if ((Object.op_Implicit((Object)(object)body.teamComponent) && (int)body.teamComponent.teamIndex == 1) || (Object.op_Implicit((Object)(object)body.inventory) && body.inventory.GetItemCount(Items.TeleportWhenOob) > 0))
				{
					Vector3 val = Run.instance.FindSafeTeleportPosition(body, (Transform)null, 0f, 0f);
					TeleportHelper.TeleportBody(body, val);
					GameObject teleportEffectPrefab = Run.instance.GetTeleportEffectPrefab(((Component)body).gameObject);
					if (Object.op_Implicit((Object)(object)teleportEffectPrefab))
					{
						EffectManager.SimpleEffect(teleportEffectPrefab, val, Quaternion.identity, true);
					}
				}
				else if (Object.op_Implicit((Object)(object)body.healthComponent))
				{
					body.healthComponent.TakeDamage(new DamageInfo
					{
						damage = oobHealthLoss * body.healthComponent.fullCombinedHealth,
						position = body.corePosition,
						damageType = DamageTypeCombo.op_Implicit((DamageType)66),
						damageColorIndex = (DamageColorIndex)9
					});
				}
			}

			public void OnEnable()
			{
				ObjectivePanelController.collectObjectiveSources += ObjectivePanelController_collectObjectiveSources;
			}

			public void OnCompleted()
			{
				if (BulwarksHauntGhostWaveController.onGhostWaveComplete != null)
				{
					BulwarksHauntGhostWaveController.onGhostWaveComplete();
				}
				ObjectivePanelController.collectObjectiveSources -= ObjectivePanelController_collectObjectiveSources;
			}

			public void OnDisable()
			{
				ObjectivePanelController.collectObjectiveSources -= ObjectivePanelController_collectObjectiveSources;
			}

			private void ObjectivePanelController_collectObjectiveSources(CharacterMaster master, List<ObjectiveSourceDescriptor> objectiveSourcesList)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				objectiveSourcesList.Add(new ObjectiveSourceDescriptor
				{
					master = master,
					objectiveType = typeof(ClearGhostWavesObjectiveController),
					source = (Object)(object)this
				});
			}
		}

		public class GhostWaveControllerBaseState : EntityState
		{
			public class Intro : GhostWaveControllerBaseState
			{
				public float speechTimer = 5f;

				public float speechInterval = 8f;

				public int speechVariant = 1;

				public int speechProgress = 1;

				public override void OnEnter()
				{
					base.OnEnter();
					speechVariant = RoR2Application.rng.RangeInt(1, 4);
				}

				public override void Update()
				{
					//IL_0083: 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_008f: Unknown result type (might be due to invalid IL or missing references)
					//IL_009b: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ae: Expected O, but got Unknown
					base.Update();
					if (Run.instance.livingPlayerCount > 0)
					{
						speechTimer -= Time.deltaTime;
					}
					if (!(speechTimer <= 0f))
					{
						return;
					}
					string text = "BULWARKSHAUNT_GHOSTWAVE_INTRO_" + speechVariant + "_" + speechProgress;
					if (!Language.IsTokenInvalid(text))
					{
						if (NetworkServer.active)
						{
							Chat.SendBroadcastChat((ChatMessageBase)new NpcChatMessage
							{
								baseToken = text,
								formatStringToken = chatFormatStringToken,
								sender = null,
								sound = null
							});
						}
					}
					else if (((EntityState)this).isAuthority)
					{
						((EntityState)this).outer.SetNextState((EntityState)(object)new MonsterWaves());
					}
					speechTimer = speechInterval;
					speechProgress++;
				}
			}

			public class MonsterWaves : GhostWaveControllerBaseState
			{
				public class KillGhostEnemiesObjectiveController : ObjectiveTracker
				{
					public int killedEnemies = -1;

					public int totalEnemies = 1;

					public override string GenerateString()
					{
						//IL_000c: Unknown result type (might be due to invalid IL or missing references)
						MonsterWaves monsterWaves = (MonsterWaves)(object)((EntityStateMachine)base.sourceDescriptor.source).state;
						killedEnemies = monsterWaves.killedEnemies;
						totalEnemies = Mathf.Max(monsterWaves.totalEnemies, 1);
						float num = (float)killedEnemies / (float)totalEnemies;
						if (killedEnemies == -1)
						{
							num = 0f;
						}
						return string.Format(Language.GetString("OBJECTIVE_BULWARKSHAUNT_GHOSTWAVE_KILLENEMIES"), Mathf.FloorToInt(num * 100f).ToString());
					}

					public override bool IsDirty()
					{
						//IL_000c: Unknown result type (might be due to invalid IL or missing references)
						if (((EntityStateMachine)base.sourceDescriptor.source).state is MonsterWaves monsterWaves)
						{
							return monsterWaves.killedEnemies != killedEnemies;
						}
						return false;
					}
				}

				public class SyncTotalEnemies : INetMessage, ISerializableObject
				{
					private NetworkInstanceId objID;

					private int totalEnemies;

					public SyncTotalEnemies()
					{
					}

					public SyncTotalEnemies(NetworkInstanceId objID, int totalEnemies)
					{
						//IL_0009: Unknown result type (might be due to invalid IL or missing references)
						//IL_000a: Unknown result type (might be due to invalid IL or missing references)
						this.objID = objID;
						this.totalEnemies = totalEnemies;
					}

					public void Deserialize(NetworkReader reader)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						//IL_0008: Unknown result type (might be due to invalid IL or missing references)
						objID = reader.ReadNetworkId();
						totalEnemies = reader.ReadInt32();
					}

					public void OnReceived()
					{
						//IL_000d: Unknown result type (might be due to invalid IL or missing references)
						if (NetworkServer.active)
						{
							return;
						}
						GameObject val = Util.FindNetworkObject(objID);
						if (Object.op_Implicit((Object)(object)val))
						{
							EntityStateMachine component = val.GetComponent<EntityStateMachine>();
							if (Object.op_Implicit((Object)(object)component) && component.state is MonsterWaves monsterWaves)
							{
								monsterWaves.totalEnemies = totalEnemies;
							}
						}
					}

					public void Serialize(NetworkWriter writer)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						writer.Write(objID);
						writer.Write(totalEnemies);
					}
				}

				public class SyncKilledEnemies : INetMessage, ISerializableObject
				{
					private NetworkInstanceId objID;

					private int killedEnemies;

					public SyncKilledEnemies()
					{
					}

					public SyncKilledEnemies(NetworkInstanceId objID, int killedEnemies)
					{
						//IL_0009: Unknown result type (might be due to invalid IL or missing references)
						//IL_000a: Unknown result type (might be due to invalid IL or missing references)
						this.objID = objID;
						this.killedEnemies = killedEnemies;
					}

					public void Deserialize(NetworkReader reader)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						//IL_0008: Unknown result type (might be due to invalid IL or missing references)
						objID = reader.ReadNetworkId();
						killedEnemies = reader.ReadInt32();
					}

					public void OnReceived()
					{
						//IL_000d: Unknown result type (might be due to invalid IL or missing references)
						if (NetworkServer.active)
						{
							return;
						}
						GameObject val = Util.FindNetworkObject(objID);
						if (Object.op_Implicit((Object)(object)val))
						{
							EntityStateMachine component = val.GetComponent<EntityStateMachine>();
							if (Object.op_Implicit((Object)(object)component) && component.state is MonsterWaves monsterWaves)
							{
								monsterWaves.killedEnemies = killedEnemies;
							}
						}
					}

					public void Serialize(NetworkWriter writer)
					{
						//IL_0003: Unknown result type (might be due to invalid IL or missing references)
						writer.Write(objID);
						writer.Write(killedEnemies);
					}
				}

				public List<KilledEnemyData> enemiesThisWave;

				public Xoroshiro128Plus rng;

				public List<CharacterMaster> aliveEnemies = new List<CharacterMaster>();

				public int killedEnemies = 0;

				public int totalEnemies = 0;

				public float spawnTimer = 0.1f;

				public float spawnInterval = 20f;

				public int spawnBatchCount = 10;

				public int speechVariant = 1;

				public float spawnBatchTimer = 0f;

				public float spawnBatchInterval = 0.1f;

				public int spawnBatchCurrent = 0;

				public float aliveEnemiesRecheckTimer = 60f;

				public float aliveEnemiesRecheckInterval = 60f;

				public float antiSoftlockTimer = 600f;

				public List<BulwarksHauntWaveModifier> activeModifiers = new List<BulwarksHauntWaveModifier>();

				public override void OnEnter()
				{
					//IL_0181: Unknown result type (might be due to invalid IL or missing references)
					//IL_018b: Expected O, but got Unknown
					//IL_0196: Unknown result type (might be due to invalid IL or missing references)
					//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
					//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
					//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
					//IL_01da: Unknown result type (might be due to invalid IL or missing references)
					//IL_0210: Unknown result type (might be due to invalid IL or missing references)
					//IL_0221: Unknown result type (might be due to invalid IL or missing references)
					//IL_0232: Unknown result type (might be due to invalid IL or missing references)
					//IL_0243: Unknown result type (might be due to invalid IL or missing references)
					//IL_0254: Unknown result type (might be due to invalid IL or missing references)
					//IL_0265: 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_0287: Unknown result type (might be due to invalid IL or missing references)
					//IL_0298: Unknown result type (might be due to invalid IL or missing references)
					//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
					//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
					//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
					//IL_0302: Unknown result type (might be due to invalid IL or missing references)
					//IL_0313: Unknown result type (might be due to invalid IL or missing references)
					//IL_0324: Unknown result type (might be due to invalid IL or missing references)
					//IL_0335: Unknown result type (might be due to invalid IL or missing references)
					//IL_0346: Unknown result type (might be due to invalid IL or missing references)
					//IL_0357: Unknown result type (might be due to invalid IL or missing references)
					//IL_012f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0136: Expected O, but got Unknown
					//IL_0112: Unknown result type (might be due to invalid IL or missing references)
					//IL_011c: Expected O, but got Unknown
					//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
					//IL_0483: Unknown result type (might be due to invalid IL or missing references)
					//IL_0488: Unknown result type (might be due to invalid IL or missing references)
					//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
					//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
					//IL_0553: Unknown result type (might be due to invalid IL or missing references)
					//IL_0558: Unknown result type (might be due to invalid IL or missing references)
					//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
					base.OnEnter();
					if (ghostWaveController.wave == 1)
					{
						speechVariant = RoR2Application.rng.RangeInt(1, 4);
						ghostWaveController.currentSpeechVariant = speechVariant;
					}
					else
					{
						speechVariant = ghostWaveController.currentSpeechVariant;
					}
					PlaySoundForViewedCameras("Play_ui_obj_nullWard_activate");
					if (killedEnemiesPerStage.ContainsKey(ghostWaveController.wave))
					{
						enemiesThisWave = killedEnemiesPerStage[ghostWaveController.wave].Where((KilledEnemyData x) => ((int)x.bodyIndex != -1 && Object.op_Implicit((Object)(object)BodyCatalog.GetBodyPrefab(x.bodyIndex))) ? true : false).ToList();
						totalEnemies = enemiesThisWave.Count;
						if (NetworkServer.active)
						{
							NetMessageExtensions.Send((INetMessage)(object)new SyncTotalEnemies(((EntityState)this).gameObject.GetComponent<NetworkIdentity>().netId, totalEnemies), (NetworkDestination)1);
						}
						rng = new Xoroshiro128Plus(waveRng[ghostWaveController.wave]);
					}
					else
					{
						if (NetworkServer.active)
						{
							SimpleChatMessage val = new SimpleChatMessage();
							val.baseToken = "BULWARKSHAUNT_GHOSTWAVE_SYSTEM_WAVEFALLBACK";
							val.paramTokens = new string[1] { ghostWaveController.wave.ToString() };
							Chat.SendBroadcastChat((ChatMessageBase)(object)val);
						}
						enemiesThisWave = new List<KilledEnemyData>();
						rng = new Xoroshiro128Plus(RoR2Application.rng.nextUlong);
						List<BodyIndex> list = new List<BodyIndex>
						{
							BodyCatalog.FindBodyIndex("BeetleBody"),
							BodyCatalog.FindBodyIndex("WispBody"),
							BodyCatalog.FindBodyIndex("LemurianBody"),
							BodyCatalog.FindBodyIndex("ImpBody"),
							BodyCatalog.FindBodyIndex("JellyfishBody")
						};
						int num = Mathf.FloorToInt(18f + 7f * (float)ghostWaveController.wave);
						List<BodyIndex> list2 = new List<BodyIndex>
						{
							BodyCatalog.FindBodyIndex("BeetleGuardBody"),
							BodyCatalog.FindBodyIndex("GreaterWispBody"),
							BodyCatalog.FindBodyIndex("LemurianBruiserBody"),
							BodyCatalog.FindBodyIndex("BellBody"),
							BodyCatalog.FindBodyIndex("ClayBruiserBody"),
							BodyCatalog.FindBodyIndex("BellBody"),
							BodyCatalog.FindBodyIndex("MiniMushroomBody"),
							BodyCatalog.FindBodyIndex("ParentBody"),
							BodyCatalog.FindBodyIndex("GolemBody")
						};
						int num2 = Mathf.FloorToInt(2f + 3f * (float)ghostWaveController.wave);
						List<BodyIndex> list3 = new List<BodyIndex>
						{
							BodyCatalog.FindBodyIndex("BeetleQueen2Body"),
							BodyCatalog.FindBodyIndex("ClayBossBody"),
							BodyCatalog.FindBodyIndex("GrandParentBody"),
							BodyCatalog.FindBodyIndex("GravekeeperBody"),
							BodyCatalog.FindBodyIndex("ImpBossBody"),
							BodyCatalog.FindBodyIndex("MagmaWormBody"),
							BodyCatalog.FindBodyIndex("RoboBallBossBody"),
							BodyCatalog.FindBodyIndex("VagrantBody"),
							BodyCatalog.FindBodyIndex("TitanBody")
						};
						int num3 = Mathf.FloorToInt(1f + 0.5f * (float)ghostWaveController.wave);
						WeightedSelection<EquipmentDef> val2 = new WeightedSelection<EquipmentDef>(8);
						val2.AddChoice((EquipmentDef)null, 1f);
						if (ghostWaveController.wave >= 3)
						{
							val2.AddChoice(Equipment.AffixRed, 0.0111f * (float)ghostWaveController.wave);
							val2.AddChoice(Equipment.AffixBlue, 0.0111f * (float)ghostWaveController.wave);
							val2.AddChoice(Equipment.AffixWhite, 0.0111f * (float)ghostWaveController.wave);
						}
						if (ghostWaveController.wave >= 6)
						{
							val2.AddChoice(Equipment.AffixPoison, 0.0085f * (float)ghostWaveController.wave);
							val2.AddChoice(Equipment.AffixHaunted, 0.0085f * (float)ghostWaveController.wave);
						}
						for (int i = 0; i < num; i++)
						{
							enemiesThisWave.Add(new KilledEnemyData
							{
								bodyIndex = rng.NextElementUniform<BodyIndex>(list),
								inventory = new List<ItemCountPair>(),
								equipment = val2.Evaluate(rng.nextNormalizedFloat)
							});
						}
						for (int j = 0; j < num2; j++)
						{
							enemiesThisWave.Add(new KilledEnemyData
							{
								bodyIndex = rng.NextElementUniform<BodyIndex>(list2),
								inventory = new List<ItemCountPair>(),
								equipment = val2.Evaluate(rng.nextNormalizedFloat)
							});
						}
						for (int k = 0; k < num3; k++)
						{
							enemiesThisWave.Add(new KilledEnemyData
							{
								bodyIndex = rng.NextElementUniform<BodyIndex>(list3),
								inventory = new List<ItemCountPair>(),
								equipment = null
							});
						}
						enemiesThisWave = enemiesThisWave.Where((KilledEnemyData x) => ((int)x.bodyIndex != -1 && Object.op_Implicit((Object)(object)BodyCatalog.GetBodyPrefab(x.bodyIndex))) ? true : false).ToList();
						totalEnemies = enemiesThisWave.Count;
						if (NetworkServer.active)
						{
							NetMessageExtensions.Send((INetMessage)(object)new SyncTotalEnemies(((EntityState)this).gameObject.GetComponent<NetworkIdentity>().netId, totalEnemies), (NetworkDestination)1);
						}
					}
					spawnBatchCount += ghostWaveController.wave - 1;
					GlobalEventManager.onCharacterDeathGlobal += GlobalEventManager_onCharacterDeathGlobal;
					ObjectivePanelController.collectObjectiveSources += ObjectivePanelController_collectObjectiveSources;
					if (!NetworkServer.active || !ShouldActivateModifier())
					{
						return;
					}
					List<BulwarksHauntWaveModifier> list4 = new List<BulwarksHauntWaveModifier>(WaveModifierCatalog.allWaveModifiers);
					for (int l = 0; l < ModifiersToActivateThisWave(); l++)
					{
						if (list4.Count <= 0)
						{
							break;
						}
						BulwarksHauntWaveModifier bulwarksHauntWaveModifier = rng.NextElementUniform<BulwarksHauntWaveModifier>(list4);
						list4.Remove(bulwarksHauntWaveModifier);
						bulwarksHauntWaveModifier.Activate(this);
						activeModifiers.Add(bulwarksHauntWaveModifier);
					}
				}

				public uint GetCoinReward()
				{
					return (uint)(1 + Mathf.CeilToInt((float)ghostWaveController.wave / 4f));
				}

				public bool ShouldActivateModifier()
				{
					int num = 4;
					if (ConfigurableValue<bool>.op_Implicit(moreFrequentModifiers))
					{
						num = 2;
					}
					if (ConfigurableValue<bool>.op_Implicit(superFrequentModifiers))
					{
						num = 1;
					}
					return ghostWaveController.wave % num == 0;
				}

				public int ModifiersToActivateThisWave()
				{
					if (ghostWaveController.wave == maxWaves && ConfigurableValue<bool>.op_Implicit(finalWaveAllModifiers))
					{
						return WaveModifierCatalog.allWaveModifiers.Count;
					}
					return 1;
				}

				private void GlobalEventManager_onCharacterDeathGlobal(DamageReport damageReport)
				{
					//IL_004e: Unknown result type (might be due to invalid IL or missing references)
					//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
					//IL_0102: Unknown result type (might be due to invalid IL or missing references)
					//IL_0127: Unknown result type (might be due to invalid IL or missing references)
					//IL_0133: Unknown result type (might be due to invalid IL or missing references)
					//IL_013a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0146: Expected O, but got Unknown
					if (aliveEnemies.Contains(damageReport.victimMaster))
					{
						aliveEnemies.Remove(damageReport.victimMaster);
						killedEnemies++;
						if (NetworkServer.active)
						{
							NetMessageExtensions.Send((INetMessage)(object)new SyncKilledEnemies(((EntityState)this).gameObject.GetComponent<NetworkIdentity>().netId, killedEnemies), (NetworkDestination)1);
						}
						aliveEnemiesRecheckTimer = 0.1f;
						spawnTimer -= spawnInterval / (float)spawnBatchCount * 0.8f;
						if (aliveEnemies.Count <= 3 && spawnTimer > 0.1f && spawnBatchCurrent <= 0)
						{
							spawnTimer = 0.1f;
						}
					}
					if (Object.op_Implicit((Object)(object)damageReport.victimMaster) && (Object)(object)damageReport.victimMaster.playerCharacterMasterController != (Object)null && NetworkServer.active)
					{
						Chat.SendBroadcastChat((ChatMessageBase)new NpcChatMessage
						{
							baseToken = "BULWARKSHAUNT_GHOSTWAVE_LOSS_" + RoR2Application.rng.RangeInt(1, 5),
							formatStringToken = chatFormatStringToken,
							sender = null,
							sound = null
						});
					}
				}

				public override void FixedUpdate()
				{
					((EntityState)this).FixedUpdate();
					if (NetworkServer.active)
					{
						if (enemiesThisWave.Count > 0)
						{
							spawnTimer -= Time.fixedDeltaTime;
							if (spawnTimer <= 0f)
							{
								spawnTimer += spawnInterval;
								spawnBatchTimer = 0f;
								spawnBatchCurrent = spawnBatchCount;
							}
							if (spawnBatchCurrent > 0)
							{
								spawnBatchTimer -= Time.fixedDeltaTime;
								if (spawnBatchTimer <= 0f)
								{
									spawnBatchTimer += spawnBatchInterval;
									TryUnloadFromBatch();
								}
							}
						}
						aliveEnemiesRecheckTimer -= Time.fixedDeltaTime;
						antiSoftlockTimer -= Time.fixedDeltaTime;
						if ((aliveEnemiesRecheckTimer <= 0f || antiSoftlockTimer <= 0f) && Run.instance.livingPlayerCount > 0)
						{
							aliveEnemiesRecheckTimer = aliveEnemiesRecheckInterval;
							CheckAllEnemiesDead();
						}
						ghostWaveController.oobShrinkTimer += Time.fixedDeltaTime;
					}
					foreach (BulwarksHauntWaveModifier activeModifier in activeModifiers)
					{
						if (activeModifier.onFixedUpdate != null)
						{
							activeModifier.onFixedUpdate(this);
						}
					}
				}

				public override void Update()
				{
					base.Update();
					foreach (BulwarksHauntWaveModifier activeModifier in activeModifiers)
					{
						if (activeModifier.onUpdate != null)
						{
							activeModifier.onUpdate(this);
						}
					}
				}

				public void TryUnloadFromBatch()
				{
					//IL_0068: Unknown result type (might be due to invalid IL or missing references)
					//IL_006d: Unknown result type (might be due to invalid IL or missing references)
					//IL_006f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0076: Expected O, but got Unknown
					//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
					//IL_0111: Unknown result type (might be due to invalid IL or missing references)
					//IL_0118: Expected O, but got Unknown
					//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cb: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f2: Expected O, but got Unknown
					TeamDef teamDef = TeamCatalog.GetTeamDef((TeamIndex)2);
					if (TeamComponent.GetTeamMembers((TeamIndex)2).Count >= teamDef.softCharacterLimit)
					{
						return;
					}
					KilledEnemyData newEnemy = rng.NextElementUniform<KilledEnemyData>(enemiesThisWave);
					CharacterSpawnCard val = GenerateSpawnCardForKilledEnemy(newEnemy);
					if (Object.op_Implicit((Object)(object)val))
					{
						DirectorPlacementRule val2 = new DirectorPlacementRule
						{
							placementMode = (PlacementMode)4
						};
						List<PlayerCharacterMasterController> list = PlayerCharacterMasterController.instances.Where((PlayerCharacterMasterController x) => x.master.hasBody).ToList();
						if (list.Count > 0)
						{
							PlayerCharacterMasterController val3 = rng.NextElementUniform<PlayerCharacterMasterController>(list);
							val2 = new DirectorPlacementRule
							{
								placementMode = (PlacementMode)1,
								spawnOnTarget = val3.master.GetBodyObject().transform,
								preventOverhead = true
							};
							DirectorCore.GetMonsterSpawnDistance((MonsterSpawnDistance)0, ref val2.minDistance, ref val2.maxDistance);
						}
						DirectorSpawnRequest val4 = new DirectorSpawnRequest((SpawnCard)(object)val, val2, rng);
						val4.teamIndexOverride = (TeamIndex)2;
						val4.ignoreTeamMemberLimit = true;
						val4.onSpawnedServer = (Action<SpawnResult>)Delegate.Combine(val4.onSpawnedServer, (Action<SpawnResult>)delegate(SpawnResult spawnResult)
						{
							//IL_0001: Unknown result type (might be due to invalid IL or missing references)
							//IL_003e: Unknown result type (might be due to invalid IL or missing references)
							if (spawnResult.success)
							{
								enemiesThisWave.Remove(newEnemy);
								spawnBatchCurrent--;
								CharacterMaster component = spawnResult.spawnedInstance.GetComponent<CharacterMaster>();
								aliveEnemies.Add(component);
								if (Object.op_Implicit((Object)(object)component.inventory) && component.inventory.GetItemCount(BulwarksHauntContent.Items.BulwarksHaunt_GhostFury) <= 0)
								{
									component.inventory.GiveItem(BulwarksHauntContent.Items.BulwarksHaunt_GhostFury, 1);
								}
							}
						});
						DirectorCore.instance.TrySpawnObject(val4);
					}
					else
					{
						enemiesThisWave.Remove(newEnemy);
						spawnBatchCurrent--;
						killedEnemies++;
						if (NetworkServer.active)
						{
							NetMessageExtensions.Send((INetMessage)(object)new SyncKilledEnemies(((EntityState)this).gameObject.GetComponent<NetworkIdentity>().netId, killedEnemies), (NetworkDestination)1);
						}
					}
				}

				public void CheckAllEnemiesDead()
				{
					//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					if (!NetworkServer.active)
					{
						return;
					}
					FilterInvalidAliveEnemies();
					if (killedEnemies < totalEnemies && !(antiSoftlockTimer <= 0f) && (aliveEnemies.Count != 0 || enemiesThisWave.Count != 0))
					{
						return;
					}
					Advance();
					foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers((TeamIndex)2))
					{
						if (Object.op_Implicit((Object)(object)teamMember.body) && Object.op_Implicit((Object)(object)teamMember.body.healthComponent) && teamMember.body.healthComponent.alive)
						{
							teamMember.body.healthComponent.Suicide((GameObject)null, (GameObject)null, default(DamageTypeCombo));
						}
					}
				}

				public void FilterInvalidAliveEnemies()
				{
					int count = aliveEnemies.Count;
					aliveEnemies = aliveEnemies.Where((CharacterMaster x) => (Object)(object)x != (Object)null && x.hasBody).ToList();
					if (aliveEnemies.Count < count)
					{
						killedEnemies += count - aliveEnemies.Count;
					}
				}

				public void Advance()
				{
					//IL_006a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0071: Expected O, but got Unknown
					//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
					//IL_011e: Unknown result type (might be due to invalid IL or missing references)
					//IL_012a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0131: Unknown result type (might be due to invalid IL or missing references)
					//IL_013d: Expected O, but got Unknown
					if (NetworkServer.active)
					{
						RespawnPlayers();
						uint coinReward = GetCoinReward();
						for (int i = 0; i < NetworkUser.readOnlyInstancesList.Count; i++)
						{
							NetworkUser val = NetworkUser.readOnlyInstancesList[i];
							if (Object.op_Implicit((Object)(object)val) && val.isParticipating)
							{
								val.AwardLunarCoins(coinReward);
							}
						}
						SimpleChatMessage val2 = new SimpleChatMessage();
						val2.baseToken = "BULWARKSHAUNT_GHOSTWAVE_SYSTEM_WAVECLEAR";
						val2.paramTokens = new string[1] { coinReward.ToString() };
						Chat.SendBroadcastChat((ChatMessageBase)(object)val2);
					}
					int num = ghostWaveController.wave + 1;
					if (num <= maxWaves)
					{
						if (((EntityState)this).isAuthority)
						{
							((EntityState)this).outer.SetNextState((EntityState)(object)new BreakBetweenWaves());
						}
						if (NetworkServer.active)
						{
							Chat.SendBroadcastChat((ChatMessageBase)new NpcChatMessage
							{
								baseToken = "BULWARKSHAUNT_GHOSTWAVE_WAVECLEAR_" + speechVariant + "_" + ghostWaveController.wave,
								formatStringToken = chatFormatStringToken,
								sender = null,
								sound = null
							});
						}
					}
					else if (((EntityState)this).isAuthority)
					{
						((EntityState)this).outer.SetNextState((EntityState)(object)new Ending());
					}
				}

				public void RespawnPlayers()
				{
					//IL_0053: Unknown result type (might be due to invalid IL or missing references)
					//IL_0058: 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_0076: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ca: 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)
					//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
					//IL_0103: Unknown result type (might be due to invalid IL or missing references)
					//IL_010e: Expected O, but got Unknown
					if (!ConfigurableValue<bool>.op_Implicit(coopRespawnEachWave))
					{
						return;
					}
					foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
					{
						CharacterMaster master = instance.master;
						if (!instance.isConnected || !master.IsDeadAndOutOfLivesServer())
						{
							continue;
						}
						Vector3 deathFootPosition = master.deathFootPosition;
						master.Respawn(deathFootPosition, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f), false);
						CharacterBody body = master.GetBody();
						if (Object.op_Implicit((Object)(object)body))
						{
							body.AddTimedBuff(Buffs.Immune, 3f);
							EntityStateMachine[] components = ((Component)body).GetComponents<EntityStateMachine>();
							foreach (EntityStateMachine val in components)
							{
								val.initialStateType = val.mainStateType;
							}
							EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HippoRezEffect"), new EffectData
							{
								origin = deathFootPosition,
								rotation = body.transform.rotation
							}, true);
						}
					}
				}

				public override void OnExit()
				{
					base.OnExit();
					ghostWaveController.oobShrinkTimer = 0f;
					PlaySoundForViewedCameras("Play_ui_obj_nullWard_complete");
					GlobalEventManager.onCharacterDeathGlobal -= GlobalEventManager_onCharacterDeathGlobal;
					ObjectivePanelController.collectObjectiveSources -= ObjectivePanelController_collectObjectiveSources;
					foreach (BulwarksHauntWaveModifier activeModifier in activeModifiers)
					{
						activeModifier.Deactivate(this);
					}
				}

				private void ObjectivePanelController_collectObjectiveSources(CharacterMaster master, List<ObjectiveSourceDescriptor> objectiveSourcesList)
				{
					//IL_0004: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					objectiveSourcesList.Add(new ObjectiveSourceDescriptor
					{
						master = master,
						objectiveType = typeof(KillGhostEnemiesObjectiveController),
						source = (Object)(object)((EntityState)this).outer
					});
				}
			}

			public class BreakBetweenWaves : GhostWaveControllerBaseState
			{
				public class WaitForNextWaveObjectiveController : ObjectiveTracker
				{
					public override string GenerateString()
					{
						//IL_000c: Unknown result type (might be due to invalid IL or missing references)
						BreakBetweenWaves breakBetweenWaves = (BreakBetweenWaves)(object)((EntityStateMachine)base.sourceDescriptor.source).state;
						float num = Mathf.Max(breakBetweenWaves.timeLeft, 0f);
						TimeSpan timeSpan = TimeSpan.FromSeconds(num);
						string arg = $"{timeSpan.Seconds:D2}:{timeSpan.Milliseconds / 10:D2}";
						return string.Format(Language.GetString("OBJECTIVE_BULWARKSHAUNT_GHOSTWAVE_WAITFORNEXTWAVE"), arg);
					}

					public override bool IsDirty()
					{
						//IL_000c: Unknown result type (might be due to invalid IL or missing references)
						return ((EntityStateMachine)base.sourceDescriptor.source).state is BreakBetweenWaves;
					}
				}

				public float timeLeft = 15f;

				public override void OnEnter()
				{
					base.OnEnter();
					ObjectivePanelController.collectObjectiveSources += ObjectivePanelController_collectObjectiveSources;
				}

				private void ObjectivePanelController_collectObjectiveSources(CharacterMaster master, List<ObjectiveSourceDescriptor> objectiveSourcesList)
				{
					//IL_0004: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					objectiveSourcesList.Add(new ObjectiveSourceDescriptor
					{
						master = master,
						objectiveType = typeof(WaitForNextWaveObjectiveController),
						source = (Object)(object)((EntityState)this).outer
					});
				}

				public override void OnExit()
				{
					base.OnExit();
					ObjectivePanelController.collectObjectiveSources -= ObjectivePanelController_collectObjectiveSources;
					ghostWaveController.wave++;
				}

				public override void Update()
				{
					base.Update();
					if (Run.instance.livingPlayerCount > 0)
					{
						timeLeft -= Time.deltaTime;
					}
					if (timeLeft <= 0f && ((EntityState)this).isAuthority)
					{
						((EntityState)this).outer.SetNextState((EntityState)(object)new MonsterWaves());
					}
				}
			}

			public class Ending : GhostWaveControllerBaseState
			{
				public float speechTimer = 0f;

				public float speechInterval = 8f;

				public int speechVariant = 1;

				public int speechProgress = 1;

				public override void OnEnter()
				{
					//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_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					base.OnEnter();
					PlaySoundForViewedCameras("Play_moonBrother_swing_horizontal");
					if (NetworkServer.active)
					{
						GameObject val = Object.Instantiate<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/Common/LogPickup.prefab").WaitForCompletion(), new Vector3(-3.090973f, 65.82108f, 42.75804f), Quaternion.identity);
						val.GetComponentInChildren<UnlockPickup>().unlockableDef = UnlockableCatalog.GetUnlockableDef("Logs.Stages.BulwarksHaunt_GhostWave");
						val.GetComponent<TeamFilter>().teamIndex = (TeamIndex)1;
						NetworkServer.Spawn(val);
					}
					speechVariant = RoR2Application.rng.RangeInt(1, 4);
					ghostWaveController.OnCompleted();
					List<CombatDirector> list = new List<CombatDirector>(CombatDirector.instancesList);
					foreach (CombatDirector item in list)
					{
						((Behaviour)item).enabled = false;
					}
				}

				public override void Update()
				{
					//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
					//IL_00dc: Expected O, but got Unknown
					base.Update();
					if (Run.instance.livingPlayerCount > 0)
					{
						speechTimer -= Time.deltaTime;
					}
					if (speechTimer <= 0f)
					{
						string text = "BULWARKSHAUNT_GHOSTWAVE_WIN_" + speechVariant + "_" + speechProgress;
						string text2 = "BULWARKSHAUNT_GHOSTWAVE_WIN_" + speechVariant + "_" + (speechProgress + 1);
						if (!Language.IsTokenInvalid(text) && NetworkServer.active)
						{
							Chat.SendBroadcastChat((ChatMessageBase)new NpcChatMessage
							{
								baseToken = text,
								formatStringToken = chatFormatStringToken,
								sender = null,
								sound = null
							});
						}
						if ((Language.IsTokenInvalid(text2) || Language.IsTokenInvalid(text)) && ((EntityState)this).isAuthority)
						{
							((EntityState)this).outer.SetNextState((EntityState)(object)new FadeOut());
						}
						speechProgress++;
						speechTimer = speechInterval;
					}
				}
			}

			public class FadeOut : GhostWaveControllerBaseState
			{
				public float duration = 8f;

				public GameObject postProcessingObj;

				public PostProcessVolume postProcessVolume;

				public bool ended = false;

				public override void OnEnter()
				{
					base.OnEnter();
					postProcessingObj = ((Component)((EntityState)this).transform.Find("PostProcessing (FadeOut)")).gameObject;
					if (Object.op_Implicit((Object)(object)postProcessingObj))
					{
						postProcessingObj.SetActive(true);
						postProcessVolume = postProcessingObj.GetComponent<PostProcessVolume>();
					}
				}

				public override void Update()
				{
					base.Update();
					float num = Mathf.Clamp01(((EntityState)this).age / duration);
					num *= num;
					if (Object.op_Implicit((Object)(object)postProcessVolume))
					{
						postProcessVolume.weight = num;
					}
					if (!ended && num >= 1f)
					{
						ended = true;
						PlaySoundForViewedCameras("Play_elite_haunt_spawn");
						if (NetworkServer.active)
						{
							Run.instance.BeginGameOver(BulwarksHauntContent.GameEndings.BulwarksHaunt_HauntedEnding);
						}
					}
				}

				public override void FixedUpdate()
				{
					//IL_0070: Unknown result type (might be due to invalid IL or missing references)
					//IL_007b: Expected O, but got Unknown
					((EntityState)this).FixedUpdate();
					if (!ended)
					{
						return;
					}
					foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
					{
						if (readOnlyInstances.hasEffectiveAuthority)
						{
							EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)readOnlyInstances).gameObject, "Body");
							if (Object.op_Implicit((Object)(object)val) && !(val.state is Idle))
							{
								val.SetInterruptState((EntityState)new Idle(), (InterruptPriority)5);
							}
						}
					}
				}
			}

			public string chatFormatStringToken = "BULWARKSHAUNT_GHOSTWAVE_VOICE_FORMAT";

			public BulwarksHauntGhostWaveController ghostWaveController;

			public override void OnEnter()
			{
				((EntityState)this).OnEnter();
				ghostWaveController = ((EntityState)this).GetComponent<BulwarksHauntGhostWaveController>();
			}

			public override void Update()
			{
				((EntityState)this).Update();
			}

			public override void OnExit()
			{
				((EntityState)this).OnExit();
			}
		}

		public static class WaveModifierCatalog
		{
			public static List<BulwarksHauntWaveModifier> allWaveModifiers = new List<BulwarksHauntWaveModifier>();

			public static Dictionary<string, BulwarksHauntWaveModifier> nameToModifier = new Dictionary<string, BulwarksHauntWaveModifier>();

			public static Dictionary<int, BulwarksHauntWaveModifier> indexToModifier = new Dictionary<int, BulwarksHauntWaveModifier>();

			public static List<string> activeWaveModifiers = new List<string>();

			public static Action<List<BulwarksHauntWaveModifier>> CollectWaveModifiers;

			public static void SetWaveModifiers(List<BulwarksHauntWaveModifier> newWaveModifiers)
			{
				allWaveModifiers.Clear();
				nameToModifier.Clear();
				indexToModifier.Clear();
				for (int i = 0; i < newWaveModifiers.Count; i++)
				{
					BulwarksHauntWaveModifier bulwarksHauntWaveModifier = newWaveModifiers[i];
					bulwarksHauntWaveModifier.index = i;
					allWaveModifiers.Add(bulwarksHauntWaveModifier);
					nameToModifier.Add(((Object)bulwarksHauntWaveModifier).name, bulwarksHauntWaveModifier);
					indexToModifier.Add(bulwarksHauntWaveModifier.index, bulwarksHauntWaveModifier);
				}
			}

			public static BulwarksHauntWaveModifier GetWaveModifier(int index)
			{
				if (indexToModifier.ContainsKey(index))
				{
					return indexToModifier[index];
				}
				return null;
			}

			public static bool IsActive(string name)
			{
				return activeWaveModifiers.Contains(name);
			}
		}

		public class WaveModifierObjectiveController : ObjectiveTracker
		{
			public bool mustBeDirty = true;

			public override string GenerateString()
			{
				mustBeDirty = false;
				BulwarksHauntWaveModifier bulwarksHauntWaveModifier = (BulwarksHauntWaveModifier)(object)base.sourceDescriptor.source;
				return string.Format(Language.GetString("OBJECTIVE_BULWARKSHAUNT_GHOSTWAVE_MODIFIERACTIVE"), Language.GetString(bulwarksHauntWaveModifier.nameToken), Language.GetString(bulwarksHauntWaveModifier.descriptionToken));
			}

			public override bool IsDirty()
			{
				return mustBeDirty;
			}
		}

		public static SceneDef sceneDef;

		public static GameObject sceneInfoObj;

		public static GameObject directorObj;

		public static GameObject gameManagerObj;

		public static GameObject ghostWaveControllerObj;

		public static MapNodeGroup groundNodeGroup;

		public static NodeGraph groundNodeGraph;

		public static MapNodeGroup airNodeGroup;

		public static NodeGraph airNodeGraph;

		public static DirectorCardCategorySelection dccsBulwarksHaunt_GhostWaveMonsters;

		public static DccsPool dpBulwarksHaunt_GhostWaveMonsters;

		public static DirectorCardCategorySelection dccsBulwarksHaunt_GhostWaveInteractables;

		public static DccsPool dpBulwarksHaunt_GhostWaveInteractables;

		public static GameObject ghostWaveControllerObjPrefab;

		private static DateTime debugTimestamp;

		public static ConfigurableValue<string> bannedEnemiesNames;

		public static List<BodyIndex> bannedEnemiesBodyIndices = new List<BodyIndex>();

		public static ConfigurableValue<bool> coopRespawnEachWave;

		public static ConfigurableValue<bool> moreFrequentModifiers;

		public static ConfigurableValue<bool> superFrequentModifiers;

		public static ConfigurableValue<bool> finalWaveAllModifiers;

		public static Dictionary<int, List<KilledEnemyData>> killedEnemiesPerStage = new Dictionary<int, List<KilledEnemyData>>();

		public static Dictionary<int, Xoroshiro128Plus> waveRng = new Dictionary<int, Xoroshiro128Plus>();

		public static int waveEnemyHardCap = 120;

		public static int maxWaves = 8;

		public static Texture waveModifierNotificationIcon;

		public override void OnPluginAwake()
		{
			((BaseLoadableAsset)this).OnPluginAwake();
			ghostWaveControllerObjPrefab = Utils.CreateBlankPrefab("GhostWaveController2", true);
			NetworkingAPI.RegisterMessageType<GhostWaveControllerBaseState.MonsterWaves.SyncTotalEnemies>();
			NetworkingAPI.RegisterMessageType<GhostWaveControllerBaseState.MonsterWaves.SyncKilledEnemies>();
		}

		public override void Load()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			SetUpStage();
			SetUpGameEnding();
			SetUpGamemode();
			SetUpWaveModifiers();
			((BaseLoadableAsset)this).OnLoad();
			base.asset = sceneDef;
			BulwarksHauntContent.Resources.sceneDefs.Add(sceneDef);
			MusicTrackCatalog.Init += new hook_Init(SetUpStageMusic);
			BazaarController.SetUpSeerStations += new hook_SetUpSeerStations(BazaarController_SetUpSeerStations);
		}

		private void MapNodeGroup_Bake1(orig_Bake orig, MapNodeGroup self, NodeGraph nodeGraph)
		{
			debugTimestamp = DateTime.Now;
			orig.Invoke(self, nodeGraph);
			BulwarksHauntPlugin.logger.LogMessage((object)("Nodes baked! " + DateTime.Now.Subtract(debugTimestamp).TotalSeconds + "s elapsed"));
		}

		private void MapNodeGroup_Bake(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_003d: 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)
			ILCursor val = new ILCursor(il);
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<MapNode>(x, "BuildLinks")
			}))
			{
				return;
			}
			val.Emit(OpCodes.Ldloc, 0);
			val.Emit(OpCodes.Ldloc, 3);
			val.EmitDelegate<Action<List<MapNode>, int>>((Action<List<MapNode>, int>)delegate(List<MapNode> nodes, int i)
			{
				if (i % 250 == 0)
				{
					BulwarksHauntPlugin.logger.LogMessage((object)("Bake: " + i + "/" + nodes.Count + " nodes done, " + DateTime.Now.Subtract(debugTimestamp).TotalSeconds + "s elapsed"));
				}
			});
		}

		public void SetUpStage()
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Expected O, but got Unknown
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Expected O, but got Unknown
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Expected O, but got Unknown
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Expected O, but got Unknown
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Expected O, but got Unknown
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(BulwarksHauntPlugin.pluginInfo.Location), "bulwarkshauntsceneassetbundle"));
			SceneManager.sceneLoaded += SceneManager_sceneLoaded;
			sceneDef = ScriptableObject.CreateInstance<SceneDef>();
			sceneDef.nameToken = "MAP_BULWARKSHAUNT_GHOSTWAVE_NAME";
			sceneDef.subtitleToken = "MAP_BULWARKSHAUNT_GHOSTWAVE_SUBTITLE";
			sceneDef.loreToken = "MAP_BULWARKSHAUNT_GHOSTWAVE_LORE";
			sceneDef.baseSceneNameOverride = "BulwarksHaunt_GhostWave";
			sceneDef.cachedName = "BulwarksHaunt_GhostWave";
			sceneDef.blockOrbitalSkills = false;
			sceneDef.dioramaPrefab = BulwarksHauntPlugin.AssetBundle.LoadAsset<GameObject>("Assets/Mods/Bulwark's Haunt/GhostWave/DioramaDisplay.prefab");
			ModelPanelParameters val2 = sceneDef.dioramaPrefab.AddComponent<ModelPanelParameters>();
			val2.cameraPositionTransform = ((Component)val2).transform.Find("Camera Position");
			val2.focusPointTransform = ((Component)val2).transform.Find("Focus Point");
			val2.minDistance = 10f;
			val2.maxDistance = 120f;
			sceneDef.isOfflineScene = false;
			sceneDef.previewTexture = (Texture)(object)BulwarksHauntPlugin.AssetBundle.LoadAsset<Sprite>("Assets/Mods/Bulwark's Haunt/GhostWave/texBulwarksHaunt_GhostWavePreview.png").texture;
			sceneDef.portalMaterial = Object.Instantiate<Material>(Addressables.LoadAssetAsync<Material>((object)"RoR2/Base/bazaar/matBazaarSeerFrozenwall.mat").WaitForCompletion());
			sceneDef.portalMaterial.SetTexture("_MainTex", sceneDef.previewTexture);
			sceneDef.portalSelectionMessageString = "BAZAAR_SEER_BULWARKSHAUNT_GHOSTWAVE";
			sceneDef.sceneType = (SceneType)2;
			sceneDef.shouldIncludeInLogbook = true;
			sceneDef.stageOrder = 101;
			sceneDef.suppressNpcEntry = false;
			sceneDef.suppressPlayerEntry = false;
			sceneDef.validForRandomSelection = false;
			DateTime now = DateTime.Now;
			BulwarksHauntPlugin.logger.LogMessage((object)"Loading prebaked nodes...");
			groundNodeGraph = LoadBakedNodesFromFile((GraphType)0);
			((Object)groundNodeGraph).name = "BulwarksHaunt_GhostWaveGroundNodeGraph";
			GameObject val3 = Utils.CreateBlankPrefab("BulwarksHaunt_GhostWaveGroundNodeGroup", false);
			groundNodeGroup = val3.AddComponent<MapNodeGroup>();
			groundNodeGroup.graphType = (GraphType)0;
			groundNodeGroup.nodeGraph = groundNodeGraph;
			Node[] nodes = groundNodeGraph.nodes;
			foreach (Node val4 in nodes)
			{
				groundNodeGroup.AddNode(val4.position);
			}
			airNodeGraph = LoadBakedNodesFromFile((GraphType)1);
			((Object)airNodeGraph).name = "BulwarksHaunt_GhostWaveAirNodeGraph";
			val3 = Utils.CreateBlankPrefab("BulwarksHaunt_GhostWaveAirNodeGroup", false);
			airNodeGroup = val3.AddComponent<MapNodeGroup>();
			airNodeGroup.graphType = (GraphType)1;
			airNodeGroup.nodeGraph = airNodeGraph;
			Node[] nodes2 = airNodeGraph.nodes;
			foreach (Node val5 in nodes2)
			{
				airNodeGroup.AddNode(val5.position);
			}
			BulwarksHauntPlugin.logger.LogMessage((object)("Loaded baked nodes! " + DateTime.Now.Subtract(now).TotalSeconds + "s elapsed"));
			dccsBulwarksHaunt_GhostWaveMonsters = ScriptableObject.CreateInstance<DirectorCardCategorySelection>();
			dccsBulwarksHaunt_GhostWaveMonsters.AddCategory("Normal", 1f);
			dccsBulwarksHaunt_GhostWaveMonsters.AddCard(0, new DirectorCard
			{
				spawnCard = (SpawnCard)(object)Addressables.LoadAssetAsync<CharacterSpawnCard>((object)"RoR2/Base/Wisp/cscLesserWisp.asset").WaitForCompletion(),
				selectionWeight = 100,
				spawnDistance = (MonsterSpawnDistance)0
			});
			dccsBulwarksHaunt_GhostWaveMonsters.AddCard(0, new DirectorCard
			{
				spawnCard = (SpawnCard)(object)Addressables.LoadAssetAsync<CharacterSpawnCard>((object)"RoR2/Base/GreaterWisp/cscGreaterWisp.asset").WaitForCompletion(),
				selectionWeight = 40,
				spawnDistance = (MonsterSpawnDistance)0
			});
			dpBulwarksHaunt_GhostWaveMonsters = ScriptableObject.CreateInstance<DccsPool>();
			DccsPool obj = dpBulwarksHaunt_GhostWaveMonsters;
			Category[] array = new Category[1];
			Category val6 = new Category();
			val6.name = "Base";
			val6.alwaysIncluded = (PoolEntry[])(object)new PoolEntry[1]
			{
				new PoolEntry
				{
					dccs = dccsBulwarksHaunt_GhostWaveMonsters,
					weight = 1f
				}
			};
			val6.categoryWeight = 1f;
			val6.includedIfConditionsMet = (ConditionalPoolEntry[])(object)new ConditionalPoolEntry[0];
			val6.includedIfNoConditionsMet = (PoolEntry[])(object)new PoolEntry[0];
			array[0] = val6;
			obj.poolCategories = (Category[])(object)array;
			dccsBulwarksHaunt_GhostWaveInteractables = ScriptableObject.CreateInstance<DirectorCardCategorySelection>();
			dpBulwarksHaunt_GhostWaveInteractables = ScriptableObject.CreateInstance<DccsPool>();
			DccsPool obj2 = dpBulwarksHaunt_GhostWaveInteractables;
			Category[] array2 = new Category[1];
			val6 = new Category();
			val6.name = "Base";
			val6.alwaysIncluded = (PoolEntry[])(object)new PoolEntry[0];
			val6.categoryWeight = 1f;
			val6.includedIfConditionsMet = (ConditionalPoolEntry[])(object)new ConditionalPoolEntry[0];
			val6.includedIfNoConditionsMet = (PoolEntry[])(object)new PoolEntry[0];
			array2[0] = val6;
			obj2.poolCategories = (Category[])(object)array2;
			UnlockableDef val7 = ScriptableObject.CreateInstance<UnlockableDef>();
			val7.cachedName = "Logs.Stages.BulwarksHaunt_GhostWave";
			val7.nameToken = "UNLOCKABLE_LOG_STAGES_BULWARKSHAUNT_GHOSTWAVE";
			BulwarksHauntContent.Resources.unlockableDefs.Add(val7);
			static NodeGraph LoadBakedNodesFromFile(GraphType graphType)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				//IL_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Expected O, but got Unknown
				string text = "Ground";
				if ((int)graphType == 1)
				{
					text = "Air";
				}
				string directoryName = Path.GetDirectoryName(BulwarksHauntPlugin.pluginInfo.Location);
				FileStream fileStream = File.OpenRead(Path.Combine(directoryName, "BakedNodeGraph_" + sceneDef.baseSceneName + "_" + text));
				MemoryStream memoryStream = new MemoryStream();
				using (GZipStream gZipStream = new GZipStream(fileStream, CompressionMode.Decompress))
				{
					gZipStream.CopyTo(memoryStream);
				}
				BakedNodes bakedNodes = JsonConvert.DeserializeObject<BakedNodes>(new UTF8Encoding().GetString(memoryStream.GetBuffer()), new JsonSerializerSettings
				{
					Culture = CultureInfo.InvariantCulture
				});
				fileStream.Close();
				memoryStream.Close();
				NodeGraph val8 = ScriptableObject.CreateInstance<NodeGraph>();
				val8.Clear();
				val8.nodes = bakedNodes.nodes.Select(delegate(NodeSerialized x)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Expected O, but got Unknown
					//IL_001b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0024: Unknown result type (might be due to invalid IL or missing references)
					//IL_0029: 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)
					//IL_0036: Unknown result type (might be due to invalid IL or missing references)
					//IL_0053: Unknown result type (might be due to invalid IL or missing references)
					//IL_0058: 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_007b: Unknown result type (might be due to invalid IL or missing references)
					//IL_007c: Unknown result type (might be due to invalid IL or missing references)
					//IL_007f: Unknown result type (might be due to invalid IL or missing references)
					SerializableBitArray val9 = new SerializableBitArray(x.lineOfSightMaskLength);
					val9.bytes = x.lineOfSightMaskBytes;
					Node result = default(Node);
					result.flags = x.flags;
					result.forbiddenHulls = x.forbiddenHulls;
					result.gateIndex = x.gateIndex;
					result.lineOfSightMask = val9;
					result.linkListIndex = x.linkListIndex;
					result.position = new Vector3(x.x, x.y, x.z);
					return result;
				}).ToArray();
				val8.links = bakedNodes.links.ToArray();
				val8.gateNames = bakedNodes.gateNames.ToList();
				val8.OnNodeCountChanged();
				val8.RebuildBlockMap();
				return val8;
			}
		}

		private void SetUpStageMusic(orig_Init orig)
		{
			orig.Invoke();
			sceneDef.mainTrack = MusicTrackCatalog.FindMusicTrackDef("muSong13");
			sceneDef.bossTrack = MusicTrackCatalog.FindMusicTrackDef("muSong13");
		}

		private void SceneManager_sceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Expected O, but got Unknown
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			GameObject worldObj;
			if (((Scene)(ref scene)).name == "BulwarksHaunt_GhostWave")
			{
				List<GameObject> list = new List<GameObject>();
				((Scene)(ref scene)).GetRootGameObjects(list);
				sceneInfoObj = list.First((GameObject x) => ((Object)x).name == "SceneInfo");
				sceneInfoObj.SetActive(false);
				SceneInfo val = sceneInfoObj.AddComponent<SceneInfo>();
				val.groundNodeGroup = groundNodeGroup;
				val.groundNodesAsset = groundNodeGraph;
				val.airNodeGroup = airNodeGroup;
				val.airNodesAsset = airNodeGraph;
				ClassicStageInfo val2 = sceneInfoObj.AddComponent<ClassicStageInfo>();
				val2.monsterDccsPool = dpBulwarksHaunt_GhostWaveMonsters;
				val2.interactableDccsPool = null;
				val2.interactableCategories = dccsBulwarksHaunt_GhostWaveInteractables;
				val2.sceneDirectorInteractibleCredits = 0;
				val2.sceneDirectorMonsterCredits = 30;
				val2.bonusInteractibleCreditObjects = (BonusInteractibleCreditObject[])(object)new BonusInteractibleCreditObject[0];
				val2.possibleMonsterFamilies = (MonsterFamily[])(object)new MonsterFamily[0];
				sceneInfoObj.SetActive(true);
				directorObj = list.First((GameObject x) => ((Object)x).name == "Director");
				directorObj.AddComponent<DirectorCore>();
				SceneDirector val3 = directorObj.AddComponent<SceneDirector>();
				val3.expRewardCoefficient = 0.4f;
				val3.eliteBias = 9999f;
				val3.spawnDistanceMultiplier = 1.4f;
				CombatDirector val4 = directorObj.AddComponent<CombatDirector>();
				val4.customName = "Normal";
				val4.monsterCredit = 0f;
				val4.eliteBias = 9999f;
				val4.expRewardCoefficient = 0.2f;
				val4.goldRewardCoefficient = 1f;
				val4.minSeriesSpawnInterval = 0.1f;
				val4.maxSeriesSpawnInterval = 1f;
				val4.minRerollSpawnInterval = 2f;
				val4.maxRerollSpawnInterval = 4f;
				val4.moneyWaveIntervals = (RangeFloat[])(object)new RangeFloat[1]
				{
					new RangeFloat
					{
						min = 20f,
						max = 30f
					}
				};
				val4.creditMultiplier = 0.75f;
				val4.skipSpawnIfTooCheap = false;
				val4.teamIndex = (TeamIndex)2;
				val4.onSpawnedServer = new OnSpawnedServer();
				val4 = directorObj.AddComponent<CombatDirector>();
				val4.customName = "Strong";
				val4.monsterCredit = 0f;
				val4.eliteBias = 1f;
				val4.expRewardCoefficient = 0.2f;
				val4.goldRewardCoefficient = 1f;
				val4.minSeriesSpawnInterval = 0.1f;
				val4.maxSeriesSpawnInterval = 1f;
				val4.minRerollSpawnInterval = 2f;
				val4.maxRerollSpawnInterval = 4f;
				val4.maximumNumberToSpawnBeforeSkipping = 1;
				val4.moneyWaveIntervals = (RangeFloat[])(object)new RangeFloat[1]
				{
					new RangeFloat
					{
						min = 20f,
						max = 40f
					}
				};
				val4.creditMultiplier = 1.6f;
				val4.teamIndex = (TeamIndex)2;
				val4.onSpawnedServer = new OnSpawnedServer();
				RoR2Application.onLateUpdate += enableDirector;
				gameManagerObj = list.First((GameObject x) => ((Object)x).name == "GameManager");
				gameManagerObj.AddComponent<GlobalEventManager>();
				if (NetworkServer.active)
				{
					ghostWaveControllerObj = Object.Instantiate<GameObject>(ghostWaveControllerObjPrefab);
					NetworkServer.Spawn(ghostWaveControllerObj);
				}
				worldObj = list.First((GameObject x) => ((Object)x).name == "World");
				SurfaceDef surfaceDef2 = Addressables.LoadAssetAsync<SurfaceDef>((object)"RoR2/Base/Common/sdMystery.asset").WaitForCompletion();
				SurfaceDef surfaceDef3 = Addressables.LoadAssetAsync<SurfaceDef>((object)"RoR2/Base/Common/sdWood.asset").WaitForCompletion();
				SurfaceDef surfaceDef4 = Addressables.LoadAssetAsync<SurfaceDef>((object)"RoR2/Base/Common/sdMetal.asset").WaitForCompletion();
				SurfaceDef surfaceDef5 = Addressables.LoadAssetAsync<SurfaceDef>((object)"RoR2/Base/Common/sdStone.asset").WaitForCompletion();
				((Component)worldObj.transform.Find("Main Island")).gameObject.AddComponent<SurfaceDefProvider>().surfaceDef = surfaceDef2;
				AssignSurfaceDefToChildColliders(surfaceDef3, new List<string> { "island_tree_02_1k", "island_tree_01_1k" });
				AssignSurfaceDefToChildColliders(surfaceDef4, new List<string> { "ironFenceBorder", "ironFenceCurve", "ironFenceBorderGate", "ironFence", "ironFence (1)" });
				AssignSurfaceDefToChildColliders(surfaceDef5, new List<string> { "cross", "gravestoneBroken", "gravestoneCrossLarge", "columnLarge" });
				GameObject val5 = list.First((GameObject x) => ((Object)x).name == "MapZones");
				Transform obj = val5.transform.Find("OutOfBounds/TriggerEnter/Top");
				obj.position += Vector3.down * 50f;
				Transform val6 = val5.transform.Find("OutOfBounds/TriggerEnter");
				for (int i = 0; i < val6.childCount; i++)
				{
					Transform child = val6.GetChild(i);
					MapZone val7 = ((Component)child).gameObject.AddComponent<MapZone>();
					val7.triggerType = (TriggerType)1;
					val7.zoneType = (ZoneType)0;
				}
				val6 = val5.transform.Find("OutOfBounds/TriggerExit");
				for (int j = 0; j < val6.childCount; j++)
				{
					Transform child2 = val6.GetChild(j);
					MapZone val8 = ((Component)child2).gameObject.AddComponent<MapZone>();
					val8.triggerType = (TriggerType)0;
					val8.zoneType = (ZoneType)0;
				}
			}
			void AssignSurfaceDefToChildColliders(SurfaceDef surfaceDef, List<string> parentNames)
			{
				foreach (string parentName in parentNames)
				{
					Transform val9 = worldObj.transform.Find(parentName);
					if (Object.op_Implicit((Object)(object)val9))
					{
						Collider[] componentsInChildren = ((Component)val9).GetComponentsInChildren<Collider>();
						foreach (Collider val10 in componentsInChildren)
						{
							SurfaceDefProvider component = ((Component)val10).GetComponent<SurfaceDefProvider>();
							if (!((Object)(object)component != (Object)null))
							{
								component = ((Component)val10).gameObject.AddComponent<SurfaceDefProvider>();
								component.surfaceDef = surfaceDef;
							}
						}
					}
				}
			}
			static void enableDirector()
			{
				directorObj.SetActive(true);
				RoR2Application.onLateUpdate -= enableDirector;
			}
		}

		private void BazaarController_SetUpSeerStations(orig_SetUpSeerStations orig, BazaarController self)
		{
			orig.Invoke(self);
			bool flag = Run.instance.stageClearCount >= 8 && !Run.instance.GetEventFlag("NoMysterySpace");
			SeerStationController[] seerStations = self.seerStations;
			foreach (SeerStationController val in seerStations)
			{
				if (((Component)val).GetComponent<PurchaseInteraction>().available && flag && self.rng.nextNormalizedFloat < 0.01f)
				{
					val.SetTargetScene(sceneDef);
				}
			}
		}

		public void SetUpGameEnding()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			GameEndingDef val = ScriptableObject.CreateInstance<GameEndingDef>();
			val.cachedName = "BulwarksHaunt_HauntedEnding";
			val.backgroundColor = Color32.op_Implicit(new Color32((byte)76, (byte)43, (byte)30, byte.MaxValue));
			val.foregroundColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)144, (byte)48, byte.MaxValue));
			val.endingTextToken = "GAME_RESULT_UNKNOWN";
			val.icon = BulwarksHauntPlugin.AssetBundle.LoadAsset<Sprite>("Assets/Mods/Bulwark's Haunt/texGameResultHauntedIcon.png");
			val.material = Addressables.LoadAssetAsync<GameEndingDef>((object)"RoR2/Base/ClassicRun/LimboEnding.asset").WaitForCompletion().material;
			val.isWin = true;
			val.showCredits = false;
			val.gameOverControllerState = new SerializableEntityStateType(typeof(LingerShort));
			val.lunarCoinReward = 0u;
			BulwarksHauntContent.GameEndings.BulwarksHaunt_HauntedEnding = val;
			BulwarksHauntContent.Resources.gameEndingDefs.Add(val);
		}

		public void SetUpGamemode()
		{
			//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			BulwarksHauntGhostWaveController bulwarksHauntGhostWaveController = ghostWaveControllerObjPrefab.AddComponent<BulwarksHauntGhostWaveController>();
			EntityStateMachine val = ghostWaveControllerObjPrefab.AddComponent<EntityStateMachine>();
			val.mainStateType = (val.initialStateType = new SerializableEntityStateType(typeof(GhostWaveControllerBaseState.Intro)));
			NetworkStateMachine val2 = ghostWaveControllerObjPrefab.AddComponent<NetworkStateMachine>();
			val2.stateMachines = (EntityStateMachine[])(object)new EntityStateMachine[1] { val };
			GameObject val3 = new GameObject("PostProcessing (FadeOut)");
			val3.SetActive(false);
			val3.layer = LayerIndex.postProcess.intVal;
			val3.transform.SetParent(ghostWaveControllerObjPrefab.transform);
			PostProcessVolume val4 = val3.AddComponent<PostProcessVolume>();
			val4.isGlobal = true;
			val4.priority = 70f;
			val4.weight = 0f;
			val4.sharedProfile = BulwarksHauntPlugin.AssetBundle.LoadAsset<PostProcessProfile>("Assets/Mods/Bulwark's Haunt/GhostWave/ppGhostWaveFadeOut.asset");
			Run.onRunStartGlobal += Run_onRunStartGlobal;
			GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(GlobalEventManager_OnCharacterDeath);
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState));
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState.Intro));
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState.MonsterWaves));
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState.BreakBetweenWaves));
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState.Ending));
			BulwarksHauntContent.Resources.entityStateTypes.Add(typeof(GhostWaveControllerBaseState.FadeOut));
			bannedEnemiesNames = ConfigurableValue.CreateString("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", BulwarksHauntPlugin.config, "Settings", "Banned Enemies", "BrotherHurtBody,GeepBody,GipBody", "Comma-separated list of enemies to prevent from being tracked towards A Moment, Haunted.", (List<string>)null, (ConfigEntry<bool>)null, false, (Action<string>)RebuildBannedEnemiesList);
			coopRespawnEachWave = ConfigurableValue.CreateBool("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", BulwarksHauntPlugin.config, "Settings", "Respawn Players Each Wave", true, "If true, dead players will be respawned after each wave completion.", (List<string>)null, (ConfigEntry<bool>)null, false, (Action<bool>)null);
			moreFrequentModifiers = ConfigurableValue.CreateBool("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", BulwarksHauntPlugin.config, "Challenge", "Frequent Modifiers", false, "If true, Wave Modifiers will be activated every 2 waves instead of every 4.", (List<string>)null, (ConfigEntry<bool>)null, false, (Action<bool>)null);
			superFrequentModifiers = ConfigurableValue.CreateBool("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", BulwarksHauntPlugin.config, "Challenge", "Super Frequent Modifiers", false, "If true, Wave Modifiers will be activated every wave.", (List<string>)null, (ConfigEntry<bool>)null, false, (Action<bool>)null);
			finalWaveAllModifiers = ConfigurableValue.CreateBool("com.themysticsword.bulwarkshaunt", "Bulwark's Haunt", BulwarksHauntPlugin.config, "Challenge", "All Modifier Final Wave", false, "If true, the Final Wave will feature all Wave Modifiers at once. You'll probably lose.", (List<string>)null, (ConfigEntry<bool>)null, false, (Action<bool>)null);
		}

		public static void PlaySoundForViewedCameras(string soundName)
		{
			foreach (CameraRigController item in CameraRigController.instancesList.Where((CameraRigController x) => x.localUserViewer != null))
			{
				Util.PlaySound(soundName, ((Component)item).gameObject);
			}
		}

		private void Run_onRunStartGlobal(Run obj)
		{
			killedEnemiesPerStage.Clear();
			waveRng.Clear();
		}

		public static void RebuildBannedEnemiesList(string newBannedEnemiesList)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (bannedEnemiesBodyIndices == null)
			{
				bannedEnemiesBodyIndices = new List<BodyIndex>();
			}
			bannedEnemiesBodyIndices.Clear();
			string[] array = newBannedEnemiesList.Split(',');
			foreach (string text in array)
			{
				BodyIndex val = BodyCatalog.FindBodyIndex(text);
				if ((int)val != -1)
				{
					bannedEnemiesBodyIndices.Add(val);
				}
			}
		}

		private void GlobalEventManager_OnCharacterDeath(orig_OnCharacterDeath orig, GlobalEventManager self, DamageReport damageReport)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Expected O, but got Unknown
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self, damageReport);
			if ((int)damageReport.victimTeamIndex != 2 || (int)damageReport.attackerTeamIndex != 1 || !Object.op_Implicit((Object)(object)damageReport.victimMaster) || bannedEnemiesBodyIndices.Contains(damageReport.victimBodyIndex))
			{
				return;
			}
			int num = Run.instance.stageClearCount + 1;
			if (num > maxWaves || !SceneInfo.instance.countsAsStage)
			{
				return;
			}
			KilledEnemyData killedEnemyData = default(KilledEnemyData);
			killedEnemyData.bodyIndex = damageReport.victimBodyIndex;
			killedEnemyData.inventory = new List<ItemCountPair>();
			killedEnemyData.equipment = null;
			KilledEnemyData item = killedEnemyData;
			if (Object.op_Implicit((Object)(object)damageReport.victimBody))
			{
				if (Object.op_Implicit((Object)(object)damageReport.victimBody.inventory))
				{
					foreach (ItemIndex item2 in damageReport.victimBody.inventory.itemAcquisitionOrder)
					{
						int count = damageReport.victimBody.inventory.itemStacks[item2];
						item.inventory.Add(new ItemCountPair
						{
							itemDef = ItemCatalog.GetItemDef(item2),
							count = count
						});
					}
				}
				if (Object.op_Implicit((Object)(object)damageReport.victimBody.equipmentSlot))
				{
					item.equipment = EquipmentCatalog.GetEquipmentDef(damageReport.victimBody.equipmentSlot.equipmentIndex);
				}
			}
			if (!killedEnemiesPerStage.ContainsKey(num))
			{
				killedEnemiesPerStage.Add(num, new List<KilledEnemyData>());
				Xoroshiro128Plus val = new Xoroshiro128Plus(Run.instance.runRNG);
				for (int i = 0; i < num; i++)
				{
					val = new Xoroshiro128Plus(val.nextUlong);
				}
				waveRng.Add(num, val);
			}
			killedEnemiesPerStage[num].Add(item);
			while (killedEnemiesPerStage[num].Count > waveEnemyHardCap)
			{
				killedEnemiesPerStage[num].RemoveAt(0);
			}
		}

		public static CharacterSpawnCard GenerateSpawnCardForKilledEnemy(KilledEnemyData killedEnemyData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(killedEnemyData.bodyIndex);
			CharacterBody component = bodyPrefab.GetComponent<CharacterBody>();
			string bodyName = BodyCatalog.GetBodyName(killedEnemyData.bodyIndex);
			CharacterSpawnCard val = ScriptableObject.CreateInstance<CharacterSpawnCard>();
			((SpawnCard)val).hullSize = component.hullClassification;
			((SpawnCard)val).prefab = MasterCatalog.GetMasterPrefab(MasterCatalog.FindAiMasterIndexForBody(killedEnemyData.bodyIndex));
			val.itemsToGrant = killedEnemyData.inventory.ToArray();
			val.equipmentToGrant = (EquipmentDef[])(object)new EquipmentDef[0];
			if ((Object)(object)killedEnemyData.equipment != (Object)null)
			{
				ArrayUtils.ArrayAppend<EquipmentDef>(ref val.equipmentToGrant, ref killedEnemyData.equipment);
			}
			((SpawnCard)val).nodeGraphType = (GraphType)1;
			CharacterMotor component2 = bodyPrefab.GetComponent<CharacterMotor>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				((SpawnCard)val).nodeGraphType = (GraphType)(component2.isFlying ? 1 : 0);
			}
			if (bodyName == "GrandParentBody")
			{
				((SpawnCard)val).nodeGraphType = (GraphType)0;
			}
			if ((Object)(object)((SpawnCard)val).prefab == (Object)null)
			{
				return null;
			}
			return val;
		}

		public void SetUpWaveModifiers()
		{
			//IL_0021: Unk