Decompiled source of ArenaGauntlet v0.34.0

BepInEx/plugins/ArenaGauntlet/ArenaGauntlet.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.EngiTurret.EngiTurretWeapon;
using EntityStates.InfiniteTowerSafeWard;
using EntityStates.Scrapper;
using HG;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using On.EntityStates.InfiniteTowerSafeWard;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.CharacterAI;
using R2API;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.CharacterAI;
using RoR2.ContentManagement;
using RoR2.ExpansionManagement;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.UI;
using RoR2BepInExPack.GameAssetPathsBetter;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArenaGauntlet")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.34.0.0")]
[assembly: AssemblyInformationalVersion("0.34.0")]
[assembly: AssemblyProduct("ArenaGauntlet")]
[assembly: AssemblyTitle("ArenaGauntlet")]
[assembly: AssemblyVersion("0.34.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BazaarGauntlet
{
	internal static class ArenaMaterials
	{
		internal static Material Create(FortressArchitectureData.Surface surface, List<Texture2D> ownedTextures)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			Shader obj = FortressAssets.Load<Shader>("HGStandard_shader");
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidOperationException("Native arena shader unavailable.");
			}
			Material val = new Material(obj)
			{
				name = "ArenaGauntlet " + surface.Name,
				color = new Color(surface.R, surface.G, surface.B),
				enableInstancing = true
			};
			try
			{
				bool flag = surface.Name == "grass";
				Texture2D val2 = (flag ? FortressAssets.Load<Texture2D>("texGPGrassTerrain_png") : Read(surface.Name, normal: false, ownedTextures));
				Texture2D val3 = (flag ? FortressAssets.Load<Texture2D>("texGPGrassTerrainNormal_png") : Read(surface.Name, normal: true, ownedTextures));
				if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3))
				{
					throw new InvalidDataException("Arena surface is incomplete: " + surface.Name);
				}
				val.SetTexture("_MainTex", (Texture)(object)val2);
				val.SetTexture("_NormalTex", (Texture)(object)val3);
				string[] array = new string[6] { "LIMBREMOVAL", "FLOWMAP", "SPLATMAP", "FRESNEL_EMISSION", "CUTOUT", "FORCE_SPEC" };
				foreach (string text in array)
				{
					val.DisableKeyword(text);
				}
				val.EnableKeyword("NORMALMAP");
				val.EnableKeyword("USE_VERTEX_COLORS");
				val.SetFloat("_ColorsOn", 1f);
				val.SetFloat("_NormalStrength", flag ? 0.2f : 0.45f);
				val.SetFloat("_Smoothness", surface.Smoothness);
				val.SetFloat("_SpecularStrength", flag ? 0.02f : 0.1f);
				val.SetFloat("_SpecularExponent", 24f);
				val.SetFloat("_EmPower", 0f);
				val.SetFloat("_LimbRemovalOn", 0f);
				return val;
			}
			catch
			{
				Object.Destroy((Object)(object)val);
				throw;
			}
		}

		private static Texture2D Read(string surface, bool normal, List<Texture2D> ownedTextures)
		{
			//IL_007a: 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)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			string text = "BazaarGauntlet.assets.arena_" + surface + (normal ? "_normal" : "") + ".png";
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
			if (stream == null)
			{
				throw new FileNotFoundException("Arena surface " + text);
			}
			byte[] array = new byte[stream.Length];
			int num;
			for (int i = 0; i < array.Length; i += num)
			{
				num = stream.Read(array, i, array.Length - i);
				if (num == 0)
				{
					throw new EndOfStreamException();
				}
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, normal)
			{
				name = text,
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)2,
				anisoLevel = 8
			};
			ownedTextures.Add(val);
			if (!ImageConversion.LoadImage(val, array, true))
			{
				throw new InvalidDataException("Arena texture " + text);
			}
			return val;
		}
	}
	internal sealed class FortressApproach : MonoBehaviour
	{
		internal static readonly Vector3[] Route = (Vector3[])(object)new Vector3[9]
		{
			new Vector3(82f, -20f, -70f),
			new Vector3(65f, -20f, -67f),
			new Vector3(-14f, 0f, -58f),
			new Vector3(-21.416f, 0f, -56.825f),
			new Vector3(-28.107f, 0f, -53.416f),
			new Vector3(-33.416f, 0f, -48.107f),
			new Vector3(-36.825f, 0f, -41.416f),
			new Vector3(-38f, 0f, -34f),
			new Vector3(-38f, 0f, -26.8f)
		};

		internal const float Width = 26f;

		private GameObject root;

		private NodeGraph graph;

		private Node[] originalNodes;

		private Link[] originalLinks;

		private bool attempted;

		internal static void Ensure(FortressController fortress)
		{
			FortressApproach fortressApproach = ((Component)fortress).GetComponent<FortressApproach>() ?? ((Component)fortress).gameObject.AddComponent<FortressApproach>();
			if (fortressApproach.attempted || !fortress.InCastle)
			{
				return;
			}
			fortressApproach.attempted = true;
			if (fortress.State.Map != "ancientloft")
			{
				return;
			}
			try
			{
				fortressApproach.Build(fortress);
			}
			catch (Exception ex)
			{
				fortressApproach.RestoreGraph();
				GauntletPlugin.Log.LogError((object)("Main causeway unavailable; castle spawning continues. " + ex));
			}
		}

		private void Build(FortressController fortress)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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: Expected O, but got Unknown
			root = new GameObject("Castle main causeway");
			root.transform.position = fortress.Center;
			root.transform.rotation = Quaternion.Euler(0f, fortress.State.Yaw, 0f);
			FortressMeshLifetime fortressMeshLifetime = root.AddComponent<FortressMeshLifetime>();
			foreach (var item2 in FortressCausewayMesh.Build(Route, 26f))
			{
				Mesh item = item2.Mesh;
				fortressMeshLifetime.Meshes.Add(item);
				GameObject val = new GameObject(((Object)item).name, new Type[2]
				{
					typeof(MeshFilter),
					typeof(MeshRenderer)
				});
				val.transform.SetParent(root.transform, false);
				val.GetComponent<MeshFilter>().sharedMesh = item;
				if (item2.Name == "stone")
				{
					val.layer = LayerIndex.world.intVal;
					val.AddComponent<MeshCollider>().sharedMesh = item;
				}
				try
				{
					((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = FortressArchitecture.Surface(item2.Name);
				}
				catch (Exception ex)
				{
					GauntletPlugin.Log.LogWarning((object)("Causeway material unavailable; collision and navigation remain active. " + ex));
				}
			}
			Physics.SyncTransforms();
			if (NetworkServer.active)
			{
				ExtendNavigation();
			}
		}

		private void ExtendNavigation()
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00bb: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: 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_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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_02c4: Expected I4, but got Unknown
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: 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_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: 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_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Expected O, but got Unknown
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_063a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			graph = SceneInfo.instance.GetNodeGraph((GraphType)0);
			originalNodes = NativeAccess.Get<Node[]>(graph, "nodes");
			originalLinks = NativeAccess.Get<Link[]>(graph, "links");
			List<Node> nodes = new List<Node>(originalNodes);
			List<Link> links = new List<Link>(originalLinks);
			List<int> list = new List<int>();
			int[] array = new int[0];
			for (int i = 0; i < Route.Length - 1; i++)
			{
				Vector3 val = Route[i];
				Vector3 val2 = Route[i + 1];
				Vector3 val3 = Vector3.Cross(Vector3.up, val2 - val);
				Vector3 normalized = ((Vector3)(ref val3)).normalized;
				int num = Mathf.CeilToInt(Vector3.Distance(val, val2) / 4f);
				for (int j = 0; j <= num; j++)
				{
					int[] array2 = new int[3];
					for (int k = 0; k < 3; k++)
					{
						array2[k] = nodes.Count;
						Vector3 val4 = Vector3.Lerp(val, val2, (float)j / (float)num) + normalized * (float)(k - 1) * 5f;
						nodes.Add(new Node
						{
							position = root.transform.TransformPoint(val4) + Vector3.up * 0.06f,
							flags = (NodeFlags)0
						});
						if ((i == 0 && j == 0) || (i == Route.Length - 2 && j == num))
						{
							list.Add(array2[k]);
						}
						if (k > 0)
						{
							Both(array2[k - 1], array2[k], 7);
						}
					}
					if (array.Length != 0)
					{
						for (int l = 0; l < 3; l++)
						{
							for (int m = 0; m < 3; m++)
							{
								if (Math.Abs(l - m) <= 1)
								{
									Both(array[l], array2[m], 7);
								}
							}
						}
					}
					array = array2;
				}
			}
			foreach (int item in list)
			{
				for (int n = 0; n < originalNodes.Length; n++)
				{
					Vector3 position = nodes[item].position;
					Vector3 position2 = nodes[n].position;
					Vector3 val5 = position2 - position;
					if (Mathf.Abs(val5.y) > 1.2f || ((Vector3)(ref val5)).sqrMagnitude > 324f || originalNodes[n].gateIndex != 0)
					{
						continue;
					}
					int num2 = 7 & ~originalNodes[n].forbiddenHulls;
					if (num2 != 0)
					{
						Vector3 val6 = position + Vector3.up;
						Vector3 val7 = position2 + Vector3.up;
						LayerIndex world = LayerIndex.world;
						if (!Physics.Linecast(val6, val7, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask)))
						{
							Both(item, n, num2);
						}
					}
				}
			}
			Link[] ordered = links.OrderBy((Link link) => link.nodeIndexA.nodeIndex).ToArray();
			int num3 = 0;
			for (int num4 = 0; num4 < nodes.Count; num4++)
			{
				Node val8 = nodes[num4];
				int num5 = num3;
				for (; num3 < ordered.Length && ordered[num3].nodeIndexA.nodeIndex == num4; num3++)
				{
				}
				val8.linkListIndex = new LinkListIndex
				{
					index = num5,
					size = (uint)(num3 - num5)
				};
				SerializableBitArray val9 = new SerializableBitArray(nodes.Count);
				if (num4 < originalNodes.Length && val8.lineOfSightMask != null)
				{
					for (int num6 = 0; num6 < Math.Min(val8.lineOfSightMask.length, originalNodes.Length); num6++)
					{
						val9[num6] = val8.lineOfSightMask[num6];
					}
				}
				val9[num4] = true;
				val8.lineOfSightMask = val9;
				nodes[num4] = val8;
			}
			Link[] array3 = ordered;
			foreach (Link val10 in array3)
			{
				if (val10.nodeIndexA.nodeIndex >= originalNodes.Length || val10.nodeIndexB.nodeIndex >= originalNodes.Length)
				{
					nodes[val10.nodeIndexA.nodeIndex].lineOfSightMask[val10.nodeIndexB.nodeIndex] = true;
				}
			}
			NativeAccess.Set(graph, "nodes", nodes.ToArray());
			NativeAccess.Set(graph, "links", ordered);
			NativeAccess.Call(graph, "Awake");
			for (int hull = 0; hull < 3; hull++)
			{
				int mask = 1 << hull;
				IEnumerable<(int, int)> edges = from index in Enumerable.Range(0, ordered.Length)
					where (ordered[index].hullMask & mask) != 0 && (ordered[index].jumpHullMask & mask) == 0 && graph.IsLinkSuitableForHull(new LinkIndex
					{
						linkIndex = index
					}, (HullClassification)hull)
					select (ordered[index].nodeIndexA.nodeIndex, ordered[index].nodeIndexB.nodeIndex);
				NodeIndex val11 = graph.FindClosestNode(root.transform.position, (HullClassification)hull, float.PositiveInfinity);
				if (!GauntletRoutePlan.Reaches(nodes.Count, val11.nodeIndex, edges)[originalNodes.Length])
				{
					throw new InvalidOperationException("Causeway does not connect the lower landing to the keep for " + ((object)(HullClassification)hull/*cast due to .constrained prefix*/).ToString());
				}
			}
			GauntletPlugin.Log.LogInfo((object)$"Main causeway: {26f:0}m wide, {nodes.Count - originalNodes.Length} navigation nodes; original ground graph preserved for cleanup.");
			void Both(int a, int b, int mask2)
			{
				Link(a, b, mask2);
				Link(b, a, mask2);
			}
			void Link(int from, int to, int hullMask)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_004a: 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_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val12 = nodes[to].position - nodes[from].position;
				Vector2 val13 = new Vector2(val12.x, val12.z);
				float magnitude = ((Vector2)(ref val13)).magnitude;
				links.Add(new Link
				{
					nodeIndexA = new NodeIndex(from),
					nodeIndexB = new NodeIndex(to),
					distanceScore = ((Vector3)(ref val12)).magnitude,
					maxSlope = Mathf.Atan2(Mathf.Abs(val12.y), Mathf.Max(0.01f, magnitude)) * 57.29578f,
					hullMask = hullMask
				});
			}
		}

		private void RestoreGraph()
		{
			if (Object.op_Implicit((Object)(object)graph) && originalNodes != null)
			{
				NativeAccess.Set(graph, "nodes", originalNodes);
				NativeAccess.Set(graph, "links", originalLinks);
				NativeAccess.Call(graph, "Awake");
			}
			graph = null;
			originalNodes = null;
			originalLinks = null;
		}

		private void OnDestroy()
		{
			RestoreGraph();
			if (Object.op_Implicit((Object)(object)root))
			{
				Object.Destroy((Object)(object)root);
			}
		}
	}
	internal static class FortressArchitecture
	{
		private static FortressArchitectureData library;

		private static Material[] surfaces;

		private static Mesh[] meshes;

		private static bool prepared;

		internal static Material Surface(string name)
		{
			Prepare();
			for (int i = 0; i < library.Surfaces.Length; i++)
			{
				if (library.Surfaces[i].Name == name)
				{
					return surfaces[i];
				}
			}
			throw new ArgumentException("Unknown castle surface: " + name);
		}

		private static void Prepare()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			if (prepared)
			{
				return;
			}
			Shader val = FortressAssets.Load<Shader>("HGStandard_shader");
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Native castle shader unavailable.");
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using (Stream stream = executingAssembly.GetManifestResourceStream("BazaarGauntlet.assets.castle.meshbin"))
			{
				library = FortressArchitectureData.Read(stream ?? throw new FileNotFoundException("Castle architecture asset."));
			}
			surfaces = (Material[])(object)new Material[library.Surfaces.Length];
			meshes = (Mesh[])(object)new Mesh[library.Parts.Length];
			Color val2 = default(Color);
			for (int i = 0; i < surfaces.Length; i++)
			{
				FortressArchitectureData.Surface surface = library.Surfaces[i];
				((Color)(ref val2))..ctor(surface.R, surface.G, surface.B);
				Material val3 = new Material(val)
				{
					name = "Castle " + surface.Name,
					color = val2,
					enableInstancing = true
				};
				using (Stream stream2 = executingAssembly.GetManifestResourceStream("BazaarGauntlet.assets.castle_" + surface.Name + ".png"))
				{
					if (stream2 == null)
					{
						throw new FileNotFoundException("Castle surface " + surface.Name);
					}
					byte[] array = new byte[stream2.Length];
					int num;
					for (int j = 0; j < array.Length; j += num)
					{
						num = stream2.Read(array, j, array.Length - j);
						if (num == 0)
						{
							throw new EndOfStreamException();
						}
					}
					Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, true)
					{
						name = "Castle " + surface.Name,
						wrapMode = (TextureWrapMode)0,
						filterMode = (FilterMode)2,
						anisoLevel = 4
					};
					if (!ImageConversion.LoadImage(val4, array, true))
					{
						throw new InvalidDataException("Castle texture " + surface.Name);
					}
					if (val3.HasProperty("_MainTex"))
					{
						val3.SetTexture("_MainTex", (Texture)(object)val4);
					}
				}
				string[] array2 = new string[8] { "LIMBREMOVAL", "NORMALMAP", "_NORMALMAP", "FLOWMAP", "SPLATMAP", "FRESNEL_EMISSION", "CUTOUT", "FORCE_SPEC" };
				foreach (string text in array2)
				{
					val3.DisableKeyword(text);
				}
				if (val3.HasProperty("_NormalStrength"))
				{
					val3.SetFloat("_NormalStrength", 0f);
				}
				if (val3.HasProperty("_LimbRemovalOn"))
				{
					val3.SetFloat("_LimbRemovalOn", 0f);
				}
				if (val3.HasProperty("_Smoothness"))
				{
					val3.SetFloat("_Smoothness", surface.Smoothness);
				}
				if (val3.HasProperty("_Glossiness"))
				{
					val3.SetFloat("_Glossiness", surface.Smoothness);
				}
				if (val3.HasProperty("_SpecularStrength"))
				{
					val3.SetFloat("_SpecularStrength", (surface.Name == "brass") ? 0.35f : 0.12f);
				}
				if (val3.HasProperty("_SpecularExponent"))
				{
					val3.SetFloat("_SpecularExponent", 28f);
				}
				if (val3.HasProperty("_EmTex"))
				{
					val3.SetTexture("_EmTex", (Texture)(object)Texture2D.whiteTexture);
				}
				if (val3.HasProperty("_EmColor"))
				{
					val3.SetColor("_EmColor", val2);
				}
				if (val3.HasProperty("_EmPower"))
				{
					val3.SetFloat("_EmPower", surface.Emission);
				}
				surfaces[i] = val3;
			}
			prepared = true;
		}

		private static Mesh Mesh(int index)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//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_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)meshes[index]))
			{
				return meshes[index];
			}
			FortressArchitectureData.Part part = library.Parts[index];
			int num = part.Vertices.Length / 8;
			Vector3[] array = (Vector3[])(object)new Vector3[num];
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector2[] array3 = (Vector2[])(object)new Vector2[num];
			for (int i = 0; i < num; i++)
			{
				int num2 = i * 8;
				array[i] = new Vector3(part.Vertices[num2], part.Vertices[num2 + 1], part.Vertices[num2 + 2]);
				array2[i] = new Vector3(part.Vertices[num2 + 3], part.Vertices[num2 + 4], part.Vertices[num2 + 5]);
				array3[i] = new Vector2(part.Vertices[num2 + 6], part.Vertices[num2 + 7]);
			}
			Mesh val = new Mesh
			{
				name = part.Name,
				indexFormat = (IndexFormat)1,
				vertices = array,
				normals = array2,
				uv = array3,
				triangles = part.Indices
			};
			val.RecalculateBounds();
			meshes[index] = val;
			return val;
		}

		internal static GameObject Build(FortressController fortress)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0017: 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_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_00ef: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Expected O, but got Unknown
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			Prepare();
			GameObject val = new GameObject("Gauntlet tiered citadel");
			val.transform.position = fortress.Center;
			val.transform.rotation = Quaternion.Euler(0f, fortress.State.Yaw, 0f);
			try
			{
				Dictionary<int, List<CombineInstance>> dictionary = new Dictionary<int, List<CombineInstance>>();
				for (int i = 0; i < library.Parts.Length; i++)
				{
					FortressArchitectureData.Part part = library.Parts[i];
					if (part.Visible(fortress.State))
					{
						int key = (((part.Attachment == 0) ? (-1) : ((part.Attachment == 2) ? (-2) : part.Module)) + 2) * surfaces.Length + part.Surface;
						if (!dictionary.TryGetValue(key, out var value))
						{
							value = (dictionary[key] = new List<CombineInstance>());
						}
						Vector3 val2 = FortressController.Offset(part.Module) + Vector3.up * fortress.State.Modules[part.Module].GroundOffset;
						Quaternion val3 = Quaternion.Euler(0f, (float)((part.Module >= 1 && part.Module <= 4) ? ((part.Module - 1) * 90) : 0), 0f);
						List<CombineInstance> list2 = value;
						CombineInstance item = default(CombineInstance);
						((CombineInstance)(ref item)).mesh = Mesh(i);
						((CombineInstance)(ref item)).transform = ((part.Attachment == 0) ? Matrix4x4.TRS(val2, val3, Vector3.one) : Matrix4x4.identity);
						list2.Add(item);
					}
				}
				Dictionary<int, Transform> dictionary2 = new Dictionary<int, Transform>();
				FortressMeshLifetime fortressMeshLifetime = val.AddComponent<FortressMeshLifetime>();
				foreach (KeyValuePair<int, List<CombineInstance>> item2 in dictionary)
				{
					int num = item2.Key / surfaces.Length - 2;
					int num2 = item2.Key % surfaces.Length;
					Transform value2 = val.transform;
					if (num != -1 && !dictionary2.TryGetValue(num, out value2))
					{
						value2 = new GameObject((num == -2) ? "Living reactor" : ("Aiming tower " + num)).transform;
						value2.SetParent(val.transform, false);
						int num3 = ((num != -2) ? num : 0);
						value2.localPosition = FortressController.Offset(num3) + Vector3.up * (fortress.State.Modules[num3].GroundOffset + ((num == -2) ? 4.5f : 3.65f));
						if (num == -2)
						{
							((Component)value2).gameObject.AddComponent<FortressReactorMotion>().Fortress = fortress;
						}
						else
						{
							((Component)value2).gameObject.AddComponent<FortressAimingHead>().Module = num;
						}
						dictionary2[num] = value2;
					}
					Mesh val4 = new Mesh
					{
						name = "Castle batched " + num + " " + library.Surfaces[num2].Name,
						indexFormat = (IndexFormat)1
					};
					val4.CombineMeshes(item2.Value.ToArray(), true, true);
					val4.RecalculateBounds();
					fortressMeshLifetime.Meshes.Add(val4);
					GameObject val5 = new GameObject(((Object)val4).name, new Type[2]
					{
						typeof(MeshFilter),
						typeof(MeshRenderer)
					});
					val5.transform.SetParent(value2, false);
					val5.layer = LayerIndex.defaultLayer.intVal;
					val5.GetComponent<MeshFilter>().sharedMesh = val4;
					((Renderer)val5.GetComponent<MeshRenderer>()).sharedMaterial = surfaces[num2];
					if (num == -1 && library.Surfaces[num2].Name != "energy")
					{
						AddHullCollision(val5, val4);
					}
				}
				return val;
			}
			catch
			{
				Object.Destroy((Object)(object)val);
				throw;
			}
		}

		private static void AddHullCollision(GameObject rendered, Mesh mesh)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Castle hull collision", new Type[1] { typeof(MeshCollider) });
			val.transform.SetParent(rendered.transform, false);
			val.layer = LayerIndex.collideWithCharacterHullOnly.intVal;
			val.GetComponent<MeshCollider>().sharedMesh = mesh;
		}
	}
	internal sealed class FortressReactorMotion : MonoBehaviour
	{
		internal FortressController Fortress;

		private Vector3 rest;

		private Renderer glow;

		private MaterialPropertyBlock block;

		private void Start()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			rest = ((Component)this).transform.localPosition;
			block = new MaterialPropertyBlock();
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
			foreach (Renderer val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val.sharedMaterial) && ((Object)val.sharedMaterial).name == "Castle energy")
				{
					glow = val;
					break;
				}
			}
		}

		private void Update()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			((Component)this).transform.localPosition = rest + Vector3.up * (Mathf.Sin(time * 1.4f) * 0.09f);
			((Component)this).transform.localRotation = Quaternion.Euler(0f, time * 10f, 0f);
			if (Object.op_Implicit((Object)(object)glow) && Object.op_Implicit((Object)(object)Fortress))
			{
				FortressModuleState fortressModuleState = Fortress.State.Modules[0];
				float num = ((fortressModuleState.Maximum > 0f) ? (fortressModuleState.Health / fortressModuleState.Maximum) : 1f);
				float num2 = Mathf.Clamp01((0.4f - num) / 0.4f);
				block.SetColor("_EmColor", Color.Lerp(new Color(0.18f, 0.76f, 1f), new Color(1f, 0.35f, 0.12f), num2));
				block.SetFloat("_EmPower", 1.55f + (0.16f + num2 * 0.35f) * Mathf.Sin(time * (1.8f + num2 * 4f)));
				glow.SetPropertyBlock(block);
			}
		}
	}
	internal sealed class FortressArchitectureData
	{
		internal sealed class Surface
		{
			internal string Name;

			internal float R;

			internal float G;

			internal float B;

			internal float Smoothness;

			internal float Emission;
		}

		internal sealed class Condition
		{
			internal int Upgrade;

			internal int Minimum;

			internal int Maximum;
		}

		internal sealed class Part
		{
			internal string Name;

			internal int Module;

			internal int Attachment;

			internal int Surface;

			internal bool Ruin;

			internal Condition[] Conditions;

			internal float[] Vertices;

			internal int[] Indices;

			internal bool Visible(FortressState state)
			{
				if (!state.Built(Module) || state.Modules[Module].Destroyed != Ruin)
				{
					return false;
				}
				Condition[] conditions = Conditions;
				foreach (Condition condition in conditions)
				{
					int num = state.Rank((FortressUpgrade)condition.Upgrade);
					if (num < condition.Minimum || num > condition.Maximum)
					{
						return false;
					}
				}
				return true;
			}
		}

		internal Surface[] Surfaces;

		internal Part[] Parts;

		private static ulong Mix(ulong hash, int value)
		{
			return (hash ^ (uint)value) * 1099511628211L;
		}

		internal static ulong AppearanceKey(FortressState state)
		{
			ulong hash = 14695981039346656037uL;
			int[] ranks = state.Ranks;
			foreach (int value in ranks)
			{
				hash = Mix(hash, value);
			}
			for (int j = 0; j < state.Modules.Length; j++)
			{
				hash = Mix(hash, state.Built(j) ? 1 : 0);
				hash = Mix(hash, state.Modules[j].Destroyed ? 1 : 0);
				hash = Mix(hash, state.Modules[j].GroundOffset.GetHashCode());
			}
			hash = Mix(hash, state.X.GetHashCode());
			hash = Mix(hash, state.Y.GetHashCode());
			hash = Mix(hash, state.Z.GetHashCode());
			return Mix(hash, state.Yaw.GetHashCode());
		}

		internal static FortressArchitectureData Read(Stream stream)
		{
			using BinaryReader binaryReader = new BinaryReader(stream, Encoding.UTF8, leaveOpen: true);
			if (new string(binaryReader.ReadChars(5)) != "CAST1")
			{
				throw new InvalidDataException("Castle mesh format.");
			}
			int num = binaryReader.ReadInt32();
			if (num < 1 || num > 24)
			{
				throw new InvalidDataException("Castle material count.");
			}
			FortressArchitectureData fortressArchitectureData = new FortressArchitectureData
			{
				Surfaces = new Surface[num]
			};
			for (int i = 0; i < num; i++)
			{
				fortressArchitectureData.Surfaces[i] = new Surface
				{
					Name = binaryReader.ReadString(),
					R = binaryReader.ReadSingle(),
					G = binaryReader.ReadSingle(),
					B = binaryReader.ReadSingle(),
					Smoothness = binaryReader.ReadSingle(),
					Emission = binaryReader.ReadSingle()
				};
			}
			int num2 = binaryReader.ReadInt32();
			if (num2 < 1 || num2 > 2048)
			{
				throw new InvalidDataException("Castle part count.");
			}
			fortressArchitectureData.Parts = new Part[num2];
			for (int j = 0; j < num2; j++)
			{
				Part part = new Part
				{
					Name = binaryReader.ReadString(),
					Module = binaryReader.ReadInt32(),
					Attachment = binaryReader.ReadInt32(),
					Surface = binaryReader.ReadInt32(),
					Ruin = binaryReader.ReadBoolean()
				};
				if (part.Module < 0 || part.Module >= 16 || part.Attachment < 0 || part.Attachment > 2 || part.Surface < 0 || part.Surface >= num)
				{
					throw new InvalidDataException("Castle part assignment.");
				}
				int num3 = binaryReader.ReadInt32();
				if (num3 < 0 || num3 > 8)
				{
					throw new InvalidDataException("Castle part conditions.");
				}
				part.Conditions = new Condition[num3];
				for (int k = 0; k < num3; k++)
				{
					Condition condition = new Condition
					{
						Upgrade = binaryReader.ReadInt32(),
						Minimum = binaryReader.ReadInt32(),
						Maximum = binaryReader.ReadInt32()
					};
					if (condition.Upgrade < 0 || condition.Upgrade >= 26 || condition.Minimum < 0 || condition.Maximum < condition.Minimum)
					{
						throw new InvalidDataException("Castle rank condition.");
					}
					part.Conditions[k] = condition;
				}
				int num4 = binaryReader.ReadInt32();
				int num5 = binaryReader.ReadInt32();
				if (num4 < 3 || num4 > 250000 || num5 < 3 || num5 > 1500000 || num5 % 3 != 0)
				{
					throw new InvalidDataException("Castle geometry limits.");
				}
				part.Vertices = new float[num4 * 8];
				part.Indices = new int[num5];
				for (int l = 0; l < part.Vertices.Length; l++)
				{
					float num6 = binaryReader.ReadSingle();
					if (float.IsNaN(num6) || float.IsInfinity(num6))
					{
						throw new InvalidDataException("Non-finite castle geometry.");
					}
					part.Vertices[l] = num6;
				}
				for (int m = 0; m < num5; m++)
				{
					int num7 = binaryReader.ReadInt32();
					if (num7 < 0 || num7 >= num4)
					{
						throw new InvalidDataException("Castle mesh index.");
					}
					part.Indices[m] = num7;
				}
				fortressArchitectureData.Parts[j] = part;
			}
			if (stream.Position != stream.Length)
			{
				throw new InvalidDataException("Trailing castle mesh data.");
			}
			return fortressArchitectureData;
		}
	}
	internal static class FortressAssets
	{
		private static readonly Dictionary<string, string> keys = new Dictionary<string, string>();

		private static readonly Dictionary<string, Object> loaded = new Dictionary<string, Object>();

		private static readonly GameObject[] masters = (GameObject[])(object)new GameObject[3];

		internal static GameObject ForModule(int index)
		{
			return masters[(index != 0) ? ((index <= 4) ? 1 : 2) : 0];
		}

		internal static T Load<T>(string field) where T : Object
		{
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			if (loaded.TryGetValue(field, out var value))
			{
				return (T)(object)((value is T) ? value : null);
			}
			if (keys.Count == 0)
			{
				foreach (Type item in from type in typeof(RoR2_Base_Engi).Assembly.GetTypes()
					where type.Namespace == "RoR2BepInExPack.GameAssetPathsBetter" && !type.Name.Contains("_Junk_")
					select type)
				{
					FieldInfo[] fields = item.GetFields(BindingFlags.Static | BindingFlags.Public);
					foreach (FieldInfo fieldInfo in fields)
					{
						if (fieldInfo.FieldType == typeof(string) && !keys.ContainsKey(fieldInfo.Name))
						{
							keys[fieldInfo.Name] = fieldInfo.GetValue(null) as string;
						}
					}
				}
			}
			if (!keys.TryGetValue(field, out var value2) || string.IsNullOrEmpty(value2))
			{
				return default(T);
			}
			IList<IResourceLocation> list = default(IList<IResourceLocation>);
			foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators)
			{
				if (resourceLocator.Locate((object)value2, typeof(T), ref list) && list.Count > 0)
				{
					T val = Addressables.LoadAssetAsync<T>(list[0]).WaitForCompletion();
					if (Object.op_Implicit((Object)(object)val))
					{
						loaded[field] = (Object)(object)val;
					}
					return val;
				}
			}
			return default(T);
		}

		internal static void Register()
		{
			GameObject val = FortressAssets.Load<GameObject>("EngiTurretBody_prefab");
			GameObject val2 = FortressAssets.Load<GameObject>("EngiTurretMaster_prefab");
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				throw new InvalidOperationException("Native fortress body templates are unavailable.");
			}
			for (int i = 0; i < masters.Length; i++)
			{
				RegisterKind(val, val2, i);
			}
		}

		private static void RegisterKind(GameObject bodySource, GameObject masterSource, int kind)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: 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_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = PrefabAPI.InstantiateClone(bodySource, "BazaarGauntletFortressBody" + kind);
			CharacterBody component = val.GetComponent<CharacterBody>();
			component.baseNameToken = "GAUNTLET_FORTRESS_STRUCTURE";
			LanguageAPI.Add(component.baseNameToken, "Fortress structure");
			component.baseMaxHealth = 4000f;
			component.levelMaxHealth = 0f;
			component.baseRegen = 0f;
			component.levelRegen = 0f;
			component.baseArmor = 10f;
			component.baseMoveSpeed = 0f;
			component.isNotFlying = true;
			component.bodyFlags = (BodyFlags)(component.bodyFlags & -536870913);
			component.bodyFlags = (BodyFlags)(component.bodyFlags | 0x94811);
			TeamComponent component2 = val.GetComponent<TeamComponent>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.hideAllyCardDisplay = true;
				component2.hideIndicator = true;
			}
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].forceRenderingOff = true;
			}
			HurtBoxGroup component3 = ((Component)val.GetComponent<ModelLocator>().modelTransform).GetComponent<HurtBoxGroup>();
			HurtBox[] componentsInChildren2 = val.GetComponentsInChildren<HurtBox>(true);
			foreach (HurtBox obj in componentsInChildren2)
			{
				((Behaviour)obj).enabled = false;
				Collider component4 = ((Component)obj).GetComponent<Collider>();
				if (Object.op_Implicit((Object)(object)component4))
				{
					component4.enabled = false;
				}
			}
			Vector3 val2 = (Vector3)(kind switch
			{
				1 => new Vector3(15f, 3.4f, 1.8f), 
				0 => new Vector3(5.6f, 6f, 5.6f), 
				_ => new Vector3(4.5f, 4f, 4.5f), 
			});
			GameObject val3 = new GameObject("Fortress target", new Type[1] { typeof(BoxCollider) })
			{
				layer = LayerIndex.entityPrecise.intVal
			};
			val3.transform.SetParent(val.transform, false);
			val3.transform.localPosition = Vector3.up * val2.y * 0.5f;
			val3.GetComponent<BoxCollider>().size = val2;
			HurtBox val4 = val3.AddComponent<HurtBox>();
			val4.healthComponent = val.GetComponent<HealthComponent>();
			val4.isBullseye = true;
			val4.hurtBoxGroup = component3;
			val4.indexInGroup = 0;
			component3.hurtBoxes = (HurtBox[])(object)new HurtBox[1] { val4 };
			component3.mainHurtBox = val4;
			component3.bullseyeCount = 1;
			Rigidbody component5 = val.GetComponent<Rigidbody>();
			if (Object.op_Implicit((Object)(object)component5))
			{
				component5.isKinematic = true;
				component5.useGravity = false;
			}
			EntityStateMachine[] components = val.GetComponents<EntityStateMachine>();
			foreach (EntityStateMachine val5 in components)
			{
				if (val5.customName == "Body")
				{
					val5.initialStateType = new SerializableEntityStateType(typeof(Idle));
					val5.mainStateType = val5.initialStateType;
				}
			}
			val.AddComponent<FortressBodyMarker>();
			GameObject val6 = PrefabAPI.InstantiateClone(masterSource, "BazaarGauntletFortressMaster" + kind);
			val6.GetComponent<CharacterMaster>().bodyPrefab = val;
			BaseAI[] components2 = val6.GetComponents<BaseAI>();
			for (int i = 0; i < components2.Length; i++)
			{
				((Behaviour)components2[i]).enabled = false;
			}
			masters[kind] = val6;
			ContentAddition.AddBody(val);
			ContentAddition.AddMaster(val6);
		}
	}
	internal sealed class FortressBodyMarker : MonoBehaviour
	{
		private void Awake()
		{
			HideNativeModel();
		}

		private void Start()
		{
			HideNativeModel();
		}

		private void HideNativeModel()
		{
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].forceRenderingOff = true;
			}
		}
	}
	internal sealed class FortressBattlefield : MonoBehaviour
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_OnEnable <0>__SceneReady;

			public static hook_OnDisable <1>__SceneLeaving;
		}

		internal static readonly Vector3 Origin = new Vector3(87.54f, -115f, -213.626f);

		private readonly List<(Renderer Renderer, bool Enabled)> hiddenRenderers = new List<(Renderer, bool)>();

		private readonly List<(Collider Collider, bool Enabled)> hiddenColliders = new List<(Collider, bool)>();

		private readonly List<(MapZone Zone, bool Enabled)> hiddenZones = new List<(MapZone, bool)>();

		private readonly HashSet<int> zoneIDs = new HashSet<int>();

		private readonly HashSet<int> rendererIDs = new HashSet<int>();

		private readonly HashSet<int> colliderIDs = new HashSet<int>();

		private readonly HashSet<int> nativeRendererIDs = new HashSet<int>();

		private readonly HashSet<int> nativeColliderIDs = new HashSet<int>();

		private readonly List<(NodeGraph Graph, Node[] Nodes, Link[] Links)> graphs = new List<(NodeGraph, Node[], Link[])>();

		private readonly List<(MeshRenderer Renderer, string Surface)> surfaces = new List<(MeshRenderer, string)>();

		private GameObject root;

		private FortressArchitectureData.Surface[] arenaSurfaces;

		private readonly Dictionary<string, Material> arenaMaterials = new Dictionary<string, Material>();

		private readonly List<Texture2D> ownedTextures = new List<Texture2D>();

		private int sceneHandle;

		private readonly Dictionary<CharacterBody, float> stranded = new Dictionary<CharacterBody, float>();

		private float nextRescue;

		private bool built;

		private bool materialsReady;

		private bool released;

		private float rescanUntil;

		private float nextRescan;

		private float nextMaterialTry;

		internal static void Install()
		{
			//IL_0010: 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_001b: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			object obj = <>O.<0>__SceneReady;
			if (obj == null)
			{
				hook_OnEnable val = SceneReady;
				<>O.<0>__SceneReady = val;
				obj = (object)val;
			}
			SceneInfo.OnEnable += (hook_OnEnable)obj;
			object obj2 = <>O.<1>__SceneLeaving;
			if (obj2 == null)
			{
				hook_OnDisable val2 = SceneLeaving;
				<>O.<1>__SceneLeaving = val2;
				obj2 = (object)val2;
			}
			SceneInfo.OnDisable += (hook_OnDisable)obj2;
		}

		private static void SceneLeaving(orig_OnDisable original, SceneInfo info)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			GauntletController current = GauntletController.Current;
			if (Object.op_Implicit((Object)(object)current))
			{
				FortressBattlefield[] components = ((Component)current).GetComponents<FortressBattlefield>();
				foreach (FortressBattlefield fortressBattlefield in components)
				{
					int num = fortressBattlefield.sceneHandle;
					Scene scene = ((Component)info).gameObject.scene;
					if (num == ((Scene)(ref scene)).handle)
					{
						fortressBattlefield.Release();
						Object.Destroy((Object)(object)fortressBattlefield);
					}
				}
			}
			original.Invoke(info);
		}

		private static void SceneReady(orig_OnEnable original, SceneInfo info)
		{
			original.Invoke(info);
			GauntletController current = GauntletController.Current;
			if (Object.op_Implicit((Object)(object)current) && Object.op_Implicit((Object)(object)info.sceneDef) && info.sceneDef.cachedName == "golemplains")
			{
				Ensure(current);
			}
		}

		internal static FortressBattlefield Ensure(GauntletController owner)
		{
			if (!Object.op_Implicit((Object)(object)owner) || owner.ShuttingDown || !Object.op_Implicit((Object)(object)SceneInfo.instance) || !Object.op_Implicit((Object)(object)SceneInfo.instance.sceneDef) || SceneInfo.instance.sceneDef.cachedName != "golemplains")
			{
				return null;
			}
			FortressBattlefield fortressBattlefield = ((Component)owner).GetComponents<FortressBattlefield>().FirstOrDefault((FortressBattlefield candidate) => !candidate.released) ?? ((Component)owner).gameObject.AddComponent<FortressBattlefield>();
			if (fortressBattlefield.built)
			{
				return fortressBattlefield;
			}
			try
			{
				fortressBattlefield.Build();
				fortressBattlefield.built = true;
				return fortressBattlefield;
			}
			catch (Exception ex)
			{
				fortressBattlefield.Release();
				Object.Destroy((Object)(object)fortressBattlefield);
				GauntletPlugin.Log.LogError((object)("Battlefield construction failed; no incomplete arena is accepted. " + ex));
				throw;
			}
		}

		private bool NativeScene(Component component)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)component) && component.gameObject.scene == ((Component)SceneInfo.instance).gameObject.scene && (!Object.op_Implicit((Object)(object)root) || !component.transform.IsChildOf(root.transform)) && !Object.op_Implicit((Object)(object)component.GetComponentInParent<NetworkIdentity>()))
			{
				return !Object.op_Implicit((Object)(object)component.GetComponentInParent<CharacterBody>());
			}
			return false;
		}

		private void ClearNativeScenery()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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)
			Bounds val = default(Bounds);
			((Bounds)(ref val))..ctor(Origin + Vector3.up * 98f, new Vector3(510f, 204f, 510f));
			Physics.SyncTransforms();
			MapZone[] array = Object.FindObjectsOfType<MapZone>(true);
			Collider[] components;
			foreach (MapZone val2 in array)
			{
				if (NativeScene((Component)(object)val2))
				{
					components = ((Component)val2).GetComponents<Collider>();
					foreach (Collider collider in components)
					{
						Hide(collider);
					}
					if (zoneIDs.Add(((Object)val2).GetInstanceID()))
					{
						hiddenZones.Add((val2, ((Behaviour)val2).enabled));
					}
					((Behaviour)val2).enabled = false;
				}
			}
			components = Object.FindObjectsOfType<Collider>(true);
			foreach (Collider val3 in components)
			{
				if (NativeScene((Component)(object)val3) && val3.enabled && ((Component)val3).gameObject.activeInHierarchy && !val3.isTrigger && ((Bounds)(ref val)).Intersects(val3.bounds))
				{
					Hide(val3);
				}
			}
			Renderer[] array2 = Object.FindObjectsOfType<Renderer>(true);
			foreach (Renderer val4 in array2)
			{
				if (NativeScene((Component)(object)val4) && nativeRendererIDs.Contains(((Object)val4).GetInstanceID()) && val4.enabled && ((Component)val4).gameObject.activeInHierarchy && (((Component)val4).gameObject.layer == LayerIndex.world.intVal || ((Object)((Component)val4).transform.root).name.StartsWith("HOLDER:", StringComparison.Ordinal) || ((Object)((Component)val4).transform.root).name.StartsWith("FOLIAGE:", StringComparison.Ordinal)))
				{
					if (rendererIDs.Add(((Object)val4).GetInstanceID()))
					{
						hiddenRenderers.Add((val4, val4.enabled));
					}
					val4.enabled = false;
				}
			}
		}

		private void Hide(Collider collider)
		{
			if (Object.op_Implicit((Object)(object)collider) && collider.enabled && nativeColliderIDs.Contains(((Object)collider).GetInstanceID()))
			{
				if (colliderIDs.Add(((Object)collider).GetInstanceID()))
				{
					hiddenColliders.Add((collider, collider.enabled));
				}
				collider.enabled = false;
			}
		}

		private void Build()
		{
			//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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Object.FindObjectsOfType<Collider>(true);
			foreach (Collider val in array)
			{
				if (NativeScene((Component)(object)val))
				{
					nativeColliderIDs.Add(((Object)val).GetInstanceID());
				}
			}
			Renderer[] array2 = Object.FindObjectsOfType<Renderer>(true);
			foreach (Renderer val2 in array2)
			{
				if (NativeScene((Component)(object)val2))
				{
					nativeRendererIDs.Add(((Object)val2).GetInstanceID());
				}
			}
			Scene scene = ((Component)SceneInfo.instance).gameObject.scene;
			sceneHandle = ((Scene)(ref scene)).handle;
			root = new GameObject("ArenaGauntlet Hellenic arena");
			root.transform.position = Origin;
			SceneManager.MoveGameObjectToScene(root, ((Component)SceneInfo.instance).gameObject.scene);
			ClearNativeScenery();
			BuildGeometry();
			BuildBoundary();
			Physics.SyncTransforms();
			LayerIndex world = LayerIndex.world;
			int num = LayerMask.op_Implicit(((LayerIndex)(ref world)).mask) | LayerMask.op_Implicit(CommonMasks.allCharacterCollisions);
			Collider[] array3 = (from collider in Physics.OverlapBox(Origin + Vector3.up * 41f, new Vector3(175f, 40f, 175f), Quaternion.identity, num, (QueryTriggerInteraction)1)
				where Object.op_Implicit((Object)(object)collider) && !((Component)collider).transform.IsChildOf(root.transform) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<NetworkIdentity>()) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<CharacterBody>())
				select collider).ToArray();
			if (array3.Length != 0)
			{
				throw new InvalidOperationException("Native scenery still blocks the battlefield: " + string.Join(", ", array3.Select((Collider collider) => ((Object)collider).name).Distinct()));
			}
			if (NetworkServer.active)
			{
				ReplaceGraph(SceneInfo.instance.groundNodes, FortressBattlefieldGrid.Ground());
				ReplaceGraph(SceneInfo.instance.airNodes, FortressBattlefieldGrid.Air());
			}
			rescanUntil = Time.unscaledTime + 8f;
			nextRescan = 0f;
			GauntletPlugin.Log.LogInfo((object)$"Hellenic stone arena: 358m diameter fighting floor on Titanic Plains, origin {Origin}; native obstacles cleared locally. Ground and aerial approaches use the same flat surface.");
		}

		private void BuildGeometry()
		{
			//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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			FortressMeshLifetime fortressMeshLifetime = root.AddComponent<FortressMeshLifetime>();
			GameObject val = new GameObject("Continuous arena collision", new Type[1] { typeof(BoxCollider) })
			{
				layer = LayerIndex.world.intVal
			};
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = Vector3.down * 6f;
			val.GetComponent<BoxCollider>().size = new Vector3(500f, 12f, 500f);
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BazaarGauntlet.assets.colosseum.meshbin"))
			{
				FortressArchitectureData fortressArchitectureData = FortressArchitectureData.Read(stream ?? throw new InvalidOperationException("Colosseum art is missing."));
				arenaSurfaces = fortressArchitectureData.Surfaces;
				FortressArchitectureData.Part[] parts = fortressArchitectureData.Parts;
				foreach (FortressArchitectureData.Part part in parts)
				{
					int num = part.Vertices.Length / 8;
					Vector3[] array = (Vector3[])(object)new Vector3[num];
					Vector3[] array2 = (Vector3[])(object)new Vector3[num];
					Vector2[] array3 = (Vector2[])(object)new Vector2[num];
					for (int j = 0; j < num; j++)
					{
						int num2 = j * 8;
						array[j] = new Vector3(part.Vertices[num2], part.Vertices[num2 + 1], part.Vertices[num2 + 2]);
						array2[j] = new Vector3(part.Vertices[num2 + 3], part.Vertices[num2 + 4], part.Vertices[num2 + 5]);
						array3[j] = new Vector2(part.Vertices[num2 + 6], part.Vertices[num2 + 7]);
					}
					Mesh val2 = new Mesh
					{
						name = part.Name,
						indexFormat = (IndexFormat)1,
						vertices = array,
						normals = array2,
						uv = array3,
						triangles = part.Indices
					};
					val2.colors32 = Enumerable.Repeat<Color32>(new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue), num).ToArray();
					val2.RecalculateBounds();
					val2.RecalculateTangents();
					fortressMeshLifetime.Meshes.Add(val2);
					Render(val2, fortressArchitectureData.Surfaces[part.Surface].Name);
					if (!part.Name.StartsWith("Courtyard", StringComparison.Ordinal) && !part.Name.StartsWith("MerchantShutters", StringComparison.Ordinal))
					{
						GameObject val3 = new GameObject("Colosseum solid architecture", new Type[1] { typeof(MeshCollider) })
						{
							layer = LayerIndex.world.intVal
						};
						val3.transform.SetParent(root.transform, false);
						val3.GetComponent<MeshCollider>().sharedMesh = val2;
					}
				}
			}
			GauntletShopVisuals.Build(root);
		}

		private void Render(Mesh mesh, string surface)
		{
			//IL_0026: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(((Object)mesh).name, new Type[2]
			{
				typeof(MeshFilter),
				typeof(MeshRenderer)
			});
			val.transform.SetParent(root.transform, false);
			val.layer = LayerIndex.world.intVal;
			val.GetComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer component = val.GetComponent<MeshRenderer>();
			((Renderer)component).enabled = false;
			surfaces.Add((component, surface));
		}

		private void BuildBoundary()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0089: 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_00c7: 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)
			GameObject val = new GameObject("Battlefield return boundary", new Type[1] { typeof(BoxCollider) })
			{
				layer = LayerIndex.triggerZone.intVal
			};
			val.transform.SetParent(root.transform, false);
			BoxCollider component = val.GetComponent<BoxCollider>();
			((Collider)component).isTrigger = true;
			component.center = new Vector3(0f, 190f, 0f);
			component.size = new Vector3(520f, 420f, 520f);
			Transform transform = new GameObject("Safe castle return").transform;
			transform.SetParent(root.transform, false);
			transform.localPosition = new Vector3(6f, 3f, 6f);
			MapZone obj = val.AddComponent<MapZone>();
			obj.zoneType = (ZoneType)1;
			obj.triggerType = (TriggerType)0;
			obj.explicitDestination = transform;
			obj.useExactExplicitPositionAndRotation = true;
		}

		private void ReplaceGraph(NodeGraph graph, FortressBattlefieldGrid layout)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_00c9: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)graph))
			{
				throw new InvalidOperationException("Native battlefield navigation graph missing.");
			}
			graphs.Add((graph, NativeAccess.Get<Node[]>(graph, "nodes"), NativeAccess.Get<Link[]>(graph, "links")));
			Node[] array = (Node[])(object)new Node[layout.Count];
			List<Link> list = new List<Link>();
			for (int i = 0; i < array.Length; i++)
			{
				(float, float, float) tuple = layout.Position(i);
				int count = list.Count;
				SerializableBitArray val = new SerializableBitArray(array.Length);
				val[i] = true;
				foreach (int item in layout.Neighbors(i))
				{
					(float X, float Y, float Z) tuple2 = layout.Position(item);
					float num = tuple2.X - tuple.Item1;
					float num2 = tuple2.Y - tuple.Item2;
					float num3 = tuple2.Z - tuple.Item3;
					list.Add(new Link
					{
						nodeIndexA = new NodeIndex(i),
						nodeIndexB = new NodeIndex(item),
						hullMask = 7,
						distanceScore = Mathf.Sqrt(num * num + num2 * num2 + num3 * num3),
						maxSlope = 0f
					});
					val[item] = true;
				}
				array[i] = new Node
				{
					position = Origin + new Vector3(tuple.Item1, tuple.Item2, tuple.Item3),
					flags = (NodeFlags)(layout.Edge(i) ? 4 : 0),
					lineOfSightMask = val,
					linkListIndex = new LinkListIndex
					{
						index = count,
						size = (uint)(list.Count - count)
					}
				};
			}
			NativeAccess.Set(graph, "nodes", array);
			NativeAccess.Set(graph, "links", list.ToArray());
			NativeAccess.Call(graph, "Awake");
		}

		private void ConfigureMaterials()
		{
			if (arenaMaterials.Count == 0)
			{
				try
				{
					FortressArchitectureData.Surface[] array = arenaSurfaces;
					foreach (FortressArchitectureData.Surface surface in array)
					{
						arenaMaterials.Add(surface.Name, ArenaMaterials.Create(surface, ownedTextures));
					}
				}
				catch
				{
					ReleaseMaterials();
					throw;
				}
			}
			foreach (var surface2 in surfaces)
			{
				((Renderer)surface2.Renderer).sharedMaterial = arenaMaterials[surface2.Surface];
				((Renderer)surface2.Renderer).enabled = true;
			}
			materialsReady = true;
		}

		private void ReleaseMaterials()
		{
			foreach (Material value in arenaMaterials.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value);
				}
			}
			arenaMaterials.Clear();
			foreach (Texture2D ownedTexture in ownedTextures)
			{
				if (Object.op_Implicit((Object)(object)ownedTexture))
				{
					Object.Destroy((Object)(object)ownedTexture);
				}
			}
			ownedTextures.Clear();
			materialsReady = false;
		}

		private void LateUpdate()
		{
			if (!built || released || !Object.op_Implicit((Object)(object)SceneInfo.instance))
			{
				return;
			}
			if (!materialsReady && Time.unscaledTime >= nextMaterialTry)
			{
				nextMaterialTry = Time.unscaledTime + 3f;
				try
				{
					ConfigureMaterials();
				}
				catch (Exception ex)
				{
					GauntletPlugin.Log.LogWarning((object)("Battlefield appearance will retry; terrain collision/navigation remain active. " + ex));
				}
			}
			if (Time.unscaledTime < rescanUntil && Time.unscaledTime >= nextRescan)
			{
				nextRescan = Time.unscaledTime + 1f;
				ClearNativeScenery();
			}
			foreach (var hiddenRenderer in hiddenRenderers)
			{
				if (Object.op_Implicit((Object)(object)hiddenRenderer.Renderer) && hiddenRenderer.Renderer.enabled)
				{
					hiddenRenderer.Renderer.enabled = false;
				}
			}
			foreach (var hiddenCollider in hiddenColliders)
			{
				if (Object.op_Implicit((Object)(object)hiddenCollider.Collider) && hiddenCollider.Collider.enabled)
				{
					hiddenCollider.Collider.enabled = false;
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_0122: 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_012c: 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_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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: 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_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !built || released || Time.fixedTime < nextRescue)
			{
				return;
			}
			nextRescue = Time.fixedTime + 1f;
			GauntletController component = ((Component)this).GetComponent<GauntletController>();
			if (!Object.op_Implicit((Object)(object)component) || component.ShuttingDown || !component.Fortress.IsCombat)
			{
				stranded.Clear();
				return;
			}
			HashSet<CharacterBody> present = new HashSet<CharacterBody>();
			Vector3 val5 = default(Vector3);
			foreach (TeamComponent teamMember in TeamComponent.GetTeamMembers((TeamIndex)2))
			{
				CharacterBody val = (Object.op_Implicit((Object)(object)teamMember) ? teamMember.body : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.master) || !Object.op_Implicit((Object)(object)((Component)val.master).GetComponent<GauntletAggression>()) || !Object.op_Implicit((Object)(object)val.healthComponent) || !val.healthComponent.alive || ((Object)val).name.IndexOf("Worm", StringComparison.OrdinalIgnoreCase) >= 0 || val.HasBuff(Buffs.HiddenInvincibility))
				{
					continue;
				}
				Vector3 val2 = val.corePosition - Origin;
				Vector2 val3 = new Vector2(val2.x, val2.z);
				if (((Vector2)(ref val3)).sqrMagnitude <= 30276f && val2.y >= -24f)
				{
					continue;
				}
				present.Add(val);
				if (!stranded.TryGetValue(val, out var value))
				{
					stranded[val] = Time.fixedTime;
				}
				else if (!(Time.fixedTime - value < 3f))
				{
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude < 3025f)
					{
						val2 = ((((Vector3)(ref val2)).sqrMagnitude > 0.1f) ? (((Vector3)(ref val2)).normalized * 66f) : (Vector3.forward * 66f));
					}
					if (((Vector3)(ref val2)).magnitude > 150f)
					{
						val2 = ((Vector3)(ref val2)).normalized * 150f;
					}
					NodeGraph nodeGraph = SceneInfo.instance.GetNodeGraph((GraphType)(val.isFlying ? 1 : 0));
					NodeIndex val4 = nodeGraph.FindClosestNode(Origin + val2, val.hullClassification, float.PositiveInfinity);
					if (nodeGraph.GetNodePosition(val4, ref val5))
					{
						TeleportBodyArgs val6 = default(TeleportBodyArgs);
						((TeleportBodyArgs)(ref val6)).body = val;
						val6.targetPosition = val5 + Vector3.up;
						TeleportHelper.TeleportBody(val6);
					}
					stranded.Remove(val);
				}
			}
			CharacterBody[] array = stranded.Keys.Where((CharacterBody body) => !Object.op_Implicit((Object)(object)body) || !present.Contains(body)).ToArray();
			foreach (CharacterBody key in array)
			{
				stranded.Remove(key);
			}
		}

		internal void RefreshScenery()
		{
			if (built && !released)
			{
				ClearNativeScenery();
			}
		}

		internal void Release()
		{
			if (released)
			{
				return;
			}
			released = true;
			foreach (var graph in graphs)
			{
				if (Object.op_Implicit((Object)(object)graph.Graph))
				{
					NativeAccess.Set(graph.Graph, "nodes", graph.Nodes);
					NativeAccess.Set(graph.Graph, "links", graph.Links);
					NativeAccess.Call(graph.Graph, "Awake");
				}
			}
			graphs.Clear();
			foreach (var hiddenRenderer in hiddenRenderers)
			{
				if (Object.op_Implicit((Object)(object)hiddenRenderer.Renderer))
				{
					hiddenRenderer.Renderer.enabled = hiddenRenderer.Enabled;
				}
			}
			foreach (var hiddenCollider in hiddenColliders)
			{
				if (Object.op_Implicit((Object)(object)hiddenCollider.Collider))
				{
					hiddenCollider.Collider.enabled = hiddenCollider.Enabled;
				}
			}
			foreach (var hiddenZone in hiddenZones)
			{
				if (Object.op_Implicit((Object)(object)hiddenZone.Zone))
				{
					((Behaviour)hiddenZone.Zone).enabled = hiddenZone.Enabled;
				}
			}
			hiddenRenderers.Clear();
			hiddenColliders.Clear();
			hiddenZones.Clear();
			surfaces.Clear();
			stranded.Clear();
			if (Object.op_Implicit((Object)(object)root))
			{
				Object.Destroy((Object)(object)root);
			}
			ReleaseMaterials();
		}

		private void OnDestroy()
		{
			Release();
		}
	}
	internal sealed class FortressBattlefieldGrid
	{
		internal const int HalfSize = 180;

		internal readonly int Step;

		internal readonly int Radius;

		internal readonly int Side;

		internal readonly float[] Heights;

		private readonly List<(int X, int Z)> cells = new List<(int, int)>();

		private readonly Dictionary<(int X, int Z), int> lookup = new Dictionary<(int, int), int>();

		internal int Count => cells.Count * Heights.Length;

		internal FortressBattlefieldGrid(int extent, int step, params float[] heights)
		{
			if (extent < step || step <= 0 || heights.Length == 0)
			{
				throw new ArgumentException("Invalid battlefield grid.");
			}
			Step = step;
			Radius = extent / step;
			Side = Radius * 2 + 1;
			Heights = (float[])heights.Clone();
			for (int i = -Radius; i <= Radius; i++)
			{
				for (int j = -Radius; j <= Radius; j++)
				{
					if (j * j + i * i <= Radius * Radius)
					{
						lookup[(j, i)] = cells.Count;
						cells.Add((j, i));
					}
				}
			}
		}

		internal (float X, float Y, float Z) Position(int index)
		{
			(int, int) tuple = cells[index % cells.Count];
			return (X: tuple.Item1 * Step, Y: Heights[index / cells.Count], Z: tuple.Item2 * Step);
		}

		internal IEnumerable<int> Neighbors(int index)
		{
			int layer = index / cells.Count;
			(int X, int Z) cell = cells[index % cells.Count];
			for (int dz = -1; dz <= 1; dz++)
			{
				for (int dx = -1; dx <= 1; dx++)
				{
					if ((dx != 0 || dz != 0) && lookup.TryGetValue((cell.X + dx, cell.Z + dz), out var value))
					{
						yield return layer * cells.Count + value;
					}
				}
			}
			if (layer > 0)
			{
				yield return index - cells.Count;
			}
			if (layer + 1 < Heights.Length)
			{
				yield return index + cells.Count;
			}
		}

		internal bool Edge(int index)
		{
			(float, float, float) tuple = Position(index);
			return tuple.Item1 * tuple.Item1 + tuple.Item3 * tuple.Item3 >= (float)((Radius - 1) * (Radius - 1) * Step * Step);
		}

		internal static FortressBattlefieldGrid Ground()
		{
			return new FortressBattlefieldGrid(168, 6, 0.06f);
		}

		internal static FortressBattlefieldGrid Air()
		{
			return new FortressBattlefieldGrid(156, 12, 16f, 32f, 52f);
		}
	}
	internal static class FortressCausewayMesh
	{
		private sealed class Surface
		{
			private readonly List<Vector3> vertices = new List<Vector3>();

			private readonly List<Vector3> normals = new List<Vector3>();

			private readonly List<Vector2> uv = new List<Vector2>();

			private readonly List<int> triangles = new List<int>();

			internal void Quad(Vector3 a, Vector3 b, Vector3 c, Vector3 d, Vector3 outward)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: 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)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: 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_0035: 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_003b: 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_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: 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_004f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: 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_0026: Unknown result type (might be due to invalid IL or missing references)
				//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_0090: 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_00a9: 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_00f1: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c2: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
				if (Vector3.Dot(Vector3.Cross(b - a, c - a), outward) < 0f)
				{
					Vector3 val = b;
					b = d;
					d = val;
				}
				int count = vertices.Count;
				Vector3 val2 = Vector3.Cross(b - a, c - a);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				Vector3[] array = (Vector3[])(object)new Vector3[4] { a, b, c, d };
				foreach (Vector3 val3 in array)
				{
					vertices.Add(val3);
					normals.Add(normalized);
					uv.Add((Mathf.Abs(normalized.y) > 0.5f) ? new Vector2(val3.x / 3f, val3.z / 3f) : new Vector2((val3.x + val3.z) / 3f, val3.y / 3f));
				}
				triangles.AddRange(new int[6]
				{
					count,
					count + 1,
					count + 2,
					count,
					count + 2,
					count + 3
				});
			}

			internal Mesh Finish(string name)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Expected O, but got Unknown
				Mesh val = new Mesh
				{
					name = "Causeway " + name
				};
				val.SetVertices(vertices);
				val.SetNormals(normals);
				val.SetUVs(0, uv);
				val.SetTriangles(triangles, 0);
				val.RecalculateBounds();
				return val;
			}
		}

		private struct Section
		{
			internal Vector3 Center;

			internal Vector3 Side;

			internal float HalfWidth;

			internal float Thickness;

			internal float Curb;

			internal float Distance;
		}

		private static float Smooth(float t)
		{
			t = Mathf.Clamp01(t);
			return t * t * (3f - 2f * t);
		}

		private static Vector3 Side(Vector3 direction)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.Cross(Vector3.up, direction);
			return ((Vector3)(ref val)).normalized;
		}

		internal static IEnumerable<(string Name, Mesh Mesh)> Build(Vector3[] route, float width)
		{
			Surface surface = new Surface();
			Surface ivory = new Surface();
			Surface brass = new Surface();
			Surface glow = new Surface();
			List<Section> list = new List<Section>();
			float num = 0f;
			float num2 = 0f;
			for (int i = 1; i < route.Length; i++)
			{
				num += Vector3.Distance(route[i - 1], route[i]);
			}
			Vector3 val5;
			for (int j = 0; j < route.Length - 1; j++)
			{
				Vector3 val = route[j];
				Vector3 val2 = route[j + 1];
				float num3 = Vector3.Distance(val, val2);
				int num4 = Mathf.CeilToInt(num3 / 4f);
				for (int k = ((j != 0) ? 1 : 0); k <= num4; k++)
				{
					float num5 = (float)k / (float)num4;
					float num6 = num2 + num3 * num5;
					float num7 = num - num6;
					Vector3 val3 = Side(val2 - val);
					if (k == num4 && j < route.Length - 2)
					{
						Vector3 val4 = Side(route[j + 2] - val2);
						val5 = val3 + val4;
						Vector3 normalized = ((Vector3)(ref val5)).normalized;
						val3 = normalized / Mathf.Max(0.6f, Vector3.Dot(normalized, val3));
					}
					list.Add(new Section
					{
						Center = Vector3.Lerp(val, val2, num5),
						Side = val3,
						Distance = num6,
						HalfWidth = width * 0.5f + 2f * Smooth(1f - num7 / 12f),
						Thickness = 0.025f + 0.8f * Smooth(Mathf.Min(num6, num7) / 8f),
						Curb = 0.2f * Smooth(Mathf.Min(num6 / 10f, (num7 - 16f) / 12f))
					});
				}
				num2 += num3;
			}
			for (int l = 1; l < list.Count; l++)
			{
				Section section = list[l - 1];
				Section section2 = list[l];
				Vector3 val6 = section.Center - section.Side * section.HalfWidth;
				Vector3 val7 = section.Center + section.Side * section.HalfWidth;
				Vector3 val8 = section2.Center - section2.Side * section2.HalfWidth;
				Vector3 val9 = section2.Center + section2.Side * section2.HalfWidth;
				Vector3 val10 = val6 + section.Side * 0.35f - Vector3.up * section.Thickness;
				Vector3 val11 = val7 - section.Side * 0.35f - Vector3.up * section.Thickness;
				Vector3 val12 = val8 + section2.Side * 0.35f - Vector3.up * section2.Thickness;
				Vector3 val13 = val9 - section2.Side * 0.35f - Vector3.up * section2.Thickness;
				surface.Quad(val6, val7, val9, val8, Vector3.up);
				surface.Quad(val11, val10, val12, val13, Vector3.down);
				float[] array = new float[2] { -1f, 1f };
				foreach (float num8 in array)
				{
					Vector3 val14 = ((num8 < 0f) ? val6 : val7);
					Vector3 val15 = ((num8 < 0f) ? val8 : val9);
					Vector3 val16 = ((num8 < 0f) ? val10 : val11);
					Vector3 val17 = ((num8 < 0f) ? val12 : val13);
					val5 = section.Side + section2.Side;
					Vector3 val18 = ((Vector3)(ref val5)).normalized * num8;
					surface.Quad(val14, val15, val17, val16, val18);
					ivory.Quad(val14 + val18 * 0.01f, val15 + val18 * 0.01f, val17 + val18 * 0.01f, val16 + val18 * 0.01f, val18);
					Vector3 val19 = section.Center + section.Side * num8 * (section.HalfWidth - 0.55f);
					Vector3 val20 = section2.Center + section2.Side * num8 * (section2.HalfWidth - 0.55f);
					if (section.Curb > 0.001f || section2.Curb > 0.001f)
					{
						Vector3 val21 = val19 + Vector3.up * section.Curb;
						Vector3 val22 = val20 + Vector3.up * section2.Curb;
						ivory.Quad(val21 - section.Side * 0.18f, val21 + section.Side * 0.18f, val22 + section2.Side * 0.18f, val22 - section2.Side * 0.18f, Vector3.up);
						ivory.Quad(val19, val20, val22, val21, -val18);
					}
					Vector3 val23 = val19 - section.Side * num8 * 0.75f + Vector3.up * 0.018f;
					Vector3 val24 = val20 - section2.Side * num8 * 0.75f + Vector3.up * 0.018f;
					brass.Quad(val23 - section.Side * 0.07f, val23 + section.Side * 0.07f, val24 + section2.Side * 0.07f, val24 - section2.Side * 0.07f, Vector3.up);
					if (l % 3 == 0 && section2.Distance < num - 18f && section.Distance > 10f)
					{
						Vector3 val25 = Vector3.Lerp(val19, val20, 0.5f) + Vector3.up * 0.025f;
						val5 = section2.Center - section.Center;
						Vector3 val26 = ((Vector3)(ref val5)).normalized * 0.5f;
						Vector3 val27 = val18 * 0.08f;
						glow.Quad(val25 - val26 - val27, val25 - val26 + val27, val25 + val26 + val27, val25 + val26 - val27, Vector3.up);
					}
				}
				if (l == 1)
				{
					val5 = section.Center - section2.Center;
					surface.Quad(val7, val6, val10, val11, ((Vector3)(ref val5)).normalized);
				}
				if (l == list.Count - 1)
				{
					val5 = section2.Center - section.Center;
					surface.Quad(val8, val9, val13, val12, ((Vector3)(ref val5)).normalized);
				}
			}
			yield return (Name: "stone", Mesh: surface.Finish("stone"));
			yield return (Name: "ivory", Mesh: ivory.Finish("ivory"));
			yield return (Name: "brass", Mesh: brass.Finish("brass"));
			yield return (Name: "energy", Mesh: glow.Finish("energy"));
		}
	}
	internal sealed class FortressController : MonoBehaviour
	{
		internal FortressState State = new FortressState();

		internal GauntletController Owner;

		internal readonly CharacterMaster[] Masters = (CharacterMaster[])(object)new CharacterMaster[16];

		internal readonly Dictionary<uint, ulong> Requests = new Dictionary<uint, ulong>();

		internal readonly Dictionary<uint, float> RequestTimes = new Dictionary<uint, float>();

		private readonly GauntletArrivalGate arrival = new GauntletArrivalGate();

		private readonly HashSet<CharacterMaster> funded = new HashSet<CharacterMaster>();

		private readonly GauntletStartingItems starters = new GauntletStartingItems();

		internal bool Leaving;

		internal Vector3? PlannedAnchor;

		internal bool WaitingForStart
		{
			get
			{
				return State.Preparing;
			}
			set
			{
				State.Preparing = value;
			}
		}

		internal int Round
		{
			get
			{
				if (!NetworkServer.active)
				{
					return Owner.RemoteRound;
				}
				return Owner.Flow.Round;
			}
		}

		internal GauntletPhase Phase
		{
			get
			{
				if (!NetworkServer.active)
				{
					return Owner.RemotePhase;
				}
				return Owner.Flow.Phase;
			}
		}

		internal int PlanningRound => Round;

		internal Vector3 Center => FortressBattlefield.Origin;

		internal bool InCastle
		{
			get
			{
				if (Object.op_Implicit((Object)(object)SceneInfo.instance) && Object.op_Implicit((Object)(object)SceneInfo.instance.sceneDef))
				{
					return SceneInfo.instance.sceneDef.cachedName == "golemplains";
				}
				return false;
			}
		}

		internal bool CanManage
		{
			get
			{
				if (!Leaving && !Owner.ShuttingDown && !((Run)Owner.Run).isGameOverServer && InCastle)
				{
					if (!WaitingForStart && Phase != GauntletPhase.AwaitingExit)
					{
						return Phase == GauntletPhase.FinalDecision;
					}
					return true;
				}
				return false;
			}
		}

		internal bool IsCombat
		{
			get
			{
				if (!WaitingForStart && !Leaving && InCastle)
				{
					if (Phase != GauntletPhase.Horde)
					{
						return Phase == GauntletPhase.Boss;
					}
					return true;
				}
				return false;
			}
		}

		private void Awake()
		{
			Owner = ((Component)this).GetComponent<GauntletController>();
		}

		internal void Arrive(InfiniteTowerSafeWardController ward)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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)
			if (NetworkServer.active && Object.op_Implicit((Object)(object)ward))
			{
				FortressBattlefield.Ensure(Owner);
				Leaving = false;
				WaitingForStart = true;
				arrival.Reset();
				State.X = Center.x;
				State.Y = Center.y;
				State.Z = Center.z;
				State.Yaw = 0f;
				State.Map = "golemplains";
				State.Placed = true;
				State.Revision++;
				((Component)ward).transform.position = Center;
				GauntletWaves.HideWard(((Component)ward).gameObject);
				PurchaseInteraction component = ((Component)ward).GetComponent<PurchaseInteraction>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.SetAvailable(false);
				}
				GauntletPortals.Clear();
			}
		}

		internal bool BeginRound()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			if (!NetworkServer.active || !CanManage || !Owner.ArenaReady || !Object.op_Implicit((Object)(object)Owner.ArenaWard))
			{
				return false;
			}
			if (!WaitingForStart || Phase != GauntletPhase.Horde)
			{
				return false;
			}
			Owner.Shop.Close();
			State.Revision++;
			try
			{
				GauntletRecovery.RestorePlayers();
			}
			catch (Exception ex)
			{
				GauntletPlugin.Log.LogWarning((object)("A recovery callback failed; automatic combat start continues. " + ex));
			}
			Owner.UpdateLevelFloor();
			EntityStateMachine[] components = ((Component)Owner.ArenaWard).GetComponents<EntityStateMachine>();
			foreach (EntityStateMachine val in components)
			{
				if (val.state is BaseSafeWardState)
				{
					val.SetNextState((EntityState)new Active());
				}
			}
			return GauntletWaves.StartRound(Owner);
		}

		internal void RoundEnded()
		{
			Owner.Meta.RoundCleared();
			if (Owner.CollectLoot)
			{
				Owner.PortalLoot.RoundCleared();
			}
			State.Revision++;
			ClearStragglers();
			((MonoBehaviour)this).StartCoroutine(SettleSummons());
			try
			{
				GauntletRecovery.RestorePlayers();
			}
			catch (Exception ex)
			{
				GauntletPlugin.Log.LogWarning((object)("Intermission recovery will retry at combat start. " + ex));
			}
			if (Phase == GauntletPhase.FinalDecision && !Owner.AllowLoop)
			{
				GauntletPortals.Announce("Final champion defeated. Victory!");
				((MonoBehaviour)this).StartCoroutine(FinishVictory());
			}
			else
			{
				if (Phase == GauntletPhase.FinalDecision)
				{
					Owner.Flow.ContinueThroughBazaar();
				}
				Owner.Shop.Open();
				GauntletPortals.Announce("Round complete. The merchant alcoves are open at the south gate. Use the ready brazier when you have finished shopping.");
			}
			Owner.Economy.CompleteRound();
			GauntletNetwork.Broadcast(Owner);
		}

		private void ClearStragglers()
		{
			TeamComponent[] array = TeamComponent.GetTeamMembers((TeamIndex)2).ToArray();
			foreach (TeamComponent val