Decompiled source of Custom Characters Mod v2.2.6

CustomCharacters.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using Dungeonator;
using Gungeon;
using GungeonAPI;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using ItemAPI;
using MonoMod.RuntimeDetour;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CustomCharacters")]
[assembly: AssemblyProduct("CustomCharacters")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ItemAPI
{
	public static class SpriteBuilder
	{
		private static tk2dSpriteCollectionData itemCollection = ((BraveBehaviour)PickupObjectDatabase.GetById(155)).sprite.Collection;

		private static tk2dSpriteCollectionData ammonomiconCollection = AmmonomiconController.ForceInstance.EncounterIconCollection;

		private static tk2dSprite baseSprite = ((Component)PickupObjectDatabase.GetById(155)).GetComponent<tk2dSprite>();

		public static GameObject SpriteFromFile(string spriteName, GameObject obj = null, bool copyFromExisting = true)
		{
			string fileName = spriteName.Replace(".png", "");
			Texture2D textureFromFile = ResourceExtractor.GetTextureFromFile(fileName);
			if ((Object)(object)textureFromFile == (Object)null)
			{
				return null;
			}
			return SpriteFromTexture(textureFromFile, spriteName, obj, copyFromExisting);
		}

		public static GameObject SpriteFromResource(string spriteName, GameObject obj = null, bool copyFromExisting = true)
		{
			string text = ((!spriteName.EndsWith(".png")) ? ".png" : "");
			string text2 = spriteName + text;
			Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(text2);
			if ((Object)(object)textureFromResource == (Object)null)
			{
				return null;
			}
			return SpriteFromTexture(textureFromResource, text2, obj, copyFromExisting);
		}

		public static GameObject SpriteFromTexture(Texture2D texture, string spriteName, GameObject obj = null, bool copyFromExisting = true)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if ((Object)(object)obj == (Object)null)
			{
				obj = new GameObject();
			}
			tk2dSprite val = ((!copyFromExisting) ? obj.AddComponent<tk2dSprite>() : obj.AddComponent<tk2dSprite>(baseSprite));
			tk2dSpriteCollectionData val2 = ConstructCollection(obj, ((Object)texture).name.ToLower().Replace(" ", "_") + "_collection");
			int num = AddSpriteToCollection(spriteName, val2);
			val2.InitMaterialIds();
			((tk2dBaseSprite)val).SetSprite(val2, num);
			((tk2dBaseSprite)val).SortingOrder = 0;
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return obj;
		}

		public static int AddSpriteToCollection(string resourcePath, tk2dSpriteCollectionData collection)
		{
			string text = ((!resourcePath.EndsWith(".png")) ? ".png" : "");
			resourcePath += text;
			Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(resourcePath);
			tk2dSpriteDefinition val = ConstructDefinition(textureFromResource);
			val.name = ((Object)textureFromResource).name;
			return AddSpriteToCollection(val, collection);
		}

		public static int AddSpriteToCollection(tk2dSpriteDefinition spriteDefinition, tk2dSpriteCollectionData collection)
		{
			tk2dSpriteDefinition[] spriteDefinitions = collection.spriteDefinitions;
			tk2dSpriteDefinition[] array = (collection.spriteDefinitions = spriteDefinitions.Concat((IEnumerable<tk2dSpriteDefinition>)(object)new tk2dSpriteDefinition[1] { spriteDefinition }).ToArray());
			FieldInfo field = typeof(tk2dSpriteCollectionData).GetField("spriteNameLookupDict", BindingFlags.Instance | BindingFlags.NonPublic);
			field.SetValue(collection, null);
			collection.InitDictionary();
			return array.Length - 1;
		}

		public static int AddToAmmonomicon(tk2dSpriteDefinition spriteDefinition)
		{
			return AddSpriteToCollection(spriteDefinition, ammonomiconCollection);
		}

		public static tk2dSpriteAnimationClip AddAnimation(tk2dSpriteAnimator animator, tk2dSpriteCollectionData collection, List<int> spriteIDs, string clipName, WrapMode wrapMode = 0)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008b: Expected O, but got Unknown
			if ((Object)(object)animator.Library == (Object)null)
			{
				animator.Library = ((Component)animator).gameObject.AddComponent<tk2dSpriteAnimation>();
				animator.Library.clips = (tk2dSpriteAnimationClip[])(object)new tk2dSpriteAnimationClip[0];
				((Behaviour)animator.Library).enabled = true;
			}
			List<tk2dSpriteAnimationFrame> list = new List<tk2dSpriteAnimationFrame>();
			for (int i = 0; i < spriteIDs.Count; i++)
			{
				tk2dSpriteDefinition val = collection.spriteDefinitions[spriteIDs[i]];
				if (val.Valid)
				{
					list.Add(new tk2dSpriteAnimationFrame
					{
						spriteCollection = collection,
						spriteId = spriteIDs[i]
					});
				}
			}
			tk2dSpriteAnimationClip val2 = new tk2dSpriteAnimationClip();
			val2.name = clipName;
			val2.fps = 15f;
			val2.wrapMode = wrapMode;
			Array.Resize(ref animator.Library.clips, animator.Library.clips.Length + 1);
			animator.Library.clips[animator.Library.clips.Length - 1] = val2;
			val2.frames = list.ToArray();
			return val2;
		}

		public static SpeculativeRigidbody SetUpSpeculativeRigidbody(this tk2dSprite sprite, IntVector2 offset, IntVector2 dimensions)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_003a: 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)
			SpeculativeRigidbody orAddComponent = GameObjectExtensions.GetOrAddComponent<SpeculativeRigidbody>(((Component)sprite).gameObject);
			PixelCollider val = new PixelCollider();
			val.ColliderGenerationMode = (PixelColliderGeneration)0;
			val.CollisionLayer = (CollisionLayer)3;
			val.ManualWidth = dimensions.x;
			val.ManualHeight = dimensions.y;
			val.ManualOffsetX = offset.x;
			val.ManualOffsetY = offset.y;
			orAddComponent.PixelColliders = new List<PixelCollider> { val };
			return orAddComponent;
		}

		public static tk2dSpriteDefinition ConstructDefinition(Texture2D texture)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_013f: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: 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)
			//IL_01f8: 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_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: 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)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: 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_02bc: Unknown result type (might be due to invalid IL or missing references)
			RuntimeAtlasSegment val = Assets.Packer.Pack(texture, false);
			Material val2 = new Material(ShaderCache.Acquire(PlayerController.DefaultShaderName));
			val2.mainTexture = (Texture)(object)val.texture;
			int width = ((Texture)texture).width;
			int height = ((Texture)texture).height;
			float num = 0f;
			float num2 = 0f;
			float num3 = (float)width / 16f;
			float num4 = (float)height / 16f;
			tk2dSpriteDefinition val3 = new tk2dSpriteDefinition();
			val3.normals = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f)
			};
			val3.tangents = (Vector4[])(object)new Vector4[4]
			{
				new Vector4(1f, 0f, 0f, 1f),
				new Vector4(1f, 0f, 0f, 1f),
				new Vector4(1f, 0f, 0f, 1f),
				new Vector4(1f, 0f, 0f, 1f)
			};
			val3.texelSize = new Vector2(0.0625f, 0.0625f);
			val3.extractRegion = false;
			val3.regionX = 0;
			val3.regionY = 0;
			val3.regionW = 0;
			val3.regionH = 0;
			val3.flipped = (FlipMode)0;
			val3.complexGeometry = false;
			val3.physicsEngine = (PhysicsEngine)0;
			val3.colliderType = (ColliderType)1;
			val3.collisionLayer = (CollisionLayer)6;
			val3.position0 = new Vector3(num, num2, 0f);
			val3.position1 = new Vector3(num + num3, num2, 0f);
			val3.position2 = new Vector3(num, num2 + num4, 0f);
			val3.position3 = new Vector3(num + num3, num2 + num4, 0f);
			val3.material = val2;
			val3.materialInst = val2;
			val3.materialId = 0;
			val3.uvs = val.uvs;
			val3.boundsDataCenter = new Vector3(num3 / 2f, num4 / 2f, 0f);
			val3.boundsDataExtents = new Vector3(num3, num4, 0f);
			val3.untrimmedBoundsDataCenter = new Vector3(num3 / 2f, num4 / 2f, 0f);
			val3.untrimmedBoundsDataExtents = new Vector3(num3, num4, 0f);
			tk2dSpriteDefinition val4 = val3;
			val4.name = ((Object)texture).name;
			return val4;
		}

		public static tk2dSpriteCollectionData ConstructCollection(GameObject obj, string name)
		{
			tk2dSpriteCollectionData val = obj.AddComponent<tk2dSpriteCollectionData>();
			Object.DontDestroyOnLoad((Object)(object)val);
			val.assetName = name;
			val.spriteCollectionGUID = name;
			val.spriteCollectionName = name;
			val.spriteDefinitions = (tk2dSpriteDefinition[])(object)new tk2dSpriteDefinition[0];
			val.InitDictionary();
			return val;
		}

		public static T CopyFrom<T>(this Component comp, T other) where T : Component
		{
			Type type = ((object)comp).GetType();
			if ((object)type != ((object)other).GetType())
			{
				return default(T);
			}
			PropertyInfo[] properties = type.GetProperties();
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				if (propertyInfo.CanWrite)
				{
					try
					{
						propertyInfo.SetValue(comp, propertyInfo.GetValue(other, null), null);
					}
					catch
					{
					}
				}
			}
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array2 = fields;
			foreach (FieldInfo fieldInfo in array2)
			{
				fieldInfo.SetValue(comp, fieldInfo.GetValue(other));
			}
			return (T)(object)((comp is T) ? comp : null);
		}

		public static T AddComponent<T>(this GameObject go, T toAdd) where T : Component
		{
			return ((Component)(object)go.AddComponent<T>()).CopyFrom(toAdd);
		}
	}
}
namespace GungeonAPI
{
	public static class DungeonHandler
	{
		public static float GlobalRoomWeight = 100f;

