Decompiled source of RepoGamblingConfigure v0.1.0

plugins/RepoGamblingConfigure.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using Microsoft.CodeAnalysis;
using REPOGambling;
using REPOLib.Modules;
using UnityEngine;

[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("nezzy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("RepoGamblingConfigure")]
[assembly: AssemblyTitle("RepoGamblingConfigure")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace repo_gambling_configure_nezzy
{
	[BepInPlugin("nezzy.RepoGamblingConfigure", "REPO Gambling Configure", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class RepoGamblingConfigurePlugin : BaseUnityPlugin
	{
		internal static RepoGamblingConfigurePlugin Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded.");
		}

		private void Start()
		{
			UpgradeDropConfig.Bind(((BaseUnityPlugin)this).Config);
		}
	}
	internal static class UpgradeDropConfig
	{
		internal sealed class Upgrade
		{
			internal string Key { get; }

			internal string Label { get; }

			internal string Section { get; }

			internal Action<string> Apply { get; }

			internal Upgrade(string key, string label, string section, Action<string> apply)
			{
				Key = key;
				Label = label;
				Section = section;
				Apply = apply;
			}
		}

		internal static readonly List<Upgrade> Upgrades = new List<Upgrade>
		{
			new Upgrade("MapPlayerCount", "Map Player Count", "Green Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradeMapPlayerCount(steamId, 1);
			}),
			new Upgrade("PlayerStamina", "Player Stamina", "Yellow Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerEnergy(steamId, 1);
			}),
			new Upgrade("ExtraJump", "Extra Jump", "Blue Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerExtraJump(steamId, 1);
			}),
			new Upgrade("GrabRange", "Grab Range", "Orange Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerGrabRange(steamId, 1);
			}),
			new Upgrade("GrabStrength", "Grab Strength", "Orange Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerGrabStrength(steamId, 1);
			}),
			new Upgrade("Health", "Health", "Green Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerHealth(steamId, 1);
			}),
			new Upgrade("SprintSpeed", "Sprint Speed", "Yellow Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerSprintSpeed(steamId, 1);
			}),
			new Upgrade("TumbleLaunch", "Tumble Launch", "Blue Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerTumbleLaunch(steamId, 1);
			}),
			new Upgrade("TumbleClimb", "Tumble Climb", "Blue Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerTumbleClimb(steamId, 1);
			}),
			new Upgrade("DeathHeadBattery", "Death Head Battery", "Death", delegate(string steamId)
			{
				PunManager.instance.UpgradeDeathHeadBattery(steamId, 1);
			}),
			new Upgrade("TumbleWings", "Tumble Wings", "Blue Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerTumbleWings(steamId, 1);
			}),
			new Upgrade("CrouchRest", "Crouch Rest", "Yellow Upgrade", delegate(string steamId)
			{
				PunManager.instance.UpgradePlayerCrouchRest(steamId, 1);
			})
		};

		private static readonly Dictionary<string, ConfigEntry<bool>> Entries = new Dictionary<string, ConfigEntry<bool>>();

		private static ConfigEntry<bool> removePlayerCountRepeat = null;

		private static ConfigEntry<bool> removeRangeAtTen = null;

		private static ConfigEntry<bool> trySpawnShopSecret = null;

		private static ConfigEntry<bool> extendedShopLogging = null;

		internal static bool RemovePlayerCountRepeat => removePlayerCountRepeat.Value;

		internal static bool RemoveRangeAtTen => removeRangeAtTen.Value;

		internal static bool TrySpawnShopSecret => trySpawnShopSecret.Value;

		internal static bool ExtendedShopLogging => extendedShopLogging.Value;

		internal static void Bind(ConfigFile config)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			removePlayerCountRepeat = config.Bind<bool>("QOL", "Remove Player Count Repeat", true, "Remove Map Player Count when the player already has it.");
			ConfigDefinition val = new ConfigDefinition("QOL", "Remove Range At 10");
			bool flag = true;
			ConfigEntry<bool> val2 = default(ConfigEntry<bool>);
			if (config.TryGetEntry<bool>(val, ref val2))
			{
				flag = val2.Value;
			}
			config.Remove(val);
			removeRangeAtTen = config.Bind<bool>("QOL", "Replace Range At Max Range Upgrade", flag, "Remove Grab Range when the player has more than 9 levels.");
			trySpawnShopSecret = config.Bind<bool>("QOL", "Try To Spawn Shop Secret (Host Controlled)", true, "Try to add a second Shop dead-end for the original secret-room pool. The host controls this setting.");
			foreach (PlayerUpgrade upgrade in Upgrades.PlayerUpgrades)
			{
				string key = "REPOLib." + upgrade.UpgradeId;
				if (!Upgrades.Exists((Upgrade existing) => existing.Key == key))
				{
					Upgrades.Add(new Upgrade(key, upgrade.UpgradeId, "Custom", delegate(string steamId)
					{
						upgrade.AddLevel(steamId, 1);
					}));
				}
			}
			string[] array = new string[6] { "Yellow Upgrade", "Orange Upgrade", "Blue Upgrade", "Green Upgrade", "Death", "Custom" };
			ConfigEntry<bool> val4 = default(ConfigEntry<bool>);
			ConfigEntry<bool> val6 = default(ConfigEntry<bool>);
			foreach (string text in array)
			{
				foreach (Upgrade upgrade2 in Upgrades)
				{
					if (!(upgrade2.Section != text))
					{
						ConfigDefinition val3 = new ConfigDefinition("Upgrade Drops", upgrade2.Key);
						bool flag2 = true;
						if (config.TryGetEntry<bool>(val3, ref val4))
						{
							flag2 = val4.Value;
						}
						config.Remove(val3);
						string text2 = upgrade2.Section.Replace(" Upgrade", string.Empty);
						ConfigDefinition val5 = new ConfigDefinition(text2, upgrade2.Key);
						if (config.TryGetEntry<bool>(val5, ref val6))
						{
							flag2 = val6.Value;
						}
						config.Remove(val5);
						Entries[upgrade2.Key] = config.Bind<bool>(upgrade2.Section, upgrade2.Key, flag2, "Allow REPOGambling to award " + upgrade2.Label + ".");
					}
				}
			}
			extendedShopLogging = config.Bind<bool>("Developer", "Extended Shop Logging", false, "Log the selected Gambling room and Shop secret placement result.");
			RepoGamblingConfigurePlugin.Logger.LogInfo((object)$"Configured {Upgrades.Count} upgrade drops ({Upgrades.Count - 12} REPOLib custom).");
		}

		internal static bool IsAllowed(int index)
		{
			return index >= 0 && index < Upgrades.Count && Entries[Upgrades[index].Key].Value;
		}

		internal static void SetAllowed(int index, bool allowed)
		{
			if (index >= 0 && index < Upgrades.Count)
			{
				Entries[Upgrades[index].Key].Value = allowed;
				((BaseUnityPlugin)RepoGamblingConfigurePlugin.Instance).Config.Save();
			}
		}

		internal static int PickUpgradeIndex(PlayerAvatar avatar)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < Upgrades.Count; i++)
			{
				if (IsAllowed(i) && IsEligible(Upgrades[i], avatar.steamID))
				{
					list.Add(i);
				}
			}
			if (list.Count == 0)
			{
				RepoGamblingConfigurePlugin.Logger.LogWarning((object)"All eligible upgrade drops disabled; falling back to eligible upgrades.");
				for (int j = 0; j < Upgrades.Count; j++)
				{
					if (IsEligible(Upgrades[j], avatar.steamID))
					{
						list.Add(j);
					}
				}
			}
			return list[Random.Range(0, list.Count)];
		}

		private static bool IsEligible(Upgrade upgrade, string steamId)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)StatsManager.instance == (Object)null)
			{
				return true;
			}
			if (upgrade.Key == "MapPlayerCount" && removePlayerCountRepeat.Value && StatsManager.instance.playerUpgradeMapPlayerCount.TryGetValue(steamId, out var value) && value > 0)
			{
				return false;
			}
			int value2;
			return upgrade.Key != "GrabRange" || !removeRangeAtTen.Value || !StatsManager.instance.playerUpgradeRange.TryGetValue(steamId, out value2) || value2 <= 9;
		}

		internal static void SetRemovePlayerCountRepeat(bool enabled)
		{
			removePlayerCountRepeat.Value = enabled;
			((BaseUnityPlugin)RepoGamblingConfigurePlugin.Instance).Config.Save();
		}

		internal static void SetRemoveRangeAtTen(bool enabled)
		{
			removeRangeAtTen.Value = enabled;
			((BaseUnityPlugin)RepoGamblingConfigurePlugin.Instance).Config.Save();
		}

		internal static void SetTrySpawnShopSecret(bool enabled)
		{
			trySpawnShopSecret.Value = enabled;
			((BaseUnityPlugin)RepoGamblingConfigurePlugin.Instance).Config.Save();
		}

		internal static void SetExtendedShopLogging(bool enabled)
		{
			extendedShopLogging.Value = enabled;
			((BaseUnityPlugin)RepoGamblingConfigurePlugin.Instance).Config.Save();
		}

		internal static void LogShopInfo(string message)
		{
			if (ExtendedShopLogging)
			{
				RepoGamblingConfigurePlugin.Logger.LogInfo((object)message);
			}
		}

		internal static bool Apply(int index, string steamId)
		{
			if (index < 0 || index >= Upgrades.Count)
			{
				RepoGamblingConfigurePlugin.Logger.LogWarning((object)$"Invalid upgrade index: {index}");
				return false;
			}
			Upgrades[index].Apply(steamId);
			return true;
		}
	}
	[HarmonyPatch]
	internal static class RepoConfigMenuPatch
	{
		private static MethodBase? TargetMethod()
		{
			return AccessTools.Method("REPOConfig.ConfigMenu:CreateModEntries", new Type[2]
			{
				typeof(REPOPopupPage),
				typeof(ConfigEntryBase[])
			}, (Type[])null);
		}

		private static bool Prefix(REPOPopupPage modPage, ConfigEntryBase[] configEntryBases)
		{
			bool flag = false;
			foreach (ConfigEntryBase val in configEntryBases)
			{
				if (val.Definition.Section == "QOL" && val.Definition.Key == "Remove Player Count Repeat")
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return true;
			}
			AddHeader(modPage, "QOL");
			AddToggle(modPage, "Remove Player\nCount Repeat", UpgradeDropConfig.SetRemovePlayerCountRepeat, UpgradeDropConfig.RemovePlayerCountRepeat);
			AddToggle(modPage, "Replace Range At\nMax Range Upgrade", UpgradeDropConfig.SetRemoveRangeAtTen, UpgradeDropConfig.RemoveRangeAtTen);
			AddToggle(modPage, "Try To Spawn Shop\nSecret (Host Controlled)", UpgradeDropConfig.SetTrySpawnShopSecret, UpgradeDropConfig.TrySpawnShopSecret);
			AddUpgrades(modPage, "Yellow Upgrade");
			AddUpgrades(modPage, "Orange Upgrade");
			AddUpgrades(modPage, "Blue Upgrade");
			AddUpgrades(modPage, "Green Upgrade");
			AddUpgrades(modPage, "Death");
			AddUpgrades(modPage, "Custom");
			AddHeader(modPage, "Developer");
			AddToggle(modPage, "Extended Shop Logging", UpgradeDropConfig.SetExtendedShopLogging, UpgradeDropConfig.ExtendedShopLogging);
			return false;
		}

		private static void AddHeader(REPOPopupPage page, string text)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			page.AddElementToScrollView((ScrollViewBuilderDelegate)((Transform parent) => (RectTransform)((Component)MenuAPI.CreateREPOLabel(text, parent, default(Vector2))).transform), 0f, 4f);
		}

		private static void AddUpgrades(REPOPopupPage page, string section)
		{
			AddHeader(page, section);
			for (int i = 0; i < UpgradeDropConfig.Upgrades.Count; i++)
			{
				UpgradeDropConfig.Upgrade upgrade = UpgradeDropConfig.Upgrades[i];
				if (upgrade.Section == section)
				{
					int index = i;
					AddToggle(page, upgrade.Label, delegate(bool enabled)
					{
						UpgradeDropConfig.SetAllowed(index, enabled);
					}, UpgradeDropConfig.IsAllowed(index));
				}
			}
		}

		private static void AddToggle(REPOPopupPage page, string text, Action<bool> onToggle, bool value)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				string text2 = text;
				Action<bool> action = onToggle;
				bool flag = value;
				return (RectTransform)((Component)MenuAPI.CreateREPOToggle(text2, action, parent, default(Vector2), "ON", "OFF", flag)).transform;
			}, 0f, 2f);
		}
	}
	[HarmonyPatch(typeof(EnvironmentPlacementPatch), "HandleWheelPrize")]
	internal static class UpgradeDropRollTranspiler
	{
		private static readonly MethodInfo RandomRangeInt = AccessTools.Method(typeof(Random), "Range", new Type[2]
		{
			typeof(int),
			typeof(int)
		}, (Type[])null);

		private static readonly MethodInfo PickUpgradeIndex = AccessTools.Method(typeof(UpgradeDropConfig), "PickUpgradeIndex", new Type[1] { typeof(PlayerAvatar) }, (Type[])null);

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			int num = 0;
			for (int i = 0; i <= list.Count - 3; i++)
			{
				if (CodeInstructionExtensions.LoadsConstant(list[i], 0L) && CodeInstructionExtensions.LoadsConstant(list[i + 1], 8L) && CodeInstructionExtensions.Calls(list[i + 2], RandomRangeInt))
				{
					list[i].opcode = OpCodes.Ldarg_3;
					list[i + 1].opcode = OpCodes.Nop;
					list[i + 1].operand = null;
					list[i + 2].opcode = OpCodes.Call;
					list[i + 2].operand = PickUpgradeIndex;
					num++;
				}
			}
			RepoGamblingConfigurePlugin.Logger.LogInfo((object)$"Patched {num} REPOGambling upgrade roll(s).");
			return list;
		}
	}
	[HarmonyPatch(typeof(EnvironmentPlacementPatch), "ApplyUpgradeDirect")]
	internal static class ApplyUpgradeDirectPatch
	{
		private static bool Prefix(int upgradeIndex, string steamID)
		{
			return upgradeIndex < 8 || !UpgradeDropConfig.Apply(upgradeIndex, steamID);
		}
	}
	[HarmonyPatch(typeof(WheelMachineRPCHandler), "RPC_ApplyUpgrade")]
	internal static class RpcApplyUpgradePatch
	{
		private static bool Prefix(int upgradeIndex, string steamID)
		{
			return upgradeIndex < 8 || !UpgradeDropConfig.Apply(upgradeIndex, steamID);
		}
	}
	[HarmonyPatch(typeof(EnvironmentPlacementPatch), "UpgradeAnnounce")]
	internal static class UpgradeAnnouncePatch
	{
		private static readonly MethodInfo? PossessChat = typeof(ChatManager).GetMethods().FirstOrDefault((MethodInfo method) => method.Name == "PossessChat" && method.GetParameters().Length == 8);

		private static bool Prefix(int index, PlayerAvatar avatar)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			if (index < 8)
			{
				return true;
			}
			if ((Object)avatar == (Object)null || avatar.isDisabled || index >= UpgradeDropConfig.Upgrades.Count)
			{
				return false;
			}
			ChatManager instance = ChatManager.instance;
			if ((Object)instance == (Object)null)
			{
				return false;
			}
			if (PossessChat == null)
			{
				return false;
			}
			try
			{
				string text = ((Random.value > 0.5f) ? "Upgraded" : "Just what I wanted, a");
				ParameterInfo[] parameters = PossessChat.GetParameters();
				instance.PossessChatScheduleStart(-1);
				PossessChat.Invoke(instance, new object[8]
				{
					Enum.ToObject(parameters[0].ParameterType, 3),
					text + " " + UpgradeDropConfig.Upgrades[index].Label,
					2f,
					Color.blue,
					0f,
					false,
					0,
					null
				});
				instance.PossessChatScheduleEnd();
			}
			catch (Exception arg)
			{
				RepoGamblingConfigurePlugin.Logger.LogWarning((object)$"Failed to show upgrade announcement: {arg}");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	internal static class ShopDeadEndCapturePatch
	{
		internal static List<PrefabRef>? OriginalDeadEnds;

		internal static PrefabRef? GamblingRoom;

		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void CaptureOriginalDeadEnds()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			OriginalDeadEnds = null;
			GamblingRoom = null;
			if ((Object)RunManager.instance != (Object)null && RunManager.instance.levelCurrent.NarrativeName == "Service Station")
			{
				OriginalDeadEnds = new List<PrefabRef>(RunManager.instance.levelCurrent.ModulesDeadEnd1);
			}
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "Start")]
	internal static class ShopGamblingRoomPatch
	{
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		private static void GuaranteeGamblingRoom()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			List<PrefabRef> original = ShopDeadEndCapturePatch.OriginalDeadEnds;
			if (original == null || (Object)RunManager.instance == (Object)null || RunManager.instance.levelCurrent.NarrativeName != "Service Station")
			{
				return;
			}
			List<PrefabRef> modulesDeadEnd = RunManager.instance.levelCurrent.ModulesDeadEnd1;
			PrefabRef val = ((IEnumerable<PrefabRef>)modulesDeadEnd).FirstOrDefault((Func<PrefabRef, bool>)((PrefabRef prefab) => !original.Any((PrefabRef originalPrefab) => ((PrefabRef<GameObject>)(object)originalPrefab).ResourcePath == ((PrefabRef<GameObject>)(object)prefab).ResourcePath)));
			string text = "REPOGambling default selection";
			if (val == null)
			{
				REPOGambling val2 = Object.FindObjectOfType<REPOGambling>();
				if ((Object)val2 == (Object)null)
				{
					RepoGamblingConfigurePlugin.Logger.LogWarning((object)"Guaranteed Gambling room skipped: REPOGambling was unavailable.");
					return;
				}
				List<GameObject> list = val2.LoadModulePrefabsFromBundle();
				if (list.Count == 0)
				{
					RepoGamblingConfigurePlugin.Logger.LogWarning((object)"Guaranteed Gambling room skipped: no Gambling room prefab was available.");
					return;
				}
				GameObject val3 = list[Random.Range(0, list.Count)];
				val = NetworkPrefabs.RegisterNetworkPrefab("Level/Shop/Modules/" + ((Object)val3).name, val3);
				text = "guarantee fallback";
			}
			modulesDeadEnd.Clear();
			modulesDeadEnd.Add(val);
			ShopDeadEndCapturePatch.GamblingRoom = val;
			UpgradeDropConfig.LogShopInfo("Guaranteed Gambling room selected via " + text + ": " + ((PrefabRef<GameObject>)(object)val).ResourcePath);
		}
	}
	[HarmonyPatch(typeof(LevelGenerator), "GenerateConnectObjects")]
	internal static class ShopSecretPlacementPatch
	{
		private static readonly FieldInfo? LevelGrid = AccessTools.Field(typeof(LevelGenerator), "LevelGrid");

		[HarmonyPrefix]
		private static void TryAddSecretDeadEnd(LevelGenerator __instance)
		{
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			List<PrefabRef> originalDeadEnds = ShopDeadEndCapturePatch.OriginalDeadEnds;
			if (!UpgradeDropConfig.TrySpawnShopSecret || originalDeadEnds == null || originalDeadEnds.Count == 0 || ShopDeadEndCapturePatch.GamblingRoom == null || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				return;
			}
			if (!(LevelGrid?.GetValue(__instance) is Tile[,] array))
			{
				UpgradeDropConfig.LogShopInfo("Shop secret skipped: the store grid was unavailable.");
				return;
			}
			List<Tile> list = new List<Tile>();
			for (int i = 0; i < array.GetLength(0); i++)
			{
				for (int j = 0; j < array.GetLength(1); j++)
				{
					Tile val = array[i, j];
					if (!val.active && HasOneOpenConnection(array, i, j) && !TouchesReservedTile(array, i, j))
					{
						list.Add(val);
					}
				}
			}
			if (list.Count == 0)
			{
				UpgradeDropConfig.LogShopInfo("Shop secret skipped: no eligible second dead-end socket.");
				return;
			}
			Tile val2 = list[Random.Range(0, list.Count)];
			val2.active = true;
			val2.type = (Type)2;
			PrefabRef val3 = originalDeadEnds[Random.Range(0, originalDeadEnds.Count)];
			RunManager.instance.levelCurrent.ModulesDeadEnd1.Add(val3);
			UpgradeDropConfig.LogShopInfo("Shop secret spawned: " + ((PrefabRef<GameObject>)(object)val3).ResourcePath);
		}

		private static bool HasOneOpenConnection(Tile[,] grid, int x, int y)
		{
			int num = 0;
			(int, int)[] array = new(int, int)[4]
			{
				(x - 1, y),
				(x + 1, y),
				(x, y - 1),
				(x, y + 1)
			};
			for (int i = 0; i < array.Length; i++)
			{
				var (num2, num3) = array[i];
				if (num2 >= 0 && num2 < grid.GetLength(0) && num3 >= 0 && num3 < grid.GetLength(1) && grid[num2, num3].active)
				{
					num++;
				}
			}
			return num == 1;
		}

		private static bool TouchesReservedTile(Tile[,] grid, int x, int y)
		{
			//IL_0090: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			(int, int)[] array = new(int, int)[4]
			{
				(x - 1, y),
				(x + 1, y),
				(x, y - 1),
				(x, y + 1)
			};
			for (int i = 0; i < array.Length; i++)
			{
				var (num, num2) = array[i];
				if (num >= 0 && num < grid.GetLength(0) && num2 >= 0 && num2 < grid.GetLength(1))
				{
					Type type = grid[num, num2].type;
					if ((int)type == 2 || (int)type == 3 || (int)type == 4)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
}