Decompiled source of ShopPlus v1.0.0

Zichen-ShopPlus-1.0.0.dll

Decompiled 3 days 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.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Zichen-ShopPlus-1.0.0")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+472820085904c6c56c160a71f35727f48e95f671")]
[assembly: AssemblyProduct("Zichen-ShopPlus-1.0.0")]
[assembly: AssemblyTitle("Zichen-ShopPlus-1.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
[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;
		}
	}
}
[BepInPlugin("zichen.shopplus", "A.ShopPlus", "1.0.0")]
public class ShopPlusPlugin : BaseUnityPlugin
{
	private struct GroundPackLayout
	{
		public int PackCount;

		public int SlotsPerSet;

		public int RowsPerSet;

		public int TotalRows;

		public float FloorHeight;

		public float SpacingX;

		public float SpacingZ;

		public Vector3 GridCenter;

		public Vector3[] PackCenters;

		public Vector3 ExtractionPosition;

		public Vector3 SpawnReferencePosition;

		public Bounds ShopBounds;
	}

	private struct GroundPackSpawnSlot
	{
		public itemVolume VolumeType;

		public Vector3 Position;

		public Quaternion Rotation;
	}

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

		private object <>2__current;

		public ShopPlusPlugin <>4__this;

		private int <attempt>5__2;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			int num = <>1__state;
			ShopPlusPlugin shopPlusPlugin = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<attempt>5__2 = 0;
				break;
			case 1:
				<>1__state = -1;
				<attempt>5__2++;
				break;
			}
			if (<attempt>5__2 < 15)
			{
				if (!shopPlusPlugin.IsRandomFreeItemRuntimeEnabled() || !SemiFunc.RunIsShop())
				{
					shopPlusPlugin.freeItemSelectionCoroutine = null;
					return false;
				}
				if (shopPlusPlugin.TryAssignRandomFreeItem())
				{
					shopPlusPlugin.freeItemSelectionCoroutine = null;
					return false;
				}
				<>2__current = FreeItemRetryDelay;
				<>1__state = 1;
				return true;
			}
			shopPlusPlugin.freeItemSelectionCoroutine = null;
			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 <AssignSyncedFreeItemWhenReady>d__214 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public ShopPlusPlugin <>4__this;

		public int photonViewId;

		private int <attempt>5__2;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			int num = <>1__state;
			ShopPlusPlugin shopPlusPlugin = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<attempt>5__2 = 0;
				break;
			case 1:
				<>1__state = -1;
				<attempt>5__2++;
				break;
			}
			if (<attempt>5__2 < 15)
			{
				if (!shopPlusPlugin.IsRandomFreeItemRuntimeEnabled() || !SemiFunc.RunIsShop())
				{
					shopPlusPlugin.freeItemSelectionCoroutine = null;
					return false;
				}
				if (shopPlusPlugin.TryAssignSyncedFreeItem(photonViewId))
				{
					shopPlusPlugin.freeItemSelectionCoroutine = null;
					return false;
				}
				<>2__current = FreeItemRetryDelay;
				<>1__state = 1;
				return true;
			}
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)$"Failed to apply synced free shop item on this client. ViewID={photonViewId}");
			}
			shopPlusPlugin.freeItemSelectionCoroutine = null;
			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 = "zichen.shopplus";

	public const string PluginVersion = "1.0.0";

	public const string PluginName = "A.ShopPlus";

	private static ShopPlusPlugin Instance;

	private Harmony harmony;

	private const string InfoSection = "模组信息";

	private const string GlobalSection = "A.全局设置";

	private const string ShopItemFeaturesSection = "B.刷物和免单";

	private const string GroundPacksSection = "C.地面补货";

	private const int MaxItemSpawnMultiplier = 3;

	private const int MaxGroundItemPackCount = 3;

	private const int MaxGroundItemVolumeCount = 20;

	private ConfigEntry<string> moduleNameInfo;

	private ConfigEntry<string> moduleVersionInfo;

	private ConfigEntry<string> contactInfo;

	private ConfigEntry<bool> modEnabled;

	internal ConfigEntry<bool> shopItemFeaturesEnabled;

	internal ConfigEntry<int> itemSpawnMultiplier;

	internal ConfigEntry<bool> randomFreeItemEnabled;

	internal ConfigEntry<bool> groundItemPacksEnabled;

	internal ConfigEntry<int> groundItemPackCount;

	internal ConfigEntry<int> groundSmallItemCount;

	internal ConfigEntry<int> groundMediumItemCount;

	internal ConfigEntry<int> groundPowerCrystalCount;

	internal ConfigEntry<int> groundLargeHighItemCount;

	internal ConfigEntry<int> groundUpgradeItemCount;

	internal ConfigEntry<int> groundHealthPackCount;

	internal ConfigEntry<int> groundLargeItemCount;

	internal ConfigEntry<int> groundLargeWideItemCount;

	internal ConfigEntry<int> groundLargePlusItemCount;

	private Coroutine freeItemSelectionCoroutine;

	private readonly List<ItemAttributes> freeItemCandidateBuffer = new List<ItemAttributes>(128);

	private DateTime lastLoadedConfigWriteTimeUtc = DateTime.MinValue;

	private int lastRuntimeConfigReloadFrame = -1;

	private Rect cachedFreeItemLabelRect;

	private int cachedFreeItemLabelFrame = -1;

	private static ItemAttributes currentFreeShopItem;

	private static int currentFreeShopItemOriginalValue = -1;

	private static Vector3 currentFreeShopItemOriginalScale = Vector3.one;

	private static ShopPlusFreeItemSync freeItemNetworkSync;

	private static GUIStyle freeItemLabelStyle;

	private static readonly Color FreeItemHighlightColor = new Color(0.32f, 1f, 0.48f, 1f);

	private static readonly Color FreeItemLabelBackgroundColor = new Color(0.18f, 0.92f, 0.35f, 0.95f);

	private static readonly WaitForSeconds FreeItemRetryDelay = new WaitForSeconds(0.2f);

	private static readonly Comparison<ItemAttributes> FreeItemCandidateComparison = CompareFreeItemCandidates;

	private const int FreeItemMaxValue = 10;

	private const int FreeItemMaxSelectionAttempts = 15;

	private const float FreeItemScaleMultiplier = 0.72f;

	private const string FreeItemPromptSuffix = " <color=#52FF7A>[FREE]</color>";

	private static readonly FieldInfo ShopManagerItemVolumesField = typeof(ShopManager).GetField("itemVolumes", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerShoppingListField = typeof(ShopManager).GetField("shoppingList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerItemSpawnTargetAmountField = typeof(ShopManager).GetField("itemSpawnTargetAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerItemConsumablesAmountField = typeof(ShopManager).GetField("itemConsumablesAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerItemUpgradesAmountField = typeof(ShopManager).GetField("itemUpgradesAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerItemHealthPacksAmountField = typeof(ShopManager).GetField("itemHealthPacksAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerPotentialItemsField = typeof(ShopManager).GetField("potentialItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerPotentialItemConsumablesField = typeof(ShopManager).GetField("potentialItemConsumables", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerPotentialItemUpgradesField = typeof(ShopManager).GetField("potentialItemUpgrades", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerPotentialItemHealthPacksField = typeof(ShopManager).GetField("potentialItemHealthPacks", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerPotentialSecretItemsField = typeof(ShopManager).GetField("potentialSecretItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ShopManagerItemValueMultiplierField = typeof(ShopManager).GetField("itemValueMultiplier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemAttributesValueField = typeof(ItemAttributes).GetField("value", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ItemAttributesPromptNameField = typeof(ItemAttributes).GetField("promptName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo ExtractionPointIsShopField = typeof(ExtractionPoint).GetField("isShop", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo RoomVolumeCheckInTruckField = typeof(RoomVolumeCheck).GetField("inTruck", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo RoomVolumeCheckInExtractionPointField = typeof(RoomVolumeCheck).GetField("inExtractionPoint", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static readonly FieldInfo WorldSpaceUIValueTextField = typeof(WorldSpaceUIValue).GetField("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private const int GroundPackColumns = 11;

	private const float GroundPackMaxSpacing = 0.62f;

	private const float GroundPackMinSpacing = 0.38f;

	private const float GroundPackDesiredSpawnHeight = 1.25f;

	private const float GroundPackMinimumSpawnHeight = 0.45f;

	private const float GroundPackCeilingClearance = 0.55f;

	private const float GroundPackExtractionClearance = 3.65f;

	private const float GroundPackBoundsMargin = 0.38f;

	private const float GroundPackOccupiedClearanceFactor = 0.68f;

	private const float GroundPackOccupiedClearanceMin = 0.26f;

	private const float GroundPackOriginalVolumeClearance = 0.48f;

	private const int GroundPackRaycastHitBufferSize = 64;

	private static readonly float[] GroundPackFallbackAngles = new float[14]
	{
		0f, 24f, -24f, 48f, -48f, 72f, -72f, 96f, -96f, 120f,
		-120f, 144f, -144f, 180f
	};

	private static readonly List<GameObject> groundSpawnVolumeObjects = new List<GameObject>();

	private static readonly List<ItemVolume> sceneShopVolumeBuffer = new List<ItemVolume>(96);

	private static readonly List<ItemVolume> normalShopVolumeBuffer = new List<ItemVolume>(96);

	private static readonly List<Vector3> groundPackOccupiedPositionsBuffer = new List<Vector3>(256);

	private static readonly List<GroundPackSpawnSlot> pendingGroundPackSpawnSlots = new List<GroundPackSpawnSlot>(512);

	private static readonly Dictionary<itemVolume, int> groundPackCreatedCountsBuffer = new Dictionary<itemVolume, int>(16);

	private static readonly Dictionary<string, int> groundPackSkippedCountsBuffer = new Dictionary<string, int>(16);

	private static readonly Dictionary<string, int> groundPackUpgradeItemCountsBuffer = new Dictionary<string, int>(32);

	private static readonly List<Item> limitedItemReplacementCandidatesBuffer = new List<Item>(64);

	private static readonly float[] groundPackHeightSampleBuffer = new float[5];

	private static readonly RaycastHit[] GroundPackFloorRaycastHits = (RaycastHit[])(object)new RaycastHit[64];

	private static readonly RaycastHit[] GroundPackCeilingRaycastHits = (RaycastHit[])(object)new RaycastHit[64];

	private static int groundPackCreateLogFrame = -1;

	private static int itemVolumeCollectionLogFrame = -1;

	private static PropertyInfo worldSpaceUITextProperty;

	private static PropertyInfo worldSpaceUIColorProperty;

	private void Awake()
	{
		DetachFromManager();
		Instance = this;
		ResetConfigIfVersionChanged();
		BindConfig();
		ApplyHarmonyPatches();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ShopPlus v1.0.0 loaded.");
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		if (Instance == this)
		{
			Instance = null;
		}
	}

	private void DetachFromManager()
	{
		try
		{
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to mark plugin host persistent: " + ex.GetType().Name + ": " + ex.Message));
		}
	}

	private bool IsModEnabled()
	{
		if (modEnabled != null)
		{
			return modEnabled.Value;
		}
		return true;
	}

	private static bool IsStaticModEnabled()
	{
		ShopPlusPlugin instance = Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			return instance.IsModEnabled();
		}
		return true;
	}

	private static bool ShouldRunMasterShopLogic()
	{
		if (IsStaticModEnabled() && SemiFunc.RunIsShop())
		{
			return !SemiFunc.IsNotMasterClient();
		}
		return false;
	}

	private bool AreShopItemFeaturesEnabled()
	{
		if (shopItemFeaturesEnabled != null)
		{
			return shopItemFeaturesEnabled.Value;
		}
		return true;
	}

	private static bool AreStaticShopItemFeaturesEnabled()
	{
		ShopPlusPlugin instance = Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			return instance.AreShopItemFeaturesEnabled();
		}
		return true;
	}

	private static int GetConfiguredItemSpawnMultiplier()
	{
		if (!AreStaticShopItemFeaturesEnabled())
		{
			return 1;
		}
		return Mathf.Clamp((Instance?.itemSpawnMultiplier?.Value).GetValueOrDefault(1), 1, 3);
	}

	private bool IsRandomFreeItemRuntimeEnabled()
	{
		if (IsModEnabled() && AreShopItemFeaturesEnabled())
		{
			if (randomFreeItemEnabled != null)
			{
				return randomFreeItemEnabled.Value;
			}
			return true;
		}
		return false;
	}

	private static bool IsStaticRandomFreeItemEnabled()
	{
		ShopPlusPlugin instance = Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			return instance.IsRandomFreeItemRuntimeEnabled();
		}
		return true;
	}

	private static bool IsGroundPackEnabled()
	{
		ShopPlusPlugin instance = Instance;
		if ((Object)(object)instance != (Object)null && instance.groundItemPacksEnabled != null)
		{
			return instance.groundItemPacksEnabled.Value;
		}
		return false;
	}

	private static int GetConfiguredGroundPackCount()
	{
		return Mathf.Clamp((Instance?.groundItemPackCount?.Value).GetValueOrDefault(1), 1, 3);
	}

	private static int ClampGroundItemVolumeCount(ConfigEntry<int> entry, int fallback)
	{
		return Mathf.Clamp(entry?.Value ?? fallback, 0, 20);
	}

	private void BindConfig()
	{
		moduleNameInfo = BindReadOnlyInfo("模组名称", "商店扩展", "当前模组的中文名称。此处只是提示,不影响功能。", 1000);
		moduleVersionInfo = BindReadOnlyInfo("模组版本号", "1.0.0", "当前模组版本号。此处只是提示,不影响功能。", 990);
		contactInfo = BindReadOnlyInfo("REPO交流QQ群", "824639225", "REPO游戏交流、BUG反馈、优化建议、功能请求请加QQ群。此处只是提示,不影响功能。", 980);
		modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("A.全局设置", "模组启用", true, ConfigDescriptionWithOrder("关闭后整个模组所有功能都不生效。默认开启。", 1005));
		int fallback = ReadIntConfigValue(((BaseUnityPlugin)this).Config.ConfigFilePath, "B.刷物和免单", "系统商店倍率", 1, 1, 3);
		fallback = ReadIntConfigValue(((BaseUnityPlugin)this).Config.ConfigFilePath, "B.刷物和免单", "物品刷出倍率", fallback, 1, 3);
		bool flag = ReadRandomFreeItemDefault(((BaseUnityPlugin)this).Config.ConfigFilePath);
		shopItemFeaturesEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.刷物和免单", "启用刷物和免单", true, ConfigDescriptionWithOrder("总开关:关闭后系统商店倍率按1倍处理,免单1件10k以内商品也不生效。默认开启。", 1000));
		itemSpawnMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("B.刷物和免单", "系统商店倍率", fallback, ConfigDescriptionWithOrder("只调整官方/原版商店刷物倍率,不影响 C.地面补货。1倍为原版,最多3倍。默认1倍。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), 995));
		randomFreeItemEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("B.刷物和免单", "免单1件10k以内商品", flag, ConfigDescriptionWithOrder("开启后每次进入商店会随机挑选一件价格不高于10k的商店商品直接改成0元,并显示明显提示。默认开启。", 990));
		groundItemPacksEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("C.地面补货", "启用地面补货", true, ConfigDescriptionWithOrder("开启后独立在商店地面生成补货物品,不受 B.刷物和免单/系统商店倍率影响;关闭后完全不生成。默认开启。", 985));
		groundItemPackCount = ((BaseUnityPlugin)this).Config.Bind<int>("C.地面补货", "地面补货套数", 2, ConfigDescriptionWithOrder("每1套按配置分类数量生成一堆地面补货。最多3套。默认2套。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 3), 980));
		groundUpgradeItemCount = BindGroundVolumeCount("升级药水数量", 20, "每套地面补货生成多少个升级药水/升级道具刷点。0为不生成,最多20。", 979);
		groundSmallItemCount = BindGroundVolumeCount("小型物品数量", 10, "每套地面补货生成多少个 small 小型物品刷点。0为不生成,最多20。", 978);
		groundMediumItemCount = BindGroundVolumeCount("中型物品数量", 10, "每套地面补货生成多少个 medium 中型物品刷点。0为不生成,最多20。", 977);
		groundPowerCrystalCount = BindGroundVolumeCount("能量水晶数量", 3, "每套地面补货生成多少个 power_crystal 能量水晶刷点。0为不生成,最多20。", 976);
		groundLargeHighItemCount = BindGroundVolumeCount("高大型物品数量", 2, "每套地面补货生成多少个 large_high 高大型物品刷点。0为不生成,最多20。", 975);
		groundHealthPackCount = BindGroundVolumeCount("医疗包数量", 5, "每套地面补货生成多少个 healthPack 医疗包/血包刷点。0为不生成,最多20。", 974);
		groundLargeItemCount = BindGroundVolumeCount("大型物品数量", 0, "每套地面补货生成多少个 large 大型物品刷点。0为不生成,最多20。", 973);
		groundLargeWideItemCount = BindGroundVolumeCount("宽大型物品数量", 0, "每套地面补货生成多少个 large_wide 宽大型物品刷点。0为不生成,最多20。", 972);
		groundLargePlusItemCount = BindGroundVolumeCount("超大型物品数量", 0, "每套地面补货生成多少个 large_plus 超大型物品刷点。0为不生成,最多20。", 971);
		UpdateLoadedConfigWriteTime();
	}

	private ConfigEntry<int> BindGroundVolumeCount(string key, int defaultValue, string description, int order)
	{
		return ((BaseUnityPlugin)this).Config.Bind<int>("C.地面补货", key, defaultValue, ConfigDescriptionWithOrder(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), order));
	}

	private void ResetConfigIfVersionChanged()
	{
		try
		{
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			string text = ReadConfigPluginVersion(configFilePath);
			if (!string.IsNullOrWhiteSpace(text) && !(text == "1.0.0"))
			{
				ResetConfigFileToDefaults(configFilePath);
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Config version changed. Old config was reset to defaults.");
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reset config by version: " + ex.Message));
		}
	}

	private void ReloadRuntimeConfigForNextShop()
	{
		try
		{
			if (lastRuntimeConfigReloadFrame != Time.frameCount)
			{
				lastRuntimeConfigReloadFrame = Time.frameCount;
				string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
				DateTime dateTime = (File.Exists(configFilePath) ? File.GetLastWriteTimeUtc(configFilePath) : DateTime.MinValue);
				((BaseUnityPlugin)this).Config.Reload();
				lastLoadedConfigWriteTimeUtc = dateTime;
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Config reloaded for shop generation. fileTimeUtc={dateTime:O}");
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to reload config for next shop: " + ex.Message));
		}
	}

	private static string ReadConfigPluginVersion(string configPath)
	{
		if (!File.Exists(configPath))
		{
			return null;
		}
		Match match = Regex.Match(File.ReadAllText(configPath), "(?m)^模组版本号\\s*=\\s*(.+?)\\s*$");
		if (!match.Success)
		{
			return null;
		}
		return match.Groups[1].Value.Trim();
	}

	private static bool ReadBoolConfigValue(string configPath, string section, string key, bool fallback)
	{
		if (!TryReadConfigValue(configPath, section, key, out var value) || !bool.TryParse(value, out var result))
		{
			return fallback;
		}
		return result;
	}

	private static bool ReadRandomFreeItemDefault(string configPath)
	{
		return ReadBoolConfigValue(configPath, "B.刷物和免单", "免单1件10k以内商品", ReadBoolConfigValue(configPath, "B.刷物和免单", "十元内随机免单", ReadBoolConfigValue(configPath, "A.全局设置", "十元内随机免单", fallback: true)));
	}

	private static int ReadIntConfigValue(string configPath, string section, string key, int fallback, int min, int max)
	{
		if (!TryReadConfigValue(configPath, section, key, out var value) || !int.TryParse(value, out var result))
		{
			return fallback;
		}
		return Mathf.Clamp(result, min, max);
	}

	private static bool TryReadConfigValue(string configPath, string section, string key, out string value)
	{
		value = null;
		if (!File.Exists(configPath))
		{
			return false;
		}
		string text = null;
		string[] array = File.ReadAllLines(configPath);
		for (int i = 0; i < array.Length; i++)
		{
			string text2 = array[i].Trim();
			if (text2.Length == 0 || text2.StartsWith("#", StringComparison.Ordinal))
			{
				continue;
			}
			if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal))
			{
				text = text2.Substring(1, text2.Length - 2);
			}
			else if (!(text != section))
			{
				int num = text2.IndexOf('=');
				if (num >= 0 && !(text2.Substring(0, num).Trim() != key))
				{
					value = text2.Substring(num + 1).Trim();
					return true;
				}
			}
		}
		return false;
	}

	private void ResetConfigFileToDefaults(string configPath)
	{
		((BaseUnityPlugin)this).Config.Clear();
		if (File.Exists(configPath))
		{
			File.Delete(configPath);
		}
		((BaseUnityPlugin)this).Config.Reload();
	}

	private void UpdateLoadedConfigWriteTime()
	{
		string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
		lastLoadedConfigWriteTimeUtc = (File.Exists(configFilePath) ? File.GetLastWriteTimeUtc(configFilePath) : DateTime.MinValue);
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private static ConfigDescription ConfigDescriptionWithOrder(string description, AcceptableValueBase acceptableValues, int order)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Expected O, but got Unknown
		return new ConfigDescription(description, acceptableValues, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order
			}
		});
	}

	private ConfigEntry<string> BindReadOnlyInfo(string key, string value, string description, int order)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		ConfigEntry<string> obj = ((BaseUnityPlugin)this).Config.Bind<string>("模组信息", key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Order = order,
				CustomDrawer = DrawInfo,
				ReadOnly = true
			}
		}));
		obj.Value = value;
		return obj;
	}

	private static void DrawInfo(ConfigEntryBase entry)
	{
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		GUILayout.Label(entry.Definition.Key, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
		GUILayout.Label(entry.BoxedValue?.ToString() ?? string.Empty, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) });
		GUILayout.EndHorizontal();
	}

	private void ApplyHarmonyPatches()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		harmony = new Harmony("zichen.shopplus");
		PatchPostfix(typeof(ShopManager), "GetAllItemVolumesInScene", "ShopManagerGetAllVolumesPostfix");
		PatchPrefix(typeof(ShopManager), "GetAllItemsFromStatsManager", "ShopManagerGetAllItemsPrefix");
		PatchPostfix(typeof(ShopManager), "GetAllItemsFromStatsManager", "ShopManagerGetAllItemsPostfix");
		PatchPrefix(typeof(ShopManager), "ShopInitialize", "ShopManagerShopInitializePrefix");
		PatchPostfix(typeof(ShopManager), "ShopInitialize", "ShopManagerShopInitializePostfix");
		PatchPostfix(typeof(ItemAttributes), "ShowingInfo", "ItemAttributesShowingInfoPostfix");
		PatchPostfix(typeof(ExtractionPoint), "CancelExtraction", "ExtractionPointCancelExtractionPostfix");
		PatchPostfix(typeof(WorldSpaceUIValue), "Show", "WorldSpaceUIValueShowPhysPostfix", new Type[4]
		{
			typeof(PhysGrabObject),
			typeof(int),
			typeof(bool),
			typeof(Vector3)
		});
		((BaseUnityPlugin)this).Logger.LogInfo((object)"ShopPlus Harmony patches applied.");
	}

	private void PatchPrefix(Type originalType, string originalName, string patchName)
	{
		PatchMethod(originalType, originalName, patchName, prefix: true, null);
	}

	private void PatchPostfix(Type originalType, string originalName, string patchName)
	{
		PatchMethod(originalType, originalName, patchName, prefix: false, null);
	}

	private void PatchPostfix(Type originalType, string originalName, string patchName, Type[] argumentTypes)
	{
		PatchMethod(originalType, originalName, patchName, prefix: false, argumentTypes);
	}

	private void PatchMethod(Type originalType, string originalName, string patchName, bool prefix, Type[] argumentTypes)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Expected O, but got Unknown
		MethodInfo methodInfo = ((argumentTypes == null) ? AccessTools.Method(originalType, originalName, (Type[])null, (Type[])null) : AccessTools.Method(originalType, originalName, argumentTypes, (Type[])null));
		MethodInfo methodInfo2 = AccessTools.Method(typeof(ShopPlusPlugin), patchName, (Type[])null, (Type[])null);
		if (methodInfo == null || methodInfo2 == null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Failed to find Harmony patch target: " + originalType?.Name + "." + originalName + " -> " + patchName));
		}
		else
		{
			HarmonyMethod val = new HarmonyMethod(methodInfo2);
			if (prefix)
			{
				harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}
	}

	private static void ShopManagerGetAllItemsPostfix(ShopManager __instance)
	{
		if (!ShouldRunMasterShopLogic())
		{
			return;
		}
		int configuredItemSpawnMultiplier = GetConfiguredItemSpawnMultiplier();
		if (configuredItemSpawnMultiplier > 1)
		{
			MultiplyIntField(ShopManagerItemSpawnTargetAmountField, __instance, configuredItemSpawnMultiplier);
			MultiplyIntField(ShopManagerItemConsumablesAmountField, __instance, configuredItemSpawnMultiplier);
			MultiplyIntField(ShopManagerItemUpgradesAmountField, __instance, configuredItemSpawnMultiplier);
			MultiplyIntField(ShopManagerItemHealthPacksAmountField, __instance, configuredItemSpawnMultiplier);
			MultiplyItemList(ShopManagerPotentialItemsField, __instance, configuredItemSpawnMultiplier);
			MultiplyItemList(ShopManagerPotentialItemConsumablesField, __instance, configuredItemSpawnMultiplier);
			MultiplyItemList(ShopManagerPotentialItemUpgradesField, __instance, configuredItemSpawnMultiplier);
			MultiplyItemList(ShopManagerPotentialItemHealthPacksField, __instance, configuredItemSpawnMultiplier);
			ShopPlusPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[ItemMultiplier] Applied {configuredItemSpawnMultiplier}x item spawn multiplier.");
			}
		}
		int num = EnforceSingleSpecialShopItemAcrossShopPools(__instance);
		if (num > 0)
		{
			ShopPlusPlugin instance2 = Instance;
			if (instance2 != null)
			{
				((BaseUnityPlugin)instance2).Logger.LogInfo((object)$"[ItemLimiter] Replaced/removed {num} extra cart/vehicle candidate(s); ShopPlus keeps max 1 big cart, 1 pocket cart, and 1 of each drivable vehicle.");
			}
		}
	}

	private static void ShopManagerGetAllItemsPrefix()
	{
		if (IsStaticModEnabled() && SemiFunc.RunIsShop())
		{
			Instance?.ReloadRuntimeConfigForNextShop();
		}
	}

	private static void MultiplyIntField(FieldInfo field, ShopManager shopManager, int multiplier)
	{
		if (field == null || (Object)(object)shopManager == (Object)null)
		{
			return;
		}
		object value = field.GetValue(shopManager);
		if (value is int)
		{
			int num = (int)value;
			if (num > 0)
			{
				long num2 = (long)num * (long)multiplier;
				field.SetValue(shopManager, (int)((num2 > int.MaxValue) ? int.MaxValue : num2));
			}
		}
	}

	private static void MultiplyItemList(FieldInfo field, ShopManager shopManager, int multiplier)
	{
		if (field == null || (Object)(object)shopManager == (Object)null || !(field.GetValue(shopManager) is IList list) || list.Count == 0)
		{
			return;
		}
		int count = list.Count;
		for (int i = 1; i < multiplier; i++)
		{
			for (int j = 0; j < count; j++)
			{
				list.Add(list[j]);
			}
		}
	}

	private static int EnforceSingleSpecialShopItemAcrossShopPools(ShopManager shopManager)
	{
		HashSet<string> allowedItemKeys = new HashSet<string>();
		return 0 + LimitSpecialShopItemEntriesInList(ShopManagerPotentialItemsField, shopManager, allowedItemKeys) + LimitSpecialShopItemEntriesInList(ShopManagerPotentialItemConsumablesField, shopManager, allowedItemKeys) + LimitSpecialShopItemEntriesInList(ShopManagerPotentialItemUpgradesField, shopManager, allowedItemKeys) + LimitSpecialShopItemEntriesInList(ShopManagerPotentialItemHealthPacksField, shopManager, allowedItemKeys) + LimitSpecialShopItemEntriesInSecretLists(ShopManagerPotentialSecretItemsField, shopManager, allowedItemKeys);
	}

	private static int LimitSpecialShopItemEntriesInList(FieldInfo field, ShopManager shopManager, HashSet<string> allowedItemKeys)
	{
		if (field == null || (Object)(object)shopManager == (Object)null)
		{
			return 0;
		}
		if (!(field.GetValue(shopManager) is IList list) || list.Count == 0)
		{
			return 0;
		}
		return LimitSpecialShopItemEntriesInIList(list, allowedItemKeys);
	}

	private static int LimitSpecialShopItemEntriesInSecretLists(FieldInfo field, ShopManager shopManager, HashSet<string> allowedItemKeys)
	{
		if (field == null || (Object)(object)shopManager == (Object)null)
		{
			return 0;
		}
		if (!(field.GetValue(shopManager) is IDictionary dictionary) || dictionary.Count == 0)
		{
			return 0;
		}
		int num = 0;
		foreach (DictionaryEntry item in dictionary)
		{
			if (item.Value is IList items)
			{
				num += LimitSpecialShopItemEntriesInIList(items, allowedItemKeys);
			}
		}
		return num;
	}

	private static int LimitSpecialShopItemEntriesInIList(IList items, HashSet<string> allowedItemKeys)
	{
		if (items == null || items.Count == 0)
		{
			return 0;
		}
		List<Item> replacementCandidates = BuildLimitedItemReplacementCandidates(items);
		int num = 0;
		for (int num2 = items.Count - 1; num2 >= 0; num2--)
		{
			object? obj = items[num2];
			Item val = (Item)((obj is Item) ? obj : null);
			if (val != null)
			{
				string specialShopItemLimitKey = GetSpecialShopItemLimitKey(val);
				if (!string.IsNullOrEmpty(specialShopItemLimitKey) && !allowedItemKeys.Add(specialShopItemLimitKey))
				{
					Item randomLimitedItemReplacement = GetRandomLimitedItemReplacement(replacementCandidates);
					if ((Object)(object)randomLimitedItemReplacement != (Object)null)
					{
						items[num2] = randomLimitedItemReplacement;
					}
					else
					{
						items.RemoveAt(num2);
					}
					num++;
				}
			}
		}
		return num;
	}

	private static List<Item> BuildLimitedItemReplacementCandidates(IList items)
	{
		List<Item> list = limitedItemReplacementCandidatesBuffer;
		list.Clear();
		if (items == null)
		{
			return list;
		}
		for (int i = 0; i < items.Count; i++)
		{
			object? obj = items[i];
			Item val = (Item)((obj is Item) ? obj : null);
			if (val != null && string.IsNullOrEmpty(GetSpecialShopItemLimitKey(val)))
			{
				list.Add(val);
			}
		}
		return list;
	}

	private static Item GetRandomLimitedItemReplacement(List<Item> replacementCandidates)
	{
		if (replacementCandidates == null || replacementCandidates.Count == 0)
		{
			return null;
		}
		return replacementCandidates[Random.Range(0, replacementCandidates.Count)];
	}

	private static string GetSpecialShopItemLimitKey(Item item)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Invalid comparison between Unknown and I4
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Invalid comparison between Unknown and I4
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		if ((Object)(object)item == (Object)null)
		{
			return string.Empty;
		}
		if ((int)item.itemType == 2)
		{
			return "cart:big";
		}
		if ((int)item.itemType == 12)
		{
			return "cart:pocket";
		}
		if ((int)item.itemType != 14)
		{
			return string.Empty;
		}
		return "vehicle:" + GetItemStableKey(item);
	}

	private static string GetItemStableKey(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return string.Empty;
		}
		if (item.prefab != null && !string.IsNullOrEmpty(item.prefab.ResourcePath))
		{
			return item.prefab.ResourcePath;
		}
		if (!string.IsNullOrEmpty(((Object)item).name))
		{
			return ((Object)item).name;
		}
		if (!string.IsNullOrEmpty(item.itemName))
		{
			return item.itemName;
		}
		return string.Empty;
	}

	private static string GetItemLogName(Item item)
	{
		if ((Object)(object)item == (Object)null)
		{
			return "unknown";
		}
		if (!string.IsNullOrEmpty(item.itemName) && !string.IsNullOrEmpty(((Object)item).name))
		{
			return item.itemName + " (" + ((Object)item).name + ")";
		}
		if (!string.IsNullOrEmpty(item.itemName))
		{
			return item.itemName;
		}
		return ((Object)item).name;
	}

	private static void ShopManagerGetAllVolumesPostfix(ShopManager __instance)
	{
		if (ShouldRunMasterShopLogic() && itemVolumeCollectionLogFrame != Time.frameCount && ShopManagerItemVolumesField?.GetValue(__instance) is IList list)
		{
			itemVolumeCollectionLogFrame = Time.frameCount;
			LogGroundPack($"ShopManager collected {list.Count} item volume(s); ShopPlus generated {groundSpawnVolumeObjects.Count} ground-pack root object(s).");
		}
	}

	private static void ShopManagerShopInitializePrefix()
	{
		Instance?.ReloadRuntimeConfigForNextShop();
		CleanGroundSpawnVolumes();
		Instance?.ResetFreeItemSelectionForShopChange();
		if (IsStaticModEnabled() && SemiFunc.RunIsShop())
		{
			ShopPlusPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[Config] Shop settings snapshot: itemMultiplier={GetConfiguredItemSpawnMultiplier()}, groundPackEnabled={IsGroundPackEnabled()}, groundPackCount={GetConfiguredGroundPackCount()}, freeItemEnabled={IsStaticRandomFreeItemEnabled()}.");
			}
			if (SemiFunc.IsNotMasterClient())
			{
				LogGroundPack("Shop logic skipped on non-master client; waiting for host-generated shop items.");
			}
			else if (!IsGroundPackEnabled())
			{
				LogGroundPack("Ground pack skipped: disabled by config.");
			}
			else
			{
				CreateGroundItemPacks();
			}
		}
	}

	private static void CreateGroundItemPacks()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		List<ItemVolume> sceneShopItemVolumes = GetSceneShopItemVolumes(sceneShopVolumeBuffer);
		if (sceneShopItemVolumes.Count == 0)
		{
			LogGroundPack("Ground pack skipped: no original ItemVolume objects found in current shop scene.");
			return;
		}
		List<ItemVolume> normalShopItemVolumes = GetNormalShopItemVolumes(sceneShopItemVolumes, normalShopVolumeBuffer);
		List<ItemVolume> list = ((normalShopItemVolumes.Count > 0) ? normalShopItemVolumes : sceneShopItemVolumes);
		if (!TryGetShopSearchBounds(list, out var bounds))
		{
			LogGroundPack("Ground pack skipped: failed to build shop bounds from original ItemVolume objects.");
			return;
		}
		itemVolume[] array = BuildConfiguredGroundPackTemplate();
		if (array.Length == 0)
		{
			LogGroundPack("Ground pack skipped: all configured ground item category counts are 0.");
			return;
		}
		GroundPackLayout layout = BuildGroundPackLayout(bounds, array.Length);
		int num = 0;
		int num2 = 0;
		Dictionary<itemVolume, int> dictionary = groundPackCreatedCountsBuffer;
		dictionary.Clear();
		int num3 = 0;
		Dictionary<string, int> dictionary2 = groundPackSkippedCountsBuffer;
		dictionary2.Clear();
		List<Vector3> list2 = groundPackOccupiedPositionsBuffer;
		list2.Clear();
		AddExistingShopVolumePositions(list, list2);
		pendingGroundPackSpawnSlots.Clear();
		int num4 = layout.PackCount * Mathf.Max(array.Length, 1);
		if (list2.Capacity < num4)
		{
			list2.Capacity = num4;
		}
		if (pendingGroundPackSpawnSlots.Capacity < num4)
		{
			pendingGroundPackSpawnSlots.Capacity = num4;
		}
		int seed = GetStableShopSeed(list) + layout.PackCount * 977 + array.Length * 13;
		string text = FormatVolumeCounts(CountVolumeTypes(array));
		LogGroundPack($"Ground pack template uses configured category counts: sourceNormalVolumes={normalShopItemVolumes.Count}, sourceAllVolumes={sceneShopItemVolumes.Count}, 1 set = {array.Length} hidden ground spawn point(s), typeCounts={text}.");
		LogGroundPack($"Ground pack placement: sets={layout.PackCount}, gridPerSet={11}x{layout.RowsPerSet}, spacing=({layout.SpacingX:F2}, {layout.SpacingZ:F2}), centers={FormatPackCenters(layout.PackCenters)}, floorY={layout.FloorHeight:F2}, desiredHeight={1.25f:F2}, ceilingClearance={0.55f:F2}, existingVolumeAvoidance={0.48f:F2}, bounds={FormatBounds(layout.ShopBounds)}, extraction={FormatVector3(layout.ExtractionPosition)}, spawnReference={FormatVector3(layout.SpawnReferencePosition)}.");
		for (int i = 0; i < layout.PackCount; i++)
		{
			itemVolume[] array2 = CopyGroundPackTemplate(array);
			for (int j = 0; j < array2.Length; j++)
			{
				if (!TryCreateGroundPackSpawnSlot(layout, i, j, array2[j], seed, list2, out var spawnSlot, out var skipReason, out var usedFallback))
				{
					num3++;
					AddStringCount(dictionary2, skipReason);
					continue;
				}
				pendingGroundPackSpawnSlots.Add(spawnSlot);
				num++;
				if (usedFallback)
				{
					num2++;
				}
				AddVolumeCount(dictionary, array2[j]);
			}
		}
		if (num == 0)
		{
			LogGroundPack("Ground pack prepared 0 valid manual spawn slot(s).");
		}
		else if (groundPackCreateLogFrame != Time.frameCount)
		{
			groundPackCreateLogFrame = Time.frameCount;
			LogGroundPack($"Ground pack prepared {num}/{layout.PackCount * array.Length} manual spawn slot(s), typeCounts={FormatVolumeCounts(dictionary)}.");
			if (num2 > 0)
			{
				LogGroundPack($"Ground pack fallback search relocated {num2} slot(s) to keep them inside the shop and away from extraction.");
			}
			if (num3 > 0)
			{
				LogGroundPack($"Ground pack skipped {num3} slot(s), reasons={FormatStringCounts(dictionary2)}.");
			}
		}
	}

	private static GroundPackLayout BuildGroundPackLayout(Bounds shopBounds, int slotsPerSet)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		int configuredGroundPackCount = GetConfiguredGroundPackCount();
		Transform val = FindShopExtractionTransform();
		Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : ((Bounds)(ref shopBounds)).center);
		Vector3 spawnReferencePosition = FindGroundPackSpawnReferencePosition(shopBounds, val2);
		float approximateFloorHeight = GetApproximateFloorHeight(shopBounds, val2);
		int num = Mathf.Max(1, Mathf.CeilToInt((float)Mathf.Max(1, slotsPerSet) / 11f));
		int totalRows = num * configuredGroundPackCount;
		float spacingX = ResolveGridSpacing(((Bounds)(ref shopBounds)).size.x, 11);
		float spacingZ = ResolveGridSpacing(((Bounds)(ref shopBounds)).size.z, num);
		Vector3 val3 = FindGroundPackCenter(shopBounds, approximateFloorHeight, val2, spawnReferencePosition, 11, num, spacingX, spacingZ);
		GroundPackLayout result = default(GroundPackLayout);
		result.PackCount = configuredGroundPackCount;
		result.SlotsPerSet = slotsPerSet;
		result.RowsPerSet = num;
		result.TotalRows = totalRows;
		result.FloorHeight = approximateFloorHeight;
		result.SpacingX = spacingX;
		result.SpacingZ = spacingZ;
		result.GridCenter = val3;
		result.PackCenters = FindGroundPackCenters(shopBounds, approximateFloorHeight, val2, spawnReferencePosition, 11, num, spacingX, spacingZ, configuredGroundPackCount, val3);
		result.ExtractionPosition = val2;
		result.SpawnReferencePosition = spawnReferencePosition;
		result.ShopBounds = shopBounds;
		return result;
	}

	private static bool TryCreateGroundPackSpawnSlot(GroundPackLayout layout, int setIndex, int slotIndex, itemVolume volumeType, int seed, List<Vector3> occupiedPositions, out GroundPackSpawnSlot spawnSlot, out string skipReason, out bool usedFallback)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		spawnSlot = default(GroundPackSpawnSlot);
		int row = slotIndex / 11;
		int column = slotIndex % 11;
		if (!TryResolveGroundSpawnPosition(GridToWorldPosition(GetGroundPackCenterForSet(layout, setIndex), column, row, 11, layout.RowsPerSet, layout.SpacingX, layout.SpacingZ), layout, occupiedPositions, out var spawnPosition, out var skipReason2, out usedFallback))
		{
			skipReason = skipReason2;
			return false;
		}
		spawnSlot = new GroundPackSpawnSlot
		{
			VolumeType = volumeType,
			Position = spawnPosition,
			Rotation = Quaternion.Euler(0f, (float)((seed + setIndex * 101 + slotIndex * 37) % 360), 0f)
		};
		occupiedPositions?.Add(spawnPosition);
		skipReason = null;
		return true;
	}

	private static void SpawnPendingGroundPackItems()
	{
		//IL_0079: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Invalid comparison between Unknown and I4
		if (pendingGroundPackSpawnSlots.Count == 0 || (Object)(object)StatsManager.instance == (Object)null || (Object)(object)ShopManager.instance == (Object)null)
		{
			return;
		}
		Dictionary<itemVolume, List<Item>> candidatesByVolume = BuildGroundPackItemCandidates();
		Dictionary<itemVolume, int> candidateIndexes = new Dictionary<itemVolume, int>();
		Dictionary<itemVolume, int> dictionary = groundPackCreatedCountsBuffer;
		dictionary.Clear();
		Dictionary<string, int> dictionary2 = groundPackSkippedCountsBuffer;
		dictionary2.Clear();
		Dictionary<string, int> dictionary3 = groundPackUpgradeItemCountsBuffer;
		dictionary3.Clear();
		int num = 0;
		int num2 = 0;
		for (int i = 0; i < pendingGroundPackSpawnSlots.Count; i++)
		{
			GroundPackSpawnSlot groundPackSpawnSlot = pendingGroundPackSpawnSlots[i];
			if (!TryGetNextGroundPackItem(candidatesByVolume, candidateIndexes, groundPackSpawnSlot.VolumeType, out var item))
			{
				num2++;
				AddStringCount(dictionary2, "no candidate for " + ((object)(itemVolume)(ref groundPackSpawnSlot.VolumeType)).ToString());
				continue;
			}
			Quaternion val = ResolveItemSpawnRotation(item, groundPackSpawnSlot.Rotation);
			if (SemiFunc.IsMultiplayer())
			{
				PhotonNetwork.InstantiateRoomObject(item.prefab.ResourcePath, groundPackSpawnSlot.Position, val, (byte)0, (object[])null);
			}
			else
			{
				Object.Instantiate<GameObject>(item.prefab.Prefab, groundPackSpawnSlot.Position, val);
			}
			num++;
			AddVolumeCount(dictionary, groundPackSpawnSlot.VolumeType);
			if ((int)groundPackSpawnSlot.VolumeType == 6)
			{
				AddStringCount(dictionary3, GetItemLogName(item));
			}
		}
		LogGroundPack($"Manual ground pack spawned {num}/{pendingGroundPackSpawnSlots.Count} item(s), typeCounts={FormatVolumeCounts(dictionary)}.");
		if (dictionary3.Count > 0)
		{
			LogGroundPack("Manual ground pack upgrade distribution: " + FormatStringCounts(dictionary3) + ".");
		}
		if (num2 > 0)
		{
			LogGroundPack($"Manual ground pack skipped {num2} slot(s), reasons={FormatStringCounts(dictionary2)}.");
		}
		pendingGroundPackSpawnSlots.Clear();
	}

	private static Dictionary<itemVolume, List<Item>> BuildGroundPackItemCandidates()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<itemVolume, List<Item>> dictionary = new Dictionary<itemVolume, List<Item>>();
		foreach (Item value2 in StatsManager.instance.itemDictionary.Values)
		{
			if (IsGroundPackItemCandidate(value2))
			{
				if (!dictionary.TryGetValue(value2.itemVolume, out var value))
				{
					value = new List<Item>();
					dictionary[value2.itemVolume] = value;
				}
				value.Add(value2);
			}
		}
		foreach (List<Item> value3 in dictionary.Values)
		{
			ShuffleList(value3);
		}
		return dictionary;
	}

	private static bool IsGroundPackItemCandidate(Item item)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Invalid comparison between Unknown and I4
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Invalid comparison between Unknown and I4
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Invalid comparison between Unknown and I4
		if ((Object)(object)item == (Object)null || item.disabled || item.prefab == null || string.IsNullOrEmpty(item.prefab.ResourcePath))
		{
			return false;
		}
		if ((int)item.itemSecretShopType != 0)
		{
			return false;
		}
		if ((int)item.itemType == 2 || (int)item.itemType == 12 || (int)item.itemType == 14)
		{
			return false;
		}
		if (SemiFunc.StatGetItemsPurchased(((Object)item).name) >= item.maxAmountInShop)
		{
			return false;
		}
		if (item.maxPurchase && StatsManager.instance.GetItemsUpgradesPurchasedTotal(((Object)item).name) >= item.maxPurchaseAmount)
		{
			return false;
		}
		if (item.minPlayerCount > 1 && (Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList.Count < item.minPlayerCount)
		{
			return false;
		}
		return true;
	}

	private static float GetShopItemValueMultiplier()
	{
		if ((Object)(object)ShopManager.instance == (Object)null || ShopManagerItemValueMultiplierField == null)
		{
			return 4f;
		}
		object value = ShopManagerItemValueMultiplierField.GetValue(ShopManager.instance);
		if (value is float)
		{
			return (float)value;
		}
		return 4f;
	}

	private static bool TryGetNextGroundPackItem(Dictionary<itemVolume, List<Item>> candidatesByVolume, Dictionary<itemVolume, int> candidateIndexes, itemVolume volumeType, out Item item)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		item = null;
		if (!candidatesByVolume.TryGetValue(volumeType, out var value) || value.Count == 0)
		{
			return false;
		}
		candidateIndexes.TryGetValue(volumeType, out var value2);
		if (value2 >= value.Count)
		{
			ShuffleList(value);
			value2 = 0;
		}
		item = value[value2];
		candidateIndexes[volumeType] = value2 + 1;
		return (Object)(object)item != (Object)null;
	}

	private static Quaternion ResolveItemSpawnRotation(Item item, Quaternion slotRotation)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)item == (Object)null || (Object)(object)ShopManager.instance == (Object)null || (Object)(object)ShopManager.instance.itemRotateHelper == (Object)null)
		{
			return slotRotation;
		}
		Transform transform = ((Component)ShopManager.instance.itemRotateHelper).transform;
		Transform parent = transform.parent;
		Quaternion rotation = transform.rotation;
		transform.rotation = slotRotation;
		transform.localRotation *= item.spawnRotationOffset;
		Quaternion rotation2 = transform.rotation;
		transform.parent = parent;
		transform.rotation = rotation;
		return rotation2;
	}

	private static void ShuffleList<T>(List<T> list)
	{
		if (list != null && list.Count > 1)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int index = Random.Range(0, num + 1);
				T value = list[num];
				list[num] = list[index];
				list[index] = value;
			}
		}
	}

	private static List<ItemVolume> GetNormalShopItemVolumes(List<ItemVolume> sceneVolumes, List<ItemVolume> buffer)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		List<ItemVolume> list = buffer ?? new List<ItemVolume>();
		list.Clear();
		for (int i = 0; i < sceneVolumes.Count; i++)
		{
			ItemVolume val = sceneVolumes[i];
			if ((Object)(object)val != (Object)null && (int)val.itemSecretShopType == 0)
			{
				list.Add(val);
			}
		}
		return list;
	}

	private static itemVolume[] BuildConfiguredGroundPackTemplate()
	{
		ShopPlusPlugin instance = Instance;
		List<itemVolume> list = new List<itemVolume>(180);
		AddTemplateEntries(list, (itemVolume)6, ClampGroundItemVolumeCount(instance?.groundUpgradeItemCount, 20));
		AddTemplateEntries(list, (itemVolume)0, ClampGroundItemVolumeCount(instance?.groundSmallItemCount, 10));
		AddTemplateEntries(list, (itemVolume)1, ClampGroundItemVolumeCount(instance?.groundMediumItemCount, 10));
		AddTemplateEntries(list, (itemVolume)4, ClampGroundItemVolumeCount(instance?.groundPowerCrystalCount, 3));
		AddTemplateEntries(list, (itemVolume)5, ClampGroundItemVolumeCount(instance?.groundLargeHighItemCount, 2));
		AddTemplateEntries(list, (itemVolume)7, ClampGroundItemVolumeCount(instance?.groundHealthPackCount, 5));
		AddTemplateEntries(list, (itemVolume)2, ClampGroundItemVolumeCount(instance?.groundLargeItemCount, 0));
		AddTemplateEntries(list, (itemVolume)3, ClampGroundItemVolumeCount(instance?.groundLargeWideItemCount, 0));
		AddTemplateEntries(list, (itemVolume)8, ClampGroundItemVolumeCount(instance?.groundLargePlusItemCount, 0));
		return list.ToArray();
	}

	private static void AddTemplateEntries(List<itemVolume> template, itemVolume volumeType, int count)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < count; i++)
		{
			template.Add(volumeType);
		}
	}

	private static itemVolume[] CopyGroundPackTemplate(itemVolume[] template)
	{
		itemVolume[] array = (itemVolume[])(object)new itemVolume[template.Length];
		Array.Copy(template, array, template.Length);
		return array;
	}

	private static List<ItemVolume> GetSceneShopItemVolumes(List<ItemVolume> buffer)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		List<ItemVolume> list = buffer ?? new List<ItemVolume>();
		list.Clear();
		ItemVolume[] array = Object.FindObjectsOfType<ItemVolume>();
		foreach (ItemVolume val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				Scene scene = ((Component)val).gameObject.scene;
				if (((Scene)(ref scene)).IsValid() && ((Component)val).gameObject.activeInHierarchy && !IsShopPlusGeneratedVolume(val))
				{
					list.Add(val);
				}
			}
		}
		return list;
	}

	private static bool IsShopPlusGeneratedVolume(ItemVolume itemVolume)
	{
		Transform val = (((Object)(object)itemVolume != (Object)null) ? ((Component)itemVolume).transform : null);
		while ((Object)(object)val != (Object)null)
		{
			if (((Object)val).name.StartsWith("ShopPlus_GroundPack", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			val = val.parent;
		}
		return false;
	}

	private static bool TryGetShopSearchBounds(List<ItemVolume> volumes, out Bounds bounds)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		bounds = new Bounds(Vector3.zero, Vector3.zero);
		bool flag = false;
		for (int i = 0; i < volumes.Count; i++)
		{
			ItemVolume val = volumes[i];
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 position = ((Component)val).transform.position;
				if (!flag)
				{
					bounds = new Bounds(position, Vector3.zero);
					flag = true;
				}
				else
				{
					((Bounds)(ref bounds)).Encapsulate(position);
				}
			}
		}
		if (!flag)
		{
			return false;
		}
		((Bounds)(ref bounds)).Expand(new Vector3(1.1f, 1.5f, 1.1f));
		return true;
	}

	private static Transform FindShopExtractionTransform()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>();
		bool flag = default(bool);
		foreach (ExtractionPoint val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			Scene scene = ((Component)val).gameObject.scene;
			if (((Scene)(ref scene)).IsValid() && ((Component)val).gameObject.activeInHierarchy)
			{
				if (ExtractionPointIsShopField == null)
				{
					return ((Component)val).transform;
				}
				object value = ExtractionPointIsShopField.GetValue(val);
				int num;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != 0)
				{
					return ((Component)val).transform;
				}
			}
		}
		return null;
	}

	private static Vector3 FindGroundPackSpawnReferencePosition(Bounds shopBounds, Vector3 fallbackPosition)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.zero;
		int num = 0;
		if ((Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList != null)
		{
			List<PlayerAvatar> playerList = GameDirector.instance.PlayerList;
			for (int i = 0; i < playerList.Count; i++)
			{
				PlayerAvatar val2 = playerList[i];
				if (!((Object)(object)val2 == (Object)null) && ((Component)val2).gameObject.activeInHierarchy)
				{
					Vector3 position = ((Component)val2).transform.position;
					if (IsGroundPackReferenceInsideShopArea(position, shopBounds))
					{
						val += position;
						num++;
					}
				}
			}
		}
		if (num > 0)
		{
			Vector3 result = val / (float)num;
			result.y = fallbackPosition.y;
			return result;
		}
		if ((Object)(object)PlayerAvatar.instance != (Object)null)
		{
			Vector3 position2 = ((Component)PlayerAvatar.instance).transform.position;
			if (IsGroundPackReferenceInsideShopArea(position2, shopBounds))
			{
				position2.y = fallbackPosition.y;
				return position2;
			}
		}
		return fallbackPosition;
	}

	private static bool IsGroundPackReferenceInsideShopArea(Vector3 position, Bounds shopBounds)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		Bounds val = shopBounds;
		((Bounds)(ref val)).Expand(new Vector3(8f, 6f, 8f));
		return ((Bounds)(ref val)).Contains(position);
	}

	private static float GetApproximateFloorHeight(Bounds shopBounds, Vector3 extractionPosition)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		if (TryGetHighestFloorHit(new Vector3(extractionPosition.x, ((Bounds)(ref shopBounds)).max.y + 8f, extractionPosition.z), out var floorHit))
		{
			return ((RaycastHit)(ref floorHit)).point.y;
		}
		int num = 0;
		num += TryStoreFloorHeightSample(new Vector3(((Bounds)(ref shopBounds)).center.x, ((Bounds)(ref shopBounds)).max.y + 8f, ((Bounds)(ref shopBounds)).center.z), num);
		num += TryStoreFloorHeightSample(new Vector3(((Bounds)(ref shopBounds)).min.x, ((Bounds)(ref shopBounds)).max.y + 8f, ((Bounds)(ref shopBounds)).min.z), num);
		num += TryStoreFloorHeightSample(new Vector3(((Bounds)(ref shopBounds)).max.x, ((Bounds)(ref shopBounds)).max.y + 8f, ((Bounds)(ref shopBounds)).min.z), num);
		num += TryStoreFloorHeightSample(new Vector3(((Bounds)(ref shopBounds)).min.x, ((Bounds)(ref shopBounds)).max.y + 8f, ((Bounds)(ref shopBounds)).max.z), num);
		num += TryStoreFloorHeightSample(new Vector3(((Bounds)(ref shopBounds)).max.x, ((Bounds)(ref shopBounds)).max.y + 8f, ((Bounds)(ref shopBounds)).max.z), num);
		if (num == 0)
		{
			return ((Bounds)(ref shopBounds)).min.y;
		}
		Array.Sort(groundPackHeightSampleBuffer, 0, num);
		return groundPackHeightSampleBuffer[num / 2];
	}

	private static int TryStoreFloorHeightSample(Vector3 sampleOrigin, int writeIndex)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if (!TryGetHighestFloorHit(sampleOrigin, out var floorHit))
		{
			return 0;
		}
		groundPackHeightSampleBuffer[writeIndex] = ((RaycastHit)(ref floorHit)).point.y;
		return 1;
	}

	private static float ResolveGridSpacing(float boundsSize, int slotCount)
	{
		if (slotCount <= 1)
		{
			return 0.62f;
		}
		return Mathf.Clamp(Mathf.Max(0.2f, boundsSize - 1.2f) / (float)(slotCount - 1), 0.38f, 0.62f);
	}

	private static Vector3 FindGroundPackCenter(Bounds shopBounds, float floorHeight, Vector3 extractionPosition, Vector3 spawnReferencePosition, int columns, int rows, float spacingX, float spacingZ)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: 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_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: 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_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: 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)
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(((Bounds)(ref shopBounds)).center.x, floorHeight, ((Bounds)(ref shopBounds)).center.z);
		Vector3 val2 = Vector3.ProjectOnPlane(val - spawnReferencePosition, Vector3.up);
		if (((Vector3)(ref val2)).sqrMagnitude < 0.1f)
		{
			val2 = Vector3.ProjectOnPlane(val - extractionPosition, Vector3.up);
		}
		if (((Vector3)(ref val2)).sqrMagnitude < 0.1f)
		{
			val2 = Vector3.back;
		}
		((Vector3)(ref val2)).Normalize();
		Vector3 val3 = default(Vector3);
		((Vector3)(ref val3))..ctor(0f - val2.z, 0f, val2.x);
		float num = Mathf.Min(((Bounds)(ref shopBounds)).extents.x, ((Bounds)(ref shopBounds)).extents.z) * 0.38f;
		float num2 = (float)(columns - 1) * spacingX;
		float num3 = (float)(rows - 1) * spacingZ;
		Vector3 best = val;
		float bestScore = float.MinValue;
		TrySelectGroundPackCenterCandidate(val + val2 * num, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		Vector3 val4 = val;
		Vector3 val5 = val2 + val3;
		TrySelectGroundPackCenterCandidate(val4 + ((Vector3)(ref val5)).normalized * num, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		Vector3 val6 = val;
		val5 = val2 - val3;
		TrySelectGroundPackCenterCandidate(val6 + ((Vector3)(ref val5)).normalized * num, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		TrySelectGroundPackCenterCandidate(val + val3 * num, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		TrySelectGroundPackCenterCandidate(val - val3 * num, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		TrySelectGroundPackCenterCandidate(val, floorHeight, val, extractionPosition, spawnReferencePosition, shopBounds, num2, num3, ref best, ref bestScore);
		if (bestScore == float.MinValue)
		{
			LogGroundPack($"Ground pack grid does not fully fit inside bounds at current spacing; using shop center fallback. gridSize=({num2:F2}, {num3:F2}), bounds={FormatBounds(shopBounds)}.");
		}
		return best;
	}

	private static void TrySelectGroundPackCenterCandidate(Vector3 candidate, float floorHeight, Vector3 center, Vector3 extractionPosition, Vector3 spawnReferencePosition, Bounds shopBounds, float gridWidth, float gridDepth, ref Vector3 best, ref float bestScore)
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		candidate.y = floorHeight;
		if (GridFitsBounds(candidate, shopBounds, gridWidth, gridDepth))
		{
			float num = Vector2.Distance(new Vector2(candidate.x, candidate.z), new Vector2(extractionPosition.x, extractionPosition.z));
			float num2 = Vector2.Distance(new Vector2(candidate.x, candidate.z), new Vector2(spawnReferencePosition.x, spawnReferencePosition.z));
			float num3 = Vector2.Distance(new Vector2(candidate.x, candidate.z), new Vector2(center.x, center.z)) * 0.15f;
			float num4 = num2 * 2.2f + num * 0.45f - num3;
			if (!(num4 <= bestScore))
			{
				bestScore = num4;
				best = candidate;
			}
		}
	}

	private static bool GridFitsBounds(Vector3 center, Bounds bounds, float gridWidth, float gridDepth)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		if (center.x - gridWidth * 0.5f >= ((Bounds)(ref bounds)).min.x + 0.38f && center.x + gridWidth * 0.5f <= ((Bounds)(ref bounds)).max.x - 0.38f && center.z - gridDepth * 0.5f >= ((Bounds)(ref bounds)).min.z + 0.38f)
		{
			return center.z + gridDepth * 0.5f <= ((Bounds)(ref bounds)).max.z - 0.38f;
		}
		return false;
	}

	private static Vector3[] FindGroundPackCenters(Bounds shopBounds, float floorHeight, Vector3 extractionPosition, Vector3 spawnReferencePosition, int columns, int rows, float spacingX, float spacingZ, int packCount, Vector3 fallbackCenter)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: 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_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: 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_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: 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_0192: 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_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: 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_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0314: Unknown result type (might be due to invalid IL or missing references)
		//IL_0338: Unknown result type (might be due to invalid IL or missing references)
		Vector3[] array = (Vector3[])(object)new Vector3[Mathf.Max(1, packCount)];
		List<Vector3> list = new List<Vector3>(13);
		Vector3 center = ((Bounds)(ref shopBounds)).center;
		center.y = floorHeight;
		Vector3 val = Vector3.ProjectOnPlane(center - spawnReferencePosition, Vector3.up);
		if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
		{
			val = Vector3.ProjectOnPlane(center - extractionPosition, Vector3.up);
		}
		if (((Vector3)(ref val)).sqrMagnitude < 0.01f)
		{
			val = Vector3.forward;
		}
		((Vector3)(ref val)).Normalize();
		Vector3 val2 = Vector3.Cross(Vector3.up, val);
		Vector3 normalized = ((Vector3)(ref val2)).normalized;
		float num = Mathf.Min(((Bounds)(ref shopBounds)).size.x, ((Bounds)(ref shopBounds)).size.z) * 0.26f;
		AddGroundPackCenterCandidate(list, fallbackCenter, shopBounds, columns, rows, spacingX, spacingZ);
		AddGroundPackCenterCandidate(list, center + val * num, shopBounds, columns, rows, spacingX, spacingZ);
		AddGroundPackCenterCandidate(list, center - val * num, shopBounds, columns, rows, spacingX, spacingZ);
		AddGroundPackCenterCandidate(list, center + normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		AddGroundPackCenterCandidate(list, center - normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		Vector3 val3 = center;
		val2 = val + normalized;
		AddGroundPackCenterCandidate(list, val3 + ((Vector3)(ref val2)).normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		Vector3 val4 = center;
		val2 = val - normalized;
		AddGroundPackCenterCandidate(list, val4 + ((Vector3)(ref val2)).normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		Vector3 val5 = center;
		val2 = -val + normalized;
		AddGroundPackCenterCandidate(list, val5 + ((Vector3)(ref val2)).normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		Vector3 val6 = center;
		val2 = -val - normalized;
		AddGroundPackCenterCandidate(list, val6 + ((Vector3)(ref val2)).normalized * num, shopBounds, columns, rows, spacingX, spacingZ);
		if (list.Count == 0)
		{
			list.Add(fallbackCenter);
		}
		List<Vector3> list2 = new List<Vector3>(array.Length);
		for (int i = 0; i < array.Length; i++)
		{
			int index = 0;
			float num2 = float.MinValue;
			for (int j = 0; j < list.Count; j++)
			{
				Vector3 val7 = list[j];
				float num3 = Vector2.Distance(new Vector2(val7.x, val7.z), new Vector2(extractionPosition.x, extractionPosition.z));
				float num4 = Vector2.Distance(new Vector2(val7.x, val7.z), new Vector2(spawnReferencePosition.x, spawnReferencePosition.z));
				float minGroundPackCenterDistance = GetMinGroundPackCenterDistance(val7, list2);
				float num5 = Vector2.Distance(new Vector2(val7.x, val7.z), new Vector2(center.x, center.z)) * 0.05f;
				float num6 = num4 * 2.2f + num3 * 0.45f + minGroundPackCenterDistance * 1.6f - num5;
				if (num6 > num2)
				{
					num2 = num6;
					index = j;
				}
			}
			array[i] = list[index];
			list2.Add(list[index]);
			list.RemoveAt(index);
			if (list.Count == 0 && i + 1 < array.Length)
			{
				list.Add(fallbackCenter);
			}
		}
		return array;
	}

	private static void AddGroundPackCenterCandidate(List<Vector3> candidates, Vector3 candidate, Bounds shopBounds, int columns, int rows, float spacingX, float spacingZ)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		candidate.y = ((Bounds)(ref shopBounds)).center.y;
		float gridWidth = (float)(columns - 1) * spacingX;
		float gridDepth = (float)(rows - 1) * spacingZ;
		if (!GridFitsBounds(candidate, shopBounds, gridWidth, gridDepth))
		{
			return;
		}
		for (int i = 0; i < candidates.Count; i++)
		{
			if (Vector2.Distance(new Vector2(candidate.x, candidate.z), new Vector2(candidates[i].x, candidates[i].z)) < 0.35f)
			{
				return;
			}
		}
		candidates.Add(candidate);
	}

	private static float GetMinGroundPackCenterDistance(Vector3 candidate, List<Vector3> selected)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		if (selected == null || selected.Count == 0)
		{
			return 0f;
		}
		float num = float.MaxValue;
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(candidate.x, candidate.z);
		for (int i = 0; i < selected.Count; i++)
		{
			float num2 = Vector2.Distance(val, new Vector2(selected[i].x, selected[i].z));
			if (num2 < num)
			{
				num = num2;
			}
		}
		return num;
	}

	private static Vector3 GetGroundPackCenterForSet(GroundPackLayout layout, int setIndex)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		if (layout.PackCenters == null || layout.PackCenters.Length == 0)
		{
			return layout.GridCenter;
		}
		return layout.PackCenters[Mathf.Clamp(setIndex, 0, layout.PackCenters.Length - 1)];
	}

	private static Vector3 GridToWorldPosition(Vector3 center, int column, int row, int columns, int rows, float spacingX, float spacingZ)
	{
		//IL_0023: 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_0030: Unknown result type (might be due to invalid IL or missing references)
		float num = ((float)column - (float)(columns - 1) * 0.5f) * spacingX;
		float num2 = ((float)row - (float)(rows - 1) * 0.5f) * spacingZ;
		return center + new Vector3(num, 0f, num2);
	}

	private static void AddExistingShopVolumePositions(List<ItemVolume> sourceVolumes, List<Vector3> occupiedPositions)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (sourceVolumes == null || occupiedPositions == null)
		{
			return;
		}
		int num = 0;
		for (int i = 0; i < sourceVolumes.Count; i++)
		{
			ItemVolume val = sourceVolumes[i];
			if (!((Object)(object)val == (Object)null))
			{
				occupiedPositions.Add(((Component)val).transform.position);
				num++;
			}
		}
		if (num > 0)
		{
			LogGroundPack($"Ground pack reserved {num} original shop volume position(s) before placing ShopPlus ground items.");
		}
	}

	private static bool TryResolveGroundSpawnPosition(Vector3 targetPosition, GroundPackLayout layout, List<Vector3> occupiedPositions, out Vector3 spawnPosition, out string skipReason, out bool usedFallback)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		spawnPosition = Vector3.zero;
		skipReason = null;
		usedFallback = false;
		if (TryResolveGroundSpawnPositionAt(targetPosition, layout, occupiedPositions, out spawnPosition, out skipReason))
		{
			return true;
		}
		string text = skipReason;
		Vector3 groundPackFallbackDirection = GetGroundPackFallbackDirection(targetPosition, layout);
		float num = Mathf.Max(0.4f, Mathf.Min(layout.SpacingX, layout.SpacingZ));
		float num2 = Vector2.Distance(new Vector2(targetPosition.x, targetPosition.z), new Vector2(layout.ExtractionPosition.x, layout.ExtractionPosition.z));
		for (int i =