Decompiled source of ExpandTheGungeon v2.9.17

ExpandTheGungeon.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BepInEx;
using Dungeonator;
using ExpandTheGungeon.ExpandComponent;
using ExpandTheGungeon.ExpandComponents;
using ExpandTheGungeon.ExpandDungeonFlows;
using ExpandTheGungeon.ExpandMain;
using ExpandTheGungeon.ExpandPrefab;
using ExpandTheGungeon.ExpandUtilities;
using ExpandTheGungeon.ItemAPI;
using ExpandTheGungeon.SpriteAPI;
using FullInspector;
using Gungeon;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using InControl;
using Ionic.Zip;
using MonoMod.RuntimeDetour;
using Pathfinding;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
using UnityEngine.Video;
using tk2dRuntime.TileMap;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ExpandTheGungeon")]
[assembly: AssemblyDescription("ExpandTheGungeon for Enter the Gungeon.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Apache Modding Inc")]
[assembly: AssemblyProduct("ExpandTheGungeon")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("879a1d67-4a5c-4a21-9823-426d1752d3d2")]
[assembly: AssemblyFileVersion("2.9.17")]
[assembly: AssemblyVersion("2.9.17.0")]
namespace ExpandTheGungeon
{
	public class ExpandFoyer : BraveBehaviour
	{
		private enum State
		{
			PreFoyerCheck,
			CheckSettings,
			SpawnObjects,
			Exit
		}

		private State m_State;

		public ExpandFoyer()
		{
			m_State = State.PreFoyerCheck;
		}

		public void Awake()
		{
		}

		public void Start()
		{
		}

		public void Update()
		{
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_0165: 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_0085: Expected O, but got Unknown
			switch (m_State)
			{
			case State.PreFoyerCheck:
				if (Foyer.DoIntroSequence && Foyer.DoMainMenu)
				{
					break;
				}
				if (ExpandTheGungeon.GameManagerHook == null)
				{
					if (ExpandSettings.debugMode)
					{
						Debug.Log((object)"[ExpandTheGungeon] Installing GameManager.Awake Hook....");
					}
					ExpandTheGungeon.GameManagerHook = new Hook((MethodBase)typeof(GameManager).GetMethod("Awake", BindingFlags.Instance | BindingFlags.NonPublic), typeof(ExpandTheGungeon).GetMethod("GameManager_Awake", BindingFlags.Instance | BindingFlags.NonPublic), (object)typeof(GameManager));
				}
				m_State = State.CheckSettings;
				break;
			case State.CheckSettings:
				if (!ExpandTheGungeon.ListsCleared)
				{
					StaticReferenceManager.AllHealthHavers.Clear();
					StaticReferenceManager.AllBros.Clear();
					StaticReferenceManager.AllEnemies.Clear();
					ExpandTheGungeon.ListsCleared = true;
				}
				if (ExpandSettings.EnableTestDungeonFlow)
				{
					GameManager.Instance.InjectedFlowPath = ExpandSettings.TestFlow;
					GameManager.Instance.InjectedLevelName = ExpandSettings.TestFloor;
				}
				if (GameManager.Instance.EnemyReplacementTiers != null)
				{
					ExpandEnemyReplacements.Init(GameManager.Instance.EnemyReplacementTiers);
				}
				ExpandDungeonMusicAPI.EnteredNewCustomFloor = false;
				m_State = State.SpawnObjects;
				break;
			case State.SpawnObjects:
			{
				if (!GameStatsManager.Instance.GetFlag((GungeonFlags)50120))
				{
					m_State = State.Exit;
					break;
				}
				GameObject obj = Object.Instantiate<GameObject>(ExpandPrefabs.EXFoyerTrigger, new Vector3(50.2f, 60.7f, 61.8f), Quaternion.identity);
				RoomHandler absoluteRoom = Vector3Extensions.GetAbsoluteRoom(obj.transform.position);
				ExpandCasinoWarpTrigger component = obj.GetComponent<ExpandCasinoWarpTrigger>();
				component.ConfigureOnPlacement(Vector3Extensions.GetAbsoluteRoom(((Component)this).gameObject.transform.position));
				absoluteRoom.RegisterInteractable((IPlayerInteractable)(object)component);
				m_State = State.Exit;
				break;
			}
			case State.Exit:
				if (Object.op_Implicit((Object)(object)((Component)this).gameObject))
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				break;
			}
		}

		protected override void OnDestroy()
		{
			((BraveBehaviour)this).OnDestroy();
		}
	}
	public class ExpandObjectMods
	{
		public static void InitSpecialMods()
		{
			ExpandSettings.randomSeed = Random.value;
			if (!(!Object.op_Implicit((Object)(object)GameManager.Instance) | !Object.op_Implicit((Object)(object)GameManager.Instance.Dungeon)))
			{
				ExpandStaticReferenceManager.PopulateLists();
				InitObjectMods(GameManager.Instance.Dungeon);
				ExpandDungeonFlow.isGlitchFlow = false;
			}
		}

		private static void InitObjectMods(Dungeon dungeon)
		{
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Invalid comparison between Unknown and I4
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Invalid comparison between Unknown and I4
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Invalid comparison between Unknown and I4
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Invalid comparison between Unknown and I4
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Invalid comparison between Unknown and I4
			//IL_09a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_09be: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)GameManager.Instance) | !Object.op_Implicit((Object)(object)dungeon))
			{
				return;
			}
			if (ExpandSettings.EnableJungleRain && (int)dungeon.tileIndices.tilesetId == 8192)
			{
				GameObject obj = Object.Instantiate<GameObject>(ExpandAssets.LoadAsset<GameObject>("ExpandJungleThunderStorm"));
				obj.transform.parent = ((Component)dungeon).gameObject.transform;
				ExpandThunderStormPlacable component = obj.GetComponent<ExpandThunderStormPlacable>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.RainIntensity = ExpandSettings.JungleRainIntensity;
					component.ConfigureOnPlacement(null);
				}
			}
			ExpandDungeonMusicAPI.EnteredNewCustomFloor = false;
			try
			{
				GameManager instance = GameManager.Instance;
				if (Object.op_Implicit((Object)(object)((instance != null) ? instance.DungeonMusicController : null)))
				{
					bool value = false;
					bool num = ExpandDungeonMusicAPI.CustomLevelMusic.TryGetValue(dungeon.musicEventName, out value);
					FieldInfo field = typeof(DungeonFloorMusicController).GetField("COOLDOWN_TIMER", BindingFlags.Instance | BindingFlags.NonPublic);
					FieldInfo field2 = typeof(DungeonFloorMusicController).GetField("MUSIC_CHANGE_TIMER", BindingFlags.Instance | BindingFlags.NonPublic);
					if (num && value)
					{
						field.SetValue(GameManager.Instance.DungeonMusicController, 34f);
						field2.SetValue(GameManager.Instance.DungeonMusicController, 50f);
					}
					else
					{
						field.SetValue(GameManager.Instance.DungeonMusicController, 22.5f);
						field2.SetValue(GameManager.Instance.DungeonMusicController, 40f);
					}
				}
			}
			catch (Exception)
			{
			}
			if ((int)dungeon.tileIndices.tilesetId == 4096 && dungeon.data != null && dungeon.data.rooms != null)
			{
				foreach (RoomHandler room in dungeon.data.rooms)
				{
					if (room == null || room.area == null || (int)room.area.PrototypeRoomCategory != 3)
					{
						continue;
					}
					foreach (AIActor activeEnemy in room.GetActiveEnemies((ActiveEnemyType)1))
					{
						if (Object.op_Implicit((Object)(object)activeEnemy) && activeEnemy.EnemyGuid == ExpandEnemyDatabase.ParasiteBossGUID)
						{
							activeEnemy.AdditionalSafeItemDrops = new List<PickupObject> { (PickupObject)(object)ExpandKeyBulletPickup.OldKeyObject.GetComponent<ExpandKeyBulletPickup>() };
							break;
						}
					}
					break;
				}
			}
			if (GameManager.Instance.CurrentFloor == 1)
			{
				ExpandSettings.HasSpawnedSecretBoss = false;
			}
			if ((int)dungeon.LevelOverrideType != 2)
			{
				ExpandPrefabs.SerManuel.GetComponent<HealthHaver>().forcePreventVictoryMusic = true;
			}
			else
			{
				ExpandPrefabs.SerManuel.GetComponent<HealthHaver>().forcePreventVictoryMusic = false;
			}
			if (((int)GameManager.Instance.CurrentGameMode == 2) | ((int)GameManager.Instance.CurrentGameMode == 3) | dungeon.IsGlitchDungeon)
			{
				foreach (RoomHandler room2 in dungeon.data.rooms)
				{
					if (!string.IsNullOrEmpty(room2.GetRoomName()) && room2.GetRoomName().ToLower().StartsWith("elevatormaintenance") && (((int)dungeon.tileIndices.tilesetId == 2) | dungeon.IsGlitchDungeon) && dungeon.data.Entrance != null && dungeon.data.Entrance.GetRoomName().ToLower().StartsWith("elevator entrance"))
					{
						dungeon.data.Entrance.TargetPitfallRoom = room2;
						dungeon.data.Entrance.ForcePitfallForFliers = true;
					}
				}
			}
			PlayerController primaryPlayer = GameManager.Instance.PrimaryPlayer;
			PlayerController secondaryPlayer = GameManager.Instance.SecondaryPlayer;
			bool flag = false;
			if (ExpandPlaceWallMimic.PlayerHasThirdEye && Object.op_Implicit((Object)(object)Pixelator.Instance) && Pixelator.Instance.DoOcclusionLayer)
			{
				Pixelator.Instance.DoOcclusionLayer = false;
			}
			if (Object.op_Implicit((Object)(object)primaryPlayer) && primaryPlayer.HasPassiveItem(CorruptedJunk.CorruptedJunkID))
			{
				flag = true;
			}
			if (Object.op_Implicit((Object)(object)secondaryPlayer) && secondaryPlayer.HasPassiveItem(CorruptedJunk.CorruptedJunkID))
			{
				flag = true;
			}
			AIActor[] array;
			if (ExpandSettings.EnableExpandedGlitchFloors && ((dungeon.IsGlitchDungeon | ExpandDungeonFlow.isGlitchFlow) || flag))
			{
				if (!dungeon.IsGlitchDungeon && !ExpandDungeonFlow.isGlitchFlow && flag)
				{
					if (Object.FindObjectsOfType<AIActor>() == null || Object.FindObjectsOfType<AIActor>().Length == 0)
					{
						return;
					}
					array = Object.FindObjectsOfType<AIActor>();
					foreach (AIActor val in array)
					{
						if (!val.IsBlackPhantom && !((BraveBehaviour)val).healthHaver.IsBoss && !string.IsNullOrEmpty(val.EnemyGuid) && (Object)(object)val.optionalPalette == (Object)null && (string.IsNullOrEmpty(((GameActor)val).OverrideDisplayName) | !((GameActor)val).OverrideDisplayName.StartsWith("Corrupted")) && !ExpandLists.DontGlitchMeList.Contains(val.EnemyGuid) && ((DungeonPlaceableBehaviour)val).GetAbsoluteParentRoom() != null && !string.IsNullOrEmpty(((DungeonPlaceableBehaviour)val).GetAbsoluteParentRoom().GetRoomName()) && ((DungeonPlaceableBehaviour)val).GetAbsoluteParentRoom().GetRoomName().ToLower()
							.StartsWith("corrupted"))
						{
							if (Random.value <= 0.6f)
							{
								ExpandShaders.Instance.BecomeGlitched(val, 0.04f, 0.07f, 0.05f, 0.07f, 0.05f);
								ExpandEnemyCorruptor.CorruptExistingEnemy(val);
							}
							if (Random.value <= 0.25f && !ExpandLists.blobsAndCritters.Contains(val.EnemyGuid) && (Object)(object)((Component)val).GetComponent<ExpandSpawnGlitchObjectOnDeath>() == (Object)null)
							{
								((Component)val).gameObject.AddComponent<ExpandSpawnGlitchObjectOnDeath>();
							}
						}
					}
					MaybeSetupGlitchEnemyStun(dungeon, forceRun: true);
					return;
				}
				if (dungeon.IsGlitchDungeon | ExpandDungeonFlow.isGlitchFlow)
				{
					dungeon.BossMasteryTokenItemId = CustomMasterRounds.GtlichFloorMasterRoundID;
					if (ExpandSettings.EnableGlitchFloorScreenShader)
					{
						Object.Instantiate<GameObject>(ExpandAssets.LoadAsset<GameObject>("EXGlitchFloorScreenFX")).transform.SetParent(((Component)dungeon).gameObject.transform);
					}
					if (Object.FindObjectsOfType<AIActor>() != null && Object.FindObjectsOfType<AIActor>().Length != 0)
					{
						array = Object.FindObjectsOfType<AIActor>();
						foreach (AIActor val2 in array)
						{
							float glitchInterval = Random.Range(0.02f, 0.04f);
							float dispProbability = Random.Range(0.06f, 0.08f);
							float dispIntensity = Random.Range(0.07f, 0.1f);
							float colorProbability = Random.Range(0.035f, 0.1f);
							float colorIntensity = Random.Range(0.05f, 0.1f);
							if (!val2.IsBlackPhantom && !((BraveBehaviour)val2).healthHaver.IsBoss && !string.IsNullOrEmpty(val2.EnemyGuid) && (Object)(object)val2.optionalPalette == (Object)null && (string.IsNullOrEmpty(((GameActor)val2).OverrideDisplayName) | !((GameActor)val2).OverrideDisplayName.StartsWith("Corrupted")) && !ExpandLists.DontGlitchMeList.Contains(val2.EnemyGuid))
							{
								if (Random.value <= 0.6f)
								{
									ExpandShaders.Instance.BecomeGlitched(val2, glitchInterval, dispProbability, dispIntensity, colorProbability, colorIntensity);
									ExpandEnemyCorruptor.CorruptExistingEnemy(val2);
								}
								if (Random.value <= 0.25f && !ExpandLists.blobsAndCritters.Contains(val2.EnemyGuid) && (Object)(object)((Component)val2).GetComponent<ExpandSpawnGlitchObjectOnDeath>() == (Object)null)
								{
									((Component)val2).gameObject.AddComponent<ExpandSpawnGlitchObjectOnDeath>();
								}
							}
						}
					}
					if (Object.FindObjectsOfType<BraveBehaviour>() != null && Object.FindObjectsOfType<BraveBehaviour>().Length != 0)
					{
						BraveBehaviour[] array2 = Object.FindObjectsOfType<BraveBehaviour>();
						foreach (BraveBehaviour val3 in array2)
						{
							if (Random.value <= 0.05f && Object.op_Implicit((Object)(object)((Component)val3).gameObject) && !Object.op_Implicit((Object)(object)((Component)val3).gameObject.GetComponent<AIActor>()) && !Object.op_Implicit((Object)(object)((Component)val3).gameObject.GetComponent<Chest>()) && (string.IsNullOrEmpty(((Object)((Component)val3).gameObject).name) | (!((Object)((Component)val3).gameObject).name.ToLower().StartsWith("glitchtile") && !((Object)((Component)val3).gameObject).name.ToLower().StartsWith("ex secret door") && !((Object)((Component)val3).gameObject).name.ToLower().StartsWith("lock") && !((Object)((Component)val3).gameObject).name.ToLower().StartsWith("chest"))))
							{
								float glitchInterval2 = Random.Range(0.02f, 0.04f);
								float dispProbability2 = Random.Range(0.06f, 0.08f);
								float dispIntensity2 = Random.Range(0.07f, 0.1f);
								float colorProbability2 = Random.Range(0.035f, 0.1f);
								float colorIntensity2 = Random.Range(0.05f, 0.1f);
								ExpandShaders.Instance.BecomeGlitched(val3, glitchInterval2, dispProbability2, dispIntensity2, colorProbability2, colorIntensity2);
							}
						}
					}
					ExpandPlaceCorruptedEnemies.PlaceRandomEnemies(dungeon, GameManager.Instance.CurrentFloor);
					MaybeSetupGlitchEnemyStun(dungeon);
					GameObject[] array3 = Object.FindObjectsOfType<GameObject>();
					List<GameObject> list = new List<GameObject>();
					if (array3 != null && array3.Length != 0)
					{
						GameObject[] array4 = array3;
						foreach (GameObject val4 in array4)
						{
							if (!string.IsNullOrEmpty(((Object)val4).name) && ((Object)val4).name.ToLower().StartsWith("red barrel") && val4.transform.childCount > 0 && (Object)(object)val4.transform.Find("Red Barrel") != (Object)null && Random.value <= 0.45f)
							{
								list.Add(val4);
							}
						}
						if (list.Count > 0)
						{
							for (int j = 0; j < list.Count; j++)
							{
								Vector2 val5 = TransformExtensions.PositionVector2(list[j].transform) + new Vector2(0.5f, 0.5f);
								RoomHandler absoluteRoom = Vector3Extensions.GetAbsoluteRoom(val5);
								Object.Destroy((Object)(object)list[j]);
								AIActor aiActor = AIActor.Spawn(EnemyDatabase.GetOrLoadByGuid(ExpandEnemyDatabase.ExplodyBoyGUID), val5, absoluteRoom, true, (AwakenAnimationType)0, true);
								float glitchInterval3 = Random.Range(0.02f, 0.04f);
								float dispProbability3 = Random.Range(0.06f, 0.08f);
								float dispIntensity3 = Random.Range(0.07f, 0.1f);
								float colorProbability3 = Random.Range(0.035f, 0.1f);
								float colorIntensity3 = Random.Range(0.05f, 0.1f);
								ExpandShaders.Instance.BecomeGlitched(aiActor, glitchInterval3, dispProbability3, dispIntensity3, colorProbability3, colorIntensity3);
							}
						}
					}
				}
			}
			if (string.IsNullOrEmpty(ExpandDungeonMusicAPI.TempCustomBossMusic))
			{
				return;
			}
			AIActor[] array5 = Object.FindObjectsOfType<AIActor>();
			if (array5 == null || array5.Length == 0)
			{
				return;
			}
			array = array5;
			foreach (AIActor val6 in array)
			{
				if (Object.op_Implicit((Object)(object)((BraveBehaviour)val6).healthHaver) && ((BraveBehaviour)val6).healthHaver.HasHealthBar && ((BraveBehaviour)val6).healthHaver.IsBoss && Object.op_Implicit((Object)(object)((Component)val6).gameObject.GetComponent<GenericIntroDoer>()))
				{
					((Component)val6).gameObject.GetComponent<GenericIntroDoer>().BossMusicEvent = ExpandDungeonMusicAPI.TempCustomBossMusic;
					ExpandDungeonMusicAPI.TempCustomBossMusic = string.Empty;
				}
			}
		}