		private static bool initialized = false;

		public static bool debugFlow = false;

		public static void Init()
		{
			if (!initialized)
			{
				DungeonHooks.OnPreDungeonGeneration += OnPreDungeonGen;
				initialized = true;
			}
		}

		public static void OnPreDungeonGen(LoopDungeonGenerator generator, Dungeon dungeon, DungeonFlow flow, int dungeonSeed)
		{
			Tools.Print("Attempting to override floor layout...", "5599FF");
			if (((Object)flow).name != "Foyer Flow" && !GameManager.IsReturningToFoyerWithPlayer)
			{
				if (debugFlow)
				{
					generator.AssignFlow(flow);
				}
				Tools.Print("Dungeon name: " + ((Object)dungeon).name);
				Tools.Print("Override Flow set to: " + ((Object)flow).name);
			}
			dungeon = null;
		}

		public static void Register(RoomFactory.RoomData roomData)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected I4, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_007c: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Invalid comparison between Unknown and I4
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			PrototypeDungeonRoom room = roomData.room;
			WeightedRoom val = new WeightedRoom();
			val.room = room;
			val.additionalPrerequisites = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0];
			val.weight = ((roomData.weight == 0f) ? GlobalRoomWeight : roomData.weight);
			WeightedRoom val2 = val;
			RoomCategory category = room.category;
			RoomCategory val3 = category;
			switch (val3 - 3)
			{
			case 2:
			{
				RoomSpecialSubCategory subCategorySpecial = room.subCategorySpecial;
				RoomSpecialSubCategory val4 = subCategorySpecial;
				if ((int)val4 != 1)
				{
					if ((int)val4 == 2)
					{
						StaticReferences.subShopTable.InjectionData.Add(GetFlowModifier(roomData));
					}
					else
					{
						StaticReferences.RoomTables["special"].includedRooms.Add(val2);
					}
				}
				else
				{
					StaticReferences.RoomTables["shop"].includedRooms.Add(val2);
				}
				return;
			}
			case 3:
				StaticReferences.RoomTables["secret"].includedRooms.Add(val2);
				return;
			case 0:
				return;
			}
			List<DungeonPrerequisite> list = new List<DungeonPrerequisite>();
			foreach (DungeonPrerequisite prerequisite in room.prerequisites)
			{
				if (prerequisite.requireTileset)
				{
					StaticReferences.GetRoomTable(prerequisite.requiredTileset).includedRooms.Add(val2);
					list.Add(prerequisite);
				}
			}
			foreach (DungeonPrerequisite item in list)
			{
				room.prerequisites.Remove(item);
			}
		}

		public static ProceduralFlowModifierData GetFlowModifier(RoomFactory.RoomData roomData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			return new ProceduralFlowModifierData
			{
				annotation = ((Object)roomData.room).name,
				placementRules = new List<FlowModifierPlacementType>
				{
					(FlowModifierPlacementType)1,
					(FlowModifierPlacementType)3
				},
				exactRoom = roomData.room,
				selectionWeight = roomData.weight,
				chanceToSpawn = 1f,
				prerequisites = roomData.room.prerequisites.ToArray(),
				CanBeForcedSecret = true
			};
		}

		public static bool BelongsOnThisFloor(RoomFactory.RoomData data, string dungeonName)
		{
			if (data.floors == null || data.floors.Length == 0)
			{
				return true;
			}
			bool result = false;
			string[] floors = data.floors;
			foreach (string text in floors)
			{
				if (text.ToLower().Equals(dungeonName.ToLower()))
				{
					result = true;
					break;
				}
			}
			return result;
		}

		public static GenericRoomTable GetSpecialRoomTable()
		{
			foreach (MetaInjectionDataEntry entry in GameManager.Instance.GlobalInjectionData.entries)
			{
				if (entry.injectionData?.InjectionData == null)
				{
					continue;
				}
				foreach (ProceduralFlowModifierData injectionDatum in entry.injectionData.InjectionData)
				{
					if ((Object)(object)injectionDatum.roomTable != (Object)null && ((Object)injectionDatum.roomTable).name.ToLower().Contains("basic special rooms"))
					{
						return injectionDatum.roomTable;
					}
				}
			}
			return null;
		}

		public static void CollectDataForAnalysis(DungeonFlow flow, Dungeon dungeon)
		{
			try
			{
				foreach (WeightedRoom element in flow.fallbackRoomTable.includedRooms.elements)
				{
					object obj;
					if (element == null)
					{
						obj = null;
					}
					else
					{
						PrototypeDungeonRoom room = element.room;
						obj = ((room != null) ? ((Object)room).name : null);
					}
					Tools.Print("Fallback table: " + (string?)obj);
				}
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
			dungeon = null;
		}

		public static void LogProtoRoomData(PrototypeDungeonRoom room)
		{
			int num = 0;
			Tools.LogPropertiesAndFields<PrototypeDungeonRoom>(room, "ROOM");
			foreach (PrototypePlacedObjectData placedObject in room.placedObjects)
			{
				Tools.Log($"\n----------------Object #{num++}----------------");
				Tools.LogPropertiesAndFields<PrototypePlacedObjectData>(placedObject, "PLACED OBJECT");
				Tools.LogPropertiesAndFields<DungeonPlaceable>(placedObject?.placeableContents, "PLACEABLE CONTENT");
				Tools.LogPropertiesAndFields<DungeonPlaceableVariant>(placedObject?.placeableContents?.variantTiers[0], "VARIANT TIERS");
			}
			Tools.Print("==LAYERS==");
			foreach (PrototypeRoomObjectLayer additionalObjectLayer in room.additionalObjectLayers)
			{
			}
		}
	}
	public static class DungeonHooks
	{
		private static GameManager targetInstance;

		public static FieldInfo m_assignedFlow = typeof(LoopDungeonGenerator).GetField("m_assignedFlow", BindingFlags.Instance | BindingFlags.NonPublic);

		private static Hook preDungeonGenHook = new Hook((MethodBase)typeof(LoopDungeonGenerator).GetConstructor(new Type[2]
		{
			typeof(Dungeon),
			typeof(int)
		}), typeof(DungeonHooks).GetMethod("LoopGenConstructor"));

		private static Hook foyerAwakeHook = new Hook((MethodBase)typeof(MainMenuFoyerController).GetMethod("Awake", BindingFlags.Instance | BindingFlags.NonPublic), typeof(DungeonHooks).GetMethod("FoyerAwake"));

		public static event Action<LoopDungeonGenerator, Dungeon, DungeonFlow, int> OnPreDungeonGeneration;

		public static event Action OnPostDungeonGeneration;

		public static event Action OnFoyerAwake;

		public static void FoyerAwake(Action<MainMenuFoyerController> orig, MainMenuFoyerController self)
		{
			orig(self);
			DungeonHooks.OnFoyerAwake?.Invoke();
		}

		public static void LoopGenConstructor(Action<LoopDungeonGenerator, Dungeon, int> orig, LoopDungeonGenerator self, Dungeon dungeon, int dungeonSeed)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			Tools.Print("-Loop Gen Called-", "5599FF");
			orig(self, dungeon, dungeonSeed);
			if ((Object)(object)GameManager.Instance != (Object)null && (Object)(object)GameManager.Instance != (Object)(object)targetInstance)
			{
				targetInstance = GameManager.Instance;
				targetInstance.OnNewLevelFullyLoaded += OnLevelLoad;
			}
			DungeonFlow arg = (DungeonFlow)m_assignedFlow.GetValue(self);
			DungeonHooks.OnPreDungeonGeneration?.Invoke(self, dungeon, arg, dungeonSeed);
			dungeon = null;
		}

		public static void OnLevelLoad()
		{
			Tools.Print("-Post Gen Called-", "5599FF");
			DungeonHooks.OnPostDungeonGeneration?.Invoke();
		}
	}
	public class FakePrefab : Component
	{
		internal static HashSet<GameObject> ExistingFakePrefabs = new HashSet<GameObject>();

		public static bool IsFakePrefab(Object o)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (o is GameObject)
			{
				return ExistingFakePrefabs.Contains((GameObject)o);
			}
			if (o is Component)
			{
				return ExistingFakePrefabs.Contains(((Component)o).gameObject);
			}
			return false;
		}

		public static void MarkAsFakePrefab(GameObject obj)
		{
			ExistingFakePrefabs.Add(obj);
			Object.DontDestroyOnLoad((Object)(object)obj);
		}

		public static GameObject Clone(GameObject obj)
		{
			bool flag = IsFakePrefab((Object)(object)obj);
			bool activeSelf = obj.activeSelf;
			if (activeSelf)
			{
				obj.SetActive(false);
			}
			GameObject val = Object.Instantiate<GameObject>(obj);
			if (activeSelf)
			{
				obj.SetActive(true);
			}
			Object.DontDestroyOnLoad((Object)(object)val);
			ExistingFakePrefabs.Add(val);
			return val;
		}

		public static Object Instantiate(Object o, Object new_o)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (o is GameObject && ExistingFakePrefabs.Contains((GameObject)o))
			{
				((GameObject)new_o).SetActive(true);
			}
			else if (o is Component && ExistingFakePrefabs.Contains(((Component)o).gameObject))
			{
				((Component)new_o).gameObject.SetActive(true);
			}
			return new_o;
		}
	}
	public static class FakePrefabHooks
	{
		public delegate TResult Func<T1, T2, T3, T4, T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);

		public static void Init()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			try
			{
				Hook val = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[3]
				{
					typeof(Object),
					typeof(Transform),
					typeof(bool)
				}), typeof(FakePrefabHooks).GetMethod("InstantiateOPI"));
				Hook val2 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[2]
				{
					typeof(Object),
					typeof(Transform)
				}), typeof(FakePrefabHooks).GetMethod("InstantiateOP"));
				Hook val3 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[1] { typeof(Object) }), typeof(FakePrefabHooks).GetMethod("InstantiateO"));
				Hook val4 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[3]
				{
					typeof(Object),
					typeof(Vector3),
					typeof(Quaternion)
				}), typeof(FakePrefabHooks).GetMethod("InstantiateOPR"));
				Hook val5 = new Hook((MethodBase)typeof(Object).GetMethod("Instantiate", new Type[4]
				{
					typeof(Object),
					typeof(Vector3),
					typeof(Quaternion),
					typeof(Transform)
				}), typeof(FakePrefabHooks).GetMethod("InstantiateOPRP"));
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
		}

		public static T InstantiateGeneric<T>(Object original) where T : Object
		{
			return (T)(object)FakePrefab.Instantiate(original, Object.Instantiate(original));
		}

		public static Object InstantiateOPI(Func<Object, Transform, bool, Object> orig, Object original, Transform parent, bool instantiateInWorldSpace)
		{
			return FakePrefab.Instantiate(original, orig(original, parent, instantiateInWorldSpace));
		}

		public static Object InstantiateOP(Func<Object, Transform, Object> orig, Object original, Transform parent)
		{
			return FakePrefab.Instantiate(original, orig(original, parent));
		}

		public static Object InstantiateO(Func<Object, Object> orig, Object original)
		{
			return FakePrefab.Instantiate(original, orig(original));
		}

		public static Object InstantiateOPR(Func<Object, Vector3, Quaternion, Object> orig, Object original, Vector3 position, Quaternion rotation)
		{
			//IL_0004: 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)
			return FakePrefab.Instantiate(original, orig(original, position, rotation));
		}

		public static Object InstantiateOPRP(Func<Object, Vector3, Quaternion, Transform, Object> orig, Object original, Vector3 position, Quaternion rotation, Transform parent)
		{
			//IL_0004: 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)
			return FakePrefab.Instantiate(original, orig(original, position, rotation, parent));
		}
	}
	public static class ResourceExtractor
	{
		private static string spritesDirectory = Path.Combine(ETGMod.ResourcesDirectory, "sprites");

		public static List<Texture2D> GetTexturesFromDirectory(string directoryPath)
		{
			if (!Directory.Exists(directoryPath))
			{
				Tools.PrintError(directoryPath + " not found.");
				return null;
			}
			List<Texture2D> list = new List<Texture2D>();
			string[] files = Directory.GetFiles(directoryPath);
			foreach (string text in files)
			{
				if (text.EndsWith(".png"))
				{
					Texture2D item = BytesToTexture(File.ReadAllBytes(text), Path.GetFileName(text).Replace(".png", ""));
					list.Add(item);
				}
			}
			return list;
		}

		public static Texture2D GetTextureFromFile(string fileName, string extension = ".png")
		{
			fileName = fileName.Replace(extension, "");
			string text = Path.Combine(spritesDirectory, fileName + extension);
			if (!File.Exists(text))
			{
				Tools.PrintError(text + " not found.");
				return null;
			}
			return BytesToTexture(File.ReadAllBytes(text), fileName);
		}

		public static List<string> GetCollectionFiles()
		{
			List<string> list = new List<string>();
			string[] files = Directory.GetFiles(spritesDirectory);
			foreach (string text in files)
			{
				if (text.EndsWith(".png"))
				{
					list.Add(Path.GetFileName(text).Replace(".png", ""));
				}
			}
			return list;
		}

		public static Texture2D BytesToTexture(byte[] bytes, string resourceName)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, bytes);
			((Texture)val).filterMode = (FilterMode)0;
			((Object)val).name = resourceName;
			return val;
		}

		public static string[] GetLinesFromEmbeddedResource(string filePath)
		{
			string text = BytesToString(ExtractEmbeddedResource(filePath));
			return text.Split(new char[1] { '\n' });
		}

		public static string[] GetLinesFromFile(string filePath)
		{
			string text = BytesToString(File.ReadAllBytes(filePath));
			return text.Split(new char[1] { '\n' });
		}

		public static string BytesToString(byte[] bytes)
		{
			return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
		}

		public static List<string> GetResourceFolders()
		{
			List<string> list = new List<string>();
			string path = Path.Combine(ETGMod.ResourcesDirectory, "sprites");
			if (Directory.Exists(path))
			{
				string[] directories = Directory.GetDirectories(path);
				foreach (string path2 in directories)
				{
					list.Add(Path.GetFileName(path2));
				}
			}
			return list;
		}

		public static byte[] ExtractEmbeddedResource(string filePath)
		{
			filePath = filePath.Replace("/", ".");
			filePath = filePath.Replace("\\", ".");
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			using Stream stream = callingAssembly.GetManifestResourceStream(filePath);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			return array;
		}

		public static Texture2D GetTextureFromResource(string resourceName)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			byte[] array = ExtractEmbeddedResource(resourceName);
			if (array == null)
			{
				Tools.PrintError("No bytes found in " + resourceName);
				return null;
			}
			Texture2D val = new Texture2D(1, 1, (TextureFormat)20, false);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = (FilterMode)0;
			string text = resourceName.Substring(0, resourceName.LastIndexOf('.'));
			if (text.LastIndexOf('.') >= 0)
			{
				text = text.Substring(text.LastIndexOf('.') + 1);
			}
			((Object)val).name = text;
			return val;
		}

		public static string[] GetResourceNames()
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string[] manifestResourceNames = callingAssembly.GetManifestResourceNames();
			if (manifestResourceNames == null)
			{
				ETGModConsole.Log((object)"No manifest resources found.", false);
				return null;
			}
			return manifestResourceNames;
		}
	}
	public static class RoomFactory
	{
		public struct RoomData
		{
			public string category;

			public string normalSubCategory;

			public string specialSubCatergory;

			public string bossSubCategory;

			public Vector2[] enemyPositions;

			public string[] enemyGUIDs;

			public Vector2[] placeablePositions;

			public string[] placeableGUIDs;

			public int[] enemyReinforcementLayers;

			public Vector2[] exitPositions;

			public string[] exitDirections;

			public string[] floors;

			public float weight;

			public bool isSpecialRoom;

			[NonSerialized]
			public PrototypeDungeonRoom room;
		}

		public static Dictionary<string, RoomData> rooms = new Dictionary<string, RoomData>();

		public static AssetBundle[] assetBundles = (AssetBundle[])(object)new AssetBundle[2]
		{
			ResourceManager.LoadAssetBundle("shared_auto_001"),
			ResourceManager.LoadAssetBundle("shared_auto_002")
		};

		private static readonly string dataHeader = "***DATA***";

		private static FieldInfo m_cellData = typeof(PrototypeDungeonRoom).GetField("m_cellData", BindingFlags.Instance | BindingFlags.NonPublic);

		private static RoomEventDefinition sealOnEnterWithEnemies = new RoomEventDefinition((RoomEventTriggerCondition)3, (RoomEventTriggerAction)0);

		private static RoomEventDefinition unsealOnRoomClear = new RoomEventDefinition((RoomEventTriggerCondition)2, (RoomEventTriggerAction)1);

		public static RoomData BuildFromFile(string roomPath)
		{
			Texture2D textureFromFile = ResourceExtractor.GetTextureFromFile(roomPath, ".room");
			((Object)textureFromFile).name = Path.GetFileName(roomPath);
			RoomData roomData = ExtractRoomDataFromFile(roomPath);
			roomData.room = Build(textureFromFile, roomData);
			return roomData;
		}

		public static RoomData BuildFromResource(string roomPath)
		{
			Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(roomPath);
			RoomData roomData = ExtractRoomDataFromResource(roomPath);
			roomData.room = Build(textureFromResource, roomData);
			return roomData;
		}

		public static PrototypeDungeonRoom Build(Texture2D texture, RoomData roomData)
		{
			try
			{
				PrototypeDungeonRoom val = CreateRoomFromTexture(texture);
				ApplyRoomData(val, roomData);
				val.UpdatePrecalculatedData();
				return val;
			}
			catch (Exception e)
			{
				Tools.PrintError("Failed to build room!");
				Tools.PrintException(e);
			}
			return CreateEmptyRoom();
		}

		public static void ApplyRoomData(PrototypeDungeonRoom room, RoomData roomData)
		{
			//IL_0073: 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_00ab: 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_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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: 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)
			if (roomData.exitPositions != null)
			{
				for (int i = 0; i < roomData.exitPositions.Length; i++)
				{
					Direction direction = (Direction)Enum.Parse(typeof(Direction), roomData.exitDirections[i].ToUpper());
					AddExit(room, roomData.exitPositions[i], direction);
				}
			}
			else
			{
				AddExit(room, new Vector2((float)(room.Width / 2), (float)room.Height), (Direction)0);
				AddExit(room, new Vector2((float)(room.Width / 2), 0f), (Direction)4);
				AddExit(room, new Vector2((float)room.Width, (float)(room.Height / 2)), (Direction)2);
				AddExit(room, new Vector2(0f, (float)(room.Height / 2)), (Direction)6);
			}
			if (roomData.enemyPositions != null)
			{
				for (int j = 0; j < roomData.enemyPositions.Length; j++)
				{
					AddEnemyToRoom(room, roomData.enemyPositions[j], roomData.enemyGUIDs[j], roomData.enemyReinforcementLayers[j]);
				}
			}
			if (roomData.placeablePositions != null)
			{
				for (int k = 0; k < roomData.placeablePositions.Length; k++)
				{
					AddPlaceableToRoom(room, roomData.placeablePositions[k], roomData.placeableGUIDs[k]);
				}
			}
			if (roomData.floors != null)
			{
				string[] floors = roomData.floors;
				foreach (string val in floors)
				{
					room.prerequisites.Add(new DungeonPrerequisite
					{
						prerequisiteType = (PrerequisiteType)3,
						requiredTileset = Tools.GetEnumValue<ValidTilesets>(val)
					});
				}
			}
			if (!string.IsNullOrEmpty(roomData.category))
			{
				room.category = Tools.GetEnumValue<RoomCategory>(roomData.category);
			}
			if (!string.IsNullOrEmpty(roomData.normalSubCategory))
			{
				room.subCategoryNormal = Tools.GetEnumValue<RoomNormalSubCategory>(roomData.normalSubCategory);
			}
			if (!string.IsNullOrEmpty(roomData.bossSubCategory))
			{
				room.subCategoryBoss = Tools.GetEnumValue<RoomBossSubCategory>(roomData.bossSubCategory);
			}
			if (!string.IsNullOrEmpty(roomData.specialSubCatergory))
			{
				room.subCategorySpecial = Tools.GetEnumValue<RoomSpecialSubCategory>(roomData.specialSubCatergory);
			}
		}

		public static RoomData ExtractRoomDataFromFile(string path)
		{
			string data = ResourceExtractor.BytesToString(File.ReadAllBytes(path));
			return ExtractRoomData(data);
		}

		public static RoomData ExtractRoomDataFromResource(string path)
		{
			string data = ResourceExtractor.BytesToString(ResourceExtractor.ExtractEmbeddedResource(path));
			return ExtractRoomData(data);
		}

		public static RoomData ExtractRoomData(string data)
		{
			if (data.Contains(dataHeader))
			{
				string text = data.Substring(data.IndexOf(dataHeader) + dataHeader.Length);
				return JsonUtility.FromJson<RoomData>(text);
			}
			return default(RoomData);
		}

		public static PrototypeDungeonRoom CreateRoomFromTexture(Texture2D texture)
		{
			//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)
			int width = ((Texture)texture).width;
			int height = ((Texture)texture).height;
			PrototypeDungeonRoom newPrototypeDungeonRoom = GetNewPrototypeDungeonRoom(width, height);
			PrototypeDungeonRoomCellData[] array = m_cellData.GetValue(newPrototypeDungeonRoom) as PrototypeDungeonRoomCellData[];
			array = (PrototypeDungeonRoomCellData[])(object)new PrototypeDungeonRoomCellData[width * height];
			for (int i = 0; i < width; i++)
			{
				for (int j = 0; j < height; j++)
				{
					array[i + j * width] = CellDataFromColor(Color32.op_Implicit(texture.GetPixel(i, j)));
				}
			}
			m_cellData.SetValue(newPrototypeDungeonRoom, array);
			((Object)newPrototypeDungeonRoom).name = ((Object)texture).name;
			return newPrototypeDungeonRoom;
		}

		public static PrototypeDungeonRoomCellData CellDataFromColor(Color32 color)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_005a: Expected O, but got Unknown
			if (((object)(Color32)(ref color)).Equals((object?)Color.magenta))
			{
				return null;
			}
			PrototypeDungeonRoomCellData val = new PrototypeDungeonRoomCellData();
			val.state = TypeFromColor(Color32.op_Implicit(color));
			val.diagonalWallType = DiagonalWallTypeFromColor(Color32.op_Implicit(color));
			val.appearance = new PrototypeDungeonRoomCellAppearance
			{
				OverrideFloorType = (CellFloorType)0
			};
			return val;
		}

		public static CellType TypeFromColor(Color color)
		{
			//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_0014: 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_0011: 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_0024: 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)
			if (color == Color.black)
			{
				return (CellType)4;
			}
			if (color == Color.white)
			{
				return (CellType)2;
			}
			return (CellType)1;
		}

		public static DiagonalWallType DiagonalWallTypeFromColor(Color color)
		{
			//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_0014: 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_0011: 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_0024: 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_003a: 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_0037: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (color == Color.red)
			{
				return (DiagonalWallType)1;
			}
			if (color == Color.green)
			{
				return (DiagonalWallType)2;
			}
			if (color == Color.blue)
			{
				return (DiagonalWallType)3;
			}
			if (color == Color.yellow)
			{
				return (DiagonalWallType)4;
			}
			return (DiagonalWallType)0;
		}

		public static RoomData CreateEmptyRoomData(int width = 12, int height = 12)
		{
			RoomData result = default(RoomData);
			result.room = CreateEmptyRoom(width, height);
			result.category = "NORMAL";
			result.weight = DungeonHandler.GlobalRoomWeight;
			return result;
		}

		public static PrototypeDungeonRoom CreateEmptyRoom(int width = 12, int height = 12)
		{
			//IL_0011: 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_003a: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00a5: Expected O, but got Unknown
			try
			{
				PrototypeDungeonRoom newPrototypeDungeonRoom = GetNewPrototypeDungeonRoom(width, height);
				AddExit(newPrototypeDungeonRoom, new Vector2((float)(width / 2), (float)height), (Direction)0);
				AddExit(newPrototypeDungeonRoom, new Vector2((float)(width / 2), 0f), (Direction)4);
				AddExit(newPrototypeDungeonRoom, new Vector2((float)width, (float)(height / 2)), (Direction)2);
				AddExit(newPrototypeDungeonRoom, new Vector2(0f, (float)(height / 2)), (Direction)6);
				PrototypeDungeonRoomCellData[] array = m_cellData.GetValue(newPrototypeDungeonRoom) as PrototypeDungeonRoomCellData[];
				array = (PrototypeDungeonRoomCellData[])(object)new PrototypeDungeonRoomCellData[width * height];
				for (int i = 0; i < width; i++)
				{
					for (int j = 0; j < height; j++)
					{
						array[i + j * width] = new PrototypeDungeonRoomCellData
						{
							state = (CellType)2,
							appearance = new PrototypeDungeonRoomCellAppearance
							{
								OverrideFloorType = (CellFloorType)0
							}
						};
					}
				}
				m_cellData.SetValue(newPrototypeDungeonRoom, array);
				newPrototypeDungeonRoom.UpdatePrecalculatedData();
				return newPrototypeDungeonRoom;
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
				return null;
			}
		}

		public static int GetStyleValue(string dungeonName, string shrineID)
		{
			if (ShrineFactory.registeredShrines != null && ShrineFactory.registeredShrines.ContainsKey(shrineID))
			{
				GameObject obj = ShrineFactory.registeredShrines[shrineID];
				ShrineFactory.CustomShrineController customShrineController = ((obj != null) ? obj.GetComponent<ShrineFactory.CustomShrineController>() : null);
				if ((Object)(object)customShrineController != (Object)null && customShrineController.roomStyles != null && customShrineController.roomStyles.ContainsKey(dungeonName))
				{
					return customShrineController.roomStyles[dungeonName];
				}
			}
			return -1;
		}

		public static void AddPlaceableToRoom(PrototypeDungeonRoom room, Vector2 location, string assetPath)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0038: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			try
			{
				GameObject placeableFromBundles = GetPlaceableFromBundles(assetPath);
				if (Object.op_Implicit((Object)(object)placeableFromBundles))
				{
					DungeonPrerequisite[] array = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0];
					room.placedObjectPositions.Add(location);
					List<PrototypePlacedObjectData> placedObjects = room.placedObjects;
					PrototypePlacedObjectData val = new PrototypePlacedObjectData();
					val.contentsBasePosition = location;
					val.fieldData = new List<PrototypePlacedObjectFieldData>();
					val.instancePrerequisites = array;
					val.linkedTriggerAreaIDs = new List<int>();
					DungeonPlaceable val2 = new DungeonPlaceable();
					val2.width = 2;
					val2.height = 2;
					val2.respectsEncounterableDifferentiator = true;
					List<DungeonPlaceableVariant> list = new List<DungeonPlaceableVariant>();
					DungeonPlaceableVariant val3 = new DungeonPlaceableVariant();
					val3.percentChance = 1f;
					val3.nonDatabasePlaceable = placeableFromBundles;
					val3.prerequisites = array;
					val3.materialRequirements = (DungeonPlaceableRoomMaterialRequirement[])(object)new DungeonPlaceableRoomMaterialRequirement[0];
					list.Add(val3);
					val2.variantTiers = list;
					val.placeableContents = val2;
					placedObjects.Add(val);
				}
				else
				{
					Tools.PrintError("Unable to find asset in asset bundles: " + assetPath);
				}
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
		}

		public static GameObject GetPlaceableFromBundles(string assetPath)
		{
			GameObject val = null;
			AssetBundle[] array = assetBundles;
			foreach (AssetBundle val2 in array)
			{
				Object obj = val2.LoadAsset(assetPath);
				val = (GameObject)(object)((obj is GameObject) ? obj : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					break;
				}
			}
			return val;
		}

		public static void AddEnemyToRoom(PrototypeDungeonRoom room, Vector2 location, string guid, int layer)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00c6: 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)
			DungeonPrerequisite[] array = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0];
			DungeonPlaceable val = ScriptableObject.CreateInstance<DungeonPlaceable>();
			val.width = 1;
			val.height = 1;
			val.respectsEncounterableDifferentiator = true;
			List<DungeonPlaceableVariant> list = new List<DungeonPlaceableVariant>();
			DungeonPlaceableVariant val2 = new DungeonPlaceableVariant();
			val2.percentChance = 1f;
			val2.prerequisites = array;
			val2.enemyPlaceableGuid = guid;
			val2.materialRequirements = (DungeonPlaceableRoomMaterialRequirement[])(object)new DungeonPlaceableRoomMaterialRequirement[0];
			list.Add(val2);
			val.variantTiers = list;
			PrototypePlacedObjectData val3 = new PrototypePlacedObjectData
			{
				contentsBasePosition = location,
				fieldData = new List<PrototypePlacedObjectFieldData>(),
				instancePrerequisites = array,
				linkedTriggerAreaIDs = new List<int>(),
				placeableContents = val
			};
			if (layer > 0)
			{
				AddObjectDataToReinforcementLayer(room, val3, layer - 1, location);
			}
			else
			{
				room.placedObjects.Add(val3);
				room.placedObjectPositions.Add(location);
			}
			if (!room.roomEvents.Contains(sealOnEnterWithEnemies))
			{
				room.roomEvents.Add(sealOnEnterWithEnemies);
			}
			if (!room.roomEvents.Contains(unsealOnRoomClear))
			{
				room.roomEvents.Add(unsealOnRoomClear);
			}
		}

		public static void AddObjectDataToReinforcementLayer(PrototypeDungeonRoom room, PrototypePlacedObjectData objectData, int layer, Vector2 location)
		{
			//IL_0090: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if (room.additionalObjectLayers.Count <= layer)
			{
				for (int i = room.additionalObjectLayers.Count; i <= layer; i++)
				{
					PrototypeRoomObjectLayer item = new PrototypeRoomObjectLayer
					{
						layerIsReinforcementLayer = true,
						placedObjects = new List<PrototypePlacedObjectData>(),
						placedObjectBasePositions = new List<Vector2>()
					};
					room.additionalObjectLayers.Add(item);
				}
			}
			room.additionalObjectLayers[layer].placedObjects.Add(objectData);
			room.additionalObjectLayers[layer].placedObjectBasePositions.Add(location);
		}

		public static void AddExit(PrototypeDungeonRoom room, Vector2 location, Direction direction)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//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_0043: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0072: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (room.exitData == null)
			{
				room.exitData = new PrototypeRoomExitData();
			}
			if (room.exitData.exits == null)
			{
				room.exitData.exits = new List<PrototypeRoomExit>();
			}
			PrototypeRoomExit val = new PrototypeRoomExit(direction, location);
			val.exitType = (ExitType)0;
			Vector2 val2 = (((int)direction == 2 || (int)direction == 6) ? new Vector2(0f, 1f) : new Vector2(1f, 0f));
			val.containedCells.Add(location + val2);
			room.exitData.exits.Add(val);
		}

		public static PrototypeDungeonRoom GetNewPrototypeDungeonRoom(int width = 12, int height = 12)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			PrototypeDungeonRoom val = ScriptableObject.CreateInstance<PrototypeDungeonRoom>();
			val.injectionFlags = new RuntimeInjectionFlags();
			val.RoomId = Random.Range(10000, 1000000);
			val.pits = new List<PrototypeRoomPitEntry>();
			val.placedObjects = new List<PrototypePlacedObjectData>();
			val.placedObjectPositions = new List<Vector2>();
			val.additionalObjectLayers = new List<PrototypeRoomObjectLayer>();
			val.eventTriggerAreas = new List<PrototypeEventTriggerArea>();
			val.roomEvents = new List<RoomEventDefinition>();
			val.paths = new List<SerializedPath>();
			val.prerequisites = new List<DungeonPrerequisite>();
			val.excludedOtherRooms = new List<PrototypeDungeonRoom>();
			val.rectangularFeatures = new List<PrototypeRectangularFeature>();
			val.exitData = new PrototypeRoomExitData();
			val.exitData.exits = new List<PrototypeRoomExit>();
			val.allowWallDecoration = false;
			val.allowFloorDecoration = false;
			val.Width = width;
			val.Height = height;
			return val;
		}

		public static void LogExampleRoomData()
		{
			//IL_0013: 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_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_003f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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)
			Vector2[] enemyPositions = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(4f, 4f),
				new Vector2(4f, 14f),
				new Vector2(14f, 4f),
				new Vector2(14f, 14f)
			};
			string[] enemyGUIDs = new string[4] { "01972dee89fc4404a5c408d50007dad5", "7b0b1b6d9ce7405b86b75ce648025dd6", "ffdc8680bdaa487f8f31995539f74265", "01972dee89fc4404a5c408d50007dad5" };
			Vector2[] exitPositions = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 9f),
				new Vector2(9f, 0f),
				new Vector2(20f, 9f),
				new Vector2(9f, 20f)
			};
			string[] exitDirections = new string[4] { "EAST", "SOUTH", "WEST", "NORTH" };
			RoomData roomData = default(RoomData);
			roomData.enemyPositions = enemyPositions;
			roomData.enemyGUIDs = enemyGUIDs;
			roomData.exitPositions = exitPositions;
			roomData.exitDirections = exitDirections;
			RoomData roomData2 = roomData;
			Tools.Print("Data to JSON: " + JsonUtility.ToJson((object)roomData2));
		}

		public static void StraightLine()
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector2[] array = (Vector2[])(object)new Vector2[100];
				string[] array2 = new string[100];
				int[] array3 = new int[100];
				for (int i = 0; i < array2.Length; i++)
				{
					List<EnemyDatabaseEntry> entries = ((AssetBundleDatabase<AIActor, EnemyDatabaseEntry>)(object)EnemyDatabase.Instance).Entries;
					int index = Random.Range(0, entries.Count);
					array2[i] = entries[index].encounterGuid;
					array[i] = new Vector2((float)(i * 2), 10f);
					array3[i] = 0;
				}
				Vector2[] exitPositions = (Vector2[])(object)new Vector2[2]
				{
					new Vector2(0f, 9f),
					new Vector2(200f, 9f)
				};
				string[] exitDirections = new string[2] { "WEST", "EAST" };
				RoomData roomData = default(RoomData);
				roomData.enemyPositions = array;
				roomData.enemyGUIDs = array2;
				roomData.enemyReinforcementLayers = array3;
				roomData.exitPositions = exitPositions;
				roomData.exitDirections = exitDirections;
				RoomData roomData2 = roomData;
				Tools.Log("Data to JSON: " + JsonUtility.ToJson((object)roomData2));
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
		}
	}
	public static class NPCBuilder
	{
		public enum AnimationType
		{
			Move,
			Idle,
			Fidget,
			Flight,
			Hit,
			Talk,
			Other
		}

		public static tk2dSpriteAnimationClip AddAnimation(this GameObject obj, string name, string spriteDirectory, int fps, AnimationType type, DirectionType directionType = 0, FlipType flipType = 0)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected I4, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			obj.AddComponent<tk2dSpriteAnimator>();
			AIAnimator val = obj.GetComponent<AIAnimator>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = CreateNewAIAnimator(obj);
			}
			DirectionalAnimation val2 = val.GetDirectionalAnimation(name, directionType, type);
			if (val2 == null)
			{
				DirectionalAnimation val3 = new DirectionalAnimation();
				val3.AnimNames = new string[0];
				val3.Flipped = (FlipType[])(object)new FlipType[0];
				val3.Type = directionType;
				val3.Prefix = string.Empty;
				val2 = val3;
			}
			val2.AnimNames = val2.AnimNames.Concat(new string[1] { name }).ToArray();
			val2.Flipped = val2.Flipped.Concat((IEnumerable<FlipType>)(object)new FlipType[1] { (FlipType)(int)flipType }).ToArray();
			val.AssignDirectionalAnimation(name, val2, type);
			return BuildAnimation(val, name, spriteDirectory, fps);
		}

		private static AIAnimator CreateNewAIAnimator(GameObject obj)
		{
			AIAnimator val = obj.AddComponent<AIAnimator>();
			val.FlightAnimation = CreateNewDirectionalAnimation();
			val.HitAnimation = CreateNewDirectionalAnimation();
			val.IdleAnimation = CreateNewDirectionalAnimation();
			val.TalkAnimation = CreateNewDirectionalAnimation();
			val.MoveAnimation = CreateNewDirectionalAnimation();
			val.OtherAnimations = new List<NamedDirectionalAnimation>();
			val.IdleFidgetAnimations = new List<DirectionalAnimation>();
			val.OtherVFX = new List<NamedVFXPool>();
			return val;
		}

		private static DirectionalAnimation CreateNewDirectionalAnimation()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			DirectionalAnimation val = new DirectionalAnimation();
			val.AnimNames = new string[0];
			val.Flipped = (FlipType[])(object)new FlipType[0];
			val.Type = (DirectionType)0;
			return val;
		}

		public static tk2dSpriteAnimationClip BuildAnimation(AIAnimator aiAnimator, string name, string spriteDirectory, int fps)
		{
			tk2dSpriteCollectionData val = ((Component)aiAnimator).GetComponent<tk2dSpriteCollectionData>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = SpriteBuilder.ConstructCollection(((Component)aiAnimator).gameObject, ((Object)aiAnimator).name + "_collection");
			}
			string[] resourceNames = ResourceExtractor.GetResourceNames();
			List<int> list = new List<int>();
			for (int i = 0; i < resourceNames.Length; i++)
			{
				if (resourceNames[i].StartsWith(spriteDirectory.Replace('/', '.'), StringComparison.OrdinalIgnoreCase))
				{
					list.Add(SpriteBuilder.AddSpriteToCollection(resourceNames[i], val));
				}
			}
			if (list.Count == 0)
			{
				Tools.PrintError("No sprites found for animation " + name);
			}
			tk2dSpriteAnimationClip val2 = SpriteBuilder.AddAnimation(((BraveBehaviour)aiAnimator).spriteAnimator, val, list, name, (WrapMode)0);
			val2.fps = fps;
			return val2;
		}

		public static DirectionalAnimation GetDirectionalAnimation(this AIAnimator aiAnimator, string name, DirectionType directionType, AnimationType type)
		{
			DirectionalAnimation val = null;
			switch (type)
			{
			case AnimationType.Idle:
				val = aiAnimator.IdleAnimation;
				break;
			case AnimationType.Move:
				val = aiAnimator.MoveAnimation;
				break;
			case AnimationType.Flight:
				val = aiAnimator.FlightAnimation;
				break;
			case AnimationType.Hit:
				val = aiAnimator.HitAnimation;
				break;
			case AnimationType.Talk:
				val = aiAnimator.TalkAnimation;
				break;
			}
			if (val != null)
			{
				return val;
			}
			return null;
		}

		public static void AssignDirectionalAnimation(this AIAnimator aiAnimator, string name, DirectionalAnimation animation, AnimationType type)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			switch (type)
			{
			case AnimationType.Idle:
				aiAnimator.IdleAnimation = animation;
				return;
			case AnimationType.Move:
				aiAnimator.MoveAnimation = animation;
				return;
			case AnimationType.Flight:
				aiAnimator.FlightAnimation = animation;
				return;
			case AnimationType.Hit:
				aiAnimator.HitAnimation = animation;
				return;
			case AnimationType.Talk:
				aiAnimator.TalkAnimation = animation;
				return;
			case AnimationType.Fidget:
				aiAnimator.IdleFidgetAnimations.Add(animation);
				return;
			}
			aiAnimator.OtherAnimations.Add(new NamedDirectionalAnimation
			{
				anim = animation,
				name = name
			});
		}
	}
	public class ShrineFactory
	{
		public class CustomShrineController : DungeonPlaceableBehaviour
		{
			public string ID;

			public bool isBreachShrine;

			public Vector3 offset;

			public List<PixelCollider> pixelColliders;

			public Dictionary<string, int> roomStyles;

			public ShrineFactory factory;

			public Action<PlayerController, GameObject> OnAccept;

			public Action<PlayerController, GameObject> OnDecline;

			public Func<PlayerController, GameObject, bool> CanUse;

			private RoomHandler m_parentRoom;

			private GameObject m_instanceMinimapIcon;

			public int numUses = 0;

			public string text;

			public string acceptText;

			public string declineText;

			private void Start()
			{
				string text = ((Object)this).name.Replace("(Clone)", "");
				if (registeredShrines.ContainsKey(text))
				{
					Copy(registeredShrines[text].GetComponent<CustomShrineController>());
				}
				else
				{
					Tools.PrintError("Was this shrine registered correctly?: " + text);
				}
				SimpleInteractable component = ((Component)this).GetComponent<SimpleInteractable>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.OnAccept = OnAccept;
					component.OnDecline = OnDecline;
					component.CanUse = CanUse;
					component.text = this.text;
					component.acceptText = acceptText;
					component.declineText = declineText;
					Tools.Print("Started shrine: " + text);
				}
			}

			public void Copy(CustomShrineController other)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				ID = other.ID;
				roomStyles = other.roomStyles;
				isBreachShrine = other.isBreachShrine;
				offset = other.offset;
				pixelColliders = other.pixelColliders;
				factory = other.factory;
				OnAccept = other.OnAccept;
				OnDecline = other.OnDecline;
				CanUse = other.CanUse;
				text = other.text;
				acceptText = other.acceptText;
				declineText = other.declineText;
			}

			public void ConfigureOnPlacement(RoomHandler room)
			{
				m_parentRoom = room;
				RegisterMinimapIcon();
			}

			public void RegisterMinimapIcon()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				m_instanceMinimapIcon = Minimap.Instance.RegisterRoomIcon(m_parentRoom, (GameObject)BraveResources.Load("Global Prefabs/Minimap_Shrine_Icon", ".prefab"), false);
			}

			public void GetRidOfMinimapIcon()
			{
				if ((Object)(object)m_instanceMinimapIcon != (Object)null)
				{
					Minimap.Instance.DeregisterRoomIcon(m_parentRoom, m_instanceMinimapIcon);
					m_instanceMinimapIcon = null;
				}
			}
		}

		public string name;

		public string modID;

		public string spritePath;

		public string shadowSpritePath;

		public string text;

		public string acceptText;

		public string declineText;

		public Action<PlayerController, GameObject> OnAccept;

		public Action<PlayerController, GameObject> OnDecline;

		public Func<PlayerController, GameObject, bool> CanUse;

		public Vector3 talkPointOffset;

		public Vector3 offset = new Vector3(43.8f, 42.4f, 42.9f);

		public IntVector2 colliderOffset;

		public IntVector2 colliderSize;

		public bool isToggle;

		public bool usesCustomColliderOffsetAndSize;

		public Type interactableComponent = null;

		public bool isBreachShrine = false;

		public PrototypeDungeonRoom room;

		public Dictionary<string, int> roomStyles;

		public static Dictionary<string, GameObject> registeredShrines = new Dictionary<string, GameObject>();

		private static bool m_initialized;

		public static void Init()
		{
			if (m_initialized)
			{
				return;
			}
			DungeonHooks.OnFoyerAwake += PlaceBreachShrines;
			DungeonHooks.OnPreDungeonGeneration += delegate(LoopDungeonGenerator generator, Dungeon dungeon, DungeonFlow flow, int dungeonSeed)
			{
				if (((Object)flow).name != "Foyer Flow" && !GameManager.IsReturningToFoyerWithPlayer)
				{
					CleanupBreachShrines();
				}
			};
			m_initialized = true;
		}

		public GameObject Build()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D textureFromResource = ResourceExtractor.GetTextureFromResource(spritePath);
				GameObject val = SpriteBuilder.SpriteFromResource(spritePath, null, copyFromExisting: false);
				string text2 = (((Object)val).name = (modID + ":" + name).ToLower().Replace(" ", "_"));
				tk2dSprite component = val.GetComponent<tk2dSprite>();
				((tk2dBaseSprite)component).IsPerpendicular = true;
				((tk2dBaseSprite)component).PlaceAtPositionByAnchor(offset, (Anchor)1);
				Transform transform = new GameObject("talkpoint").transform;
				transform.position = val.transform.position + talkPointOffset;
				transform.SetParent(val.transform);
				if (!usesCustomColliderOffsetAndSize)
				{
					IntVector2 val2 = default(IntVector2);
					((IntVector2)(ref val2))..ctor(((Texture)textureFromResource).width, ((Texture)textureFromResource).height);
					colliderOffset = new IntVector2(0, 0);
					colliderSize = new IntVector2(val2.x, val2.y / 2);
				}
				SpeculativeRigidbody val3 = component.SetUpSpeculativeRigidbody(colliderOffset, colliderSize);
				CustomShrineController customShrineController = val.AddComponent<CustomShrineController>();
				customShrineController.ID = text2;
				customShrineController.roomStyles = roomStyles;
				customShrineController.isBreachShrine = true;
				customShrineController.offset = offset;
				customShrineController.pixelColliders = ((BraveBehaviour)val3).specRigidbody.PixelColliders;
				customShrineController.factory = this;
				customShrineController.OnAccept = OnAccept;
				customShrineController.OnDecline = OnDecline;
				customShrineController.CanUse = CanUse;
				customShrineController.text = this.text;
				customShrineController.acceptText = acceptText;
				customShrineController.declineText = declineText;
				if ((object)interactableComponent == null)
				{
					SimpleShrine simpleShrine = val.AddComponent<SimpleShrine>();
					simpleShrine.isToggle = isToggle;
					simpleShrine.OnAccept = OnAccept;
					simpleShrine.OnDecline = OnDecline;
					simpleShrine.CanUse = CanUse;
					simpleShrine.text = this.text;
					simpleShrine.acceptText = acceptText;
					simpleShrine.declineText = declineText;
					simpleShrine.talkPoint = transform;
				}
				else
				{
					val.AddComponent(interactableComponent);
				}
				((Object)val).name = text2;
				if (!isBreachShrine)
				{
					if (!Object.op_Implicit((Object)(object)room))
					{
						room = RoomFactory.CreateEmptyRoom();
					}
					RegisterShrineRoom(val, room, text2, Vector2.op_Implicit(offset));
				}
				registeredShrines.Add(text2, val);
				FakePrefab.MarkAsFakePrefab(val);
				Tools.Print("Added shrine: " + text2);
				return val;
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
				return null;
			}
		}

		public static void RegisterShrineRoom(GameObject shrine, PrototypeDungeonRoom protoroom, string ID, Vector2 offset)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			protoroom.category = (RoomCategory)2;
			DungeonPrerequisite[] array = (DungeonPrerequisite[])(object)new DungeonPrerequisite[0];
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((float)(protoroom.Width / 2) + offset.x, (float)(protoroom.Height / 2) + offset.y);
			protoroom.placedObjectPositions.Add(val);
			List<PrototypePlacedObjectData> placedObjects = protoroom.placedObjects;
			PrototypePlacedObjectData val2 = new PrototypePlacedObjectData();
			val2.contentsBasePosition = val;
			val2.fieldData = new List<PrototypePlacedObjectFieldData>();
			val2.instancePrerequisites = array;
			val2.linkedTriggerAreaIDs = new List<int>();
			DungeonPlaceable val3 = new DungeonPlaceable();
			val3.width = 2;
			val3.height = 2;
			val3.respectsEncounterableDifferentiator = true;
			List<DungeonPlaceableVariant> list = new List<DungeonPlaceableVariant>();
			DungeonPlaceableVariant val4 = new DungeonPlaceableVariant();
			val4.percentChance = 1f;
			val4.nonDatabasePlaceable = shrine;
			val4.prerequisites = array;
			val4.materialRequirements = (DungeonPlaceableRoomMaterialRequirement[])(object)new DungeonPlaceableRoomMaterialRequirement[0];
			list.Add(val4);
			val3.variantTiers = list;
			val2.placeableContents = val3;
			placedObjects.Add(val2);
			RoomFactory.RoomData roomData = default(RoomFactory.RoomData);
			roomData.room = protoroom;
			roomData.isSpecialRoom = true;
			roomData.category = "SPECIAL";
			roomData.specialSubCatergory = "UNSPECIFIED_SPECIAL";
			RoomFactory.RoomData roomData2 = roomData;
			RoomFactory.rooms.Add(ID, roomData2);
			DungeonHandler.Register(roomData2);
		}

		public static void PlaceBreachShrines()
		{
			//IL_0097: 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)
			CleanupBreachShrines();
			Tools.Print("Placing breach shrines: ");
			foreach (GameObject value in registeredShrines.Values)
			{
				try
				{
					CustomShrineController component = value.GetComponent<CustomShrineController>();
					if (component.isBreachShrine)
					{
						Tools.Print("    " + ((Object)value).name);
						CustomShrineController component2 = Object.Instantiate<GameObject>(value).GetComponent<CustomShrineController>();
						component2.Copy(component);
						((Component)component2).gameObject.SetActive(true);
						((BraveBehaviour)component2).sprite.PlaceAtPositionByAnchor(component2.offset, (Anchor)1);
						SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)component2).sprite, Color.black);
						IPlayerInteractable component3 = ((Component)component2).GetComponent<IPlayerInteractable>();
						if (component3 is SimpleInteractable)
						{
							((SimpleInteractable)(object)component3).OnAccept = component2.OnAccept;
							((SimpleInteractable)(object)component3).OnDecline = component2.OnDecline;
							((SimpleInteractable)(object)component3).CanUse = component2.CanUse;
						}
						if (!RoomHandler.unassignedInteractableObjects.Contains(component3))
						{
							RoomHandler.unassignedInteractableObjects.Add(component3);
						}
					}
				}
				catch (Exception e)
				{
					Tools.PrintException(e);
				}
			}
		}

		private static void CleanupBreachShrines()
		{
			CustomShrineController[] array = Object.FindObjectsOfType<CustomShrineController>();
			foreach (CustomShrineController customShrineController in array)
			{
				if (!FakePrefab.IsFakePrefab((Object)(object)customShrineController))
				{
					Object.Destroy((Object)(object)((Component)customShrineController).gameObject);
				}
				else
				{
					((Component)customShrineController).gameObject.SetActive(false);
				}
			}
		}
	}
	public class FranseisInteractable : SimpleInteractable, IPlayerInteractable
	{
		private bool m_allowMeToIntroduceMyself = true;

		private void Start()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			talkPoint = ((BraveBehaviour)this).transform.Find("talkpoint");
			m_isToggled = false;
			SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)this).sprite, Color.black);
			m_canUse = true;
			((BraveBehaviour)this).spriteAnimator.Play("idle");
		}

		public void Interact(PlayerController interactor)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!TextBoxManager.HasTextBox(talkPoint))
			{
				m_canUse = ((CanUse != null) ? CanUse(interactor, ((Component)this).gameObject) : m_canUse);
				if (!m_canUse)
				{
					TextBoxManager.ShowTextBox(talkPoint.position, talkPoint, 2f, "No takesies backsies!", interactor.characterAudioSpeechTag, false, (BoxSlideOrientation)0, false, false);
					((BraveBehaviour)this).spriteAnimator.PlayForDuration("talk", 2f, "idle", false);
				}
				else
				{
					((MonoBehaviour)this).StartCoroutine(HandleConversation(interactor));
				}
			}
		}

		private IEnumerator HandleConversation(PlayerController interactor)
		{
			SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)this).sprite, Color.black);
			((BraveBehaviour)this).spriteAnimator.PlayForDuration("talk_start", 1f, "talk", false);
			interactor.SetInputOverride("npcConversation");
			Pixelator.Instance.LerpToLetterbox(0.35f, 0.25f);
			yield return null;
			for (int conversationIndex = ((!m_allowMeToIntroduceMyself) ? (conversation.Count - 1) : 0); conversationIndex < conversation.Count - 1; conversationIndex++)
			{
				Tools.Print($"Index: {conversationIndex}");
				TextBoxManager.ClearTextBox(talkPoint);
				TextBoxManager.ShowTextBox(talkPoint.position, talkPoint, -1f, conversation[conversationIndex], interactor.characterAudioSpeechTag, false, (BoxSlideOrientation)0, true, false);
				float timer = 0f;
				while (!((OneAxisInputControl)BraveInput.GetInstanceForPlayer(interactor.PlayerIDX).ActiveActions.GetActionFromType((GungeonActionType)10)).WasPressed || timer < 0.4f)
				{
					timer += BraveTime.DeltaTime;
					yield return null;
				}
			}
			m_allowMeToIntroduceMyself = false;
			TextBoxManager.ShowTextBox(talkPoint.position, talkPoint, -1f, conversation[conversation.Count - 1], interactor.characterAudioSpeechTag, false, (BoxSlideOrientation)0, true, false);
			GameUIRoot.Instance.DisplayPlayerConversationOptions(interactor, (TalkModule)null, acceptText, declineText);
			int selectedResponse = -1;
			while (!GameUIRoot.Instance.GetPlayerConversationResponse(ref selectedResponse))
			{
				yield return null;
			}
			if (selectedResponse == 0)
			{
				TextBoxManager.ClearTextBox(talkPoint);
				((BraveBehaviour)this).spriteAnimator.PlayForDuration("do_effect", -1f, "talk", false);
				while (((BraveBehaviour)this).spriteAnimator.CurrentFrame < 20)
				{
					yield return null;
				}
				OnAccept?.Invoke(interactor, ((Component)this).gameObject);
				((BraveBehaviour)this).spriteAnimator.Play("talk");
				TextBoxManager.ShowTextBox(talkPoint.position, talkPoint, 1f, "Bam!", interactor.characterAudioSpeechTag, false, (BoxSlideOrientation)0, false, false);
				yield return (object)new WaitForSeconds(1f);
			}
			else
			{
				OnDecline?.Invoke(interactor, ((Component)this).gameObject);
				TextBoxManager.ClearTextBox(talkPoint);
			}
			interactor.ClearInputOverride("npcConversation");
			Pixelator.Instance.LerpToLetterbox(1f, 0.25f);
			((BraveBehaviour)this).spriteAnimator.Play("idle");
		}

		public void OnEnteredRange(PlayerController interactor)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)this).sprite, Color.white, 1f, 0f, (OutlineType)0);
			((BraveBehaviour)this).sprite.UpdateZDepth();
		}

		public void OnExitRange(PlayerController interactor)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)this).sprite, Color.black, 1f, 0f, (OutlineType)0);
		}

		public string GetAnimationState(PlayerController interactor, out bool shouldBeFlipped)
		{
			shouldBeFlipped = false;
			return string.Empty;
		}

		public float GetDistanceToPoint(Vector2 point)
		{
			//IL_001a: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((BraveBehaviour)this).sprite == (Object)null)
			{
				return 100f;
			}
			Vector3 val = Vector2.op_Implicit(BraveMathCollege.ClosestPointOnRectangle(point, ((BraveBehaviour)this).specRigidbody.UnitBottomLeft, ((BraveBehaviour)this).specRigidbody.UnitDimensions));
			return Vector2.Distance(point, Vector2.op_Implicit(val)) / 1.5f;
		}

		public float GetOverrideMaxDistance()
		{
			return -1f;
		}
	}
	public abstract class SimpleInteractable : BraveBehaviour
	{
		public Action<PlayerController, GameObject> OnAccept;

		public Action<PlayerController, GameObject> OnDecline;

		public List<string> conversation;

		public Func<PlayerController, GameObject, bool> CanUse;

		public Transform talkPoint;

		public string text;

		public string acceptText;

		public string declineText;

		public bool isToggle;

		protected bool m_isToggled;

		protected bool m_canUse = true;
	}
	public class SimpleShrine : SimpleInteractable, IPlayerInteractable
	{
		private void Start()
		{
			talkPoint = ((BraveBehaviour)this).transform.Find("talkpoint");
			m_isToggled = false;
		}

		public void Interact(PlayerController interactor)
		{
			if (!TextBoxManager.HasTextBox(talkPoint))
			{
				Tools.Print("Can use: " + (CanUse == null));
				m_canUse = ((CanUse != null) ? CanUse(interactor, ((Component)this).gameObject) : m_canUse);
				((MonoBehaviour)this).StartCoroutine(HandleConversation(interactor));
			}
		}

		private IEnumerator HandleConversation(PlayerController interactor)
		{
			TextBoxManager.ShowStoneTablet(talkPoint.position, talkPoint, -1f, text, true, false);
			int selectedResponse = -1;
			interactor.SetInputOverride("shrineConversation");
			yield return null;
			if (!m_canUse)
			{
				GameUIRoot.Instance.DisplayPlayerConversationOptions(interactor, (TalkModule)null, declineText, string.Empty);
			}
			else if (isToggle)
			{
				if (m_isToggled)
				{
					GameUIRoot.Instance.DisplayPlayerConversationOptions(interactor, (TalkModule)null, declineText, string.Empty);
				}
				else
				{
					GameUIRoot.Instance.DisplayPlayerConversationOptions(interactor, (TalkModule)null, acceptText, string.Empty);
				}
			}
			else
			{
				GameUIRoot.Instance.DisplayPlayerConversationOptions(interactor, (TalkModule)null, acceptText, declineText);
			}
			while (!GameUIRoot.Instance.GetPlayerConversationResponse(ref selectedResponse))
			{
				yield return null;
			}
			interactor.ClearInputOverride("shrineConversation");
			TextBoxManager.ClearTextBox(talkPoint);
			if (m_canUse)
			{
				if (selectedResponse == 0 && isToggle)
				{
					(m_isToggled ? OnDecline : OnAccept)?.Invoke(interactor, ((Component)this).gameObject);
					m_isToggled = !m_isToggled;
				}
				else if (selectedResponse == 0)
				{
					OnAccept?.Invoke(interactor, ((Component)this).gameObject);
				}
				else
				{
					OnDecline?.Invoke(interactor, ((Component)this).gameObject);
				}
			}
		}

		public void OnEnteredRange(PlayerController interactor)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SpriteOutlineManager.AddOutlineToSprite(((BraveBehaviour)this).sprite, Color.white, 1f, 0f, (OutlineType)0);
			((BraveBehaviour)this).sprite.UpdateZDepth();
		}

		public void OnExitRange(PlayerController interactor)
		{
			SpriteOutlineManager.RemoveOutlineFromSprite(((BraveBehaviour)this).sprite, false);
		}

		public string GetAnimationState(PlayerController interactor, out bool shouldBeFlipped)
		{
			shouldBeFlipped = false;
			return string.Empty;
		}

		public float GetDistanceToPoint(Vector2 point)
		{
			//IL_001a: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((BraveBehaviour)this).sprite == (Object)null)
			{
				return 100f;
			}
			Vector3 val = Vector2.op_Implicit(BraveMathCollege.ClosestPointOnRectangle(point, ((BraveBehaviour)this).specRigidbody.UnitBottomLeft, ((BraveBehaviour)this).specRigidbody.UnitDimensions));
			return Vector2.Distance(point, Vector2.op_Implicit(val)) / 1.5f;
		}

		public float GetOverrideMaxDistance()
		{
			return -1f;
		}
	}
	public static class StaticReferences
	{
		public static Dictionary<string, AssetBundle> AssetBundles;

		public static Dictionary<string, GenericRoomTable> RoomTables;

		public static SharedInjectionData subShopTable;

		public static Dictionary<string, string> roomTableMap = new Dictionary<string, string>
		{
			{ "special", "basic special rooms (shrines, etc)" },
			{ "shop", "Shop Room Table" },
			{ "secret", "secret_room_table_01" },
			{ "gungeon", "Gungeon_RoomTable" },
			{ "castle", "Castle_RoomTable" },
			{ "mines", "Mines_RoomTable" },
			{ "catacombs", "Catacomb_RoomTable" },
			{ "forge", "Forge_RoomTable" },
			{ "sewer", "Sewer_RoomTable" },
			{ "cathedral", "Cathedral_RoomTable" },
			{ "bullethell", "BulletHell_RoomTable" }
		};

		public static string[] assetBundleNames = new string[2] { "shared_auto_001", "shared_auto_002" };

		public static string[] dungeonPrefabNames = new string[6] { "base_mines", "base_catacombs", "base_forge", "base_sewer", "base_cathedral", "base_bullethell" };

		public static void Init()
		{
			AssetBundles = new Dictionary<string, AssetBundle>();
			string[] array = assetBundleNames;
			foreach (string text in array)
			{
				try
				{
					AssetBundle val = ResourceManager.LoadAssetBundle(text);
					AssetBundles.Add(text, ResourceManager.LoadAssetBundle(text));
				}
				catch (Exception e)
				{
					Tools.PrintError("Failed to load asset bundle: " + text);
					Tools.PrintException(e);
				}
			}
			RoomTables = new Dictionary<string, GenericRoomTable>();
			foreach (KeyValuePair<string, string> item in roomTableMap)
			{
				try
				{
					GenericRoomTable val2 = StaticReferences.GetAsset<GenericRoomTable>(item.Value);
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = DungeonDatabase.GetOrLoadByName("base_" + item.Key).PatternSettings.flows[0].fallbackRoomTable;
					}
					RoomTables.Add(item.Key, val2);
				}
				catch (Exception e2)
				{
					Tools.PrintError("Failed to load room table: " + item.Key + ":" + item.Value);
					Tools.PrintException(e2);
				}
			}
			Tools.Print("Static references initialized.");
		}

		public static GenericRoomTable GetRoomTable(ValidTilesets tileset)
		{
			//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_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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_0008: Invalid comparison between Unknown and I4
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			//IL_000a: 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_0022: Expected I4, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Invalid comparison between Unknown and I4
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			if ((int)tileset <= 16)
			{
				switch (tileset - 1)
				{
				default:
					if ((int)tileset != 8)
					{
						if ((int)tileset != 16)
						{
							break;
						}
						return RoomTables["mines"];
					}
					return RoomTables["cathedral"];
				case 0:
					return RoomTables["gungeon"];
				case 1:
					return RoomTables["castle"];
				case 3:
					return RoomTables["sewer"];
				case 2:
					break;
				}
			}
			else
			{
				if ((int)tileset == 32)
				{
					return RoomTables["catacombs"];
				}
				if ((int)tileset == 64)
				{
					return RoomTables["forge"];
				}
				if ((int)tileset == 128)
				{
					return RoomTables["bullethell"];
				}
			}
			return RoomTables["gungeon"];
		}

		public static T GetAsset<T>(string assetName) where T : Object
		{
			T val = default(T);
			foreach (AssetBundle value in AssetBundles.Values)
			{
				val = value.LoadAsset<T>(assetName);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			return val;
		}
	}
	public static class Tools
	{
		public static bool verbose = false;

		private static string defaultLog = Path.Combine(ETGMod.ResourcesDirectory, "customCharacterLog.txt");

		public static string modID = "CC";

		private static Dictionary<string, float> timers = new Dictionary<string, float>();

		public static void Init()
		{
			if (File.Exists(defaultLog))
			{
				File.Delete(defaultLog);
			}
		}

		public static void Print<T>(T obj, string color = "FFFFFF", bool force = false)
		{
			if (verbose || force)
			{
				string[] array = obj.ToString().Split(new char[1] { '\n' });
				string[] array2 = array;
				foreach (string text in array2)
				{
					LogToConsole("<color=#" + color + ">[" + modID + "] " + text + "</color>");
				}
			}
			Log(obj.ToString());
		}

		public static void PrintRaw<T>(T obj, bool force = false)
		{
			if (verbose || force)
			{
				LogToConsole(obj.ToString());
			}
			Log(obj.ToString());
		}

		public static void PrintError<T>(T obj, string color = "FF0000")
		{
			string[] array = obj.ToString().Split(new char[1] { '\n' });
			string[] array2 = array;
			foreach (string text in array2)
			{
				LogToConsole("<color=#" + color + ">[" + modID + "] " + text + "</color>");
			}
			Log(obj.ToString());
		}

		public static void PrintException(Exception e, string color = "FF0000")
		{
			string text = e.Message + "\n" + e.StackTrace;
			string[] array = text.Split(new char[1] { '\n' });
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				LogToConsole("<color=#" + color + ">[" + modID + "] " + text2 + "</color>");
			}
			Log(e.Message);
			Log("\t" + e.StackTrace);
		}

		public static void Log<T>(T obj)
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, defaultLog), append: true);
			streamWriter.WriteLine(obj.ToString());
		}

		public static void Log<T>(T obj, string fileName)
		{
			if (!verbose)
			{
				return;
			}
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, fileName), append: true);
			streamWriter.WriteLine(obj.ToString());
		}

		public static void LogToConsole(string message)
		{
			message.Replace("\t", "    ");
			ETGModConsole.Log((object)message, false);
		}

		private static void BreakdownComponentsInternal(this GameObject obj, int lvl = 0)
		{
			string text = "";
			for (int i = 0; i < lvl; i++)
			{
				text += "\t";
			}
			Log(text + ((Object)obj).name + "...");
			Component[] components = obj.GetComponents<Component>();
			foreach (Component val in components)
			{
				Log(text + "    -" + ((object)val).GetType());
			}
			Transform[] componentsInChildren = obj.GetComponentsInChildren<Transform>();
			foreach (Transform val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)(object)obj.transform)
				{
					((Component)val2).gameObject.BreakdownComponentsInternal(lvl + 1);
				}
			}
		}

		public static void BreakdownComponents(this GameObject obj)
		{
			obj.BreakdownComponentsInternal();
		}

		public static void ExportTexture(Texture texture, string folder = "")
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			string text = Path.Combine(ETGMod.ResourcesDirectory, folder);
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			File.WriteAllBytes(Path.Combine(text, ((Object)texture).name + DateTime.Now.Ticks + ".png"), ImageConversion.EncodeToPNG((Texture2D)texture));
		}

		public static T GetEnumValue<T>(string val) where T : Enum
		{
			return (T)Enum.Parse(typeof(T), val.ToUpper());
		}

		public static void LogPropertiesAndFields<T>(T obj, string header = "")
		{
			Log(header);
			Log("=======================");
			if (obj == null)
			{
				Log("LogPropertiesAndFields: Null object");
				return;
			}
			Type type = obj.GetType();
			Log($"Type: {type}");
			PropertyInfo[] properties = type.GetProperties();
			Log($"{typeof(T)} Properties: ");
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				try
				{
					object value = propertyInfo.GetValue(obj, null);
					string text = value.ToString();
					if ((object)obj?.GetType().GetGenericTypeDefinition() == typeof(List<>))
					{
						List<object> list = value as List<object>;
						text = $"List[{list.Count}]";
						foreach (object item in list)
						{
							text = text + "\n\t\t" + item.ToString();
						}
					}
					Log("\t" + propertyInfo.Name + ": " + text);
				}
				catch
				{
				}
			}
			Log($"{typeof(T)} Fields: ");
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array2 = fields;
			foreach (FieldInfo fieldInfo in array2)
			{
				Log($"\t{fieldInfo.Name}: {fieldInfo.GetValue(obj)}");
			}
		}

		public static void StartTimer(string name)
		{
			string key = name.ToLower();
			if (timers.ContainsKey(key))
			{
				PrintError("Timer " + name + " already exists.");
			}
			else
			{
				timers.Add(key, Time.realtimeSinceStartup);
			}
		}

		public static void StopTimerAndReport(string name)
		{
			string key = name.ToLower();
			if (!timers.ContainsKey(key))
			{
				PrintError("Could not stop timer " + name + ", no such timer exists");
				return;
			}
			float num = timers[key];
			int num2 = (int)((Time.realtimeSinceStartup - num) * 1000f);
			timers.Remove(key);
			Print(name + " finished in " + num2 + "ms");
		}
	}
}
namespace CustomCharacters
{
	public static class CharacterBuilder
	{
		public static Dictionary<string, Tuple<CustomCharacterData, GameObject>> storedCharacters = new Dictionary<string, Tuple<CustomCharacterData, GameObject>>();

		public static List<Gun> guns = new List<Gun>();

		public static void BuildCharacter(CustomCharacterData data)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			GameObject playerPrefab = GetPlayerPrefab(data.baseCharacter);
			if ((Object)(object)playerPrefab == (Object)null)
			{
				Tools.PrintError("Could not find prefab for: " + ((object)(PlayableCharacters)(ref data.baseCharacter)).ToString());
				return;
			}
			Tools.Print("");
			Tools.Print("--Building Character: " + data.nameShort + "--", "0000FF");
			GameObject val = Object.Instantiate<GameObject>(playerPrefab);
			PlayerController component = val.GetComponent<PlayerController>();
			((Component)component).gameObject.AddComponent<CustomCharacter>().data = data;
			data.characterID = storedCharacters.Count;
			Object.DontDestroyOnLoad((Object)(object)val);
			CustomizeCharacter(component, data);
			playerPrefab = null;
			store