Decompiled source of AllMapMerge v2.0.1

AllMapMerge.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Discord.Sdk;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace REPOJPAllMapMerge
{
	[BepInPlugin("REPOJP.AllMapMerge", "AllMapMerge", "2.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		private class RoomEntry
		{
			public PrefabRef PrefabRef;

			public Level SourceLevel;

			public RoomEntry(PrefabRef prefabRef, Level sourceLevel)
			{
				PrefabRef = prefabRef;
				SourceLevel = sourceLevel;
			}
		}

		private class CategoryUsage
		{
			public readonly HashSet<string> UsedPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		}

		private class CategoryPool
		{
			public readonly List<RoomEntry> Entries = new List<RoomEntry>();

			private readonly HashSet<string> uniquePaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

			public int UniqueCount => uniquePaths.Count;

			public void Add(RoomEntry entry)
			{
				if (entry != null && entry.PrefabRef != null)
				{
					Entries.Add(entry);
					uniquePaths.Add(entry.PrefabRef.ResourcePath);
				}
			}

			public bool ContainsResourcePath(string resourcePath)
			{
				if (string.IsNullOrEmpty(resourcePath))
				{
					return false;
				}
				return uniquePaths.Contains(resourcePath);
			}

			public RoomEntry ChoosePreferDifferentSource(HashSet<Level> avoidSourceLevels, CategoryUsage usage, RoomEntry currentEntry)
			{
				if (Entries.Count <= 0)
				{
					return null;
				}
				if (NoRepeatUntilPoolExhausted.Value && usage != null && usage.UsedPaths.Count >= UniqueCount)
				{
					usage.UsedPaths.Clear();
				}
				List<RoomEntry> list = BuildCandidateList(avoidSourceLevels, usage, enforceAvoidSources: true);
				if (list.Count <= 0)
				{
					list = BuildCandidateList(avoidSourceLevels, usage, enforceAvoidSources: false);
				}
				if (list.Count <= 0)
				{
					list = BuildCandidateList(null, usage, enforceAvoidSources: true);
				}
				if (list.Count <= 0)
				{
					list = new List<RoomEntry>(Entries);
				}
				if (currentEntry != null)
				{
					int num = CalculateConflictScore(currentEntry, avoidSourceLevels);
					List<RoomEntry> list2 = new List<RoomEntry>();
					for (int i = 0; i < list.Count; i++)
					{
						RoomEntry roomEntry = list[i];
						if (roomEntry != null && CalculateConflictScore(roomEntry, avoidSourceLevels) < num)
						{
							list2.Add(roomEntry);
						}
					}
					if (list2.Count <= 0)
					{
						return currentEntry;
					}
					list = list2;
				}
				RoomEntry roomEntry2 = list[Random.Range(0, list.Count)];
				if (roomEntry2 != null && usage != null && NoRepeatUntilPoolExhausted.Value && !string.IsNullOrEmpty(roomEntry2.PrefabRef.ResourcePath))
				{
					usage.UsedPaths.Add(roomEntry2.PrefabRef.ResourcePath);
				}
				return roomEntry2;
			}

			private List<RoomEntry> BuildCandidateList(HashSet<Level> avoidSourceLevels, CategoryUsage usage, bool enforceAvoidSources)
			{
				List<RoomEntry> list = new List<RoomEntry>();
				for (int i = 0; i < Entries.Count; i++)
				{
					RoomEntry roomEntry = Entries[i];
					if (roomEntry != null && roomEntry.PrefabRef != null && (!enforceAvoidSources || avoidSourceLevels == null || avoidSourceLevels.Count <= 0 || !((Object)(object)roomEntry.SourceLevel != (Object)null) || !avoidSourceLevels.Contains(roomEntry.SourceLevel)) && (!NoRepeatUntilPoolExhausted.Value || usage == null || !usage.UsedPaths.Contains(roomEntry.PrefabRef.ResourcePath)))
					{
						list.Add(roomEntry);
					}
				}
				return list;
			}

			private int CalculateConflictScore(RoomEntry entry, HashSet<Level> avoidSourceLevels)
			{
				if (entry == null || (Object)(object)entry.SourceLevel == (Object)null || avoidSourceLevels == null || avoidSourceLevels.Count <= 0)
				{
					return 0;
				}
				return avoidSourceLevels.Contains(entry.SourceLevel) ? 1 : 0;
			}
		}

		private class MergedPools
		{
			public List<Level> SourceLevels = new List<Level>();

			public CategoryPool StartRooms = new CategoryPool();

			public CategoryPool NormalRooms = new CategoryPool();

			public CategoryPool PassageRooms = new CategoryPool();

			public CategoryPool DeadEndRooms = new CategoryPool();

			public CategoryPool ExtractionRooms = new CategoryPool();
		}

		[HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")]
		private static class Patch_LevelGenerator_StartRoomGeneration
		{
			private static bool Prefix(LevelGenerator __instance, ref IEnumerator __result)
			{
				if (!ShouldApply(__instance.Level))
				{
					return true;
				}
				__result = StartRoomGenerationOverride(__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(LevelGenerator), "ModuleGeneration")]
		private static class Patch_LevelGenerator_ModuleGeneration
		{
			private static bool Prefix(LevelGenerator __instance, ref IEnumerator __result)
			{
				if (!ShouldApply(__instance.Level))
				{
					return true;
				}
				__result = ModuleGenerationOverride(__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(ValuableDirector), "SetupHost")]
		private static class Patch_ValuableDirector_SetupHost
		{
			private static void Prefix()
			{
				Level baseLevel = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.Level : null);
				PrepareMergedValuablePresets(baseLevel);
			}
		}

		[HarmonyPatch(typeof(RunManager), "SetRunLevel")]
		private static class Patch_RunManager_SetRunLevel
		{
			private static void Postfix(RunManager __instance)
			{
				try
				{
					if ((Object)(object)__instance == (Object)null || !Enabled.Value)
					{
						return;
					}
					Level levelCurrent = __instance.levelCurrent;
					if ((Object)(object)levelCurrent == (Object)null || IsAlwaysExcludedLevel(levelCurrent) || !IsSafeTargetVanillaLevel(levelCurrent) || IsForcedMuseumBaseLevel(levelCurrent))
					{
						return;
					}
					Level val = ResolveForcedMuseumBaseLevel();
					if (!((Object)(object)val == (Object)null))
					{
						__instance.levelCurrent = val;
						if (DebugLog.Value && LogSource != null)
						{
							string text = "Forced base level from " + SafeLevelName(levelCurrent) + " to " + SafeLevelName(val);
							LogSource.LogInfo((object)text);
						}
					}
				}
				catch (Exception ex)
				{
					if (LogSource != null)
					{
						LogSource.LogError((object)("RunManager SetRunLevel museum force failed\n" + ex));
					}
				}
			}
		}

		[HarmonyPatch(typeof(RunManager), "UpdateSteamRichPresence")]
		private static class Patch_RunManager_UpdateSteamRichPresence
		{
			private static bool Prefix(RunManager __instance)
			{
				UpdateRoomMergedMapActiveProperty();
				if (!ShouldOverrideRichPresence())
				{
					return true;
				}
				int num = DataDirector.instance.SettingValueFetch((Setting)59);
				string text = "In Menu";
				string text2 = GetMergedMapPresenceName();
				if ((Object)(object)__instance.levelCurrent == (Object)(object)__instance.levelMainMenu || (Object)(object)__instance.levelCurrent == (Object)(object)__instance.levelSplashScreen || SemiFunc.RunIsTutorial() || SemiFunc.RunIsLobbyMenu())
				{
					SteamFriends.SetRichPresence("levelname", num switch
					{
						2 => GetMergedMapPresenceName(), 
						1 => text, 
						_ => null, 
					});
					SteamFriends.SetRichPresence("levelnum", (string)null);
					SteamFriends.SetRichPresence("steam_display", "#Status_LevelName");
				}
				else
				{
					string text3 = (StatsManager.instance.GetRunStatLevel() + 1).ToString();
					text = ((num == 1) ? "In Game" : (SemiFunc.RunIsArena() ? "In Arena" : (SemiFunc.RunIsLobby() ? "In Truck" : (SemiFunc.RunIsShop() ? "In Shop" : "In Game"))));
					text2 = "Level " + text3 + " - " + GetMergedMapPresenceName();
					SteamFriends.SetRichPresence("levelname", num switch
					{
						2 => GetMergedMapPresenceName(), 
						1 => text, 
						_ => null, 
					});
					SteamFriends.SetRichPresence("levelnum", (num == 2) ? text3 : null);
					SteamFriends.SetRichPresence("steam_display", (num == 2) ? "#Status_LevelNameNum" : "#Status_LevelName");
				}
				DiscordManager instance = DiscordManager.instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.UpdateDiscordRichPresence(text, text2);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(DiscordManager), "RefreshDiscordRichPresence")]
		private static class Patch_DiscordManager_RefreshDiscordRichPresence
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static UpdateRichPresenceCallback <>9__3_1;

				public static UpdateRichPresenceCallback <>9__3_0;

				internal void <Prefix>b__3_1(ClientResult result)
				{
				}

				internal void <Prefix>b__3_0(ClientResult result)
				{
				}
			}

			private static readonly FieldRef<DiscordManager, Client> ClientRef = AccessTools.FieldRefAccess<DiscordManager, Client>("client");

			private static readonly FieldRef<DiscordManager, Activity> ActivityRef = AccessTools.FieldRefAccess<DiscordManager, Activity>("activity");

			private static readonly FieldRef<DiscordManager, ActivityParty> ActivityPartyRef = AccessTools.FieldRefAccess<DiscordManager, ActivityParty>("activityParty");

			private static bool Prefix(DiscordManager __instance)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Expected O, but got Unknown
				//IL_00e2: 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_00ed: Expected O, but got Unknown
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Expected O, but got Unknown
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_017b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Expected O, but got Unknown
				if (!ShouldOverrideRichPresence())
				{
					return true;
				}
				Client val = ClientRef.Invoke(__instance);
				Activity val2 = ActivityRef.Invoke(__instance);
				ActivityParty val3 = ActivityPartyRef.Invoke(__instance);
				if (val == null)
				{
					return true;
				}
				ActivityAssets val4 = new ActivityAssets();
				switch (DataDirector.instance.SettingValueFetch((Setting)59))
				{
				case 1:
				{
					val2.SetDetails((string)null);
					val4.SetLargeImage("taxman");
					ActivityAssets val7 = val4;
					BuildManager instance = BuildManager.instance;
					val7.SetLargeText(((Object)(object)instance != (Object)null) ? instance.version.title : null);
					val2.SetAssets(val4);
					val2.SetParty((ActivityParty)null);
					val2.SetSecrets((ActivitySecrets)null);
					object obj3 = <>c.<>9__3_1;
					if (obj3 == null)
					{
						UpdateRichPresenceCallback val8 = delegate
						{
						};
						<>c.<>9__3_1 = val8;
						obj3 = (object)val8;
					}
					val.UpdateRichPresence(val2, (UpdateRichPresenceCallback)obj3);
					ActivityRef.Invoke(__instance) = val2;
					return false;
				}
				default:
					val.ClearRichPresence();
					return false;
				case 2:
				{
					val4.SetLargeImage(GetMergedMapDiscordLargeImageKey());
					val4.SetLargeText(GetMergedMapPresenceName());
					val2.SetAssets(val4);
					val2.SetParty(val3);
					ActivitySecrets val5 = null;
					if (val3 != null && SemiFunc.RunIsLobbyMenu())
					{
						val5 = new ActivitySecrets();
						ActivitySecrets obj = val5;
						SteamId id = ((Lobby)(ref SteamManager.instance.currentLobby)).Id;
						obj.SetJoin(((object)(SteamId)(ref id)).ToString());
					}
					val2.SetSecrets(val5);
					object obj2 = <>c.<>9__3_0;
					if (obj2 == null)
					{
						UpdateRichPresenceCallback val6 = delegate
						{
						};
						<>c.<>9__3_0 = val6;
						obj2 = (object)val6;
					}
					val.UpdateRichPresence(val2, (UpdateRichPresenceCallback)obj2);
					ActivityRef.Invoke(__instance) = val2;
					return false;
				}
				}
			}
		}

		[HarmonyPatch(typeof(LoadingUI), "LevelAnimationStart")]
		private static class Patch_LoadingUI_LevelAnimationStart
		{
			private static void Postfix(LoadingUI __instance)
			{
				try
				{
					if ((Object)(object)__instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null || (Object)(object)LevelGenerator.Instance.Level == (Object)null)
					{
						return;
					}
					UpdateRoomMergedMapActiveProperty();
					if (!ShouldApplyClientVisuals(LevelGenerator.Instance.Level))
					{
						return;
					}
					LogLoadingGraphicCandidateNames(__instance, LevelGenerator.Instance.Level);
					if (!((Object)(object)CustomLoadingOverrideSprite == (Object)null))
					{
						ReplaceMatchedLoadingImage(__instance.loadingGraphic01, LevelGenerator.Instance.Level.LoadingGraphic01);
						ReplaceMatchedLoadingImage(__instance.loadingGraphic02, LevelGenerator.Instance.Level.LoadingGraphic02);
						ReplaceMatchedLoadingImage(__instance.loadingGraphic03, LevelGenerator.Instance.Level.LoadingGraphic03);
						if ((Object)(object)__instance.levelNameText != (Object)null)
						{
							((TMP_Text)__instance.levelNameText).text = GetMergedMapPresenceName();
						}
					}
				}
				catch (Exception ex)
				{
					if (LogSource != null)
					{
						LogSource.LogError((object)("Loading texture replace failed\n" + ex));
					}
				}
			}
		}

		[CompilerGenerated]
		private sealed class <ModuleGenerationOverride>d__63 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LevelGenerator generator;

			private MergedPools <pools>5__1;

			private Tile[,] <levelGrid>5__2;

			private int <width>5__3;

			private int <height>5__4;

			private RoomEntry[,] <plannedEntries>5__5;

			private Type[,] <plannedTypes>5__6;

			private CategoryUsage <normalUsage>5__7;

			private CategoryUsage <passageUsage>5__8;

			private CategoryUsage <deadEndUsage>5__9;

			private CategoryUsage <extractionUsage>5__10;

			private int <x>5__11;

			private int <y>5__12;

			private Tile <tile>5__13;

			private Type <targetType>5__14;

			private HashSet<Level> <avoidSources>5__15;

			private CategoryPool <targetPool>5__16;

			private CategoryUsage <targetUsage>5__17;

			private RoomEntry <chosenEntry>5__18;

			private int <x>5__19;

			private int <y>5__20;

			private Tile <tile>5__21;

			private Vector3 <position>5__22;

			private Type <targetType>5__23;

			private Vector3 <rotation>5__24;

			private RoomEntry <chosenEntry>5__25;

			private CategoryPool <fallbackPool>5__26;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ModuleGenerationOverride>d__63(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<pools>5__1 = null;
				<levelGrid>5__2 = null;
				<plannedEntries>5__5 = null;
				<plannedTypes>5__6 = null;
				<normalUsage>5__7 = null;
				<passageUsage>5__8 = null;
				<deadEndUsage>5__9 = null;
				<extractionUsage>5__10 = null;
				<tile>5__13 = null;
				<avoidSources>5__15 = null;
				<targetPool>5__16 = null;
				<targetUsage>5__17 = null;
				<chosenEntry>5__18 = null;
				<tile>5__21 = null;
				<chosenEntry>5__25 = null;
				<fallbackPool>5__26 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0426: Unknown result type (might be due to invalid IL or missing references)
				//IL_042b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0443: Unknown result type (might be due to invalid IL or missing references)
				//IL_0448: Unknown result type (might be due to invalid IL or missing references)
				//IL_0467: Unknown result type (might be due to invalid IL or missing references)
				//IL_046c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0471: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0217: Unknown result type (might be due to invalid IL or missing references)
				//IL_021c: 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_0263: Unknown result type (might be due to invalid IL or missing references)
				//IL_0298: Unknown result type (might be due to invalid IL or missing references)
				//IL_051c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0522: Unknown result type (might be due to invalid IL or missing references)
				//IL_0528: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
					<tile>5__21 = null;
					<chosenEntry>5__25 = null;
					goto IL_055f;
				}
				<>1__state = -1;
				WaitingForSubCoroutineRef.Invoke(generator) = true;
				generator.State = (LevelState)5;
				UpdateRoomMergedMapActiveProperty();
				<pools>5__1 = BuildMergedPools(generator.Level);
				if (<pools>5__1.NormalRooms.UniqueCount <= 0)
				{
					<pools>5__1 = BuildCurrentLevelPools(generator.Level);
				}
				if (<pools>5__1.NormalRooms.UniqueCount <= 0)
				{
					WaitingForSubCoroutineRef.Invoke(generator) = false;
					return false;
				}
				PassageAmountRef.Invoke(generator) = 0;
				<levelGrid>5__2 = LevelGridRef.Invoke(generator);
				if (<levelGrid>5__2 == null)
				{
					WaitingForSubCoroutineRef.Invoke(generator) = false;
					return false;
				}
				<width>5__3 = generator.LevelWidth;
				<height>5__4 = generator.LevelHeight;
				<plannedEntries>5__5 = new RoomEntry[<width>5__3, <height>5__4];
				<plannedTypes>5__6 = new Type[<width>5__3, <height>5__4];
				<normalUsage>5__7 = new CategoryUsage();
				<passageUsage>5__8 = new CategoryUsage();
				<deadEndUsage>5__9 = new CategoryUsage();
				<extractionUsage>5__10 = new CategoryUsage();
				<x>5__11 = 0;
				while (<x>5__11 < <width>5__3)
				{
					<y>5__12 = 0;
					while (<y>5__12 < <height>5__4)
					{
						<tile>5__13 = <levelGrid>5__2[<x>5__11, <y>5__12];
						if (<tile>5__13 != null && <tile>5__13.active)
						{
							<targetType>5__14 = ResolveTargetModuleType(generator, <levelGrid>5__2, <x>5__11, <y>5__12);
							<plannedTypes>5__6[<x>5__11, <y>5__12] = <targetType>5__14;
							<avoidSources>5__15 = CollectAdjacentSourceLevels(<plannedEntries>5__5, <width>5__3, <height>5__4, <x>5__11, <y>5__12);
							<targetPool>5__16 = GetPoolForType(<pools>5__1, <targetType>5__14);
							<targetUsage>5__17 = GetUsageForType(<targetType>5__14, <normalUsage>5__7, <passageUsage>5__8, <deadEndUsage>5__9, <extractionUsage>5__10);
							<chosenEntry>5__18 = ChooseRoomEntry(<targetPool>5__16, <pools>5__1, <targetType>5__14, <avoidSources>5__15, <targetUsage>5__17);
							<plannedEntries>5__5[<x>5__11, <y>5__12] = <chosenEntry>5__18;
							<tile>5__13 = null;
							<avoidSources>5__15 = null;
							<targetPool>5__16 = null;
							<targetUsage>5__17 = null;
							<chosenEntry>5__18 = null;
						}
						<y>5__12++;
					}
					<x>5__11++;
				}
				OptimizePlannedEntries(<levelGrid>5__2, <plannedEntries>5__5, <plannedTypes>5__6, <pools>5__1, <width>5__3, <height>5__4);
				<x>5__19 = 0;
				goto IL_059b;
				IL_055f:
				<y>5__20++;
				goto IL_0571;
				IL_0571:
				if (<y>5__20 < <height>5__4)
				{
					<tile>5__21 = <levelGrid>5__2[<x>5__19, <y>5__20];
					if (<tile>5__21 != null && <tile>5__21.active)
					{
						<position>5__22 = new Vector3((float)<x>5__19 * LevelGenerator.ModuleWidth * LevelGenerator.TileSize - (float)(generator.LevelWidth / 2) * LevelGenerator.ModuleWidth * LevelGenerator.TileSize, 0f, (float)<y>5__20 * LevelGenerator.ModuleWidth * LevelGenerator.TileSize + LevelGenerator.ModuleWidth * LevelGenerator.TileSize / 2f);
						<targetType>5__23 = <plannedTypes>5__6[<x>5__19, <y>5__20];
						<rotation>5__24 = ResolveRotation(generator, <levelGrid>5__2, <x>5__19, <y>5__20, <targetType>5__23);
						<chosenEntry>5__25 = <plannedEntries>5__5[<x>5__19, <y>5__20];
						if (<chosenEntry>5__25 == null)
						{
							<fallbackPool>5__26 = GetPoolForType(<pools>5__1, <targetType>5__23);
							<chosenEntry>5__25 = ChooseRoomEntry(<fallbackPool>5__26, <pools>5__1, <targetType>5__23, null, null);
							<fallbackPool>5__26 = null;
						}
						if (<chosenEntry>5__25 != null && <chosenEntry>5__25.PrefabRef != null)
						{
							SpawnMergedModule(generator, <levelGrid>5__2, <x>5__19, <y>5__20, <position>5__22, <rotation>5__24, <targetType>5__23, <chosenEntry>5__25);
							<>2__current = null;
							<>1__state = 1;
							return true;
						}
					}
					goto IL_055f;
				}
				<x>5__19++;
				goto IL_059b;
				IL_059b:
				if (<x>5__19 < <width>5__3)
				{
					<y>5__20 = 0;
					goto IL_0571;
				}
				WaitingForSubCoroutineRef.Invoke(generator) = false;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <StartRoomGenerationOverride>d__62 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LevelGenerator generator;

			private MergedPools <pools>5__1;

			private CategoryPool <startPool>5__2;

			private RoomEntry <chosenEntry>5__3;

			private GameObject <roomObject>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <StartRoomGenerationOverride>d__62(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<pools>5__1 = null;
				<startPool>5__2 = null;
				<chosenEntry>5__3 = null;
				<roomObject>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_016d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				//IL_0149: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					WaitingForSubCoroutineRef.Invoke(generator) = true;
					generator.State = (LevelState)3;
					UpdateRoomMergedMapActiveProperty();
					<pools>5__1 = BuildMergedPools(generator.Level);
					<startPool>5__2 = ((RandomizeStartRooms.Value && <pools>5__1.StartRooms.UniqueCount > 0) ? <pools>5__1.StartRooms : BuildCurrentLevelStartPool(generator.Level));
					if (<startPool>5__2 == null || <startPool>5__2.UniqueCount <= 0)
					{
						WaitingForSubCoroutineRef.Invoke(generator) = false;
						return false;
					}
					<chosenEntry>5__3 = <startPool>5__2.ChoosePreferDifferentSource(null, null, null);
					if (<chosenEntry>5__3 == null || <chosenEntry>5__3.PrefabRef == null)
					{
						WaitingForSubCoroutineRef.Invoke(generator) = false;
						return false;
					}
					<roomObject>5__4 = null;
					if (GameManager.instance.gameMode == 0)
					{
						<roomObject>5__4 = Object.Instantiate<GameObject>(<chosenEntry>5__3.PrefabRef.Prefab, Vector3.zero, Quaternion.identity);
					}
					else
					{
						<roomObject>5__4 = PhotonNetwork.InstantiateRoomObject(<chosenEntry>5__3.PrefabRef.ResourcePath, Vector3.zero, Quaternion.identity, (byte)0, (object[])null);
					}
					if ((Object)(object)<roomObject>5__4 != (Object)null && (Object)(object)generator.LevelParent != (Object)null)
					{
						<roomObject>5__4.transform.parent = generator.LevelParent.transform;
					}
					if (DebugLog.Value)
					{
						LogSource.LogInfo((object)("Merged start room selected: " + <chosenEntry>5__3.PrefabRef.ResourcePath + " / SourceLevel=" + SafeLevelName(<chosenEntry>5__3.SourceLevel)));
					}
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					WaitingForSubCoroutineRef.Invoke(generator) = false;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "REPOJP.AllMapMerge";

		public const string PluginName = "AllMapMerge";

		public const string PluginVersion = "2.0.1";

		internal const string MergedMapPresenceName = "AllMapMerge";

		internal const string MergedMapDiscordLargeImageKey = "allmapmerge";

		internal const string CustomLoadingOverrideFileName = "AllMapMerge.png";

		internal const string RoomPropertyMergedMapActiveKey = "REPOJP_AllMapMerge_Active";

		internal static readonly string[] TargetLoadingTextureNames = new string[4] { "level arctic 01", "level wizard 01", "level museum 01", "level manor 01" };

		internal static readonly string[] SafeMergedVanillaLevelNames = new string[4] { "arctic", "wizard", "museum", "manor" };

		internal const string ForcedBaseLevelNameMuseum = "museum";

		internal const string ForcedBaseLevelTextureMuseum = "level museum 01";

		internal static Sprite CustomLoadingOverrideSprite;

		internal static Plugin Instance;

		internal static ManualLogSource LogSource;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> DangerousEnableAllMapsMergeIncludingModdedMapsCanBreakMaps;

		internal static ConfigEntry<bool> RandomizeStartRooms;

		internal static ConfigEntry<bool> FullyRandomIgnoreDifficultyTier;

		internal static ConfigEntry<bool> NoRepeatUntilPoolExhausted;

		internal static ConfigEntry<bool> PreferDifferentAdjacentSourceLevel;

		internal static ConfigEntry<int> AdjacencyImprovePasses;

		internal static ConfigEntry<bool> DebugLog;

		internal static ConfigEntry<bool> LogLoadingGraphicNames;

		internal static ConfigEntry<string> ExcludedRoomResourcePaths;

		private static readonly Dictionary<Level, List<LevelValuables>> OriginalValuablePresetsByLevel = new Dictionary<Level, List<LevelValuables>>();

		private Harmony harmony;

		private static readonly FieldRef<LevelGenerator, bool> WaitingForSubCoroutineRef = AccessTools.FieldRefAccess<LevelGenerator, bool>("waitingForSubCoroutine");

		private static readonly FieldRef<LevelGenerator, int> PassageAmountRef = AccessTools.FieldRefAccess<LevelGenerator, int>("PassageAmount");

		private static readonly FieldRef<LevelGenerator, Tile[,]> LevelGridRef = AccessTools.FieldRefAccess<LevelGenerator, Tile[,]>("LevelGrid");

		private static readonly FieldRef<LevelGenerator, Vector3[]> ModuleRotationsRef = AccessTools.FieldRefAccess<LevelGenerator, Vector3[]>("ModuleRotations");

		private static readonly FieldRef<Module, int> GridXRef = AccessTools.FieldRefAccess<Module, int>("GridX");

		private static readonly FieldRef<Module, int> GridYRef = AccessTools.FieldRefAccess<Module, int>("GridY");

		private void Awake()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			try
			{
				Instance = this;
				LogSource = ((BaseUnityPlugin)this).Logger;
				((Component)this).transform.parent = null;
				((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable merged-map generation.AllMapMergeを有効化");
				DangerousEnableAllMapsMergeIncludingModdedMapsCanBreakMaps = ((BaseUnityPlugin)this).Config.Bind<bool>("Danger", "!!!DANGER_EnableAllMapsMergeIncludingModdedMaps_CanBreakMaps", false, "Recommended OFF.OFFが通常動作です ONにすると追加マップを含む全ての対象可能マップでマージを有効化し さらに追加マップを含む全ての対象可能マップの部屋をソースとして使用します 互換性崩壊や進行不能や表示崩れの可能性があります");
				RandomizeStartRooms = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RandomizeStartRooms", true, "Pick start rooms from the merged start-room pool.統合された開始部屋プールから開始部屋を選択");
				FullyRandomIgnoreDifficultyTier = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FullyRandomIgnoreDifficultyTier", true, "Ignore difficulty tiers and merge 1/2/3 pools into one pool per category.難易度帯を無視して各カテゴリの1/2/3プールを1つに統合");
				NoRepeatUntilPoolExhausted = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NoRepeatUntilPoolExhausted", false, "Do not repeat the same room in a category until its merged pool has been exhausted.カテゴリ内で統合プールを使い切るまで同じ部屋を再利用しない");
				PreferDifferentAdjacentSourceLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Generation", "PreferDifferentAdjacentSourceLevel", true, "Prefer a different source map than already planned adjacent rooms when possible.可能な限り隣接済み部屋と別の出典マップを優先");
				AdjacencyImprovePasses = ((BaseUnityPlugin)this).Config.Bind<int>("Generation", "AdjacencyImprovePasses", 2, new ConfigDescription("Improvement passes for reducing adjacent same-source rooms.隣接する同一出典部屋を減らす改善パス回数", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
				DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Enable debug logging.デバッグログを有効化");
				LogLoadingGraphicNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogLoadingGraphicNames", false, "Log loading graphic source names for replacement detection.差し替え判定用のローディング画像名ログを出力");
				ExcludedRoomResourcePaths = ((BaseUnityPlugin)this).Config.Bind<string>("Filter", "ExcludedRoomResourcePaths", "", "Exclude specific resource paths. Separate with comma, semicolon, tab, or newline.除外するResourcePathを指定 カンマ セミコロン タブ 改行で区切り");
				LoadCustomLoadingOverrideSprite();
				harmony = new Harmony("REPOJP.AllMapMerge");
				harmony.PatchAll();
				LogSource.LogInfo((object)"AllMapMerge loaded");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Awake failed\n" + ex));
			}
		}

		internal static bool ShouldApply(Level level)
		{
			if (!Enabled.Value)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(level))
			{
				return false;
			}
			if (!IsGenerationAuthority())
			{
				return false;
			}
			return IsMergedSessionActiveForLevel(level);
		}

		internal static bool ShouldApplyClientVisuals(Level level)
		{
			if (!Enabled.Value)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(level))
			{
				return false;
			}
			if (!PhotonNetwork.InRoom)
			{
				return IsMergedSessionActiveForLevel(level);
			}
			if (IsGenerationAuthority())
			{
				return IsMergedSessionActiveForLevel(level);
			}
			return IsRoomMergedMapActive();
		}

		private static bool IsGenerationAuthority()
		{
			if (!PhotonNetwork.InRoom)
			{
				return true;
			}
			return PhotonNetwork.IsMasterClient;
		}

		private static bool IsRoomMergedMapActive()
		{
			if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
			{
				return false;
			}
			if (((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties == null)
			{
				return false;
			}
			if (!((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"REPOJP_AllMapMerge_Active", out object value))
			{
				return false;
			}
			if (!(value is bool result))
			{
				if (value != null && bool.TryParse(value.ToString(), out var result2))
				{
					return result2;
				}
				return false;
			}
			return result;
		}

		private static bool IsMergedSessionActiveForLevel(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(level))
			{
				return false;
			}
			return IsEligibleMergedSourceLevel(level);
		}

		private static void UpdateRoomMergedMapActiveProperty()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			if (!Enabled.Value || !IsGenerationAuthority() || !PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null)
			{
				return;
			}
			Level level = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null);
			bool flag = IsMergedSessionActiveForLevel(level);
			bool flag2 = IsRoomMergedMapActive();
			if (flag2 != flag)
			{
				Hashtable val = new Hashtable();
				val[(object)"REPOJP_AllMapMerge_Active"] = flag;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				if (LogSource != null && DebugLog.Value)
				{
					LogSource.LogInfo((object)("Updated room merged-map flag: " + flag + " / level=" + SafeLevelName(level)));
				}
			}
		}

		private static int RunManagerLevelsCount()
		{
			if ((Object)(object)RunManager.instance == (Object)null || RunManager.instance.levels == null)
			{
				return 0;
			}
			return RunManager.instance.levels.Count;
		}

		internal static bool ShouldOverrideRichPresence()
		{
			if (!Enabled.Value)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)RunManager.instance.levelCurrent == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(RunManager.instance.levelCurrent))
			{
				return false;
			}
			if (!PhotonNetwork.InRoom)
			{
				return IsMergedSessionActiveForLevel(RunManager.instance.levelCurrent);
			}
			if (IsGenerationAuthority())
			{
				return IsMergedSessionActiveForLevel(RunManager.instance.levelCurrent);
			}
			return IsRoomMergedMapActive();
		}

		internal static string GetMergedMapPresenceName()
		{
			return "AllMapMerge";
		}

		internal static string GetMergedMapDiscordLargeImageKey()
		{
			return "allmapmerge";
		}

		internal static string GetCustomLoadingOverridePath()
		{
			string text = Path.Combine(Paths.ConfigPath, "AllMapMerge");
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			return Path.Combine(text, "AllMapMerge.png");
		}

		private static void LoadCustomLoadingOverrideSprite()
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)CustomLoadingOverrideSprite != (Object)null)
			{
				try
				{
					if ((Object)(object)CustomLoadingOverrideSprite.texture != (Object)null)
					{
						Object.Destroy((Object)(object)CustomLoadingOverrideSprite.texture);
					}
				}
				catch
				{
				}
				try
				{
					Object.Destroy((Object)(object)CustomLoadingOverrideSprite);
				}
				catch
				{
				}
				CustomLoadingOverrideSprite = null;
			}
			string customLoadingOverridePath = GetCustomLoadingOverridePath();
			if (!File.Exists(customLoadingOverridePath))
			{
				if (LogSource != null)
				{
					LogSource.LogInfo((object)("Custom loading override file not found: " + customLoadingOverridePath));
				}
				return;
			}
			try
			{
				byte[] array = File.ReadAllBytes(customLoadingOverridePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				((Object)val).name = "AllMapMerge_LoadingOverride";
				if (!ImageConversion.LoadImage(val, array, false))
				{
					if (LogSource != null)
					{
						LogSource.LogError((object)("Failed to decode image: " + customLoadingOverridePath));
					}
					Object.Destroy((Object)(object)val);
					return;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				CustomLoadingOverrideSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)CustomLoadingOverrideSprite).name = "AllMapMerge_LoadingOverride_Sprite";
				if (LogSource != null)
				{
					LogSource.LogInfo((object)("Loaded custom loading override: " + customLoadingOverridePath));
				}
			}
			catch (Exception ex)
			{
				if (LogSource != null)
				{
					LogSource.LogError((object)("LoadCustomLoadingOverrideSprite failed\n" + ex));
				}
			}
		}

		private static Level ResolveForcedMuseumBaseLevel()
		{
			if ((Object)(object)RunManager.instance != (Object)null && RunManager.instance.levels != null)
			{
				for (int i = 0; i < RunManager.instance.levels.Count; i++)
				{
					Level val = RunManager.instance.levels[i];
					if (IsForcedMuseumBaseLevel(val))
					{
						return val;
					}
				}
			}
			Level[] array = Resources.FindObjectsOfTypeAll<Level>();
			if (array != null)
			{
				foreach (Level val2 in array)
				{
					if (IsForcedMuseumBaseLevel(val2))
					{
						return val2;
					}
				}
			}
			return null;
		}

		private static bool IsForcedMuseumBaseLevel(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(level))
			{
				return false;
			}
			if (!HasMergeableRoomPools(level))
			{
				return false;
			}
			if (IsMuseumBaseLevelName(level.NarrativeName))
			{
				return true;
			}
			if (IsMuseumBaseLevelName(((Object)level).name))
			{
				return true;
			}
			if ((Object)(object)level.LoadingGraphic01 != (Object)null && IsMuseumBaseTexture(level.LoadingGraphic01))
			{
				return true;
			}
			return false;
		}

		private static bool IsMuseumBaseLevelName(string levelName)
		{
			if (string.IsNullOrWhiteSpace(levelName))
			{
				return false;
			}
			string text = NormalizeTextureName(levelName);
			text = text.Replace("level - ", string.Empty).Trim();
			text = text.Replace("level ", string.Empty).Trim();
			return string.Equals(text, "museum", StringComparison.OrdinalIgnoreCase);
		}

		private static bool IsMuseumBaseTexture(Sprite sprite)
		{
			if ((Object)(object)sprite == (Object)null)
			{
				return false;
			}
			string a = NormalizeTextureName(((Object)sprite).name);
			if (string.Equals(a, "level museum 01", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if ((Object)(object)sprite.texture != (Object)null)
			{
				string a2 = NormalizeTextureName(((Object)sprite.texture).name);
				if (string.Equals(a2, "level museum 01", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		internal static List<Level> CollectSourceLevels(Level baseLevel)
		{
			List<Level> result = new List<Level>();
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return result;
			}
			if (RunManager.instance.levels != null)
			{
				for (int i = 0; i < RunManager.instance.levels.Count; i++)
				{
					AddSourceLevelIfEligible(result, RunManager.instance.levels[i]);
				}
			}
			Level[] array = Resources.FindObjectsOfTypeAll<Level>();
			if (array != null)
			{
				for (int j = 0; j < array.Length; j++)
				{
					AddSourceLevelIfEligible(result, array[j]);
				}
			}
			AddSourceLevelIfEligible(result, baseLevel);
			AddSourceLevelIfEligible(result, RunManager.instance.levelCurrent);
			return result;
		}

		private static void AddSourceLevelIfEligible(List<Level> result, Level level)
		{
			if (result != null && IsEligibleMergedSourceLevel(level) && !result.Contains(level))
			{
				result.Add(level);
			}
		}

		private static bool IsAlwaysExcludedLevel(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return true;
			}
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return false;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelMainMenu)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelSplashScreen)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelTutorial)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelLobbyMenu)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelArena)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelShop)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelLobby)
			{
				return true;
			}
			if ((Object)(object)level == (Object)(object)RunManager.instance.levelRecording)
			{
				return true;
			}
			return false;
		}

		private static bool IsEligibleMergedSourceLevel(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return false;
			}
			if (IsAlwaysExcludedLevel(level))
			{
				return false;
			}
			if (!HasMergeableRoomPools(level))
			{
				return false;
			}
			if (DangerousEnableAllMapsMergeIncludingModdedMapsCanBreakMaps != null && DangerousEnableAllMapsMergeIncludingModdedMapsCanBreakMaps.Value)
			{
				return true;
			}
			return IsSafeTargetVanillaLevel(level);
		}

		private static bool IsSafeTargetVanillaLevel(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (IsTargetLoadingTexture(level.LoadingGraphic01))
			{
				return true;
			}
			if (IsSafeTargetVanillaLevelName(level.NarrativeName))
			{
				return true;
			}
			if (IsSafeTargetVanillaLevelName(((Object)level).name))
			{
				return true;
			}
			return false;
		}

		private static bool IsSafeTargetVanillaLevelName(string levelName)
		{
			if (string.IsNullOrWhiteSpace(levelName))
			{
				return false;
			}
			string text = NormalizeTextureName(levelName);
			text = text.Replace("level - ", string.Empty).Trim();
			text = text.Replace("level ", string.Empty).Trim();
			for (int i = 0; i < SafeMergedVanillaLevelNames.Length; i++)
			{
				if (string.Equals(text, SafeMergedVanillaLevelNames[i], StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static bool HasMergeableRoomPools(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return false;
			}
			if (HasPrefabRefList(level.StartRooms))
			{
				return true;
			}
			if (HasPrefabRefList(level.ModulesNormal1) || HasPrefabRefList(level.ModulesNormal2) || HasPrefabRefList(level.ModulesNormal3))
			{
				return true;
			}
			if (HasPrefabRefList(level.ModulesPassage1) || HasPrefabRefList(level.ModulesPassage2) || HasPrefabRefList(level.ModulesPassage3))
			{
				return true;
			}
			if (HasPrefabRefList(level.ModulesDeadEnd1) || HasPrefabRefList(level.ModulesDeadEnd2) || HasPrefabRefList(level.ModulesDeadEnd3))
			{
				return true;
			}
			if (HasPrefabRefList(level.ModulesExtraction1) || HasPrefabRefList(level.ModulesExtraction2) || HasPrefabRefList(level.ModulesExtraction3))
			{
				return true;
			}
			return false;
		}

		private static bool HasPrefabRefList(List<PrefabRef> prefabRefs)
		{
			if (prefabRefs == null || prefabRefs.Count <= 0)
			{
				return false;
			}
			for (int i = 0; i < prefabRefs.Count; i++)
			{
				PrefabRef val = prefabRefs[i];
				if (val != null && val.IsValid() && !string.IsNullOrEmpty(val.ResourcePath))
				{
					return true;
				}
			}
			return false;
		}

		private static void PrepareMergedValuablePresets(Level baseLevel)
		{
			if ((Object)(object)baseLevel == (Object)null)
			{
				return;
			}
			CacheOriginalValuablePresets(baseLevel);
			if (!ShouldApply(baseLevel))
			{
				RestoreOriginalValuablePresets(baseLevel);
				return;
			}
			List<LevelValuables> list = BuildMergedValuablePresets(baseLevel);
			if (list.Count <= 0)
			{
				RestoreOriginalValuablePresets(baseLevel);
				return;
			}
			baseLevel.ValuablePresets = list;
			if (DebugLog.Value)
			{
				LogSource.LogInfo((object)("Merged valuable preset count: " + list.Count));
			}
		}

		private static List<LevelValuables> BuildMergedValuablePresets(Level baseLevel)
		{
			List<LevelValuables> list = new List<LevelValuables>();
			List<Level> list2 = CollectValuableSourceLevels(baseLevel);
			for (int i = 0; i < list2.Count; i++)
			{
				List<LevelValuables> originalValuablePresets = GetOriginalValuablePresets(list2[i]);
				for (int j = 0; j < originalValuablePresets.Count; j++)
				{
					LevelValuables val = originalValuablePresets[j];
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
			}
			if (DebugLog.Value)
			{
				LogSource.LogInfo((object)("Merged valuable source level count: " + list2.Count));
				for (int k = 0; k < list2.Count; k++)
				{
					Level level = list2[k];
					LogSource.LogInfo((object)("ValuableSourceLevel[" + k + "]: " + SafeLevelName(level) + " / " + SafeLevelPath(level)));
				}
			}
			return list;
		}

		internal static List<Level> CollectValuableSourceLevels(Level baseLevel)
		{
			List<Level> result = new List<Level>();
			if ((Object)(object)RunManager.instance == (Object)null)
			{
				return result;
			}
			if (RunManager.instance.levels != null)
			{
				for (int i = 0; i < RunManager.instance.levels.Count; i++)
				{
					AddValuableSourceLevelIfEligible(result, RunManager.instance.levels[i]);
				}
			}
			Level[] array = Resources.FindObjectsOfTypeAll<Level>();
			if (array != null)
			{
				for (int j = 0; j < array.Length; j++)
				{
					AddValuableSourceLevelIfEligible(result, array[j]);
				}
			}
			AddValuableSourceLevelIfEligible(result, baseLevel);
			AddValuableSourceLevelIfEligible(result, RunManager.instance.levelCurrent);
			return result;
		}

		private static void AddValuableSourceLevelIfEligible(List<Level> result, Level level)
		{
			if (result != null && !((Object)(object)level == (Object)null) && !IsAlwaysExcludedLevel(level) && HasAnyValuablePresets(level) && !result.Contains(level))
			{
				result.Add(level);
			}
		}

		private static bool HasAnyValuablePresets(Level level)
		{
			List<LevelValuables> originalValuablePresets = GetOriginalValuablePresets(level);
			if (originalValuablePresets == null || originalValuablePresets.Count <= 0)
			{
				return false;
			}
			for (int i = 0; i < originalValuablePresets.Count; i++)
			{
				if ((Object)(object)originalValuablePresets[i] != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private static void CacheOriginalValuablePresets(Level level)
		{
			if (!((Object)(object)level == (Object)null) && !OriginalValuablePresetsByLevel.ContainsKey(level))
			{
				OriginalValuablePresetsByLevel[level] = CloneValuablePresetList(level.ValuablePresets);
			}
		}

		private static List<LevelValuables> GetOriginalValuablePresets(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return new List<LevelValuables>();
			}
			CacheOriginalValuablePresets(level);
			if (!OriginalValuablePresetsByLevel.TryGetValue(level, out var value) || value == null)
			{
				return new List<LevelValuables>();
			}
			return CloneValuablePresetList(value);
		}

		private static void RestoreOriginalValuablePresets(Level level)
		{
			if (!((Object)(object)level == (Object)null) && OriginalValuablePresetsByLevel.TryGetValue(level, out var value) && value != null)
			{
				level.ValuablePresets = CloneValuablePresetList(value);
			}
		}

		private static List<LevelValuables> CloneValuablePresetList(List<LevelValuables> source)
		{
			List<LevelValuables> list = new List<LevelValuables>();
			if (source == null)
			{
				return list;
			}
			for (int i = 0; i < source.Count; i++)
			{
				LevelValuables val = source[i];
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private static MergedPools BuildMergedPools(Level baseLevel)
		{
			List<Level> list = CollectSourceLevels(baseLevel);
			HashSet<string> excludedPaths = ParseExcludedPaths();
			MergedPools mergedPools = new MergedPools();
			mergedPools.SourceLevels = list;
			for (int i = 0; i < list.Count; i++)
			{
				Level val = list[i];
				AddListToCategoryPool(mergedPools.StartRooms, val, val.StartRooms, excludedPaths, allowDuplicatePaths: false);
			}
			for (int j = 0; j < list.Count; j++)
			{
				Level val2 = list[j];
				if (FullyRandomIgnoreDifficultyTier.Value)
				{
					AddListToCategoryPool(mergedPools.NormalRooms, val2, val2.ModulesNormal1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.NormalRooms, val2, val2.ModulesNormal2, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.NormalRooms, val2, val2.ModulesNormal3, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.PassageRooms, val2, val2.ModulesPassage1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.PassageRooms, val2, val2.ModulesPassage2, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.PassageRooms, val2, val2.ModulesPassage3, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.DeadEndRooms, val2, val2.ModulesDeadEnd1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.DeadEndRooms, val2, val2.ModulesDeadEnd2, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.DeadEndRooms, val2, val2.ModulesDeadEnd3, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.ExtractionRooms, val2, val2.ModulesExtraction1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.ExtractionRooms, val2, val2.ModulesExtraction2, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.ExtractionRooms, val2, val2.ModulesExtraction3, excludedPaths, allowDuplicatePaths: false);
				}
				else
				{
					AddListToCategoryPool(mergedPools.NormalRooms, val2, val2.ModulesNormal1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.PassageRooms, val2, val2.ModulesPassage1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.DeadEndRooms, val2, val2.ModulesDeadEnd1, excludedPaths, allowDuplicatePaths: false);
					AddListToCategoryPool(mergedPools.ExtractionRooms, val2, val2.ModulesExtraction1, excludedPaths, allowDuplicatePaths: false);
				}
			}
			if (DebugLog.Value)
			{
				LogSource.LogInfo((object)("Merged source level count: " + list.Count));
				for (int k = 0; k < list.Count; k++)
				{
					Level level = list[k];
					LogSource.LogInfo((object)("SourceLevel[" + k + "]: " + SafeLevelName(level) + " / " + SafeLevelPath(level)));
				}
				LogSource.LogInfo((object)("MergedStartRooms: " + mergedPools.StartRooms.UniqueCount));
				LogSource.LogInfo((object)("MergedNormalRooms: " + mergedPools.NormalRooms.UniqueCount));
				LogSource.LogInfo((object)("MergedPassageRooms: " + mergedPools.PassageRooms.UniqueCount));
				LogSource.LogInfo((object)("MergedDeadEndRooms: " + mergedPools.DeadEndRooms.UniqueCount));
				LogSource.LogInfo((object)("MergedExtractionRooms: " + mergedPools.ExtractionRooms.UniqueCount));
			}
			return mergedPools;
		}

		private static void AddListToCategoryPool(CategoryPool pool, Level sourceLevel, List<PrefabRef> sourceList, HashSet<string> excludedPaths, bool allowDuplicatePaths)
		{
			if (pool == null || (Object)(object)sourceLevel == (Object)null || sourceList == null)
			{
				return;
			}
			for (int i = 0; i < sourceList.Count; i++)
			{
				PrefabRef val = sourceList[i];
				if (val != null && val.IsValid())
				{
					string resourcePath = val.ResourcePath;
					if (!string.IsNullOrEmpty(resourcePath) && !excludedPaths.Contains(resourcePath) && (allowDuplicatePaths || !pool.ContainsResourcePath(resourcePath)))
					{
						pool.Add(new RoomEntry(val, sourceLevel));
					}
				}
			}
		}

		[IteratorStateMachine(typeof(<StartRoomGenerationOverride>d__62))]
		internal static IEnumerator StartRoomGenerationOverride(LevelGenerator generator)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <StartRoomGenerationOverride>d__62(0)
			{
				generator = generator
			};
		}

		[IteratorStateMachine(typeof(<ModuleGenerationOverride>d__63))]
		internal static IEnumerator ModuleGenerationOverride(LevelGenerator generator)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ModuleGenerationOverride>d__63(0)
			{
				generator = generator
			};
		}

		private static void OptimizePlannedEntries(Tile[,] levelGrid, RoomEntry[,] plannedEntries, Type[,] plannedTypes, MergedPools pools, int width, int height)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if (!PreferDifferentAdjacentSourceLevel.Value)
			{
				return;
			}
			int value = AdjacencyImprovePasses.Value;
			if (value <= 0)
			{
				return;
			}
			for (int i = 0; i < value; i++)
			{
				bool flag = false;
				for (int j = 0; j < width; j++)
				{
					for (int k = 0; k < height; k++)
					{
						Tile val = levelGrid[j, k];
						if (val == null || !val.active)
						{
							continue;
						}
						RoomEntry roomEntry = plannedEntries[j, k];
						if (roomEntry == null)
						{
							continue;
						}
						HashSet<Level> hashSet = CollectAdjacentSourceLevels(plannedEntries, width, height, j, k);
						if (hashSet.Count > 0 && (!((Object)(object)roomEntry.SourceLevel != (Object)null) || hashSet.Contains(roomEntry.SourceLevel)))
						{
							RoomEntry roomEntry2 = GetPoolForType(pools, plannedTypes[j, k])?.ChoosePreferDifferentSource(hashSet, null, roomEntry);
							if (roomEntry2 != null && roomEntry2.PrefabRef != null && roomEntry2 != roomEntry && !((Object)(object)roomEntry2.SourceLevel == (Object)(object)roomEntry.SourceLevel))
							{
								plannedEntries[j, k] = roomEntry2;
								flag = true;
							}
						}
					}
				}
				if (!flag)
				{
					break;
				}
			}
		}

		private static HashSet<Level> CollectAdjacentSourceLevels(RoomEntry[,] plannedEntries, int width, int height, int x, int y)
		{
			HashSet<Level> result = new HashSet<Level>();
			AddPlannedNeighborSourceLevel(plannedEntries, width, height, x, y - 1, result);
			AddPlannedNeighborSourceLevel(plannedEntries, width, height, x - 1, y, result);
			AddPlannedNeighborSourceLevel(plannedEntries, width, height, x + 1, y, result);
			AddPlannedNeighborSourceLevel(plannedEntries, width, height, x, y + 1, result);
			return result;
		}

		private static void AddPlannedNeighborSourceLevel(RoomEntry[,] plannedEntries, int width, int height, int x, int y, HashSet<Level> result)
		{
			if (plannedEntries != null && result != null && x >= 0 && x < width && y >= 0 && y < height)
			{
				RoomEntry roomEntry = plannedEntries[x, y];
				if (roomEntry != null && !((Object)(object)roomEntry.SourceLevel == (Object)null))
				{
					result.Add(roomEntry.SourceLevel);
				}
			}
		}

		private static CategoryPool GetPoolForType(MergedPools pools, Type targetType)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			if (pools == null)
			{
				return null;
			}
			if ((int)targetType == 1)
			{
				return pools.PassageRooms;
			}
			if ((int)targetType == 2)
			{
				return pools.DeadEndRooms;
			}
			if ((int)targetType == 3)
			{
				return pools.ExtractionRooms;
			}
			return pools.NormalRooms;
		}

		private static CategoryUsage GetUsageForType(Type targetType, CategoryUsage normalUsage, CategoryUsage passageUsage, CategoryUsage deadEndUsage, CategoryUsage extractionUsage)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			if ((int)targetType == 1)
			{
				return passageUsage;
			}
			if ((int)targetType == 2)
			{
				return deadEndUsage;
			}
			if ((int)targetType == 3)
			{
				return extractionUsage;
			}
			return normalUsage;
		}

		private static Type ResolveTargetModuleType(LevelGenerator generator, Tile[,] levelGrid, int x, int y)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Invalid comparison between Unknown and I4
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			Tile val = levelGrid[x, y];
			if (val == null)
			{
				return (Type)0;
			}
			if ((int)val.type == 3)
			{
				return (Type)3;
			}
			if ((int)val.type == 2)
			{
				return (Type)2;
			}
			if (PassageAmountRef.Invoke(generator) < generator.Level.PassageMaxAmount)
			{
				bool flag = GridCheckActive(generator, levelGrid, x, y + 1) && (GridCheckActive(generator, levelGrid, x, y - 1) || val.first) && !GridCheckActive(generator, levelGrid, x + 1, y) && !GridCheckActive(generator, levelGrid, x - 1, y);
				bool flag2 = !val.first && GridCheckActive(generator, levelGrid, x + 1, y) && GridCheckActive(generator, levelGrid, x - 1, y) && !GridCheckActive(generator, levelGrid, x, y + 1) && !GridCheckActive(generator, levelGrid, x, y - 1);
				if (flag || flag2)
				{
					PassageAmountRef.Invoke(generator) = PassageAmountRef.Invoke(generator) + 1;
					return (Type)1;
				}
			}
			return (Type)0;
		}

		private static Vector3 ResolveRotation(LevelGenerator generator, Tile[,] levelGrid, int x, int y, Type targetType)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			if ((int)targetType == 3 || (int)targetType == 2)
			{
				if (GridCheckActive(generator, levelGrid, x, y - 1))
				{
					return Vector3.zero;
				}
				if (GridCheckActive(generator, levelGrid, x - 1, y))
				{
					return new Vector3(0f, 90f, 0f);
				}
				if (GridCheckActive(generator, levelGrid, x, y + 1))
				{
					return new Vector3(0f, 180f, 0f);
				}
				if (GridCheckActive(generator, levelGrid, x + 1, y))
				{
					return new Vector3(0f, -90f, 0f);
				}
				return Vector3.zero;
			}
			if ((int)targetType == 1)
			{
				bool flag = GridCheckActive(generator, levelGrid, x, y + 1) && (GridCheckActive(generator, levelGrid, x, y - 1) || levelGrid[x, y].first) && !GridCheckActive(generator, levelGrid, x + 1, y) && !GridCheckActive(generator, levelGrid, x - 1, y);
				bool flag2 = !levelGrid[x, y].first && GridCheckActive(generator, levelGrid, x + 1, y) && GridCheckActive(generator, levelGrid, x - 1, y) && !GridCheckActive(generator, levelGrid, x, y + 1) && !GridCheckActive(generator, levelGrid, x, y - 1);
				if (flag)
				{
					if (Random.Range(0, 100) < 50)
					{
						return new Vector3(0f, 180f, 0f);
					}
					return Vector3.zero;
				}
				if (flag2)
				{
					if (Random.Range(0, 100) < 50)
					{
						return new Vector3(0f, -90f, 0f);
					}
					return new Vector3(0f, 90f, 0f);
				}
			}
			Vector3[] array = ModuleRotationsRef.Invoke(generator);
			if (array != null && array.Length != 0)
			{
				return array[Random.Range(0, array.Length)];
			}
			return Vector3.zero;
		}

		private static RoomEntry ChooseRoomEntry(CategoryPool targetPool, MergedPools pools, Type targetType, HashSet<Level> avoidSources, CategoryUsage usage)
		{
			RoomEntry roomEntry = targetPool?.ChoosePreferDifferentSource(avoidSources, usage, null);
			if (roomEntry != null)
			{
				return roomEntry;
			}
			CategoryPool categoryPool = pools?.NormalRooms;
			if (categoryPool != null && categoryPool.UniqueCount > 0)
			{
				return categoryPool.ChoosePreferDifferentSource(avoidSources, usage, null);
			}
			return null;
		}

		private static void SpawnMergedModule(LevelGenerator generator, Tile[,] levelGrid, int x, int y, Vector3 position, Vector3 rotation, Type targetType, RoomEntry entry)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			if (entry == null || entry.PrefabRef == null)
			{
				return;
			}
			GameObject val = null;
			val = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject(entry.PrefabRef.ResourcePath, position, Quaternion.Euler(rotation), (byte)0, (object[])null) : Object.Instantiate<GameObject>(entry.PrefabRef.Prefab, position, Quaternion.Euler(rotation)));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)generator.LevelParent != (Object)null)
			{
				val.transform.parent = generator.LevelParent.transform;
			}
			Module component = val.GetComponent<Module>();
			if ((Object)(object)component == (Object)null)
			{
				if (DebugLog.Value)
				{
					LogSource.LogWarning((object)("Spawned merged room has no Module component: " + entry.PrefabRef.ResourcePath));
				}
				return;
			}
			GridXRef.Invoke(component) = x;
			GridYRef.Invoke(component) = y;
			levelGrid[x, y].type = targetType;
			bool first = levelGrid[x, y].first;
			bool flag = GridCheckActive(generator, levelGrid, x, y + 1);
			bool flag2 = GridCheckActive(generator, levelGrid, x, y - 1) || first;
			bool flag3 = GridCheckActive(generator, levelGrid, x + 1, y);
			bool flag4 = GridCheckActive(generator, levelGrid, x - 1, y);
			component.ModuleConnectionSet(flag, flag2, flag3, flag4, first);
			if (DebugLog.Value)
			{
				LogSource.LogInfo((object)("Merged room selected: " + entry.PrefabRef.ResourcePath + " / SourceLevel=" + SafeLevelName(entry.SourceLevel) + " / Type=" + ((object)(Type)(ref targetType)).ToString() + " / Grid=(" + x + "," + y + ")"));
			}
		}

		private static bool GridCheckActive(LevelGenerator generator, Tile[,] levelGrid, int x, int y)
		{
			if ((Object)(object)generator == (Object)null || levelGrid == null)
			{
				return false;
			}
			if (x < 0 || x >= generator.LevelWidth || y < 0 || y >= generator.LevelHeight)
			{
				return false;
			}
			return levelGrid[x, y]?.active ?? false;
		}

		private static CategoryPool BuildCurrentLevelStartPool(Level level)
		{
			CategoryPool categoryPool = new CategoryPool();
			HashSet<string> excludedPaths = ParseExcludedPaths();
			AddListToCategoryPool(categoryPool, level, ((Object)(object)level != (Object)null) ? level.StartRooms : null, excludedPaths, allowDuplicatePaths: false);
			return categoryPool;
		}

		private static MergedPools BuildCurrentLevelPools(Level level)
		{
			MergedPools mergedPools = new MergedPools();
			HashSet<string> excludedPaths = ParseExcludedPaths();
			if ((Object)(object)level == (Object)null)
			{
				return mergedPools;
			}
			mergedPools.SourceLevels.Add(level);
			AddListToCategoryPool(mergedPools.StartRooms, level, level.StartRooms, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.NormalRooms, level, level.ModulesNormal1, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.NormalRooms, level, level.ModulesNormal2, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.NormalRooms, level, level.ModulesNormal3, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.PassageRooms, level, level.ModulesPassage1, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.PassageRooms, level, level.ModulesPassage2, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.PassageRooms, level, level.ModulesPassage3, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.DeadEndRooms, level, level.ModulesDeadEnd1, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.DeadEndRooms, level, level.ModulesDeadEnd2, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.DeadEndRooms, level, level.ModulesDeadEnd3, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.ExtractionRooms, level, level.ModulesExtraction1, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.ExtractionRooms, level, level.ModulesExtraction2, excludedPaths, allowDuplicatePaths: false);
			AddListToCategoryPool(mergedPools.ExtractionRooms, level, level.ModulesExtraction3, excludedPaths, allowDuplicatePaths: false);
			return mergedPools;
		}

		private static HashSet<string> ParseExcludedPaths()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string value = ExcludedRoomResourcePaths.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return hashSet;
			}
			string[] array = value.Split(new char[5] { ',', ';', '\r', '\n', '\t' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				if (!string.IsNullOrWhiteSpace(text))
				{
					hashSet.Add(text.Trim());
				}
			}
			return hashSet;
		}

		private static string SafeLevelName(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return "null";
			}
			return ((Object)level).name;
		}

		private static string SafeLevelPath(Level level)
		{
			if ((Object)(object)level == (Object)null)
			{
				return "null";
			}
			if (string.IsNullOrEmpty(level.ResourcePath))
			{
				return "";
			}
			return level.ResourcePath;
		}

		internal static bool IsTargetLoadingTexture(Sprite sprite)
		{
			if ((Object)(object)sprite == (Object)null)
			{
				return false;
			}
			string textureName = NormalizeTextureName(((Object)sprite).name);
			if (IsTargetLoadingTextureName(textureName))
			{
				return true;
			}
			if ((Object)(object)sprite.texture != (Object)null)
			{
				string textureName2 = NormalizeTextureName(((Object)sprite.texture).name);
				if (IsTargetLoadingTextureName(textureName2))
				{
					return true;
				}
			}
			return false;
		}

		internal static bool IsTargetLoadingTextureName(string textureName)
		{
			if (string.IsNullOrWhiteSpace(textureName))
			{
				return false;
			}
			string b = NormalizeTextureName(textureName);
			for (int i = 0; i < TargetLoadingTextureNames.Length; i++)
			{
				string a = NormalizeTextureName(TargetLoadingTextureNames[i]);
				if (string.Equals(a, b, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		internal static string NormalizeTextureName(string textureName)
		{
			if (string.IsNullOrWhiteSpace(textureName))
			{
				return string.Empty;
			}
			string text = textureName.Trim();
			if (text.EndsWith(".png", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - 4);
			}
			return text;
		}

		private static void LogLoadingGraphicCandidateNames(LoadingUI loadingUI, Level level)
		{
			if (LogSource != null && !((Object)(object)level == (Object)null) && LogLoadingGraphicNames != null && LogLoadingGraphicNames.Value)
			{
				LogSource.LogInfo((object)"[AllMapMerge][LoadingGraphicScan] Begin");
				LogLoadingGraphicSlotInfo("LoadingGraphic01", level.LoadingGraphic01, ((Object)(object)loadingUI != (Object)null) ? loadingUI.loadingGraphic01 : null);
				LogLoadingGraphicSlotInfo("LoadingGraphic02", level.LoadingGraphic02, ((Object)(object)loadingUI != (Object)null) ? loadingUI.loadingGraphic02 : null);
				LogLoadingGraphicSlotInfo("LoadingGraphic03", level.LoadingGraphic03, ((Object)(object)loadingUI != (Object)null) ? loadingUI.loadingGraphic03 : null);
				LogSource.LogInfo((object)"[AllMapMerge][LoadingGraphicScan] End");
			}
		}

		private static void LogLoadingGraphicSlotInfo(string slotName, Sprite sourceSprite, Image currentImage)
		{
			string safeSpriteName = GetSafeSpriteName(sourceSprite);
			string safeTextureName = GetSafeTextureName(sourceSprite);
			string text = (((Object)(object)currentImage != (Object)null) ? GetSafeSpriteName(currentImage.sprite) : "null");
			string text2 = (((Object)(object)currentImage != (Object)null) ? GetSafeTextureName(currentImage.sprite) : "null");
			bool flag = IsTargetLoadingTexture(sourceSprite);
			LogSource.LogInfo((object)("[AllMapMerge][LoadingGraphicScan] " + slotName + " | SourceSprite=\"" + safeSpriteName + "\" | SourceTexture=\"" + safeTextureName + "\" | CurrentSprite=\"" + text + "\" | CurrentTexture=\"" + text2 + "\" | MatchedByCurrentRule=" + flag));
		}

		private static string GetSafeSpriteName(Sprite sprite)
		{
			if ((Object)(object)sprite == (Object)null)
			{
				return "null";
			}
			return string.IsNullOrEmpty(((Object)sprite).name) ? "<empty>" : ((Object)sprite).name;
		}

		private static string GetSafeTextureName(Sprite sprite)
		{
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				return "null";
			}
			return string.IsNullOrEmpty(((Object)sprite.texture).name) ? "<empty>" : ((Object)sprite.texture).name;
		}

		private static void ReplaceMatchedLoadingImage(Image image, Sprite sourceSprite)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)image == (Object)null) && !((Object)(object)sourceSprite == (Object)null) && IsTargetLoadingTexture(sourceSprite))
			{
				image.sprite = CustomLoadingOverrideSprite;
				((Graphic)image).color = Color.white;
				((Behaviour)image).enabled = true;
				if (LogSource != null && DebugLog.Value)
				{
					string text = (((Object)(object)sourceSprite != (Object)null) ? ((Object)sourceSprite).name : "null");
					string text2 = (((Object)(object)sourceSprite != (Object)null && (Object)(object)sourceSprite.texture != (Object)null) ? ((Object)sourceSprite.texture).name : "null");
					LogSource.LogInfo((object)("Replaced loading image source sprite: " + text + " / texture: " + text2));
				}
			}
		}
	}
}