		private static void MaybeSetupGlitchEnemyStun(Dungeon dungeon, bool forceRun = false)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Invalid comparison between Unknown and I4
			if (!dungeon.IsGlitchDungeon && !forceRun)
			{
				return;
			}
			foreach (RoomHandler room in dungeon.data.rooms)
			{
				if (string.IsNullOrEmpty(room.GetRoomName()) || (int)room.area.PrototypeRoomCategory == 3 || !room.HasActiveEnemies((ActiveEnemyType)0))
				{
					continue;
				}
				foreach (AIActor activeEnemy in room.GetActiveEnemies((ActiveEnemyType)0))
				{
					if (!string.IsNullOrEmpty(((GameActor)activeEnemy).OverrideDisplayName) && ((GameActor)activeEnemy).OverrideDisplayName.ToLower().StartsWith("corrupted"))
					{
						((Component)activeEnemy).gameObject.AddComponent<ExpandGlitchedEnemyStunManager>();
					}
				}
			}
		}
	}
	public static class ExpandSettings
	{
		public static bool EnableLogo = true;

		public static bool EnableTestDungeonFlow = false;

		public static string TestFlow = "Test_CustomRoom_Flow";

		public static string TestFloor = "tt_phobos";

		public static bool debugMode = false;

		public static bool youtubeSafeMode = true;

		public static bool IsHardModeBuild = false;

		public static bool RestoreOldRooms = false;

		public static bool EnableJungleRain = true;

		public static bool EnableBloodiedScarfFix = true;

		public static bool EnableExpandedGlitchFloors = true;

		public static bool EnableGlitchFloorScreenShader = true;

		public static bool EnableEXItems = true;

		public static float JungleRainIntensity = 400f;

		public static bool spritesBundlePresent = false;

		public static bool allowGlitchFloor = false;

		public static bool glitchElevatorHasBeenUsed = false;

		public static bool HasSpawnedSecretBoss = false;

		public static float randomSeed = 0.5f;

		public static bool PlayingPunchoutArcade = false;

		public static bool HasSpawnedFakePastChest = false;

		public static void LoadSettings()
		{
			if (File.Exists(Path.Combine(ETGMod.ResourcesDirectory, "ExpandTheGungeon_Settings.txt")))
			{
				string text = File.ReadAllText(Path.Combine(ETGMod.ResourcesDirectory, "ExpandTheGungeon_Settings.txt"));
				ExpandCachedStats expandCachedStats = ScriptableObject.CreateInstance<ExpandCachedStats>();
				JsonUtility.FromJsonOverwrite(text, (object)expandCachedStats);
				OverwriteUserSettings(expandCachedStats);
			}
			else
			{
				SaveSettings();
			}
		}

		public static void SaveSettings()
		{
			_ = string.Empty;
			string text = JsonUtility.ToJson((object)ScriptableObject.CreateInstance<ExpandCachedStats>(), true);
			if (File.Exists(Path.Combine(ETGMod.ResourcesDirectory, "ExpandTheGungeon_Settings.txt")))
			{
				File.Delete(Path.Combine(ETGMod.ResourcesDirectory, "ExpandTheGungeon_Settings.txt"));
			}
			ExpandAssets.SaveStringToFile(text, ETGMod.ResourcesDirectory, "ExpandTheGungeon_Settings.txt");
		}

		public static void OverwriteUserSettings(ExpandCachedStats stats)
		{
			EnableLogo = stats.EnableLogo;
			EnableTestDungeonFlow = stats.EnableTestDungeonFlow;
			TestFlow = stats.TestFlow;
			TestFloor = stats.TestFloor;
			debugMode = stats.debugMode;
			youtubeSafeMode = stats.youtubeSafeMode;
			IsHardModeBuild = stats.IsHardModeBuild;
			EnableJungleRain = stats.EnableJungleRain;
			EnableBloodiedScarfFix = stats.EnableBloodiedScarfFix;
			EnableExpandedGlitchFloors = stats.EnableExpandedGlitchFloors;
			EnableGlitchFloorScreenShader = stats.EnableGlitchFloorScreenShader;
			EnableEXItems = stats.EnableEXItems;
			JungleRainIntensity = stats.JungleRainIntensity;
		}
	}
	public class ExpandCachedStats : ScriptableObject
	{
		public bool EnableLogo;

		public bool EnableTestDungeonFlow;

		public string TestFlow;

		public string TestFloor;

		public bool debugMode;

		public bool youtubeSafeMode;

		public bool IsHardModeBuild;

		public bool RestoreOldRooms;

		public bool EnableJungleRain;

		public bool EnableBloodiedScarfFix;

		public bool EnableExpandedGlitchFloors;

		public bool EnableGlitchFloorScreenShader;

		public bool EnableEXItems;

		public float JungleRainIntensity;

		public int GameLanguage;

		public ExpandCachedStats()
		{
			EnableLogo = ExpandSettings.EnableLogo;
			EnableTestDungeonFlow = ExpandSettings.EnableTestDungeonFlow;
			TestFlow = ExpandSettings.TestFlow;
			TestFloor = ExpandSettings.TestFloor;
			debugMode = ExpandSettings.debugMode;
			youtubeSafeMode = ExpandSettings.youtubeSafeMode;
			IsHardModeBuild = ExpandSettings.IsHardModeBuild;
			RestoreOldRooms = ExpandSettings.RestoreOldRooms;
			EnableJungleRain = ExpandSettings.EnableJungleRain;
			EnableBloodiedScarfFix = ExpandSettings.EnableBloodiedScarfFix;
			EnableExpandedGlitchFloors = ExpandSettings.EnableExpandedGlitchFloors;
			EnableGlitchFloorScreenShader = ExpandSettings.EnableGlitchFloorScreenShader;
			EnableEXItems = ExpandSettings.EnableEXItems;
			JungleRainIntensity = ExpandSettings.JungleRainIntensity;
		}
	}
	public class DungeonFlowModule
	{
		private static List<string> knownFlows = new List<string>();

		private static List<string> knownTilesets = new List<string>();

		private static List<string> knownScenes = new List<string>();

		private static string[] ReturnMatchesFromList(string matchThis, List<string> inThis)
		{
			List<string> list = new List<string>();
			string text = matchThis.ToLower();
			foreach (string inThi in inThis)
			{
				string text2 = inThi.ToLower();
				if (StringAutocompletionExtensions.AutocompletionMatch(text2, text))
				{
					list.Add(text2);
				}
			}
			return list.ToArray();
		}

		public static void Install()
		{
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			if (ExpandDungeonFlow.KnownFlows != null && ExpandDungeonFlow.KnownFlows.Count > 0)
			{
				foreach (DungeonFlow knownFlow in ExpandDungeonFlow.KnownFlows)
				{
					if (((Object)knownFlow).name != null && ((Object)knownFlow).name != string.Empty)
					{
						knownFlows.Add(((Object)knownFlow).name.ToLower());
					}
				}
			}
			foreach (GameLevelDefinition dungeonFloor in GameManager.Instance.dungeonFloors)
			{
				if (dungeonFloor.dungeonPrefabPath != null && dungeonFloor.dungeonPrefabPath != string.Empty)
				{
					knownTilesets.Add(dungeonFloor.dungeonPrefabPath.ToLower());
				}
				if (dungeonFloor.dungeonSceneName != null && dungeonFloor.dungeonSceneName != string.Empty)
				{
					knownScenes.Add(dungeonFloor.dungeonSceneName.ToLower());
				}
			}
			foreach (GameLevelDefinition customFloor in GameManager.Instance.customFloors)
			{
				if (customFloor.dungeonPrefabPath != null && customFloor.dungeonPrefabPath != string.Empty)
				{
					knownTilesets.Add(customFloor.dungeonPrefabPath.ToLower());
				}
				if (customFloor.dungeonSceneName != null && customFloor.dungeonSceneName != string.Empty)
				{
					knownScenes.Add(customFloor.dungeonSceneName.ToLower());
				}
			}
			ETGModConsole.Commands.AddUnit("load_flow", (Action<string[]>)LoadFlowFunction, new AutocompletionSettings((Func<int, string, string[]>)((int index, string input) => index switch
			{
				0 => ReturnMatchesFromList(input.ToLower(), knownFlows), 
				1 => ReturnMatchesFromList(input.ToLower(), knownTilesets), 
				2 => ReturnMatchesFromList(input.ToLower(), knownScenes), 
				_ => new string[0], 
			})));
		}

		public static void LoadFlowFunction(string[] args)
		{
			if ((args == null) | (args.Length == 0) | (args[0].ToLower() == "help"))
			{
				ETGModConsole.Log((object)"WARNING: this command can crash gungeon! \nIf the game hangs on loading screen, use console to load a different level!\nUsage: load_flow [FLOW NAME] [TILESET NAME]. [TILESET NAME] is optional. Press tab for a list of each.\nOnce you run the command and you press escape, you should see the loading screen. If nothing happens when you use the command, the flow you tried to load doesn't exist or the path to it needs to be manually specified. Example: \"load_flow NPCParadise\".\nIf it hangs on loading screen then the tileset you tried to use doesn't exist, is no longer functional, or the flow uses rooms that are not compatible with the chosen tileset.\nAlso, you should probably know that if you run this command from the breach, the game never gives you the ability to shoot or use active items, so you should probably start a run first.", false);
				return;
			}
			if (args != null && args.Length > 3)
			{
				ETGModConsole.Log((object)"ERROR: Too many arguments specified! DungoenFlow name, dungoen prefab name, and dungoen scene name are the expected arguments!", false);
				return;
			}
			bool flag = args.Length > 1;
			bool flag2 = args.Length > 2;
			if (flag && !knownTilesets.Contains(args[1]) && Object.op_Implicit((Object)(object)DungeonDatabase.GetOrLoadByName(args[1])))
			{
				knownTilesets.Add(args[1]);
			}
			bool num = flag && !knownTilesets.Contains(args[1]);
			string text = args[0].Replace('-', ' ');
			if (text.ToLower().StartsWith("custom_glitchchest_flow") | text.ToLower().StartsWith("custom_glitchchestalt_flow") | text.ToLower().StartsWith("custom_glitch_flow"))
			{
				ExpandDungeonFlow.isGlitchFlow = true;
			}
			if (num)
			{
				ETGModConsole.Log((object)"Not a valid tileset!", false);
				return;
			}
			try
			{
				string text2 = "Attempting to load Dungeon Flow \"" + args[0] + "\"";
				if (flag)
				{
					text2 = text2 + " with tileset \"" + args[1] + "\"";
				}
				if (flag2)
				{
					text2 = text2 + " and scene \"" + args[2] + "\"";
				}
				text2 += ".";
				ETGModConsole.Log((object)text2, false);
				if (args.Length == 1)
				{
					GameManager.Instance.LoadCustomFlowForDebug(text, "", "");
				}
				else if (args.Length == 2)
				{
					string text3 = args[1];
					GameManager.Instance.LoadCustomFlowForDebug(text, text3, "");
				}
				else if (args.Length == 3)
				{
					string text4 = args[1];
					string text5 = args[2];
					GameManager.Instance.LoadCustomFlowForDebug(text, text4, text5);
				}
				else
				{
					ETGModConsole.Log((object)"If you're trying to go nowhere, you're succeeding.", false);
				}
			}
			catch (Exception ex)
			{
				ETGModConsole.Log((object)"WHOOPS! Something went wrong! Most likely you tried to load a broken flow, or the tileset is incomplete and doesn't have the right tiles for the flow.", false);
				ETGModConsole.Log((object)"In order to get the game back into working order, the mod is now loading NPCParadise, with the castle tileset.", false);
				Debug.Log((object)"WHOOPS! Something went wrong! Most likely you tried to load a broken flow, or the tileset is incomplete and doesn't have the right tiles for the flow.");
				Debug.Log((object)"In order to get the game back into working order, the mod is now loading NPCParadise, with the castle tileset.");
				Debug.LogException(ex);
				ExpandDungeonFlow.isGlitchFlow = false;
				GameManager.Instance.LoadCustomFlowForDebug("npcparadise", "Base_Castle", "tt_castle");
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("ApacheThunder.etg.ExpandTheGungeon", "ExpandTheGungeon", "2.9.17")]
	public class ExpandTheGungeon : BaseUnityPlugin
	{
		public static Texture2D ModLogo;

		public static Hook GameManagerHook;

		public static Hook initializeMainMenuHook;

		public const string GUID = "ApacheThunder.etg.ExpandTheGungeon";

		public const string ModName = "ExpandTheGungeon";

		public const string VERSION = "2.9.17";

		public static string ZipFilePath;

		public static string FilePath;

		public static string ResourcesPath;

		public static bool ItemAPISetup = false;

		public static bool ListsCleared = false;

		public static string ModAssetBundleName = "ExpandSharedAuto";

		public const string ModSettingsFileName = "ExpandTheGungeon_Settings.txt";

		public const string ModAudioAssetBundleName = "ExpandAudio";

		public const string ModSpriteAssetBundleName = "ExpandSpritesBase";

		public const string ModSoundBankName = "EX_SFX";

		public const string ConsoleCommandName = "expand";

		public static StringDB Strings;

		public static List<string> ExceptionText;

		private static GameObject m_FoyerCheckerOBJ;

		private static List<string> itemList;

		private bool m_IsCommandValid(string[] CommandText, string validCommands, string sourceSubCommand)
		{
			if (CommandText == null)
			{
				if (!string.IsNullOrEmpty(validCommands) && !string.IsNullOrEmpty(sourceSubCommand))
				{
					ETGModConsole.Log((object)("[ExpandTheGungeon] [" + sourceSubCommand + "] ERROR: Invalid console command specified! Valid Sub-Commands: \n" + validCommands), false);
				}
				return false;
			}
			if (CommandText.Length == 0)
			{
				if (!string.IsNullOrEmpty(validCommands) && !string.IsNullOrEmpty(sourceSubCommand))
				{
					ETGModConsole.Log((object)("[ExpandTheGungeon] [" + sourceSubCommand + "] No sub-command specified. Valid Sub-Commands: \n" + validCommands), false);
				}
				return false;
			}
			if (string.IsNullOrEmpty(CommandText[0]))
			{
				if (!string.IsNullOrEmpty(validCommands) && !string.IsNullOrEmpty(sourceSubCommand))
				{
					ETGModConsole.Log((object)("[ExpandTheGungeon] [" + sourceSubCommand + "] No sub-command specified. Valid Sub-Commands: \n" + validCommands), false);
				}
				return false;
			}
			if (CommandText.Length > 1)
			{
				if (!string.IsNullOrEmpty(validCommands) && !string.IsNullOrEmpty(sourceSubCommand))
				{
					ETGModConsole.Log((object)("[ExpandTheGungeon] [" + sourceSubCommand + "] ERROR: Only one sub-command is accepted!. Valid Commands: \n" + validCommands), false);
				}
				return false;
			}
			return true;
		}

		public void Start()
		{
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Invalid comparison between Unknown and I4
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Invalid comparison between Unknown and I4
			FilePath = ETGMod.FolderPath((BaseUnityPlugin)(object)this);
			ZipFilePath = ETGMod.FolderPath((BaseUnityPlugin)(object)this);
			ResourcesPath = ETGMod.ResourcesDirectory;
			ExceptionText = new List<string>();
			try
			{
				ExpandSettings.LoadSettings();
			}
			catch (Exception ex)
			{
				ExceptionText.Add(ex.ToString());
			}
			itemList = new List<string>
			{
				"Baby Good Hammer", "Corruption Bomb", "Table Tech Assassin", "ex:bloodied_scarf", "Cronenberg Bullets", "Mimiclay", "The Lead Key", "RockSlide", "Corrupted Master Round", "Wooden Crest",
				"Bootleg Pistol", "Bootleg Shotgun", "Bootleg Machine Pistol", "Bulletkin Gun", "Baby Sitter", "Pow Block", "Cursed Brick", "Black Revolver", "Golden Revolver", "Sonic Box",
				"The Third Eye", "Clown Friend", "Clown Bullets", "Portable Elevator", "Portable Ship", "Old Key"
			};
			if (((int)Application.platform == 13) | ((int)Application.platform == 1))
			{
				ModAssetBundleName = "ExpandSharedAuto_Linux";
			}
			ExpandAssets.InitCustomAssetBundles("ExpandTheGungeon");
			ETGModMainBehaviour.WaitForGameManagerStart((Action<GameManager>)GMStart);
		}

		public void GMStart(GameManager gameManager)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			if (ExceptionText.Count > 0)
			{
				foreach (string item in ExceptionText)
				{
					ETGModConsole.Log((object)item, false);
				}
				return;
			}
			try
			{
				Strings = new StringDB();
				ExpandHooks.InstallMidGameSaveHooks();
				if (ExpandSettings.EnableLogo)
				{
					initializeMainMenuHook = new Hook((MethodBase)typeof(MainMenuFoyerController).GetMethod("InitializeMainMenu", BindingFlags.Instance | BindingFlags.Public), typeof(ExpandTheGungeon).GetMethod("InitializeMainMenuHook", BindingFlags.Instance | BindingFlags.Public), (object)typeof(MainMenuFoyerController));
				}
				gameManager.OnNewLevelFullyLoaded += ExpandObjectMods.InitSpecialMods;
			}
			catch (Exception ex)
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] ERROR: Exception occured while installing hooks!", false);
				Debug.LogException(ex);
				return;
			}
			try
			{
				ExpandHooks.InstallRequiredHooks();
				ExpandDungeonMusicAPI.InitHooks();
			}
			catch (Exception ex2)
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] ERROR: Exception occured while installing hooks!", false);
				Debug.Log((object)"[ExpandTheGungeon] ERROR: Exception occured while installing hooks!");
				Debug.LogException(ex2);
				return;
			}
			AssetBundle val = ResourceManager.LoadAssetBundle(ModAssetBundleName);
			AssetBundle expandAudio = ResourceManager.LoadAssetBundle("ExpandAudio");
			AssetBundle val2 = ResourceManager.LoadAssetBundle("shared_auto_001");
			AssetBundle sharedAssets = ResourceManager.LoadAssetBundle("shared_auto_002");
			AssetBundle braveResources = ResourceManager.LoadAssetBundle("brave_resources_001");
			AssetBundle val3 = ResourceManager.LoadAssetBundle("enemies_base_001");
			ExpandAssets.InitAudio(expandAudio, "EX_SFX");
			ExpandDungeonPrefabs.InitCustomGameLevelDefinitions(braveResources, gameManager);
			ExpandPrefabs.InitSpriteCollections(val, val2);
			ExpandEnemyDatabase.InitSpriteCollections(val);
			SetupItemAPI(val);
			try
			{
				ExpandPrefabs.InitPrefabs(val, val2, sharedAssets, braveResources, val3);
				ExpandAmmonomiconDatabase.Init(val);
				ExpandEnemyDatabase.InitPrefabs(val);
				ExpandRoomPrefabs.InitCustomRooms(val, val2, sharedAssets, braveResources, val3);
				ExpandDungeonFlow.InitDungeonFlows(sharedAssets);
				BootlegGuns.PostInit();
				ClownFriend.PostInit();
				ExpandDungeonPrefabs.InitDungoenPrefabs(val, val2, sharedAssets, braveResources);
			}
			catch (Exception ex3)
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] ERROR: Exception occured while building prefabs!", true);
				Debug.LogException(ex3);
				val = null;
				val2 = null;
				sharedAssets = null;
				val3 = null;
				braveResources = null;
				return;
			}
			DungeonFlowModule.Install();
			InitConsoleCommands("expand");
			CreateFoyerController();
			ETGModConsole.DungeonDictionary.Add("belly", "tt_belly");
			ETGModConsole.DungeonDictionary.Add("monster", "tt_belly");
			ETGModConsole.DungeonDictionary.Add("jungle", "tt_jungle");
			ETGModConsole.DungeonDictionary.Add("office", "tt_office");
			ETGModConsole.DungeonDictionary.Add("phobos", "tt_phobos");
			ETGModConsole.DungeonDictionary.Add("space", "tt_space");
			ETGModConsole.DungeonDictionary.Add("west", "tt_west");
			ETGModConsole.DungeonDictionary.Add("oldwest", "tt_west");
			val = null;
			val2 = null;
			sharedAssets = null;
			val3 = null;
			braveResources = null;
		}

		public static void CreateFoyerController()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)m_FoyerCheckerOBJ))
			{
				m_FoyerCheckerOBJ = new GameObject("ExpandTheGungeon Foyer Checker", new Type[1] { typeof(ExpandFoyer) });
			}
		}

		private void SetupItemAPI(AssetBundle expandSharedAssets1)
		{
			if (ItemAPISetup)
			{
				return;
			}
			try
			{
				Assets.SetupSpritesFromAssembly(Assembly.GetExecutingAssembly(), "ExpandTheGungeon/Sprites");
				Tools.Init();
				ItemBuilder.Init();
				BabyGoodHammer.Init(expandSharedAssets1);
				CorruptionBomb.Init(expandSharedAssets1);
				if (ExpandSettings.EnableBloodiedScarfFix)
				{
					ExpandRedScarf.Init(expandSharedAssets1);
				}
				TableTechAssassin.Init(expandSharedAssets1);
				CorruptedJunk.Init(expandSharedAssets1);
				BootlegGuns.Init(expandSharedAssets1);
				CronenbergBullets.Init(expandSharedAssets1);
				Mimiclay.Init(expandSharedAssets1);
				TheLeadKey.Init(expandSharedAssets1);
				RockSlide.Init(expandSharedAssets1);
				CustomMasterRounds.Init(expandSharedAssets1);
				WoodenCrest.Init(expandSharedAssets1);
				BulletKinGun.Init();
				BabySitter.Init(expandSharedAssets1);
				PowBlock.Init(expandSharedAssets1);
				CursedBrick.Init(expandSharedAssets1);
				SonicRing.Init(expandSharedAssets1);
				SonicBox.Init(expandSharedAssets1);
				ThirdEye.Init(expandSharedAssets1);
				ClownBullets.Init(expandSharedAssets1);
				ClownFriend.Init(expandSharedAssets1);
				PortableElevator.Init(expandSharedAssets1);
				PortableShip.Init(expandSharedAssets1);
				WestBrosRevolverGenerator.Init();
				HotShotShotGun.Init();
				ExpandKeyBulletPickup.Init(expandSharedAssets1);
				ExpandSynergies.Init();
				ItemAPISetup = true;
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
		}

		private void GameManager_Awake(Action<GameManager> orig, GameManager self)
		{
			orig(self);
			self.OnNewLevelFullyLoaded += ExpandObjectMods.InitSpecialMods;
			ExpandDungeonPrefabs.ReInitFloorDefinitions(self);
			CreateFoyerController();
		}

		public void InitializeMainMenuHook(Action<MainMenuFoyerController> orig, MainMenuFoyerController self)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			orig(self);
			if (!ExpandSettings.EnableLogo)
			{
				return;
			}
			bool flag = false;
			if (Object.FindObjectsOfType<BaseUnityPlugin>() != null)
			{
				BaseUnityPlugin[] array = Object.FindObjectsOfType<BaseUnityPlugin>();
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i].Info.Metadata.GUID.ToLower().Contains("frostandgunfire"))
					{
						flag = true;
					}
				}
			}
			if (flag)
			{
				SetupLabel(self.TitleCard, "ExpandTheGungeon: v2.9.17", Color.white, Vector2.op_Implicit(new Vector2(380f, 22f)), new Vector2(264f, 22f), new Vector2(276f, 22f));
				return;
			}
			if ((Object)(object)ModLogo == (Object)null)
			{
				ModLogo = ExpandAssets.LoadAsset<Texture2D>("EXLogo");
				((Texture)ModLogo).filterMode = (FilterMode)0;
			}
			((dfTextureSprite)self.TitleCard).Texture = (Texture)(object)ModLogo;
			SetupLabel(self.TitleCard, "v2.9.17", Color.black, Vector2.op_Implicit(new Vector2(564f, -28f)), new Vector2(64f, 16f), new Vector2(74f, 16f));
		}

		private void SetupLabel(dfControl controlParent, string TextString, Color TextColor, Vector3 UIPosition, Vector2 Size, Vector2 MaxSize)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			dfTiledSprite component = ExpandAssets.LoadOfficialAsset<GameObject>("Weapon Skull Ammo FG", ExpandAssets.AssetSource.SharedAuto1).GetComponent<dfTiledSprite>();
			dfFont component2 = ExpandAssets.LoadOfficialAsset<GameObject>("04b03_df40", ExpandAssets.AssetSource.SharedAuto1).GetComponent<dfFont>();
			dfLabel val = controlParent.AddControl<dfLabel>();
			((Object)val).name = "EXVersionLabel";
			val.Atlas = ((dfSprite)component).Atlas;
			val.Font = (dfFontBase)(object)component2;
			((dfControl)val).Anchor = (dfAnchorStyle)8;
			((dfControl)val).IsEnabled = true;
			((dfControl)val).IsVisible = true;
			((dfControl)val).IsInteractive = true;
			((dfControl)val).Tooltip = string.Empty;
			((dfControl)val).Pivot = (dfPivotPoint)8;
			((dfControl)val).zindex = 9;
			((dfControl)val).Opacity = 1f;
			((dfControl)val).Color = Color32.op_Implicit(TextColor);
			((dfControl)val).DisabledColor = Color32.op_Implicit(Color.gray);
			((dfControl)val).Size = Size;
			((dfControl)val).MinimumSize = ((dfControl)val).Size;
			((dfControl)val).MaximumSize = MaxSize;
			((dfControl)val).ClipChildren = false;
			((dfControl)val).InverseClipChildren = false;
			((dfControl)val).TabIndex = -1;
			((dfControl)val).CanFocus = false;
			((dfControl)val).AutoFocus = false;
			((dfControl)val).IsLocalized = false;
			((dfControl)val).HotZoneScale = Vector2.one;
			((dfControl)val).AllowSignalEvents = true;
			((dfControl)val).PrecludeUpdateCycle = false;
			val.PerCharacterOffset = Vector2.op_Implicit(Vector2.zero);
			val.PreventFontChanges = true;
			val.BackgroundSprite = string.Empty;
			val.BackgroundColor = Color32.op_Implicit(Color.white);
			if (TextColor == Color.white)
			{
				val.BackgroundColor = Color32.op_Implicit(Color.black);
			}
			val.AutoSize = true;
			val.AutoHeight = false;
			val.WordWrap = false;
			val.Text = TextString;
			val.BottomColor = Color32.op_Implicit(Color.white);
			if (TextColor == Color.white)
			{
				val.BottomColor = Color32.op_Implicit(Color.black);
			}
			val.TextAlignment = (TextAlignment)2;
			val.VerticalAlignment = (dfVerticalAlignment)0;
			val.TextScale = 0.5f;
			val.TextScaleMode = (dfTextScaleMode)0;
			val.CharacterSpacing = 0;
			val.ColorizeSymbols = false;
			val.ProcessMarkup = false;
			val.Outline = false;
			val.OutlineSize = 0;
			val.ShowGradient = false;
			val.OutlineColor = Color32.op_Implicit(Color.white);
			if (TextColor == Color.white)
			{
				val.OutlineColor = Color32.op_Implicit(Color.black);
			}
			val.Shadow = false;
			val.ShadowColor = Color32.op_Implicit(Color.gray);
			val.ShadowOffset = new Vector2(1f, -1f);
			val.Padding = new RectOffset
			{
				left = 0,
				right = 0,
				top = 0,
				bottom = 0
			};
			val.TabSize = 48;
			val.MaintainJapaneseFont = false;
			val.MaintainKoreanFont = false;
			val.MaintainRussianFont = false;
			((dfControl)val).Position = UIPosition;
			component2 = null;
			component = null;
		}

		private void InitConsoleCommands(string MainCommandName)
		{
			ETGModConsole.Commands.AddGroup(MainCommandName, (Action<string[]>)ExpandConsoleInfo);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("createSpriteCollection", (Action<string[]>)ExpandSerializeCollection);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("dump_layout", (Action<string[]>)ExpandDumpLayout);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("debug", (Action<string[]>)ExpandDebug);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("list_items", (Action<string[]>)ExpandCustomItemsInfo);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("youtubemode", (Action<string[]>)ExpandYouTubeSafeCommand);
			ETGModConsole.Commands.GetGroup(MainCommandName).AddUnit("savesettings", (Action<string[]>)ExpandExportSettings);
		}

		private void ExpandConsoleInfo(string[] consoleText)
		{
			if (ETGModConsole.Commands.GetGroup("expand") == null || ETGModConsole.Commands.GetGroup("expand").GetAllUnitNames() == null)
			{
				return;
			}
			List<string> list = new List<string>();
			string[] allUnitNames = ETGModConsole.Commands.GetGroup("expand").GetAllUnitNames();
			foreach (string item in allUnitNames)
			{
				list.Add(item);
			}
			if (list.Count <= 0)
			{
				return;
			}
			if (!m_IsCommandValid(consoleText, string.Empty, string.Empty))
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] No sub command specified! The following console commands are available for ExpandTheGungeon:\n", false);
				{
					foreach (string item2 in list)
					{
						ETGModConsole.Log((object)("    " + item2 + "\n"), false);
					}
					return;
				}
			}
			if (list.Contains(consoleText[0].ToLower()))
			{
				return;
			}
			ETGModConsole.Log((object)"[ExpandTheGungeon] Invalid sub-command! The following console commands are available for ExpandTheGungeon:\n", false);
			foreach (string item3 in list)
			{
				ETGModConsole.Log((object)("    " + item3 + "\n"), false);
			}
		}

		private void ExpandDebug(string[] consoleText)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Invalid comparison between Unknown and I4
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			string text = "stats\nclearroom\nunsealroom\nfixplayerinput";
			if (!m_IsCommandValid(consoleText, text, "debug"))
			{
				return;
			}
			RoomHandler currentRoom = GameManager.Instance.PrimaryPlayer.CurrentRoom;
			switch (consoleText[0].ToLower())
			{
			case "stats":
				if (!ExpandSettings.debugMode)
				{
					ExpandSettings.debugMode = true;
					ETGModConsole.Log((object)"[ExpandTheGungeon] Installing RoomHandler.OnEntered Hook....", false);
					ExpandHooks.enterRoomHook = new Hook((MethodBase)typeof(RoomHandler).GetMethod("OnEntered", BindingFlags.Instance | BindingFlags.NonPublic), typeof(ExpandHooks).GetMethod("EnteredNewRoomHook", BindingFlags.Instance | BindingFlags.NonPublic), (object)typeof(RoomHandler));
				}
				else if (ExpandSettings.debugMode)
				{
					ExpandSettings.debugMode = false;
					if (ExpandHooks.enterRoomHook != null)
					{
						ETGModConsole.Log((object)"[ExpandTheGungeon] Uninstalling RoomHandler.OnEntered Hook....", false);
						ExpandHooks.enterRoomHook.Dispose();
						ExpandHooks.enterRoomHook = null;
					}
				}
				ETGModConsole.Log((object)"[ExpandTheGungeon] Debug Stats: ", false);
				ETGModConsole.Log((object)("Debug Stats: " + ExpandSettings.debugMode), false);
				ETGModConsole.Log((object)("Debug Exceptions: " + ExpandSettings.debugMode), false);
				break;
			case "clearroom":
			{
				if (currentRoom == null)
				{
					break;
				}
				List<AIActor> activeEnemies = currentRoom.GetActiveEnemies((ActiveEnemyType)1);
				if (activeEnemies != null && activeEnemies.Count > 0)
				{
					for (int i = 0; i < activeEnemies.Count; i++)
					{
						currentRoom.DeregisterEnemy(activeEnemies[i], false);
						Object.Destroy((Object)(object)((Component)activeEnemies[i]).gameObject);
					}
				}
				break;
			}
			case "unsealroom":
				if (currentRoom != null && currentRoom.IsSealed)
				{
					currentRoom.UnsealRoom();
				}
				break;
			case "fixplayerinput":
			{
				PlayerController primaryPlayer = GameManager.Instance.PrimaryPlayer;
				CameraController mainCameraController = GameManager.Instance.MainCameraController;
				if (Object.op_Implicit((Object)(object)mainCameraController) && Object.op_Implicit((Object)(object)primaryPlayer))
				{
					mainCameraController.OverridePosition = ((BraveBehaviour)primaryPlayer).transform.position;
					mainCameraController.SetManualControl(false, true);
				}
				if (Object.op_Implicit((Object)(object)primaryPlayer))
				{
					primaryPlayer.CurrentInputState = (PlayerInputState)0;
					((BraveBehaviour)primaryPlayer).healthHaver.IsVulnerable = true;
				}
				if ((int)GameManager.Instance.CurrentGameType == 1)
				{
					PlayerController otherPlayer = GameManager.Instance.GetOtherPlayer(primaryPlayer);
					if (Object.op_Implicit((Object)(object)otherPlayer))
					{
						otherPlayer.CurrentInputState = (PlayerInputState)0;
						((BraveBehaviour)otherPlayer).healthHaver.IsVulnerable = true;
					}
				}
				break;
			}
			default:
				ETGModConsole.Log((object)("[ExpandTheGungeon] ERROR: Unknown sub-command. Valid Commands: \n" + text), false);
				break;
			}
		}

		private void ExpandDumpLayout(string[] consoleText)
		{
			string text = "currentroom\ncurrentroomhandler\nallknownroomprefabs\ncurrentdungeonlayout";
			if (!m_IsCommandValid(consoleText, text, "dump_layout"))
			{
				return;
			}
			if (consoleText[0].ToLower() == "currentroom")
			{
				RoomDebug.DumpCurrentRoomLayout();
			}
			else if (consoleText[0].ToLower() == "currentroomhandler")
			{
				RoomHandler absoluteParentRoom = ((DungeonPlaceableBehaviour)GameManager.Instance.PrimaryPlayer).GetAbsoluteParentRoom();
				RoomDebug.DumpCurrentRoomLayout(null, absoluteParentRoom);
			}
			else if (consoleText[0] == "allknownroomprefabs")
			{
				ETGModConsole.Log((object)"Saving room layouts to PNG files. Please wait...", false);
				foreach (WeightedRoom element in ExpandPrefabs.CastleRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element.room);
					}
				}
				foreach (WeightedRoom element2 in ExpandPrefabs.SewersRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element2.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element2.room);
					}
				}
				foreach (WeightedRoom element3 in ExpandPrefabs.Gungeon_RoomTable.includedRooms.elements)
				{
					if ((Object)(object)element3.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element3.room);
					}
				}
				foreach (WeightedRoom element4 in ExpandPrefabs.AbbeyRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element4.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element4.room);
					}
				}
				foreach (WeightedRoom element5 in ExpandPrefabs.MinesRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element5.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element5.room);
					}
				}
				foreach (WeightedRoom element6 in ExpandPrefabs.CatacombsRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element6.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element6.room);
					}
				}
				foreach (WeightedRoom element7 in ExpandPrefabs.ForgeRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element7.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element7.room);
					}
				}
				foreach (WeightedRoom element8 in ExpandPrefabs.BulletHellRoomTable.includedRooms.elements)
				{
					if ((Object)(object)element8.room != (Object)null)
					{
						RoomDebug.LogRoomToPNGFile(element8.room);
					}
				}
				foreach (WeightedRoom element9 in ExpandPrefabs.SecretRoomTable.includedRooms.elements)
				{
					RoomDebug.LogRoomToPNGFile(element9.room);
				}
				ETGModConsole.Log((object)"Room dump process complete!", false);
			}
			else if (consoleText[0].ToLower() == "currentdungeonlayout")
			{
				RoomDebug.LogDungeonToPNGFile();
				ETGModConsole.Log((object)("Current Dungeon '" + ((Object)((Component)GameManager.Instance.Dungeon).gameObject).name + "' has been succesfully dumped."), false);
			}
			else
			{
				ETGModConsole.Log((object)("[ExpandTheGungeon] [dump_layout] ERROR: Unknown sub-command. Valid Commands: \n" + text), false);
			}
		}

		private void ExpandCustomItemsInfo(string[] consoleText)
		{
			ETGModConsole.Log((object)"Custom Items: ", false);
			foreach (string item in itemList)
			{
				ETGModConsole.Log((object)("    " + item), false);
			}
		}

		private void ExpandYouTubeSafeCommand(string[] consoleTest)
		{
			if (ExpandSettings.youtubeSafeMode)
			{
				ETGModConsole.Log((object)"No longer YouTube safe.", false);
				ExpandSettings.youtubeSafeMode = false;
			}
			else
			{
				ETGModConsole.Log((object)"Now YouTube Safe.", false);
				ExpandSettings.youtubeSafeMode = true;
			}
		}

		private void ExpandExportSettings(string[] consoleText)
		{
			ExpandSettings.SaveSettings();
			ETGModConsole.Log((object)"[ExpandTheGungeon] Settings have been saved!", false);
		}

		public void ExpandSerializeCollection(string[] consoleText)
		{
			try
			{
				ExpandAssets.InitSpritesAssetBundle();
			}
			catch (Exception ex)
			{
				Debug.Log((object)"[ExpandTheGungeon] ERROR: Exception while loading sprite asset bundles! This is an option asset bundle however it is required for building sprite collections!");
				Debug.LogException(ex);
			}
			if (ExpandLists.SpriteCollections == null)
			{
				ExpandLists.SpriteCollections = new Dictionary<string, List<string>>
				{
					["EXTrapCollection"] = ExpandLists.EXTrapCollection,
					["EXSpaceCollection"] = ExpandLists.EXSpaceCollection,
					["EXOfficeCollection"] = ExpandLists.EXOfficeCollection,
					["EXJungleCollection"] = ExpandLists.EXJungleCollection,
					["EXPortableElevatorCollection"] = ExpandLists.EXPortableElevatorCollection,
					["EXBalloonCollection"] = ExpandLists.EXBalloonCollection,
					["EXItemCollection"] = ExpandLists.EXItemCollection,
					["ClownkinCollection"] = ExpandLists.ClownkinCollection,
					["EXFoyerCollection"] = ExpandLists.EXFoyerCollection,
					["GungeoneerMimicCollection"] = ExpandLists.EXGungeoneerMimicCollection,
					["EXSecretDoorCollection"] = ExpandLists.EXSecretDoorCollection
				};
			}
			int xres = 2048;
			int yres = 2048;
			List<string> value = null;
			string text = "EXTrapCollection";
			string text2 = text;
			string pathOverride = string.Empty;
			if (!ExpandLists.SpriteCollections.TryGetValue(text, out value))
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] ERROR: Default list not found!", false);
			}
			else if (consoleText.Length > 1)
			{
				xres = int.Parse(consoleText[0]);
				yres = int.Parse(consoleText[1]);
				if (consoleText.Length > 2)
				{
					text2 = consoleText[2];
					if (!ExpandLists.SpriteCollections.TryGetValue(text2, out value))
					{
						ETGModConsole.Log((object)"[ExpandTheGungeon] Requested Collection not found! Using predefined list instead!", false);
						ExpandLists.SpriteCollections.TryGetValue(text, out value);
					}
				}
				else
				{
					ETGModConsole.Log((object)"[ExpandTheGungeon] Collection name not specified! Using predefined fall back list...", false);
				}
				if (consoleText.Length > 3)
				{
					pathOverride = consoleText[3];
				}
				SpriteSerializer.SerializeSpriteCollection(text2, value, xres, yres, pathOverride);
				ETGModConsole.Log((object)"[ExpandTheGungeon] Sprite collection successfully built and exported!", false);
			}
			else
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] Not enough commands or too many! Must provide atlas name and resolution! Please specify a name, width, and height!", false);
				ETGModConsole.Log((object)"[ExpandTheGungeon] Using default resolution and collection...", false);
				SpriteSerializer.SerializeSpriteCollection(text, value, xres, yres);
			}
		}
	}
	public static class Tools
	{
		public static bool verbose = false;

		public static string modID = "EX";

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

		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)
			{
				ETGModConsole.Log((object)("<color=#" + color + ">" + modID + ": " + obj.ToString() + "</color>"), false);
			}
			Log(obj.ToString());
		}

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

		public static void PrintError<T>(T obj, string color = "FF0000")
		{
			ETGModConsole.Log((object)("<color=#" + color + ">" + modID + ": " + obj.ToString() + "</color>"), false);
			Log(obj.ToString());
		}

		public static void PrintException(Exception e, string color = "FF0000")
		{
			ETGModConsole.Log((object)("<color=#" + color + ">" + modID + ": " + e.Message + "</color>"), false);
			ETGModConsole.Log((object)e.StackTrace, false);
			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)
			{
				using (StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, fileName), append: true))
				{
					streamWriter.WriteLine(obj.ToString());
				}
			}
		}

		public static void LogStringToFile(string text, string fileName)
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, fileName), append: true);
			streamWriter.WriteLine(text);
		}

		public static void Dissect(this GameObject obj)
		{
			Print(((Object)obj).name + " Components:");
			Component[] components = obj.GetComponents<Component>();
			foreach (Component val in components)
			{
				Print("    " + ((object)val).GetType());
			}
		}

		public static void ShowHitBox(this SpeculativeRigidbody body)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			PixelCollider hitboxPixelCollider = body.HitboxPixelCollider;
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = "HitboxDisplay";
			obj.transform.SetParent(((BraveBehaviour)body).transform);
			Print(((Object)body).name ?? "");
			Print($"    Offset: {hitboxPixelCollider.Offset}, Dimesions: {hitboxPixelCollider.Dimensions}");
			obj.transform.localScale = new Vector3((float)hitboxPixelCollider.Dimensions.x / 16f, (float)hitboxPixelCollider.Dimensions.y / 16f, 1f);
			Vector3 localPosition = new Vector3((float)hitboxPixelCollider.Offset.x + (float)hitboxPixelCollider.Dimensions.x * 0.5f, (float)hitboxPixelCollider.Offset.y + (float)hitboxPixelCollider.Dimensions.y * 0.5f, -16f) / 16f;
			obj.transform.localPosition = localPosition;
		}

		public static void HideHitBox(this SpeculativeRigidbody body)
		{
			Transform val = ((BraveBehaviour)body).transform.Find("HitboxDisplay");
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.Destroy((Object)(object)val);
			}
		}

		public static void ExportTexture(Texture texture)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			File.WriteAllBytes(Path.Combine(ETGMod.ResourcesDirectory, ((Object)texture).name + ".png"), ImageConversion.EncodeToPNG((Texture2D)texture));
		}

		public static void ExportTexture(Texture2D texture)
		{
			File.WriteAllBytes(Path.Combine(ETGMod.ResourcesDirectory, ((Object)texture).name + ".png"), ImageConversion.EncodeToPNG(texture));
		}

		public static void DumpSpecificSpriteCollection(tk2dSpriteCollectionData sprites, bool debugMode = false, bool overrideFlag = false)
		{
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Expected O, but got Unknown
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			string spriteCollectionName = sprites.spriteCollectionName;
			string text = "DUMPsprites/" + spriteCollectionName;
			string path = Path.Combine(ETGMod.ResourcesDirectory, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
			if (debugMode)
			{
				ETGModConsole.Log((object)("[ExpandTheGungeon] Debug: Current Sprite Collection Length: " + sprites.spriteDefinitions.Length), false);
			}
			if (File.Exists(path))
			{
				return;
			}
			Texture2D val = null;
			Texture2D val2 = null;
			Color[] array = null;
			for (int i = 0; i < sprites.spriteDefinitions.Length; i++)
			{
				tk2dSpriteDefinition val3 = sprites.spriteDefinitions[i];
				Texture mainTexture = val3.material.mainTexture;
				Texture2D val4 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
				if (!((Object)(object)val4 != (Object)null) && val3.Valid && !((Object)(object)val3.materialInst != (Object)null && overrideFlag))
				{
					continue;
				}
				try
				{
					_ = val3.name;
					string text2 = text + "/" + val3.name;
					if ((Object)(object)val != (Object)(object)val4)
					{
						if (debugMode)
						{
							ETGModConsole.Log((object)"[ExpandTheGungeon] Debug: Dumping Sprite Atlas to file.", false);
						}
						val = val4;
						val2 = ETGMod.GetRW(val4);
						array = val2.GetPixels();
						path = Path.Combine(ETGMod.ResourcesDirectory, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
						Directory.GetParent(path).Create();
						File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val2));
					}
					double num = 1.0;
					double num2 = 1.0;
					double num3 = 0.0;
					double num4 = 0.0;
					for (int j = 0; j < val3.uvs.Length; j++)
					{
						if ((double)val3.uvs[j].x < num)
						{
							num = val3.uvs[j].x;
						}
						if ((double)val3.uvs[j].y < num2)
						{
							num2 = val3.uvs[j].y;
						}
						if (num3 < (double)val3.uvs[j].x)
						{
							num3 = val3.uvs[j].x;
						}
						if (num4 < (double)val3.uvs[j].y)
						{
							num4 = val3.uvs[j].y;
						}
					}
					int num5 = (int)Math.Floor(num * (double)((Texture)val4).width);
					int num6 = (int)Math.Floor(num2 * (double)((Texture)val4).height);
					int num7 = (int)Math.Ceiling(num3 * (double)((Texture)val4).width);
					int num8 = (int)Math.Ceiling(num4 * (double)((Texture)val4).height);
					int num9 = num7 - num5;
					int num10 = num8 - num6;
					Texture2D val5;
					if ((double)val3.uvs[0].x == num && (double)val3.uvs[0].y == num2 && (double)val3.uvs[1].x == num3 && (double)val3.uvs[1].y == num2 && (double)val3.uvs[2].x == num && (double)val3.uvs[2].y == num4 && (double)val3.uvs[3].x == num3 && (double)val3.uvs[3].y == num4)
					{
						if (debugMode)
						{
							ETGModConsole.Log((object)("[ExpandTheGungeon] Debug: flag8 at SpriteID " + i), false);
						}
						val5 = new Texture2D(num9, num10);
						val5.SetPixels(val2.GetPixels(num5, num6, num9, num10));
					}
					else
					{
						if (val3.uvs[0].x == val3.uvs[1].x)
						{
							int num11 = num10;
							num10 = num9;
							num9 = num11;
							if (debugMode)
							{
								ETGModConsole.Log((object)("[ExpandTheGungeon] Debug: flag9 at SpriteID " + i), false);
							}
						}
						if (debugMode)
						{
							ETGModConsole.Log((object)("[ExpandTheGungeon] Debug: Prepering to dump sprite texture at SpriteID " + i), false);
						}
						val5 = new Texture2D(num9, num10);
						double num12 = val3.uvs[1].x - val3.uvs[0].x;
						double num13 = val3.uvs[2].x - val3.uvs[0].x;
						double num14 = val3.uvs[1].y - val3.uvs[0].y;
						double num15 = val3.uvs[2].y - val3.uvs[0].y;
						double num16 = (float)((Texture)val4).width * (val3.uvs[3].x - val3.uvs[0].x);
						double num17 = (float)((Texture)val4).height * (val3.uvs[3].y - val3.uvs[0].y);
						double num18 = 0.001;
						double num19 = ((num12 < num18) ? 0.0 : num16);
						double num20 = ((num13 < num18) ? 0.0 : num16);
						double num21 = ((num14 < num18) ? 0.0 : num17);
						double num22 = ((num15 < num18) ? 0.0 : num17);
						if (debugMode)
						{
							ETGModConsole.Log((object)"[ExpandTheGungeon] Debug: Prepering to set pixels for texture2D4...", false);
						}
						for (int k = 0; k < num10; k++)
						{
							double num23 = (double)k / (double)num10;
							for (int l = 0; l < num9; l++)
							{
								double num24 = (double)l / (double)num9;
								double num25 = num24 * num19 + num23 * num20;
								double num26 = num24 * num21 + num23 * num22;
								double num27 = Math.Round((double)(val3.uvs[0].y * (float)((Texture)val4).height) + num26) * (double)((Texture)val4).width + Math.Round((double)(val3.uvs[0].x * (float)((Texture)val4).width) + num25);
								val5.SetPixel(l, k, array[(int)num27]);
							}
						}
					}
					if (debugMode)
					{
						ETGModConsole.Log((object)"[ExpandTheGungeon] Debug: Writing sprite texture to file...", false);
					}
					path = Path.Combine(ETGMod.ResourcesDirectory, text2.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
					if (!File.Exists(path))
					{
						Directory.GetParent(path).Create();
						File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val5));
					}
				}
				catch (Exception ex)
				{
					if (debugMode)
					{
						ETGModConsole.Log((object)("Exception occured while processing sprite id '" + i + "'!"), false);
						Debug.LogException(ex);
					}
				}
			}
		}
	}
	public class ExpandAssets
	{
		public enum AssetSource
		{
			BraveResources,
			SharedAuto1,
			SharedAuto2,
			EnemiesBase,
			FlowBase
		}

		public static T LoadAsset<T>(string assetPath) where T : Object
		{
			return ResourceManager.LoadAssetBundle(ExpandTheGungeon.ModAssetBundleName).LoadAsset<T>(assetPath);
		}

		public static T LoadSpriteAsset<T>(string assetPath) where T : Object
		{
			return ResourceManager.LoadAssetBundle("ExpandSpritesBase").LoadAsset<T>(assetPath);
		}

		public static T LoadOfficialAsset<T>(string assetPath, AssetSource assetType) where T : Object
		{
			return assetType switch
			{
				AssetSource.BraveResources => ResourceManager.LoadAssetBundle("brave_resources_001").LoadAsset<T>(assetPath), 
				AssetSource.SharedAuto1 => ResourceManager.LoadAssetBundle("shared_auto_001").LoadAsset<T>(assetPath), 
				AssetSource.SharedAuto2 => ResourceManager.LoadAssetBundle("shared_auto_002").LoadAsset<T>(assetPath), 
				AssetSource.EnemiesBase => ResourceManager.LoadAssetBundle("enemies_base_001").LoadAsset<T>(assetPath), 
				AssetSource.FlowBase => ResourceManager.LoadAssetBundle("flows_base_001").LoadAsset<T>(assetPath), 
				_ => ResourceManager.LoadAssetBundle("brave_resources_001").LoadAsset<T>(assetPath), 
			};
		}

		public static void InitSpritesAssetBundle()
		{
			Dictionary<string, AssetBundle> dictionary = (Dictionary<string, AssetBundle>)typeof(ResourceManager).GetField("LoadedBundles", BindingFlags.Static | BindingFlags.NonPublic).GetValue(typeof(ResourceManager));
			AssetBundle val = null;
			val = LoadFromModZIPOrModFolder("ExpandSpritesBase".ToLower());
			if ((Object)(object)val != (Object)null)
			{
				dictionary.Add("ExpandSpritesBase", val);
				ExpandSettings.spritesBundlePresent = true;
			}
		}

		public static void InitCustomAssetBundles(string nameSpace = null)
		{
			Dictionary<string, AssetBundle> dictionary = ReflectionHelpers.ReflectGetField<Dictionary<string, AssetBundle>>(typeof(ResourceManager), "LoadedBundles");
			AssetBundle val = null;
			AssetBundle val2 = null;
			try
			{
				if (string.IsNullOrEmpty(nameSpace))
				{
					val = LoadFromModZIPOrModFolder(ExpandTheGungeon.ModAssetBundleName.ToLower());
					val2 = LoadFromModZIPOrModFolder("ExpandAudio".ToLower());
				}
				else
				{
					val = LoadAssetBundleFromResource(ExpandTheGungeon.ModAssetBundleName, nameSpace);
					val2 = LoadAssetBundleFromResource("ExpandAudio", nameSpace);
				}
				if ((Object)(object)val != (Object)null)
				{
					dictionary.Add(ExpandTheGungeon.ModAssetBundleName, val);
					if ((Object)(object)val2 != (Object)null)
					{
						dictionary.Add("ExpandAudio", val2);
						return;
					}
					string text = "[ExpandTheGungeon] ERROR: ExpandAudio asset bundle not found!";
					Debug.Log((object)text);
					ExpandTheGungeon.ExceptionText.Add(text);
				}
				else
				{
					string text2 = "[ExpandTheGungeon] ERROR: ExpandSharedAuto asset bundle not found!";
					Debug.Log((object)text2);
					ExpandTheGungeon.ExceptionText.Add(text2);
				}
			}
			catch (Exception ex)
			{
				string text3 = "[ExpandTheGungeon] ERROR: Exception while loading custom asset bundles! Possible GUID conflict with other custom AssetBundles?";
				Debug.Log((object)text3);
				Debug.LogException(ex);
				ExpandTheGungeon.ExceptionText.Add(text3);
			}
		}

		public static AssetBundle LoadFromModZIPOrModFolder(string AssetBundleName)
		{
			AssetBundle val = null;
			if (File.Exists(ExpandTheGungeon.ZipFilePath))
			{
				if (ExpandSettings.debugMode)
				{
					Debug.Log((object)"Zip Found");
				}
				ZipFile val2 = ZipFile.Read(ExpandTheGungeon.ZipFilePath);
				if (val2 != null && val2.Entries.Count > 0)
				{
					foreach (ZipEntry entry in val2.Entries)
					{
						if (entry.FileName == AssetBundleName)
						{
							using (MemoryStream memoryStream = new MemoryStream())
							{
								entry.Extract((Stream)memoryStream);
								memoryStream.Seek(0L, SeekOrigin.Begin);
								val = AssetBundle.LoadFromStream((Stream)memoryStream);
							}
							break;
						}
					}
				}
			}
			else if (File.Exists(ExpandTheGungeon.FilePath + "/" + AssetBundleName))
			{
				try
				{
					val = AssetBundle.LoadFromFile(ExpandTheGungeon.FilePath + "/" + AssetBundleName);
				}
				catch (Exception)
				{
				}
			}
			if (Object.op_Implicit((Object)(object)val))
			{
				return val;
			}
			return null;
		}

		public static AssetBundle LoadAssetBundleFromResource(string AssetBundleName, string nameSpace)
		{
			using (Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream($"{nameSpace}." + AssetBundleName))
			{
				if (stream != null)
				{
					byte[] array = new byte[stream.Length];
					stream.Read(array, 0, array.Length);
					return AssetBundle.LoadFromMemory(array);
				}
			}
			ETGModConsole.Log((object)("No bytes found in " + AssetBundleName), false);
			return null;
		}

		public static void InitAudio(AssetBundle expandAudio, string assetPath)
		{
			//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_004c: Unknown result type (might be due to invalid IL or missing references)
			TextAsset val = expandAudio.LoadAsset<TextAsset>(assetPath);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			byte[] bytes = val.bytes;
			IntPtr intPtr = Marshal.AllocHGlobal(bytes.Length);
			try
			{
				Marshal.Copy(bytes, 0, intPtr, bytes.Length);
				uint num = default(uint);
				AKRESULT val2 = AkSoundEngine.LoadAndDecodeBankFromMemory(intPtr, (uint)bytes.Length, false, ((Object)val).name, false, ref num);
				if (ExpandSettings.debugMode)
				{
					Console.WriteLine($"Result of soundbank load: {val2}.");
				}
			}
			finally
			{
				Marshal.FreeHGlobal(intPtr);
			}
		}

		public static void DumpTexture2DToFile(Texture2D target, bool useRandomFilenames = false)
		{
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			string text = "DUMPsprites/DUMP" + ((Object)target).name;
			string text2 = text + "/DUMP" + ((Object)target).name;
			if (useRandomFilenames)
			{
				text = text + "_" + Guid.NewGuid();
				text2 = text2 + "_" + Guid.NewGuid();
			}
			string path = Path.Combine(ETGMod.ResourcesDirectory, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
			if (!File.Exists(path))
			{
				path = Path.Combine(ETGMod.ResourcesDirectory, text2.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
				if (!File.Exists(path))
				{
					Directory.GetParent(path).Create();
					File.WriteAllBytes(path, ImageConversion.EncodeToPNG(target));
				}
			}
		}

		public static string RetrieveStringFromAssetBundle(AssetBundle bundle, string AssetPath)
		{
			return bundle.LoadAsset<TextAsset>(AssetPath).text;
		}

		public static List<string> BuildStringListFromAssetBundle(string assetPath)
		{
			if (string.IsNullOrEmpty(assetPath))
			{
				return new List<string>();
			}
			TextAsset val = ExpandAssets.LoadAsset<TextAsset>(assetPath);
			if (!Object.op_Implicit((Object)(object)val))
			{
				ETGModConsole.Log((object)("[ExpandTheGungeon] ERROR: TextAsset: " + assetPath + " was not found!"), false);
				return new List<string>(0);
			}
			string text = BytesToString(ExpandAssets.LoadAsset<TextAsset>(assetPath).bytes);
			if (string.IsNullOrEmpty(text))
			{
				ETGModConsole.Log((object)("[ExpandTheGungeon] ERROR: TextAsset: " + ((Object)val).name + " contains no strings!"), false);
				return new List<string>(0);
			}
			List<string> list = new List<string>();
			string[] array = text.Split(new char[1] { '\n' });
			if ((array == null) | (array.Length == 0))
			{
				return list;
			}
			string[] array2 = array;
			foreach (string item in array2)
			{
				list.Add(item);
			}
			return list;
		}

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

		public static void SaveStringToFile(string text, string filePath, string fileName)
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(filePath, fileName), append: true);
			streamWriter.WriteLine(text);
		}

		public static string DeserializeJSONDataFromAssetBundle(AssetBundle bundle, string AssetPath, string basePath = "Assets/ExpandSerializedData/", string fileExtension = ".txt")
		{
			string text = string.Empty;
			try
			{
				text = bundle.LoadAsset<TextAsset>(basePath + AssetPath + fileExtension).text;
			}
			catch (Exception)
			{
			}
			if (!string.IsNullOrEmpty(text))
			{
				return text;
			}
			ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
			return string.Empty;
		}

		public static string[] GetLinesFromAssetBundle(AssetBundle bundle, string AssetPath, string basePath = "Assets/", string fileExtension = ".txt")
		{
			string text = string.Empty;
			try
			{
				text = bundle.LoadAsset<TextAsset>(basePath + AssetPath + fileExtension).text;
			}
			catch (Exception)
			{
			}
			if (!string.IsNullOrEmpty(text))
			{
				return text.Split(new char[1] { '\n' });
			}
			ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
			return new string[0];
		}

		public static TileIndexGrid DeserializeTileIndexGridFromAssetBundle(AssetBundle bundle, string AssetPath, string basePath = "Assets/ExpandSerializedData/TilesetData/", string fileExtension = ".txt")
		{
			string text = string.Empty;
			try
			{
				text = bundle.LoadAsset<TextAsset>(basePath + AssetPath + fileExtension).text;
			}
			catch (Exception)
			{
			}
			if (!string.IsNullOrEmpty(text))
			{
				TileIndexGrid val = ScriptableObject.CreateInstance<TileIndexGrid>();
				JsonUtility.FromJsonOverwrite(text, (object)val);
				return val;
			}
			ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
			return null;
		}

		public static FacewallIndexGridDefinition DeserializeFacewallGridDefinitionFromAssetBundle(AssetBundle bundle, string AssetPath, string basePath = "Assets/ExpandSerializedData/TilesetData/", string fileExtension = ".txt")
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			string text = string.Empty;
			try
			{
				text = bundle.LoadAsset<TextAsset>(basePath + AssetPath + fileExtension).text;
			}
			catch (Exception)
			{
			}
			if (!string.IsNullOrEmpty(text))
			{
				FacewallIndexGridDefinition val = new FacewallIndexGridDefinition();
				JsonUtility.FromJsonOverwrite(text, (object)val);
				return val;
			}
			ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
			return null;
		}
	}
}
namespace ExpandTheGungeon.SpriteAPI
{
	public static class SpriteSerializer
	{
		private static tk2dSpriteCollectionData newCollection;

		private static RuntimeAtlasPacker AtlasPacker;

		public static void SerializeSpriteCollection(string CollectionName, List<string> spriteNames, int Xres, int Yres, string pathOverride = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (!ExpandSettings.spritesBundlePresent)
			{
				ETGModConsole.Log((object)"[ExpandTheGungeon] Unserialized sprite textures stored in optional asset bundle but it is missing! Ensure you have it setup properly!", false);
				return;
			}
			GameObject val = new GameObject(CollectionName);
			newCollection = GenerateNewSpriteCollection(val, CollectionName);
			AtlasPacker = new RuntimeAtlasPacker(Xres, Yres, (TextureFormat)4, 2);
			AddSpriteToObject(val, ExpandAssets.LoadSpriteAsset<Texture2D>(spriteNames[0]));
			if (spriteNames.Count > 0)
			{
				for (int i = 1; i < spriteNames.Count; i++)
				{
					AddSpriteToCollection(ExpandAssets.LoadSpriteAsset<Texture2D>(spriteNames[i]), newCollection);
				}
			}
			DumpSpriteCollection(newCollection, pathOverride);
			tk2dSpriteDefinition[] spriteDefinitions = newCollection.spriteDefinitions;
			for (int j = 0; j < spriteDefinitions.Length; j++)
			{
				spriteDefinitions[j].material = null;
			}
			newCollection.material = null;
			newCollection.materials = null;
			newCollection.textures = null;
			if (!string.IsNullOrEmpty(pathOverride))
			{
				SaveStringToFile(JsonUtility.ToJson((object)newCollection), pathOverride, CollectionName + ".txt");
			}
			else
			{
				SaveStringToFile(JsonUtility.ToJson((object)newCollection), ETGMod.ResourcesDirectory, CollectionName + ".txt");
			}
			Object.Destroy((Object)(object)val);
			newCollection = null;
			AtlasPacker = null;
		}

		public static void SerializeSpriteCollection(tk2dSpriteCollectionData collectionData, bool SaveTextures = false, string pathOverride = null)
		{
			if (SaveTextures)
			{
				DumpSpriteCollection(collectionData, pathOverride);
			}
			collectionData.material = null;
			collectionData.materials = null;
			collectionData.textures = null;
			tk2dSpriteDefinition[] spriteDefinitions = collectionData.spriteDefinitions;
			for (int i = 0; i < spriteDefinitions.Length; i++)
			{
				spriteDefinitions[i].material = null;
			}
			if (!string.IsNullOrEmpty(pathOverride))
			{
				SaveStringToFile(JsonUtility.ToJson((object)collectionData), pathOverride, ((Object)collectionData).name + ".txt");
			}
			else
			{
				SaveStringToFile(JsonUtility.ToJson((object)collectionData), ETGMod.ResourcesDirectory, ((Object)collectionData).name + ".txt");
			}
		}

		public static GameObject DeserializeSpriteCollectionFromAssetBundle(AssetBundle assetBundle, string GameObjectPath, string spriteAtlasPath, string serializedCollectionJSONName, bool addSpriteToObject = false, string spriteDefintionName = null, Material overrideMaterial = null)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			GameObject val = assetBundle.LoadAsset<GameObject>(GameObjectPath);
			Texture2D mainTexture = assetBundle.LoadAsset<Texture2D>(spriteAtlasPath);
			tk2dSpriteCollectionData val2 = val.AddComponent<tk2dSpriteCollectionData>();
			JsonUtility.FromJsonOverwrite(DeserializeJSONDataFromAssetBundle(assetBundle, serializedCollectionJSONName), (object)val2);
			if (Object.op_Implicit((Object)(object)overrideMaterial))
			{
				val2.materials = (Material[])(object)new Material[1]
				{
					new Material(overrideMaterial)
				};
			}
			else
			{
				val2.materials = (Material[])(object)new Material[1]
				{
					new Material(ShaderCache.Acquire(PlayerController.DefaultShaderName))
				};
			}
			val2.materials[0].mainTexture = (Texture)(object)mainTexture;
			tk2dSpriteDefinition[] spriteDefinitions = val2.spriteDefinitions;
			for (int i = 0; i < spriteDefinitions.Length; i++)
			{
				spriteDefinitions[i].material = val2.materials[0];
			}
			val2.InitDictionary();
			val2.inst.InitDictionary();
			if (addSpriteToObject)
			{
				tk2dSprite val3 = val.AddComponent<tk2dSprite>();
				if (!string.IsNullOrEmpty(spriteDefintionName))
				{
					((tk2dBaseSprite)val3).SetSprite(val2, spriteDefintionName);
				}
				else
				{
					((tk2dBaseSprite)val3).SetSprite(val2, 0);
				}
				((tk2dBaseSprite)val3).SortingOrder = 0;
				val.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val3;
			}
			return val;
		}

		public static tk2dSprite AddSpriteToObject(GameObject obj, GameObject existingSpriteCollectionObject, string mainSpriteDefinitionName, PerpendicularState spriteAlignment = 0, float HeightOffGround = 1f)
		{
			//IL_001c: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			tk2dSprite val = obj.AddComponent<tk2dSprite>();
			((tk2dBaseSprite)val).SetSprite(existingSpriteCollectionObject.GetComponent<tk2dSpriteCollectionData>(), mainSpriteDefinitionName);
			((tk2dBaseSprite)val).SortingOrder = 0;
			if ((int)spriteAlignment != 0)
			{
				((tk2dBaseSprite)val).CachedPerpState = spriteAlignment;
			}
			if (HeightOffGround != 1f)
			{
				((tk2dBaseSprite)val).HeightOffGround = HeightOffGround;
			}
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return val;
		}

		public static tk2dSprite AddSpriteToObject(GameObject obj, GameObject existingSpriteCollectionObject, int spriteID, PerpendicularState spriteAlignment = 0)
		{
			tk2dSprite val = obj.AddComponent<tk2dSprite>();
			((tk2dBaseSprite)val).SetSprite(existingSpriteCollectionObject.GetComponent<tk2dSpriteCollectionData>(), spriteID);
			((tk2dBaseSprite)val).SortingOrder = 0;
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return val;
		}

		public static tk2dSprite AddSpriteToObject(GameObject obj, tk2dSpriteCollectionData existingSpriteCollection, string mainSpriteDefinitionName, PerpendicularState spriteAlignment = 0)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			tk2dSprite val = obj.AddComponent<tk2dSprite>();
			((tk2dBaseSprite)val).SetSprite(existingSpriteCollection, mainSpriteDefinitionName);
			((tk2dBaseSprite)val).SortingOrder = 0;
			if ((int)spriteAlignment != 0)
			{
				((tk2dBaseSprite)val).CachedPerpState = spriteAlignment;
			}
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return val;
		}

		public static tk2dSprite AddSpriteToObject(GameObject obj, tk2dSpriteCollectionData existingSpriteCollection, int spriteID, PerpendicularState spriteAlignment = 0)
		{
			//IL_0016: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			tk2dSprite val = obj.AddComponent<tk2dSprite>();
			((tk2dBaseSprite)val).SetSprite(existingSpriteCollection, spriteID);
			((tk2dBaseSprite)val).SortingOrder = 0;
			if ((int)spriteAlignment != 0)
			{
				((tk2dBaseSprite)val).CachedPerpState = spriteAlignment;
			}
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return val;
		}

		public static void DumpSpriteCollection(tk2dSpriteCollectionData sprites, string pathOverride = null)
		{
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Expected O, but got Unknown
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Expected O, but got Unknown
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			string text = "DUMPsprites/" + sprites.spriteCollectionName;
			string path = Path.Combine(ETGMod.ResourcesDirectory, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
			if (!string.IsNullOrEmpty(pathOverride))
			{
				Path.Combine(pathOverride, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
			}
			bool num = File.Exists(path);
			bool flag = false;
			if (num)
			{
				return;
			}
			Texture2D val = null;
			Texture2D val2 = null;
			Color[] array = null;
			for (int i = 0; i < sprites.spriteDefinitions.Length; i++)
			{
				tk2dSpriteDefinition val3 = sprites.spriteDefinitions[i];
				Texture mainTexture = val3.material.mainTexture;
				Texture2D val4 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
				if ((Object)(object)val4 == (Object)null || !val3.Valid || ((Object)(object)val3.materialInst != (Object)null && flag))
				{
					continue;
				}
				string text2 = text + "/" + val3.name;
				if ((Object)(object)val != (Object)(object)val4)
				{
					val = val4;
					val2 = ETGMod.GetRW(val4);
					array = val2.GetPixels();
					path = Path.Combine(ETGMod.ResourcesDirectory, text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
					Directory.GetParent(path).Create();
					File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val2));
				}
				double num2 = 1.0;
				double num3 = 1.0;
				double num4 = 0.0;
				double num5 = 0.0;
				for (int j = 0; j < val3.uvs.Length; j++)
				{
					if ((double)val3.uvs[j].x < num2)
					{
						num2 = val3.uvs[j].x;
					}
					if ((double)val3.uvs[j].y < num3)
					{
						num3 = val3.uvs[j].y;
					}
					if (num4 < (double)val3.uvs[j].x)
					{
						num4 = val3.uvs[j].x;
					}
					if (num5 < (double)val3.uvs[j].y)
					{
						num5 = val3.uvs[j].y;
					}
				}
				int num6 = (int)Math.Floor(num2 * (double)((Texture)val4).width);
				int num7 = (int)Math.Floor(num3 * (double)((Texture)val4).height);
				int num8 = (int)Math.Ceiling(num4 * (double)((Texture)val4).width);
				int num9 = (int)Math.Ceiling(num5 * (double)((Texture)val4).height);
				int num10 = num8 - num6;
				int num11 = num9 - num7;
				Texture2D val5;
				if ((double)val3.uvs[0].x == num2 && (double)val3.uvs[0].y == num3 && (double)val3.uvs[1].x == num4 && (double)val3.uvs[1].y == num3 && (double)val3.uvs[2].x == num2 && (double)val3.uvs[2].y == num5 && (double)val3.uvs[3].x == num4 && (double)val3.uvs[3].y == num5)
				{
					val5 = new Texture2D(num10, num11);
					val5.SetPixels(val2.GetPixels(num6, num7, num10, num11));
				}
				else
				{
					if (val3.uvs[0].x == val3.uvs[1].x)
					{
						int num12 = num11;
						num11 = num10;
						num10 = num12;
					}
					val5 = new Texture2D(num10, num11);
					double num13 = val3.uvs[1].x - val3.uvs[0].x;
					double num14 = val3.uvs[2].x - val3.uvs[0].x;
					double num15 = val3.uvs[1].y - val3.uvs[0].y;
					double num16 = val3.uvs[2].y - val3.uvs[0].y;
					double num17 = (float)((Texture)val4).width * (val3.uvs[3].x - val3.uvs[0].x);
					double num18 = (float)((Texture)val4).height * (val3.uvs[3].y - val3.uvs[0].y);
					double num19 = 0.001;
					double num20 = ((num13 < num19) ? 0.0 : num17);
					double num21 = ((num14 < num19) ? 0.0 : num17);
					double num22 = ((num15 < num19) ? 0.0 : num18);
					double num23 = ((num16 < num19) ? 0.0 : num18);
					for (int k = 0; k < num11; k++)
					{
						double num24 = (double)k / (double)num11;
						for (int l = 0; l < num10; l++)
						{
							double num25 = (double)l / (double)num10;
							double num26 = num25 * num20 + num24 * num21;
							double num27 = num25 * num22 + num24 * num23;
							double num28 = Math.Round((double)(val3.uvs[0].y * (float)((Texture)val4).height) + num27) * (double)((Texture)val4).width + Math.Round((double)(val3.uvs[0].x * (float)((Texture)val4).width) + num26);
							val5.SetPixel(l, k, array[(int)num28]);
						}
					}
				}
				path = Path.Combine(ETGMod.ResourcesDirectory, text2.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar) + ".png");
				if (!File.Exists(path))
				{
					Directory.GetParent(path).Create();
					File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val5));
				}
			}
		}

		public static string DeserializeJSONDataFromAssetBundle(AssetBundle bundle, string AssetPath)
		{
			string empty = string.Empty;
			try
			{
				empty = bundle.LoadAsset<TextAsset>(AssetPath).text;
			}
			catch (Exception ex)
			{
				ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
				Debug.LogException(ex);
				return string.Empty;
			}
			if (!string.IsNullOrEmpty(empty))
			{
				return empty;
			}
			ETGModConsole.Log((object)("[ExpandTheGungeon] Error! Requested Text asset: " + AssetPath + " returned null! Ensure asset exists in asset bundle!"), true);
			return string.Empty;
		}

		public static void SaveStringToFile(string text, string filePath, string fileName)
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(filePath, fileName), append: true);
			streamWriter.WriteLine(text);
		}

		private static void AddSpriteToObject(GameObject targetObject, Texture2D sourceTexture)
		{
			SpriteFromTexture(sourceTexture, targetObject);
		}

		private static GameObject SpriteFromTexture(Texture2D existingTexture, GameObject obj)
		{
			tk2dSprite val = obj.AddComponent<tk2dSprite>();
			int num = AddSpriteToCollection(existingTexture, newCollection);
			((tk2dBaseSprite)val).SetSprite(newCollection, num);
			((tk2dBaseSprite)val).SortingOrder = 0;
			obj.GetComponent<BraveBehaviour>().sprite = (tk2dBaseSprite)(object)val;
			return obj;
		}

		private static int AddSpriteToCollection(Texture2D existingTexture, tk2dSpriteCollectionData collection)
		{
			tk2dSpriteDefinition obj = ConstructDefinition(existingTexture);
			obj.name = ((Object)existingTexture).name;
			return AddSpriteToCollection(obj, collection);
		}

		private static void AddSpritesToCollection(AssetBundle assetSource, List<string> AssetNames, tk2dSpriteCollectionData collection)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			List<Texture> list = new List<Texture>();
			foreach (string AssetName in AssetNames)
			{
				list.Add((Texture)(object)assetSource.LoadAsset<Texture2D>(AssetName));
			}
			if (list.Count <= 0)
			{
				return;
			}
			foreach (Texture2D item in list)
			{
				Texture2D val = item;
				tk2dSpriteDefinition obj = ConstructDefinition(val);
				obj.name = ((Object)val).name;
				AddSpriteToCollection(obj, collection);
			}
		}

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

		private static tk2dSpriteCollectionData GenerateNewSpriteCollection(GameObject targetObject, string CollectionName = null, tk2dSpriteDefinition[] spriteDefinitions = null, bool initDictionary = false)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			tk2dSpriteCollectionData val = targetObject.AddComponent<tk2dSpriteCollectionData>();
			val.version = 3;
			val.materialIdsValid = true;
			if (spriteDefinitions != null)
			{
				val.spriteDefinitions = spriteDefinitions;
			}
			val.spriteDefinitions = (tk2dSpriteDefinition[])(object)new tk2dSpriteDefinition[0];
			val.premultipliedAlpha = false;
			val.shouldGenerateTilemapReflectionData = false;
			val.materials = (Material[])(object)new Material[0];
			val.textures = (Texture[])(object)new Texture[0];
			val.pngTextures = (TextAsset[])(object)new TextAsset[0];
			val.textureFilterMode = (FilterMode)0;
			val.textureMipMaps = false;
			val.allowMultipleAtlases = false;
			val.spriteCollectionGUID = Guid.NewGuid().ToString();
			if (!string.IsNullOrEmpty(CollectionName))
			{
				val.spriteCollectionName = CollectionName;
			}
			else
			{
				val.spriteCollectionName = ((Object)targetObject).name + "_Collection";
			}
			val.loadable = false;
			val.buildKey = Random.Range(800000000, 999999999);
			val.dataGuid = Guid.NewGuid().ToString();
			val.managedSpriteCollection = false;
			val.hasPlatformData = false;
			val.spriteCollectionPlatforms = new string[0];
			val.spriteCollectionPlatformGUIDs = new string[0];
			if (initDictionary)
			{
				val.InitDictionary();
			}
			return val;
		}

		private static tk2dSpriteDefinition ConstructDefinition(Texture2D texture)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00ac: 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_00c7: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missin