Decompiled source of Kittys Muck v0.1.87

plugins/Kittys_Muck/Kittys_Muck.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CodexMuckMod;
using HarmonyLib;
using MoreMod;
using MuckExpansionPack.Networking;
using ObamiumToolsMod;
using Steamworks;
using Steamworks.Data;
using TMPro;
using TheOtherMuck;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Kittys_Muck")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+158e51008c0983be2ab7552c2e60c7d9e1ac0649")]
[assembly: AssemblyProduct("Kittys_Muck")]
[assembly: AssemblyTitle("Kittys_Muck")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TheOtherMuck
{
	public static class MuckRuntimeDataExtractor
	{
		[HarmonyPatch(typeof(MenuUI), "Start")]
		private static class MenuStartPatch
		{
			private static void Postfix(MenuUI __instance)
			{
				if (IsEnabled())
				{
					((MonoBehaviour)__instance).StartCoroutine(StartLobbyAfterMenuReady(__instance));
				}
			}
		}

		[HarmonyPatch(typeof(SteamLobby), "StartLobby")]
		private static class SteamLobbyStartPatch
		{
			private static void Postfix(SteamLobby __instance)
			{
				if (IsEnabled())
				{
					((MonoBehaviour)__instance).StartCoroutine(StartGameAfterLobbyReady());
				}
			}
		}

		[HarmonyPatch(typeof(Hotbar), "Start")]
		private static class HotbarStartPatch
		{
			private static void Postfix(Hotbar __instance)
			{
				if (IsEnabled())
				{
					((MonoBehaviour)__instance).StartCoroutine(ExtractAfterWorldReady());
				}
			}
		}

		public const string CommandLineFlag = "--codex-muck-data-extract";

		public static readonly string JsonPath = "C:\\Users\\kolti\\OneDrive\\Documents\\Muck\\dist\\muck-runtime-data.json";

		public static readonly string SummaryPath = "C:\\Users\\kolti\\OneDrive\\Documents\\Muck\\dist\\muck-runtime-data-summary.md";

		private static bool lobbyStarted;

		private static bool gameStarted;

		private static bool extractionStarted;

		public static bool IsEnabled()
		{
			return Environment.GetCommandLineArgs().Any((string arg) => string.Equals(arg, "--codex-muck-data-extract", StringComparison.OrdinalIgnoreCase));
		}

		private static IEnumerator StartLobbyAfterMenuReady(MenuUI menu)
		{
			yield return (object)new WaitForSeconds(1.5f);
			if (IsEnabled() && !lobbyStarted)
			{
				lobbyStarted = true;
				Debug.Log((object)"[MuckDataExtractor] Starting lobby.");
				menu.StartLobby();
			}
		}

		private static IEnumerator StartGameAfterLobbyReady()
		{
			yield return (object)new WaitForSeconds(2.5f);
			if (IsEnabled() && !gameStarted && !((Object)(object)SteamLobby.Instance == (Object)null))
			{
				gameStarted = true;
				Debug.Log((object)"[MuckDataExtractor] Starting game.");
				SteamLobby.Instance.StartGame();
			}
		}

		private static IEnumerator ExtractAfterWorldReady()
		{
			if (extractionStarted)
			{
				yield break;
			}
			extractionStarted = true;
			for (int attempt = 0; attempt < 180; attempt++)
			{
				if (CanExtract())
				{
					yield return (object)new WaitForSeconds(4f);
					Debug.Log((object)"[MuckDataExtractor] Extracting runtime data.");
					Extract();
					yield return (object)new WaitForSeconds(1f);
					Application.Quit();
					yield break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			Debug.LogWarning((object)"[MuckDataExtractor] Timed out waiting for runtime managers.");
			Application.Quit();
		}

		private static bool CanExtract()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Invalid comparison between Unknown and I4
			if ((Object)(object)ItemManager.Instance != (Object)null && (Object)(object)GameLoop.Instance != (Object)null && (Object)(object)MobSpawner.Instance != (Object)null && (Object)(object)GameManager.instance != (Object)null)
			{
				return (int)GameManager.state == 1;
			}
			return false;
		}

		private static void Extract()
		{
			Directory.CreateDirectory(Path.GetDirectoryName(JsonPath));
			File.WriteAllText(JsonPath, BuildJson());
			File.WriteAllText(SummaryPath, BuildSummary());
			Debug.Log((object)("[MuckDataExtractor] Wrote " + JsonPath));
			Debug.Log((object)("[MuckDataExtractor] Wrote " + SummaryPath));
		}

		private static string BuildJson()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("{");
			Prop(stringBuilder, 1, "generatedAt", DateTime.UtcNow.ToString("o"));
			Prop(stringBuilder, 1, "gameSettings", GameSettingsJson(), raw: true);
			Prop(stringBuilder, 1, "items", ItemsJson(), raw: true);
			Prop(stringBuilder, 1, "powerups", PowerupsJson(), raw: true);
			Prop(stringBuilder, 1, "dropTables", DropTablesJson(), raw: true);
			Prop(stringBuilder, 1, "lootContainers", LootContainersJson(), raw: true);
			Prop(stringBuilder, 1, "nightSpawnTable", NightSpawnTableJson(), raw: true);
			Prop(stringBuilder, 1, "allMobs", AllMobsJson(), raw: true);
			Prop(stringBuilder, 1, "resourceGenerators", GeneratorObjectsJson(Object.FindObjectsOfType<ResourceGenerator>()), raw: true);
			Object[] spawners = (Object[])(object)Object.FindObjectsOfType<StructureSpawner>();
			Prop(stringBuilder, 1, "structureSpawners", SpawnerObjectsJson("StructureSpawner", spawners), raw: true);
			spawners = (Object[])(object)Object.FindObjectsOfType<CaveSpawner>();
			Prop(stringBuilder, 1, "caveSpawners", SpawnerObjectsJson("CaveSpawner", spawners), raw: true);
			spawners = (Object[])(object)Object.FindObjectsOfType<CampSpawner>();
			Prop(stringBuilder, 1, "campSpawners", SpawnerObjectsJson("CampSpawner", spawners), raw: true);
			spawners = (Object[])(object)Object.FindObjectsOfType<GuardianSpawner>();
			Prop(stringBuilder, 1, "guardianSpawners", SpawnerObjectsJson("GuardianSpawner", spawners), raw: true);
			spawners = (Object[])(object)Object.FindObjectsOfType<BillySpawner>();
			Prop(stringBuilder, 1, "billySpawners", SpawnerObjectsJson("BillySpawner", spawners), raw: true);
			Prop(stringBuilder, 1, "spawnChestsInLocations", ChestSpawnersJson(Object.FindObjectsOfType<SpawnChestsInLocations>()), raw: true);
			Prop(stringBuilder, 1, "spawnPowerupsInLocations", PowerupChestSpawnersJson(Object.FindObjectsOfType<SpawnPowerupsInLocations>()), raw: true, comma: false);
			stringBuilder.AppendLine("}");
			return stringBuilder.ToString();
		}

		private static string BuildSummary()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("# Muck Runtime Data Summary");
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("Generated: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
			stringBuilder.AppendLine();
			AppendGameSettings(stringBuilder);
			AppendNightSpawnTable(stringBuilder);
			AppendMobStats(stringBuilder);
			AppendPowerups(stringBuilder);
			AppendLootContainers(stringBuilder);
			AppendWeaponsAndTools(stringBuilder);
			AppendDropTables(stringBuilder);
			AppendGenerators(stringBuilder);
			AppendStructureSpawners(stringBuilder);
			return stringBuilder.ToString();
		}

		private static string GameSettingsJson()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00fd: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{");
			AppendJsonPair(stringBuilder, "easyBossDay", new GameSettings(0, 0, 0, 0, 3, 1).BossDay(), comma: true);
			AppendJsonPair(stringBuilder, "normalBossDay", new GameSettings(0, 0, 0, 1, 3, 1).BossDay(), comma: true);
			AppendJsonPair(stringBuilder, "gamerBossDay", new GameSettings(0, 0, 0, 2, 3, 1).BossDay(), comma: true);
			AppendJsonPair(stringBuilder, "easyDayLength", new GameSettings(0, 0, 0, 0, 3, 1).DayLength(), comma: true);
			AppendJsonPair(stringBuilder, "normalDayLength", new GameSettings(0, 0, 0, 1, 3, 1).DayLength(), comma: true);
			AppendJsonPair(stringBuilder, "gamerDayLength", new GameSettings(0, 0, 0, 2, 3, 1).DayLength(), comma: true);
			AppendJsonPair(stringBuilder, "easyChestPriceDivisor", new GameSettings(0, 0, 0, 0, 3, 1).GetChestPriceMultiplier(), comma: true);
			AppendJsonPair(stringBuilder, "normalChestPriceDivisor", new GameSettings(0, 0, 0, 1, 3, 1).GetChestPriceMultiplier(), comma: true);
			AppendJsonPair(stringBuilder, "gamerChestPriceDivisor", new GameSettings(0, 0, 0, 2, 3, 1).GetChestPriceMultiplier(), comma: false);
			stringBuilder.Append("}");
			return stringBuilder.ToString();
		}

		private static string ItemsJson()
		{
			InventoryItem[] array = (InventoryItem[])(((object)ItemManager.Instance.allScriptableItems) ?? ((object)new InventoryItem[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < array.Length; i++)
			{
				InventoryItem val = array[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "id", ((Object)(object)val == (Object)null) ? i : val.id, comma: true);
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "type", ((Object)(object)val == (Object)null) ? "" : ((object)Unsafe.As<ItemType, ItemType>(ref val.type)/*cast due to .constrained prefix*/).ToString(), comma: true);
				AppendJsonPair(stringBuilder, "tag", ((Object)(object)val == (Object)null) ? "" : ((object)Unsafe.As<ItemTag, ItemTag>(ref val.tag)/*cast due to .constrained prefix*/).ToString(), comma: true);
				AppendJsonPair(stringBuilder, "rarity", ((Object)(object)val == (Object)null) ? "" : ((object)Unsafe.As<ItemRarity, ItemRarity>(ref val.rarity)/*cast due to .constrained prefix*/).ToString(), comma: true);
				AppendJsonPair(stringBuilder, "tier", (!((Object)(object)val == (Object)null)) ? val.tier : 0, comma: true);
				AppendJsonPair(stringBuilder, "maxStack", (!((Object)(object)val == (Object)null)) ? val.max : 0, comma: true);
				AppendJsonPair(stringBuilder, "attackDamage", (!((Object)(object)val == (Object)null)) ? val.attackDamage : 0, comma: true);
				AppendJsonPair(stringBuilder, "resourceDamage", (!((Object)(object)val == (Object)null)) ? val.resourceDamage : 0, comma: true);
				AppendJsonPair(stringBuilder, "attackSpeed", ((Object)(object)val == (Object)null) ? 0f : val.attackSpeed, comma: true);
				AppendJsonPair(stringBuilder, "attackRange", ((Object)(object)val == (Object)null) ? 0f : val.attackRange, comma: true);
				AppendJsonPair(stringBuilder, "sharpness", ((Object)(object)val == (Object)null) ? 0f : val.sharpness, comma: true);
				AppendJsonPair(stringBuilder, "armor", (!((Object)(object)val == (Object)null)) ? val.armor : 0, comma: true);
				AppendJsonPair(stringBuilder, "heal", ((Object)(object)val == (Object)null) ? 0f : val.heal, comma: true);
				AppendJsonPair(stringBuilder, "hunger", ((Object)(object)val == (Object)null) ? 0f : val.hunger, comma: true);
				AppendJsonPair(stringBuilder, "stamina", ((Object)(object)val == (Object)null) ? 0f : val.stamina, comma: true);
				AppendJsonPair(stringBuilder, "craftable", (Object)(object)val != (Object)null && val.craftable, comma: true);
				AppendJsonPair(stringBuilder, "craftAmount", (!((Object)(object)val == (Object)null)) ? val.craftAmount : 0, comma: true);
				AppendJsonPair(stringBuilder, "stationRequirement", SafeName(((Object)(object)val == (Object)null) ? null : val.stationRequirement), comma: true);
				AppendJsonPair(stringBuilder, "requirements", RequirementsJson(val), comma: true, raw: true);
				AppendJsonPair(stringBuilder, "attackTypes", WeaknessesJson(((Object)(object)val == (Object)null) ? null : val.attackTypes), comma: false, raw: true);
				stringBuilder.Append("}");
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string PowerupsJson()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{");
			AppendJsonPair(stringBuilder, "white", PowerupArrayJson(ItemManager.Instance.powerupsWhite), comma: true, raw: true);
			AppendJsonPair(stringBuilder, "blue", PowerupArrayJson(ItemManager.Instance.powerupsBlue), comma: true, raw: true);
			AppendJsonPair(stringBuilder, "orange", PowerupArrayJson(ItemManager.Instance.powerupsOrange), comma: false, raw: true);
			stringBuilder.Append("}");
			return stringBuilder.ToString();
		}

		private static string PowerupArrayJson(Powerup[] powerups)
		{
			powerups = (Powerup[])(((object)powerups) ?? ((object)new Powerup[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			for (int i = 0; i < powerups.Length; i++)
			{
				Powerup val = powerups[i];
				stringBuilder.Append("{");
				AppendJsonPair(stringBuilder, "id", ((Object)(object)val == (Object)null) ? (-1) : val.id, comma: true);
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "tier", ((Object)(object)val == (Object)null) ? "" : ((object)Unsafe.As<PowerTier, PowerTier>(ref val.tier)/*cast due to .constrained prefix*/).ToString(), comma: true);
				AppendJsonPair(stringBuilder, "description", ((Object)(object)val == (Object)null) ? "" : val.description, comma: false);
				stringBuilder.Append("}");
				if (i < powerups.Length - 1)
				{
					stringBuilder.Append(",");
				}
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string DropTablesJson()
		{
			LootDrop[] loadedDropTables = GetLoadedDropTables();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < loadedDropTables.Length; i++)
			{
				LootDrop val = loadedDropTables[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "id", ((Object)(object)val == (Object)null) ? i : val.id, comma: true);
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "dropOne", (Object)(object)val != (Object)null && val.dropOne, comma: true);
				AppendJsonPair(stringBuilder, "loot", LootItemsJson(val), comma: false, raw: true);
				stringBuilder.Append("}");
				if (i < loadedDropTables.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string LootContainersJson()
		{
			LootContainerInteract[] loadedLootContainers = GetLoadedLootContainers();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < loadedLootContainers.Length; i++)
			{
				LootContainerInteract val = loadedLootContainers[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "basePrice", (!((Object)(object)val == (Object)null)) ? val.price : 0, comma: true);
				AppendJsonPair(stringBuilder, "whiteWeight", ((Object)(object)val == (Object)null) ? 0f : val.white, comma: true);
				AppendJsonPair(stringBuilder, "blueWeight", ((Object)(object)val == (Object)null) ? 0f : val.blue, comma: true);
				AppendJsonPair(stringBuilder, "orangeWeight", ((Object)(object)val == (Object)null) ? 0f : val.gold, comma: true);
				AppendJsonPair(stringBuilder, "whiteChance", WeightChance(((Object)(object)val == (Object)null) ? 0f : val.white, val), comma: true);
				AppendJsonPair(stringBuilder, "blueChance", WeightChance(((Object)(object)val == (Object)null) ? 0f : val.blue, val), comma: true);
				AppendJsonPair(stringBuilder, "orangeChance", WeightChance(((Object)(object)val == (Object)null) ? 0f : val.gold, val), comma: false);
				stringBuilder.Append("}");
				if (i < loadedLootContainers.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string LootItemsJson(LootDrop table)
		{
			LootItems[] array = (LootItems[])(((Object)(object)table == (Object)null || table.loot == null) ? ((Array)new LootItems[0]) : ((Array)table.loot));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			for (int i = 0; i < array.Length; i++)
			{
				LootItems val = array[i];
				stringBuilder.Append("{");
				AppendJsonPair(stringBuilder, "item", SafeName(val.item), comma: true);
				AppendJsonPair(stringBuilder, "amountMin", val.amountMin, comma: true);
				AppendJsonPair(stringBuilder, "amountMax", val.amountMax, comma: true);
				AppendJsonPair(stringBuilder, "dropChance", val.dropChance, comma: false);
				stringBuilder.Append("}");
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string NightSpawnTableJson()
		{
			MobSpawn[] array = (MobSpawn[])(((object)GameLoop.Instance.mobs) ?? ((object)new MobSpawn[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < array.Length; i++)
			{
				MobSpawn val = array[i];
				MobType val2 = val?.mob;
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "mob", SafeName(val2), comma: true);
				AppendJsonPair(stringBuilder, "dayStart", val?.dayStart ?? 0, comma: true);
				AppendJsonPair(stringBuilder, "dayPeak", val?.dayPeak ?? 0, comma: true);
				AppendJsonPair(stringBuilder, "maxWeight", val?.maxWeight ?? 0f, comma: true);
				AppendJsonPair(stringBuilder, "currentWeight", val?.currentWeight ?? 0f, comma: true);
				AppendJsonPair(stringBuilder, "mobStats", MobTypeJson(val2), comma: false, raw: true);
				stringBuilder.Append("}");
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string AllMobsJson()
		{
			MobType[] array = (MobType[])(((object)MobSpawner.Instance.allMobs) ?? ((object)new MobType[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < array.Length; i++)
			{
				Indent(stringBuilder, 2).Append(MobTypeJson(array[i]));
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string MobTypeJson(MobType mob)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("{");
			AppendJsonPair(stringBuilder, "id", ((Object)(object)mob == (Object)null) ? (-1) : mob.id, comma: true);
			AppendJsonPair(stringBuilder, "name", SafeName(mob), comma: true);
			AppendJsonPair(stringBuilder, "behaviour", ((Object)(object)mob == (Object)null) ? "" : ((object)Unsafe.As<MobBehaviour, MobBehaviour>(ref mob.behaviour)/*cast due to .constrained prefix*/).ToString(), comma: true);
			AppendJsonPair(stringBuilder, "boss", (Object)(object)mob != (Object)null && mob.boss, comma: true);
			AppendJsonPair(stringBuilder, "ranged", (Object)(object)mob != (Object)null && mob.ranged, comma: true);
			AppendJsonPair(stringBuilder, "speed", ((Object)(object)mob == (Object)null) ? 0f : mob.speed, comma: true);
			AppendJsonPair(stringBuilder, "spawnTime", ((Object)(object)mob == (Object)null) ? 0f : mob.spawnTime, comma: true);
			AppendJsonPair(stringBuilder, "rangedCooldown", ((Object)(object)mob == (Object)null) ? 0f : mob.rangedCooldown, comma: true);
			AppendJsonPair(stringBuilder, "startAttackDistance", ((Object)(object)mob == (Object)null) ? 0f : mob.startAttackDistance, comma: true);
			AppendJsonPair(stringBuilder, "startRangedAttackDistance", ((Object)(object)mob == (Object)null) ? 0f : mob.startRangedAttackDistance, comma: true);
			AppendJsonPair(stringBuilder, "maxAttackDistance", ((Object)(object)mob == (Object)null) ? 0f : mob.maxAttackDistance, comma: true);
			AppendJsonPair(stringBuilder, "defense", ((Object)(object)mob == (Object)null) ? 0f : mob.defense, comma: true);
			AppendJsonPair(stringBuilder, "sharpDefense", ((Object)(object)mob == (Object)null) ? 0f : mob.sharpDefense, comma: true);
			AppendJsonPair(stringBuilder, "knockbackThreshold", ((Object)(object)mob == (Object)null) ? 0f : mob.knockbackThreshold, comma: true);
			AppendJsonPair(stringBuilder, "weaknesses", WeaknessesJson(((Object)(object)mob == (Object)null) ? null : mob.weaknesses), comma: false, raw: true);
			stringBuilder.Append("}");
			return stringBuilder.ToString();
		}

		private static string GeneratorObjectsJson(ResourceGenerator[] generators)
		{
			generators = (ResourceGenerator[])(((object)generators) ?? ((object)new ResourceGenerator[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < generators.Length; i++)
			{
				ResourceGenerator val = generators[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "resourcePrefabs", WeightedArrayJson(GetField(val, "resourcePrefabs")), comma: true, raw: true);
				AppendJsonPair(stringBuilder, "spawnThreshold", GetFieldFloat(val, "spawnThreshold"), comma: true);
				AppendJsonPair(stringBuilder, "minSpawnHeight", GetFieldFloat(val, "minSpawnHeight"), comma: true);
				AppendJsonPair(stringBuilder, "maxSpawnHeight", GetFieldFloat(val, "maxSpawnHeight"), comma: true);
				AppendJsonPair(stringBuilder, "minSpawnAmount", GetFieldInt(val, "minSpawnAmount"), comma: true);
				AppendJsonPair(stringBuilder, "randPos", GetFieldInt(val, "randPos"), comma: true);
				AppendJsonPair(stringBuilder, "forceSeedOffset", GetFieldInt(val, "forceSeedOffset"), comma: true);
				AppendJsonPair(stringBuilder, "worldScale", ((Object)(object)val == (Object)null) ? 0f : val.worldScale, comma: false);
				stringBuilder.Append("}");
				if (i < generators.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string SpawnerObjectsJson(string typeName, Object[] spawners)
		{
			spawners = (Object[])(((object)spawners) ?? ((object)new Object[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < spawners.Length; i++)
			{
				Object val = spawners[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "type", typeName, comma: true);
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "structurePrefabs", WeightedArrayJson(GetField(val, "structurePrefabs")), comma: true, raw: true);
				AppendJsonPair(stringBuilder, "nShrines", GetFieldInt(val, "nShrines"), comma: true);
				AppendJsonPair(stringBuilder, "minCaves", GetFieldInt(val, "minCaves"), comma: true);
				AppendJsonPair(stringBuilder, "maxCaves", GetFieldInt(val, "maxCaves"), comma: true);
				AppendJsonPair(stringBuilder, "worldScale", GetPropertyFloat(val, "worldScale"), comma: false);
				stringBuilder.Append("}");
				if (i < spawners.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string ChestSpawnersJson(SpawnChestsInLocations[] spawners)
		{
			spawners = (SpawnChestsInLocations[])(((object)spawners) ?? ((object)new SpawnChestsInLocations[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < spawners.Length; i++)
			{
				SpawnChestsInLocations val = spawners[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "positionCount", (!((Object)(object)val == (Object)null) && val.positions != null) ? val.positions.Length : 0, comma: true);
				AppendJsonPair(stringBuilder, "lootTables", ChestLootTablesJson(val), comma: false, raw: true);
				stringBuilder.Append("}");
				if (i < spawners.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string ChestLootTablesJson(SpawnChestsInLocations spawner)
		{
			return WeightedArrayJson(GetField(spawner, "lootTables"), "table");
		}

		private static string PowerupChestSpawnersJson(SpawnPowerupsInLocations[] spawners)
		{
			spawners = (SpawnPowerupsInLocations[])(((object)spawners) ?? ((object)new SpawnPowerupsInLocations[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("[");
			for (int i = 0; i < spawners.Length; i++)
			{
				SpawnPowerupsInLocations val = spawners[i];
				Indent(stringBuilder, 2).Append("{");
				AppendJsonPair(stringBuilder, "name", SafeName(val), comma: true);
				AppendJsonPair(stringBuilder, "positionCount", (!((Object)(object)val == (Object)null) && val.positions != null) ? val.positions.Length : 0, comma: true);
				AppendJsonPair(stringBuilder, "powerupChests", WeightedArrayJson(GetField(val, "powerupChests")), comma: false, raw: true);
				stringBuilder.Append("}");
				if (i < spawners.Length - 1)
				{
					stringBuilder.Append(",");
				}
				stringBuilder.AppendLine();
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string WeightedArrayJson(object arrayObject, string objectFieldName = "prefab")
		{
			if (!(arrayObject is Array array))
			{
				return "[]";
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			for (int i = 0; i < array.Length; i++)
			{
				object? value = array.GetValue(i);
				object field = GetField(value, objectFieldName);
				float fieldFloat = GetFieldFloat(value, "weight");
				stringBuilder.Append("{");
				AppendJsonPair(stringBuilder, "name", SafeName(field), comma: true);
				AppendJsonPair(stringBuilder, "weight", fieldFloat, comma: false);
				stringBuilder.Append("}");
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string RequirementsJson(InventoryItem item)
		{
			CraftRequirement[] array = (CraftRequirement[])(((Object)(object)item == (Object)null || item.requirements == null) ? ((Array)new CraftRequirement[0]) : ((Array)item.requirements));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			for (int i = 0; i < array.Length; i++)
			{
				stringBuilder.Append("{");
				AppendJsonPair(stringBuilder, "item", SafeName(array[i].item), comma: true);
				AppendJsonPair(stringBuilder, "amount", array[i].amount, comma: false);
				stringBuilder.Append("}");
				if (i < array.Length - 1)
				{
					stringBuilder.Append(",");
				}
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static string WeaknessesJson(Weakness[] weaknesses)
		{
			weaknesses = (Weakness[])(((object)weaknesses) ?? ((object)new Weakness[0]));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("[");
			for (int i = 0; i < weaknesses.Length; i++)
			{
				stringBuilder.Append(Json(((object)Unsafe.As<Weakness, Weakness>(ref weaknesses[i])/*cast due to .constrained prefix*/).ToString()));
				if (i < weaknesses.Length - 1)
				{
					stringBuilder.Append(",");
				}
			}
			stringBuilder.Append("]");
			return stringBuilder.ToString();
		}

		private static void AppendGameSettings(StringBuilder sb)
		{
			sb.AppendLine("## Difficulty Settings");
			sb.AppendLine();
			sb.AppendLine("| Difficulty | Day length | Boss day interval | Chest price divisor |");
			sb.AppendLine("| --- | ---: | ---: | ---: |");
			AppendDifficultyRow(sb, "Easy", 0);
			AppendDifficultyRow(sb, "Normal", 1);
			AppendDifficultyRow(sb, "Gamer", 2);
			sb.AppendLine();
		}

		private static void AppendDifficultyRow(StringBuilder sb, string name, int difficulty)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameSettings val = new GameSettings(0, 0, 0, difficulty, 3, 1);
			sb.AppendLine("| " + name + " | " + val.DayLength() + " | " + val.BossDay() + " | " + F(val.GetChestPriceMultiplier()) + " |");
		}

		private static void AppendNightSpawnTable(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Night Spawn Table");
			sb.AppendLine();
			sb.AppendLine("| Mob | Day start | Day peak | Max weight | Current weight at extraction |");
			sb.AppendLine("| --- | ---: | ---: | ---: | ---: |");
			MobSpawn[] array = (MobSpawn[])(((object)GameLoop.Instance.mobs) ?? ((object)new MobSpawn[0]));
			foreach (MobSpawn val in array)
			{
				sb.AppendLine("| " + SafeCell(SafeName(val.mob)) + " | " + val.dayStart + " | " + val.dayPeak + " | " + F(val.maxWeight) + " | " + F(val.currentWeight) + " |");
			}
			sb.AppendLine();
		}

		private unsafe static void AppendMobStats(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Mob Stats");
			sb.AppendLine();
			sb.AppendLine("| ID | Mob | Behaviour | Boss | Ranged | Speed | Defense | Sharp defense | Weaknesses |");
			sb.AppendLine("| ---: | --- | --- | --- | --- | ---: | ---: | ---: | --- |");
			MobType[] array = (MobType[])(((object)MobSpawner.Instance.allMobs) ?? ((object)new MobType[0]));
			foreach (MobType val in array)
			{
				sb.AppendLine("| " + val.id + " | " + SafeCell(SafeName(val)) + " | " + ((object)Unsafe.As<MobBehaviour, MobBehaviour>(ref val.behaviour)/*cast due to .constrained prefix*/).ToString() + " | " + val.boss + " | " + val.ranged + " | " + F(val.speed) + " | " + F(val.defense) + " | " + F(val.sharpDefense) + " | " + SafeCell(string.Join(", ", ((IEnumerable<Weakness>)(((object)val.weaknesses) ?? ((object)new Weakness[0]))).Select((Weakness w) => ((object)(*(Weakness*)(&w))/*cast due to .constrained prefix*/).ToString()).ToArray())) + " |");
			}
			sb.AppendLine();
		}

		private static void AppendPowerups(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Powerup Lists");
			sb.AppendLine();
			AppendPowerupTier(sb, "White", ItemManager.Instance.powerupsWhite);
			AppendPowerupTier(sb, "Blue", ItemManager.Instance.powerupsBlue);
			AppendPowerupTier(sb, "Orange", ItemManager.Instance.powerupsOrange);
		}

		private static void AppendLootContainers(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Loot Container Odds");
			sb.AppendLine();
			sb.AppendLine("| Object | Base price | White weight | Blue weight | Orange weight | White chance | Blue chance | Orange chance |");
			sb.AppendLine("| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |");
			LootContainerInteract[] loadedLootContainers = GetLoadedLootContainers();
			foreach (LootContainerInteract val in loadedLootContainers)
			{
				sb.AppendLine("| " + SafeCell(SafeName(val)) + " | " + val.price + " | " + F(val.white) + " | " + F(val.blue) + " | " + F(val.gold) + " | " + Pct(WeightChance(val.white, val)) + " | " + Pct(WeightChance(val.blue, val)) + " | " + Pct(WeightChance(val.gold, val)) + " |");
			}
			sb.AppendLine();
		}

		private static void AppendPowerupTier(StringBuilder sb, string tier, Powerup[] powerups)
		{
			sb.AppendLine("### " + tier + " Powerups");
			sb.AppendLine();
			sb.AppendLine("| ID | Name | Description |");
			sb.AppendLine("| ---: | --- | --- |");
			Powerup[] array = (Powerup[])(((object)powerups) ?? ((object)new Powerup[0]));
			foreach (Powerup val in array)
			{
				sb.AppendLine("| " + val.id + " | " + SafeCell(SafeName(val)) + " | " + SafeCell(val.description) + " |");
			}
			sb.AppendLine();
		}

		private static void AppendWeaponsAndTools(StringBuilder sb)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			sb.AppendLine("## Runtime Item Combat And Crafting Data");
			sb.AppendLine();
			sb.AppendLine("| ID | Item | Type | Tier | Attack | Resource | Speed | Range | Armor | Crafting requirements | Station |");
			sb.AppendLine("| ---: | --- | --- | ---: | ---: | ---: | ---: | ---: | ---: | --- | --- |");
			InventoryItem[] array = (InventoryItem[])(((object)ItemManager.Instance.allScriptableItems) ?? ((object)new InventoryItem[0]));
			foreach (InventoryItem val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((int)val.type == 3 || (int)val.type == 1 || (int)val.type == 2 || (int)val.type == 9 || (int)val.tag == 9 || val.IsArmour() || val.attackDamage > 1 || val.resourceDamage > 1 || val.armor > 0))
				{
					sb.AppendLine("| " + val.id + " | " + SafeCell(val.name) + " | " + ((object)Unsafe.As<ItemType, ItemType>(ref val.type)/*cast due to .constrained prefix*/).ToString() + " | " + val.tier + " | " + val.attackDamage + " | " + val.resourceDamage + " | " + F(val.attackSpeed) + " | " + F(val.attackRange) + " | " + val.armor + " | " + SafeCell(RequirementText(val)) + " | " + SafeCell(SafeName(val.stationRequirement)) + " |");
				}
			}
			sb.AppendLine();
		}

		private static void AppendDropTables(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Drop Tables");
			sb.AppendLine();
			LootDrop[] loadedDropTables = GetLoadedDropTables();
			foreach (LootDrop val in loadedDropTables)
			{
				if (!((Object)(object)val == (Object)null))
				{
					sb.AppendLine("### " + SafeName(val));
					sb.AppendLine();
					sb.AppendLine("| Item | Amount min | Amount max | Drop chance |");
					sb.AppendLine("| --- | ---: | ---: | ---: |");
					LootItems[] array = (LootItems[])(((object)val.loot) ?? ((object)new LootItems[0]));
					foreach (LootItems val2 in array)
					{
						sb.AppendLine("| " + SafeCell(SafeName(val2.item)) + " | " + val2.amountMin + " | " + val2.amountMax + " | " + Pct(val2.dropChance) + " |");
					}
					sb.AppendLine();
				}
			}
		}

		private static void AppendGenerators(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Resource Generators");
			sb.AppendLine();
			ResourceGenerator[] array = (ResourceGenerator[])(((object)Object.FindObjectsOfType<ResourceGenerator>()) ?? ((object)new ResourceGenerator[0]));
			foreach (ResourceGenerator val in array)
			{
				sb.AppendLine("### " + SafeName(val));
				sb.AppendLine();
				sb.AppendLine("- Spawn threshold: `" + F(GetFieldFloat(val, "spawnThreshold")) + "`");
				sb.AppendLine("- Height window: `" + F(GetFieldFloat(val, "minSpawnHeight")) + "` to `" + F(GetFieldFloat(val, "maxSpawnHeight")) + "`");
				sb.AppendLine("- Minimum spawn amount: `" + GetFieldInt(val, "minSpawnAmount") + "`");
				sb.AppendLine("- World scale: `" + F(val.worldScale) + "`");
				sb.AppendLine();
				AppendWeightedTable(sb, GetField(val, "resourcePrefabs"), "Prefab");
			}
		}

		private static void AppendStructureSpawners(StringBuilder sb)
		{
			sb.AppendLine("## Runtime Structure And Chest Spawners");
			sb.AppendLine();
			Object[] spawners = (Object[])(object)Object.FindObjectsOfType<StructureSpawner>();
			AppendSpawnerSummary(sb, "StructureSpawner", spawners);
			spawners = (Object[])(object)Object.FindObjectsOfType<CaveSpawner>();
			AppendSpawnerSummary(sb, "CaveSpawner", spawners);
			spawners = (Object[])(object)Object.FindObjectsOfType<CampSpawner>();
			AppendSpawnerSummary(sb, "CampSpawner", spawners);
			spawners = (Object[])(object)Object.FindObjectsOfType<GuardianSpawner>();
			AppendSpawnerSummary(sb, "GuardianSpawner", spawners);
			spawners = (Object[])(object)Object.FindObjectsOfType<BillySpawner>();
			AppendSpawnerSummary(sb, "BillySpawner", spawners);
			sb.AppendLine("### SpawnChestsInLocations");
			sb.AppendLine();
			SpawnChestsInLocations[] array = (SpawnChestsInLocations[])(((object)Object.FindObjectsOfType<SpawnChestsInLocations>()) ?? ((object)new SpawnChestsInLocations[0]));
			foreach (SpawnChestsInLocations val in array)
			{
				sb.AppendLine("- `" + SafeName(val) + "` positions: `" + ((val.positions != null) ? val.positions.Length : 0) + "`");
				AppendWeightedTable(sb, GetField(val, "lootTables"), "Loot table", "table");
			}
		}

		private static void AppendSpawnerSummary(StringBuilder sb, string typeName, Object[] spawners)
		{
			sb.AppendLine("### " + typeName);
			sb.AppendLine();
			Object[] array = (Object[])(((object)spawners) ?? ((object)new Object[0]));
			foreach (Object val in array)
			{
				sb.AppendLine("- `" + SafeName(val) + "` nShrines=`" + GetFieldInt(val, "nShrines") + "`, min=`" + GetFieldInt(val, "minCaves") + "`, max=`" + GetFieldInt(val, "maxCaves") + "`, worldScale=`" + F(GetPropertyFloat(val, "worldScale")) + "`");
				AppendWeightedTable(sb, GetField(val, "structurePrefabs"), "Prefab");
			}
		}

		private static void AppendWeightedTable(StringBuilder sb, object arrayObject, string nameColumn, string objectFieldName = "prefab")
		{
			if (arrayObject is Array { Length: not 0 } array)
			{
				sb.AppendLine();
				sb.AppendLine("| " + nameColumn + " | Weight |");
				sb.AppendLine("| --- | ---: |");
				for (int i = 0; i < array.Length; i++)
				{
					object value = array.GetValue(i);
					object field = GetField(value, objectFieldName);
					sb.AppendLine("| " + SafeCell(SafeName(field)) + " | " + F(GetFieldFloat(value, "weight")) + " |");
				}
				sb.AppendLine();
			}
			else
			{
				sb.AppendLine();
			}
		}

		private static string RequirementText(InventoryItem item)
		{
			if ((Object)(object)item == (Object)null || item.requirements == null || item.requirements.Length == 0)
			{
				return "";
			}
			return string.Join(", ", (from req in item.requirements
				where req != null && (Object)(object)req.item != (Object)null
				select req.amount + " " + req.item.name).ToArray());
		}

		private static LootDrop[] GetLoadedDropTables()
		{
			List<LootDrop> list = new List<LootDrop>();
			AddUnique<LootDrop>(list, ((Object)(object)ItemManager.Instance == (Object)null) ? null : ItemManager.Instance.allScriptableDropTables);
			AddUnique<LootDrop>(list, Resources.FindObjectsOfTypeAll<LootDrop>());
			return (from table in list
				where (Object)(object)table != (Object)null
				orderby table.id, ((Object)table).name
				select table).ToArray();
		}

		private static LootContainerInteract[] GetLoadedLootContainers()
		{
			List<LootContainerInteract> list = new List<LootContainerInteract>();
			AddUnique<LootContainerInteract>(list, Object.FindObjectsOfType<LootContainerInteract>());
			AddUnique<LootContainerInteract>(list, Resources.FindObjectsOfTypeAll<LootContainerInteract>());
			return (from container in list
				where (Object)(object)container != (Object)null
				orderby container.price, ((Object)container).name
				select container).ToArray();
		}

		private static void AddUnique<T>(List<T> target, T[] values) where T : Object
		{
			if (values == null)
			{
				return;
			}
			HashSet<int> hashSet = new HashSet<int>(from item in target
				where (Object)(object)item != (Object)null
				select ((Object)item).GetInstanceID());
			foreach (T val in values)
			{
				if (!((Object)(object)val == (Object)null) && !hashSet.Contains(((Object)val).GetInstanceID()))
				{
					target.Add(val);
					hashSet.Add(((Object)val).GetInstanceID());
				}
			}
		}

		private static float WeightChance(float weight, LootContainerInteract container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return 0f;
			}
			float num = container.white + container.blue + container.gold;
			if (num <= 0f)
			{
				return 0f;
			}
			return weight / num;
		}

		private static object GetField(object target, string name)
		{
			if (target == null)
			{
				return null;
			}
			FieldInfo field = target.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field == null))
			{
				return field.GetValue(target);
			}
			return null;
		}

		private static int GetFieldInt(object target, string name)
		{
			object field = GetField(target, name);
			if (!(field is int))
			{
				return 0;
			}
			return (int)field;
		}

		private static float GetFieldFloat(object target, string name)
		{
			object field = GetField(target, name);
			if (field is float)
			{
				return (float)field;
			}
			if (field is int)
			{
				return (int)field;
			}
			return 0f;
		}

		private static float GetPropertyFloat(object target, string name)
		{
			if (target == null)
			{
				return 0f;
			}
			PropertyInfo property = target.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			object obj = ((property == null) ? null : property.GetValue(target, null));
			if (obj is float)
			{
				return (float)obj;
			}
			if (obj is int)
			{
				return (int)obj;
			}
			return 0f;
		}

		private static void Prop(StringBuilder sb, int indent, string key, string value, bool raw = false, bool comma = true)
		{
			Indent(sb, indent).Append(Json(key)).Append(": ");
			sb.Append(raw ? value : Json(value));
			if (comma)
			{
				sb.Append(",");
			}
			sb.AppendLine();
		}

		private static void AppendJsonPair(StringBuilder sb, string key, string value, bool comma, bool raw = false)
		{
			sb.Append(Json(key)).Append(": ").Append(raw ? value : Json(value));
			if (comma)
			{
				sb.Append(",");
			}
		}

		private static void AppendJsonPair(StringBuilder sb, string key, int value, bool comma)
		{
			sb.Append(Json(key)).Append(": ").Append(value.ToString(CultureInfo.InvariantCulture));
			if (comma)
			{
				sb.Append(",");
			}
		}

		private static void AppendJsonPair(StringBuilder sb, string key, float value, bool comma)
		{
			sb.Append(Json(key)).Append(": ").Append(value.ToString("0.#####", CultureInfo.InvariantCulture));
			if (comma)
			{
				sb.Append(",");
			}
		}

		private static void AppendJsonPair(StringBuilder sb, string key, bool value, bool comma)
		{
			sb.Append(Json(key)).Append(": ").Append(value ? "true" : "false");
			if (comma)
			{
				sb.Append(",");
			}
		}

		private static StringBuilder Indent(StringBuilder sb, int level)
		{
			return sb.Append(new string(' ', level * 2));
		}

		private static string SafeName(object value)
		{
			if (value == null)
			{
				return "";
			}
			Object val = (Object)((value is Object) ? value : null);
			if (val != (Object)null)
			{
				return val.name ?? "";
			}
			return value.ToString();
		}

		private static string SafeCell(string value)
		{
			return (value ?? "").Replace("|", "\\|").Replace("\r", " ").Replace("\n", " ");
		}

		private static string Json(string value)
		{
			if (value == null)
			{
				return "null";
			}
			return "\"" + value.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\r", "\\r")
				.Replace("\n", "\\n")
				.Replace("\t", "\\t") + "\"";
		}

		private static string F(float value)
		{
			return value.ToString("0.###", CultureInfo.InvariantCulture);
		}

		private static string Pct(float value)
		{
			return (value * 100f).ToString("0.##", CultureInfo.InvariantCulture) + "%";
		}
	}
	public static class MuckshroomPolicy
	{
		public const string ItemName = "Muckshroom";

		public const string Description = "glowy";

		public const float Health = 50f;

		public const float Stamina = 50f;

		public const float Hunger = 50f;

		public const string ModelResource = "TheOtherMuck.Assets.Muckshroom.glb";

		public const string IconResource = "TheOtherMuck.Assets.MuckshroomIcon.png";

		public static bool CanRequestPickup(bool playerExists, bool alive, float distance)
		{
			if (playerExists && alive && !float.IsNaN(distance) && distance >= 0f)
			{
				return distance <= 6f;
			}
			return false;
		}

		public static IEnumerable<Vector2> PatchOffsets(int seed, float terrainSize)
		{
			Random random = new Random(seed + 19841);
			int patches = Math.Max(1, (int)(80f * terrainSize * terrainSize / 1411344f));
			float radius = terrainSize * 0.4f;
			for (int i = 0; i < patches; i++)
			{
				double num = random.NextDouble() * Math.PI * 2.0;
				double num2 = Math.Sqrt(random.NextDouble()) * (double)radius;
				Vector2 center = new Vector2((float)(Math.Cos(num) * num2), (float)(Math.Sin(num) * num2));
				int count = random.Next(3, 6);
				for (int j = 0; j < count; j++)
				{
					yield return center + new Vector2((float)(random.NextDouble() - 0.5) * 5f, (float)(random.NextDouble() - 0.5) * 5f);
				}
			}
		}
	}
	internal static class MuckshroomRuntime
	{
		public static void Register()
		{
			//IL_00ba: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Expected O, but got Unknown
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			ItemManager instance = ItemManager.Instance;
			if (instance.allItems.Values.Any((InventoryItem candidate) => (Object)(object)candidate != (Object)null && candidate.name == "Muckshroom"))
			{
				return;
			}
			InventoryItem val = ((IEnumerable<InventoryItem>)instance.allItems.Values).FirstOrDefault((Func<InventoryItem, bool>)((InventoryItem candidate) => (Object)(object)candidate != (Object)null && (int)candidate.tag == 2));
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"[TheOtherMuck] Muckshroom food template missing.");
				return;
			}
			InventoryItem val2 = ScriptableObject.CreateInstance<InventoryItem>();
			val2.Copy(val, 1);
			val2.name = "Muckshroom";
			val2.description = "glowy";
			val2.id = instance.allItems.Keys.Max() + 1;
			val2.type = (ItemType)8;
			val2.tag = (ItemTag)2;
			val2.heal = 50f;
			val2.stamina = 50f;
			val2.hunger = 50f;
			val2.amount = 1;
			val2.max = 69;
			val2.stackable = true;
			val2.craftable = false;
			val2.requirements = (CraftRequirement[])(object)new CraftRequirement[0];
			val2.stationRequirement = null;
			val2.processable = false;
			val2.processedItem = null;
			val2.processTime = 0f;
			val2.fuel = null;
			val2.buildable = false;
			val2.rarity = (ItemRarity)0;
			val2.important = false;
			val2.attackDamage = 0;
			val2.resourceDamage = 0;
			val2.scale = 1f;
			val2.positionOffset = Vector3.zero;
			val2.rotationOffset = Vector3.zero;
			if (!OtherMuckDrainToiletGlbLoader.TryInstantiateResource(null, "TheOtherMuck.Assets.Muckshroom.glb", "Muckshroom", out var rootObject))
			{
				Object.Destroy((Object)(object)val2);
				Debug.LogError((object)"[TheOtherMuck] Muckshroom model could not be loaded; registration aborted.");
				return;
			}
			MeshFilter componentInChildren = rootObject.GetComponentInChildren<MeshFilter>();
			MeshRenderer componentInChildren2 = rootObject.GetComponentInChildren<MeshRenderer>();
			val2.mesh = componentInChildren.sharedMesh;
			val2.material = ((Renderer)componentInChildren2).sharedMaterial;
			Shader val3 = Shader.Find("Unlit/Texture");
			if ((Object)(object)val3 != (Object)null)
			{
				val2.material = new Material(val3)
				{
					name = "Muckshroom self-lit atlas",
					mainTexture = ((Renderer)componentInChildren2).sharedMaterial.mainTexture
				};
			}
			else
			{
				Debug.LogWarning((object)"[TheOtherMuck] Unlit/Texture unavailable; Muckshroom retains its imported emissive material.");
			}
			Object.Destroy((Object)(object)rootObject);
			using (Stream stream = typeof(MuckshroomRuntime).Assembly.GetManifestResourceStream("TheOtherMuck.Assets.MuckshroomIcon.png"))
			{
				if (stream == null)
				{
					throw new FileNotFoundException("TheOtherMuck.Assets.MuckshroomIcon.png");
				}
				byte[] array = new byte[stream.Length];
				using (BinaryReader binaryReader = new BinaryReader(stream))
				{
					array = binaryReader.ReadBytes(array.Length);
				}
				Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val4, array))
				{
					throw new InvalidDataException("Invalid Muckshroom icon.");
				}
				((Object)val4).name = "Muckshroom icon";
				val2.sprite = Sprite.Create(val4, new Rect(0f, 0f, (float)((Texture)val4).width, (float)((Texture)val4).height), new Vector2(0.5f, 0.5f), (float)((Texture)val4).width);
			}
			val2.prefab = val.prefab;
			instance.allItems.Add(val2.id, val2);
			instance.allScriptableItems = instance.allScriptableItems.Concat((IEnumerable<InventoryItem>)(object)new InventoryItem[1] { val2 }).ToArray();
			Debug.Log((object)("[TheOtherMuck] Registered Muckshroom, restores 50 health/stamina/hunger (id " + val2.id + ")."));
		}

		public static GameObject CreatePickup(Transform parent, Vector3 position)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0039: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			InventoryItem itemByName = ItemManager.Instance.GetItemByName("Muckshroom");
			if ((Object)(object)itemByName == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("Muckshroom");
			val.transform.SetParent(parent, false);
			val.transform.position = position;
			val.AddComponent<MeshFilter>().sharedMesh = itemByName.mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = itemByName.material;
			int num = LayerMask.NameToLayer("Interact");
			if (num >= 0)
			{
				val.layer = num;
			}
			BoxCollider obj = val.AddComponent<BoxCollider>();
			Bounds bounds = itemByName.mesh.bounds;
			obj.center = ((Bounds)(ref bounds)).center;
			bounds = itemByName.mesh.bounds;
			obj.size = ((Bounds)(ref bounds)).size;
			((Collider)obj).isTrigger = true;
			PickupInteract obj2 = val.AddComponent<PickupInteract>();
			obj2.item = itemByName;
			obj2.amount = 1;
			val.AddComponent<MuckshroomGlow>();
			return val;
		}
	}
	internal sealed class MuckshroomGlow : MonoBehaviour
	{
		private Light glow;

		private ParticleSystem sparkle;

		private static Material sparkleMaterial;

		private void Start()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0023: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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_0132: 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_0157: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			GameObject val = new GameObject("Muckshroom blue glow");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = Vector3.up * 0.45f;
			glow = val.AddComponent<Light>();
			glow.type = (LightType)2;
			glow.color = new Color(0.25f, 0.7f, 1f);
			glow.intensity = 0.5f;
			glow.range = 3f;
			glow.shadows = (LightShadows)0;
			((Behaviour)glow).enabled = false;
			glow.renderMode = (LightRenderMode)1;
			GameObject val2 = new GameObject("Muckshroom sparkles");
			val2.transform.SetParent(((Component)this).transform, false);
			val2.transform.localPosition = Vector3.up * 0.4f;
			sparkle = val2.AddComponent<ParticleSystem>();
			MainModule main = sparkle.main;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1.8f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.12f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.025f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.7f, 0.9f, 1f, 0.8f));
			((MainModule)(ref main)).maxParticles = 12;
			EmissionModule emission = sparkle.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(3f);
			ShapeModule shape = sparkle.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.35f;
			if ((Object)(object)sparkleMaterial == (Object)null)
			{
				sparkleMaterial = new Material(Shader.Find("Sprites/Default"));
			}
			((Renderer)((Component)sparkle).GetComponent<ParticleSystemRenderer>()).sharedMaterial = sparkleMaterial;
			sparkle.Stop(true, (ParticleSystemStopBehavior)0);
			((MonoBehaviour)this).InvokeRepeating("RefreshDistance", Random.Range(0f, 0.5f), 0.5f);
		}

		private void RefreshDistance()
		{
			//IL_001c: 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)
			PlayerMovement instance = PlayerMovement.Instance;
			float num;
			if (!((Object)(object)instance != (Object)null))
			{
				num = float.MaxValue;
			}
			else
			{
				Vector3 val = ((Component)instance).transform.position - ((Component)this).transform.position;
				num = ((Vector3)(ref val)).sqrMagnitude;
			}
			float num2 = num;
			((Behaviour)glow).enabled = num2 < 225f;
			if (num2 < 1600f)
			{
				if (!sparkle.isPlaying)
				{
					sparkle.Play();
				}
			}
			else if (sparkle.isPlaying)
			{
				sparkle.Stop(true, (ParticleSystemStopBehavior)0);
			}
		}
	}
	internal static class OtherBobCombatRuntime
	{
		private sealed class CombatState
		{
			public float NextDestinationTime;

			public float NextAttackTime;

			public float NextStatusLogTime;

			public DragonState LastState = (DragonState)(-1);

			public int LastTargetId = -1;
		}

		private static readonly Dictionary<int, CombatState> States = new Dictionary<int, CombatState>();

		public static void Reset()
		{
			States.Clear();
			OtherMuckMommyDamageRuntime.Reset();
		}

		public static bool TryTick(MobServerDragon server, Mob mob)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)server == (Object)null || (Object)(object)mob == (Object)null || !TheOtherMuckRuntime.IsOtherBob(mob))
			{
				return false;
			}
			BobMob val = (BobMob)(object)((mob is BobMob) ? mob : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			OtherMuckMommyDamageRuntime.Tick();
			if (!States.TryGetValue(mob.GetId(), out var value))
			{
				value = new CombatState();
				States[mob.GetId()] = value;
			}
			EnsureFlying(val, "combat tick");
			LogStateChange(mob, val, value);
			if (Time.time >= value.NextDestinationTime)
			{
				Vector3 val2 = ChooseFlightDestination();
				((Mob)val).SetDestination(val2);
				ServerSend.MobSetDestination(mob.GetId(), val2);
				value.NextDestinationTime = Time.time + Random.Range(2.2f, 3.8f);
				TheOtherMuckRuntime.LogOtherBobDebug("Other Bob destination -> " + Format(val2) + ".");
			}
			if (Time.time >= value.NextAttackTime)
			{
				PlayerManager val3 = ChooseTarget();
				if ((Object)(object)val3 != (Object)null)
				{
					((Mob)val).SetTarget(val3.id);
					ServerSend.SendMobTarget(mob.GetId(), val3.id);
					value.LastTargetId = val3.id;
					if ((Object)(object)val.projectileController != (Object)null)
					{
						val.projectileController.SpawnProjectilePredictNextPosition();
						TheOtherMuckRuntime.LogOtherBobDebug("Other Bob fired at player " + val3.id + ".");
					}
				}
				value.NextAttackTime = Time.time + Random.Range(2f, 3f);
			}
			if (Time.time >= value.NextStatusLogTime)
			{
				value.NextStatusLogTime = Time.time + 8f;
				TheOtherMuckRuntime.LogOtherBobDebug("Other Bob loop alive. state=" + ((object)val.state/*cast due to .constrained prefix*/).ToString() + ", target=" + value.LastTargetId + ".");
			}
			return true;
		}

		public static bool PreventLanding(BobMob bob, string source)
		{
			if ((Object)(object)bob == (Object)null || !TheOtherMuckRuntime.IsOtherBob((Mob)(object)bob))
			{
				return false;
			}
			EnsureFlying(bob, source);
			return true;
		}

		private static void EnsureFlying(BobMob bob, string source)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)bob.state != 0)
			{
				TheOtherMuckRuntime.LogOtherBobDebug("Prevented Other Bob " + ((object)bob.state/*cast due to .constrained prefix*/).ToString() + " from " + source + ".");
				bob.GroundedToFlight();
				ServerSend.DragonUpdate(0);
			}
		}

		private static void LogStateChange(Mob mob, BobMob bob, CombatState state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0016: 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)
			if (state.LastState != bob.state)
			{
				state.LastState = bob.state;
				TheOtherMuckRuntime.LogOtherBobDebug("Other Bob state -> " + ((object)bob.state/*cast due to .constrained prefix*/).ToString() + " for mob " + mob.GetId() + ".");
			}
		}

		private static Vector3 ChooseFlightDestination()
		{
			//IL_0000: 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_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 bossArenaPosition = TheOtherMuckRuntime.BossArenaPosition;
			float num = Random.Range(0f, (float)Math.PI * 2f);
			float num2 = Random.Range(45f, 120f);
			float clearance = Random.Range(24f, 48f);
			Vector3 worldPosition = bossArenaPosition + new Vector3(Mathf.Cos(num) * num2, 0f, Mathf.Sin(num) * num2);
			return TheOtherMuckPlacementPolicy.GetSafePosition(TheOtherMuckRuntime.IslandCenter, worldPosition, clearance);
		}

		private static PlayerManager ChooseTarget()
		{
			if (GameManager.players == null || GameManager.players.Count == 0)
			{
				return null;
			}
			List<PlayerManager> list = new List<PlayerManager>();
			foreach (PlayerManager value in GameManager.players.Values)
			{
				if ((Object)(object)value != (Object)null && !value.dead && !value.disconnected)
				{
					list.Add(value);
				}
			}
			if (list.Count != 0)
			{
				return list[Random.Range(0, list.Count)];
			}
			return null;
		}

		private static string Format(Vector3 value)
		{
			return "(" + value.x.ToString("0.0") + ", " + value.y.ToString("0.0") + ", " + value.z.ToString("0.0") + ")";
		}
	}
	internal sealed class OtherBobEndingController : MonoBehaviour
	{
		private bool started;

		private long scheduledGeneration;

		public void Begin(long generation)
		{
			if (!started)
			{
				started = true;
				scheduledGeneration = generation;
				((MonoBehaviour)this).Invoke("ShowEnding", 15f);
			}
		}

		private void ShowEnding()
		{
			if (OtherMuckPresentationPolicy.IsDelayedPresentationValid(scheduledGeneration, TheOtherMuckRuntime.RunGeneration, TheOtherMuckState.Complete, TheOtherMuckRuntime.State, TheOtherMuckRuntime.IsGameplayActive))
			{
				TheOtherMuckRuntime.ShowOtherBobEnding();
			}
			Object.Destroy((Object)(object)((Component)this).gameObject, 10f);
		}
	}
	internal sealed class OtherBobSummonInteract : MonoBehaviour, Interactable, SharedObject
	{
		private int id;

		private bool started;

		public static Action NetworkSummonRequest { get; set; }

		public void Interact()
		{
			if (!TheOtherMuckRuntime.AreAncientPillarsComplete() || !OtherMuckTowerGateRuntime.CanSummon)
			{
				if ((Object)(object)StatusMessage.Instance != (Object)null)
				{
					StatusMessage.Instance.DisplayMessage(TheOtherMuckRuntime.AreAncientPillarsComplete() ? "The gate is locked." : TheOtherMuckRuntime.GetAncientPillarProgressPrompt());
				}
			}
			else if (!started && NetworkSummonRequest != null)
			{
				NetworkSummonRequest();
			}
		}

		public void LocalExecute()
		{
		}

		public void AllExecute()
		{
			started = true;
			TheOtherMuckRuntime.MarkOtherBobSummoned();
			if ((Object)(object)StatusMessage.Instance != (Object)null)
			{
				StatusMessage.Instance.DisplayMessage("Bob's Mommy has awakened.");
			}
		}

		public void ServerExecute(int fromClient = -1)
		{
		}

		public void RemoveObject()
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		public string GetName()
		{
			if (!started && TheOtherMuckRuntime.State == TheOtherMuckState.OnOtherMuck)
			{
				if (!OtherMuckTowerGateRuntime.CanSummon)
				{
					return "The gate is locked.";
				}
				return "Summon Bob's Mommy";
			}
			return string.Empty;
		}

		public bool IsStarted()
		{
			return started;
		}

		public void SetId(int id)
		{
			this.id = id;
		}

		public int GetId()
		{
			return id;
		}

		public static void ApplySummonedFromNetwork()
		{
			TheOtherMuckRuntime.MarkOtherBobSummoned();
		}
	}
	public static class OtherMuckAmbientAudioController
	{
		private static OtherMuckDailyAudioScheduler scheduler = new OtherMuckDailyAudioScheduler();

		private static int[] mainTrackSequence;

		private static int nextMainTrack;

		private static bool vanillaMusicStopped;

		private static bool traderEnrageActive;

		private static OtherMuckTowerAmbushPolicy ambushCues = new OtherMuckTowerAmbushPolicy();

		public static Action<int> NetworkCueBroadcast { get; set; }

		public static void Reset()
		{
			scheduler = new OtherMuckDailyAudioScheduler();
			mainTrackSequence = null;
			nextMainTrack = 0;
			vanillaMusicStopped = false;
			traderEnrageActive = false;
			ambushCues = new OtherMuckTowerAmbushPolicy();
		}

		public static void TickHost()
		{
			bool flag = OtherMuckAmbientAudioPolicy.ShouldSuppressVanillaMusic(TheOtherMuckRuntime.State);
			if (flag && !vanillaMusicStopped)
			{
				OtherMuckAudio.StopVanillaMusic(0.35f);
				vanillaMusicStopped = true;
			}
			else if (!flag)
			{
				vanillaMusicStopped = false;
			}
			if (!LocalClient.serverOwner || TheOtherMuckRuntime.State != TheOtherMuckState.OnOtherMuck || traderEnrageActive)
			{
				return;
			}
			int seed = GameManager.GetSeed();
			if (mainTrackSequence == null)
			{
				mainTrackSequence = OtherMuckAmbientAudioPolicy.BuildMainTrackSequence(seed, 1024);
			}
			int scheduleDay = OtherMuckAmbientAudioPolicy.GetScheduleDay(DayCycle.totalTime, DayCycle.time);
			bool flag2 = (Object)(object)BossUI.Instance != (Object)null && (Object)(object)BossUI.Instance.currentBoss != (Object)null;
			if (scheduler.TryTake(seed, scheduleDay, DayCycle.time, TheOtherMuckRuntime.State, flag2 || OtherMuckAudio.IsMusicPlaying, out var kind, out var clip))
			{
				if (kind != OtherMuckSharedAudioKind.ShortAmbient)
				{
					PlayNextMainTrack(kind);
					return;
				}
				OtherMuckAudio.PlayAmbient(clip);
				NetworkCueBroadcast?.Invoke(OtherMuckAmbientAudioPolicy.EncodeSharedCue(OtherMuckSharedAudioKind.ShortAmbient, clip));
			}
		}

		public static void PlayFromNetwork(int encodedCue)
		{
			if (!OtherMuckAmbientAudioPolicy.TryDecodeSharedCue(encodedCue, out var kind, out var trackIndex))
			{
				return;
			}
			switch (kind)
			{
			case OtherMuckSharedAudioKind.TowerAmbush:
				if (ambushCues.TryPlayCue(trackIndex))
				{
					OtherMuckAudio.PlayAncientPillar();
				}
				break;
			case OtherMuckSharedAudioKind.TraderEnrage:
				traderEnrageActive = true;
				OtherMuckAudio.PlaySmeagull();
				break;
			case OtherMuckSharedAudioKind.TraderDefeated:
				traderEnrageActive = false;
				OtherMuckAudio.FadeOutMusic(1.5f);
				break;
			case OtherMuckSharedAudioKind.ShortAmbient:
				OtherMuckAudio.PlayAmbient(trackIndex);
				break;
			default:
				OtherMuckAudio.PlayOtherMuckMainTrack(trackIndex, kind == OtherMuckSharedAudioKind.Night);
				break;
			}
		}

		public static void PlayTraderEnrage()
		{
			if (LocalClient.serverOwner && !traderEnrageActive)
			{
				traderEnrageActive = true;
				OtherMuckAudio.PlaySmeagull();
				NetworkCueBroadcast?.Invoke(OtherMuckAmbientAudioPolicy.EncodeSharedCue(OtherMuckSharedAudioKind.TraderEnrage, 0));
			}
		}

		public static void PlayTowerAmbush(int group)
		{
			if (LocalClient.serverOwner && ambushCues.TryPlayCue(group))
			{
				OtherMuckAudio.PlayAncientPillar();
				NetworkCueBroadcast?.Invoke(OtherMuckAmbientAudioPolicy.EncodeSharedCue(OtherMuckSharedAudioKind.TowerAmbush, group));
			}
		}

		public static void EndTraderEnrage()
		{
			if (LocalClient.serverOwner && traderEnrageActive)
			{
				traderEnrageActive = false;
				OtherMuckAudio.FadeOutMusic(1.5f);
				NetworkCueBroadcast?.Invoke(OtherMuckAmbientAudioPolicy.EncodeSharedCue(OtherMuckSharedAudioKind.TraderDefeated, 0));
			}
		}

		private static void PlayNextMainTrack(OtherMuckSharedAudioKind kind)
		{
			if (mainTrackSequence != null && nextMainTrack < mainTrackSequence.Length)
			{
				int trackIndex = mainTrackSequence[nextMainTrack++];
				OtherMuckAudio.PlayOtherMuckMainTrack(trackIndex, kind == OtherMuckSharedAudioKind.Night);
				NetworkCueBroadcast?.Invoke(OtherMuckAmbientAudioPolicy.EncodeSharedCue(kind, trackIndex));
			}
		}
	}
	public enum OtherMuckSharedAudioKind
	{
		ShortAmbient,
		Morning,
		Night,
		TraderEnrage,
		TraderDefeated,
		TowerAmbush
	}
	public struct OtherMuckAmbientCue
	{
		public int TargetDay;

		public int CueIndex;

		public float DayThreshold;
	}
	public static class OtherMuckAmbientAudioPolicy
	{
		public const int MainTrackCount = 4;

		public const float SixAm = 0.75f;

		public const float SevenAm = 19f / 24f;

		public const float ElevenAm = 23f / 24f;

		public const float OnePm = 1f / 24f;

		public const float ElevenPm = 11f / 24f;

		public const float OneAm = 13f / 24f;

		private const int MorningCueBase = 100;

		private const int NightCueBase = 200;

		private const int TraderEnrageCue = 300;

		private const int TraderDefeatedCue = 301;

		private const int TowerAmbushCueBase = 400;

		private static readonly int[] TargetDays = new int[3] { 1, 2, 4 };

		public static int GetScheduleDay(float totalTime, float dayTime)
		{
			return (int)Math.Floor(totalTime - dayTime + 0.001f) + 1;
		}

		public static int[] BuildMainTrackSequence(int seed, int count)
		{
			if (count <= 0)
			{
				return new int[0];
			}
			Random random = new Random(seed + 271903);
			int[] array = new int[count];
			int num = 0;
			int num2 = -1;
			while (num < count)
			{
				int[] array2 = new int[4] { 0, 1, 2, 3 };
				for (int num3 = array2.Length - 1; num3 > 0; num3--)
				{
					int num4 = random.Next(num3 + 1);
					int num5 = array2[num3];
					array2[num3] = array2[num4];
					array2[num4] = num5;
				}
				if (num2 >= 0 && array2[0] == num2)
				{
					int num6 = 1 + random.Next(array2.Length - 1);
					int num7 = array2[0];
					array2[0] = array2[num6];
					array2[num6] = num7;
				}
				for (int i = 0; i < array2.Length; i++)
				{
					if (num >= count)
					{
						break;
					}
					array[num++] = array2[i];
					num2 = array2[i];
				}
			}
			return array;
		}

		public static bool ShouldPlayMorning(int seed, int otherMuckDay)
		{
			return new Random((seed * 397) ^ (otherMuckDay * 7919) ^ 0x4D55434B).NextDouble() < 0.8;
		}

		public static float GetMorningTrackThreshold(int seed, int otherMuckDay)
		{
			return GetMainTrackThreshold(seed, otherMuckDay, 1297044046, 0.75f, 19f / 24f);
		}

		public static float GetNightTrackThreshold(int seed, int otherMuckDay)
		{
			return GetMainTrackThreshold(seed, otherMuckDay, 1313425224, 11f / 24f, 13f / 24f);
		}

		public static bool CanStartMorningTrack(float dayTime, float threshold)
		{
			if (dayTime >= 0.75f && dayTime <= 19f / 24f)
			{
				return dayTime >= threshold;
			}
			return false;
		}

		public static bool CanStartNightTrack(float dayTime, float threshold)
		{
			if (dayTime >= 11f / 24f && dayTime < 0.75f)
			{
				return dayTime >= threshold;
			}
			return false;
		}

		public static bool ShouldSuppressVanillaMusic(TheOtherMuckState state)
		{
			if ((uint)(state - 3) <= 5u)
			{
				return true;
			}
			return false;
		}

		public static int EncodeSharedCue(OtherMuckSharedAudioKind kind, int trackIndex)
		{
			switch (kind)
			{
			case OtherMuckSharedAudioKind.ShortAmbient:
				return trackIndex;
			case OtherMuckSharedAudioKind.Morning:
				return 100 + trackIndex;
			case OtherMuckSharedAudioKind.Night:
				return 200 + trackIndex;
			case OtherMuckSharedAudioKind.TraderEnrage:
				return 300;
			case OtherMuckSharedAudioKind.TraderDefeated:
				return 301;
			case OtherMuckSharedAudioKind.TowerAmbush:
				if (trackIndex < 0 || trackIndex >= 6)
				{
					throw new ArgumentOutOfRangeException("trackIndex");
				}
				return 400 + trackIndex;
			default:
				throw new ArgumentOutOfRangeException("kind");
			}
		}

		public static bool TryDecodeSharedCue(int encoded, out OtherMuckSharedAudioKind kind, out int trackIndex)
		{
			if (encoded >= 0 && encoded < 3)
			{
				kind = OtherMuckSharedAudioKind.ShortAmbient;
				trackIndex = encoded;
				return true;
			}
			if (encoded >= 100 && encoded < 104)
			{
				kind = OtherMuckSharedAudioKind.Morning;
				trackIndex = encoded - 100;
				return true;
			}
			if (encoded >= 200 && encoded < 204)
			{
				kind = OtherMuckSharedAudioKind.Night;
				trackIndex = encoded - 200;
				return true;
			}
			switch (encoded)
			{
			case 300:
				kind = OtherMuckSharedAudioKind.TraderEnrage;
				trackIndex = 0;
				return true;
			case 301:
				kind = OtherMuckSharedAudioKind.TraderDefeated;
				trackIndex = 0;
				return true;
			case 400:
			case 401:
			case 402:
			case 403:
			case 404:
			case 405:
				kind = OtherMuckSharedAudioKind.TowerAmbush;
				trackIndex = encoded - 400;
				return true;
			default:
				kind = OtherMuckSharedAudioKind.ShortAmbient;
				trackIndex = -1;
				return false;
			}
		}

		public static OtherMuckAmbientCue[] BuildDailyAmbientSchedule(int seed, int otherMuckDay)
		{
			Random random = new Random((seed * 397) ^ (otherMuckDay * 7919) ^ 0x166C7);
			int num = random.Next(3);
			return new OtherMuckAmbientCue[2]
			{
				new OtherMuckAmbientCue
				{
					TargetDay = otherMuckDay,
					CueIndex = num,
					DayThreshold = (22.75f + (float)random.NextDouble() * 0.5f) / 24f
				},
				new OtherMuckAmbientCue
				{
					TargetDay = otherMuckDay,
					CueIndex = (num + 1 + random.Next(2)) % 3,
					DayThreshold = (1.75f + (float)random.NextDouble() * 0.5f) / 24f
				}
			};
		}

		public static OtherMuckAmbientCue[] BuildSchedule(int seed)
		{
			Random random = new Random(seed + 91847);
			List<int> list = new List<int> { 0, 1, 2 };
			for (int num = list.Count - 1; num > 0; num--)
			{
				int index = random.Next(num + 1);
				int value = list[num];
				list[num] = list[index];
				list[index] = value;
			}
			OtherMuckAmbientCue[] array = new OtherMuckAmbientCue[3];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new OtherMuckAmbientCue
				{
					TargetDay = TargetDays[i],
					CueIndex = list[i],
					DayThreshold = ToWrappedNoonTime(-1f + (float)random.NextDouble() * 2f)
				};
			}
			return array;
		}

		public static bool CanPlay(int currentDay, float dayTime, OtherMuckAmbientCue cue, bool encounterActive, bool alreadyPlayedToday)
		{
			if (currentDay >= cue.TargetDay && HasReachedShortCueThreshold(dayTime, cue.DayThreshold) && !encounterActive)
			{
				return !alreadyPlayedToday;
			}
			return false;
		}

		public static bool IsInsideShortCueWindow(float dayTime)
		{
			if (!(dayTime >= 23f / 24f))
			{
				return dayTime <= 1f / 24f;
			}
			return true;
		}

		private static bool HasReachedShortCueThreshold(float dayTime, float threshold)
		{
			if (!IsInsideShortCueWindow(dayTime) || !IsInsideShortCueWindow(threshold))
			{
				return false;
			}
			if (threshold >= 23f / 24f)
			{
				return dayTime >= threshold;
			}
			if (!(dayTime >= 23f / 24f))
			{
				return dayTime >= threshold;
			}
			return true;
		}

		private static float ToWrappedNoonTime(float hoursFromNoon)
		{
			float num = hoursFromNoon / 24f;
			if (!(num < 0f))
			{
				return num;
			}
			return num + 1f;
		}

		private static float GetMainTrackThreshold(int seed, int otherMuckDay, int salt, float start, float end)
		{
			Random random = new Random((seed * 397) ^ (otherMuckDay * 7919) ^ salt);
			return start + (float)random.NextDouble() * (end - start);
		}
	}
	public sealed class OtherMuckDailyAudioScheduler
	{
		private readonly int[] lastDay = new int[4] { -1, -1, -1, -1 };

		private int scheduleDay = -1;

		private OtherMuckAmbientCue[] schedule;

		private int lastAmbient = -1;

		public bool TryTake(int seed, int day, float time, TheOtherMuckState state, bool musicBlocked, out OtherMuckSharedAudioKind kind, out int clip)
		{
			kind = OtherMuckSharedAudioKind.ShortAmbient;
			clip = -1;
			if (state != TheOtherMuckState.OnOtherMuck || musicBlocked)
			{
				return false;
			}
			if (day > lastDay[0] && OtherMuckAmbientAudioPolicy.CanStartMorningTrack(time, OtherMuckAmbientAudioPolicy.GetMorningTrackThreshold(seed, day)))
			{
				lastDay[0] = day;
				if (OtherMuckAmbientAudioPolicy.ShouldPlayMorning(seed, day))
				{
					kind = OtherMuckSharedAudioKind.Morning;
					return true;
				}
			}
			if (day > lastDay[1] && OtherMuckAmbientAudioPolicy.CanStartNightTrack(time, OtherMuckAmbientAudioPolicy.GetNightTrackThreshold(seed, day)))
			{
				lastDay[1] = day;
				kind = OtherMuckSharedAudioKind.Night;
				return true;
			}
			if (schedule == null || scheduleDay != day)
			{
				schedule = OtherMuckAmbientAudioPolicy.BuildDailyAmbientSchedule(seed, day);
				scheduleDay = day;
			}
			for (int i = 0; i < 2; i++)
			{
				float num = ((i == 0) ? 23.25f : 2.25f) / 24f;
				if (day > lastDay[i + 2] && !(time < schedule[i].DayThreshold) && !(time > num))
				{
					lastDay[i + 2] = day;
					clip = schedule[i].CueIndex;
					if (clip == lastAmbient)
					{
						clip = (clip + 1 + new Random(seed ^ (day * 7919) ^ i).Next(2)) % 3;
					}
					lastAmbient = clip;
					return true;
				}
			}
			return false;
		}
	}
	internal sealed class OtherMuckAncientPillarInteractable : MonoBehaviour, SharedObject, Interactable
	{
		private static readonly Dictionary<int, OtherMuckAncientPillarInteractable> PillarsByIndex = new Dictionary<int, OtherMuckAncientPillarInteractable>();

		private static readonly Dictionary<int, bool> Presentation = new Dictionary<int, bool>();

		private int id;

		private int pillarIndex = -1;

		private int[] mobIds;

		private bool started;

		private bool completed;

		private bool visualCompleted;

		public LayerMask whatIsGround;

		public static Action<int> NetworkStartRequest { get; set; }

		public static Action<int> NetworkCompletedBroadcast { get; set; }

		public static IEnumerable<KeyValuePair<int, bool>> GetPresentation()
		{
			return Presentation;
		}

		public void Interact()
		{
			if (!started)
			{
				if (NetworkStartRequest != null && pillarIndex >= 0)
				{
					NetworkStartRequest(pillarIndex);
				}
				else
				{
					ClientSend.Interact(id);
				}
			}
		}

		public void LocalExecute()
		{
		}

		public void AllExecute()
		{
			started = true;
			if (pillarIndex >= 0 && !Presentation.ContainsKey(pillarIndex))
			{
				Presentation[pillarIndex] = false;
			}
			OtherMuckPillarBeacon.Show(((Component)this).gameObject, visualCompleted);
		}

		public void ServerExecute(int fromClient = -1)
		{
			if (!started)
			{
				StartEncounter();
			}
		}

		public void RemoveObject()
		{
			ExplodeAndRemove();
		}

		public string GetName()
		{
			if (!started)
			{
				return "Activate Ancient Pillar";
			}
			return "Ancient Pillar";
		}

		public bool IsStarted()
		{
			return started;
		}

		public void SetId(int id)
		{
			this.id = id;
		}

		public int GetId()
		{
			return id;
		}

		public void ConfigureIndex(int index)
		{
			pillarIndex = index;
			PillarsByIndex[index] = this;
			TheOtherMuckMapRuntime.RegisterPillar(index, ((Component)this).transform);
			if (Presentation.TryGetValue(index, out var value))
			{
				if (value)
				{
					ExplodeAndRemove();
				}
				else
				{
					AllExecute();
				}
			}
		}

		public static void ResetRegistry()
		{
			PillarsByIndex.Clear();
			Presentation.Clear();
		}

		public static bool TryGetInteractionPosition(int index, out Vector3 position)
		{
			//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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			position = Vector3.zero;
			if (!PillarsByIndex.TryGetValue(index, out var value) || (Object)(object)value == (Object)null || value.started)
			{
				return false;
			}
			position = ((Component)value).transform.position;
			return true;
		}

		public static bool TryStartAuthoritative(int index)
		{
			if (!PillarsByIndex.TryGetValue(index, out var value) || (Object)(object)value == (Object)null || value.started)
			{
				return false;
			}
			value.StartEncounter();
			return true;
		}

		public static void ApplyStartedFromNetwork(int index)
		{
			if (!Presentation.ContainsKey(index))
			{
				Presentation[index] = false;
			}
			if (PillarsByIndex.TryGetValue(index, out var value) && (Object)(object)value != (Object)null)
			{
				value.AllExecute();
				OtherMuckAudio.PlayAncientPillar();
			}
		}

		public static void ApplyCompletedFromNetwork(int index)
		{
			Presentation[index] = true;
			TheOtherMuckMapRuntime.MarkPillarCompleted(index);
			if (PillarsByIndex.TryGetValue(index, out var value) && !((Object)(object)value == (Object)null))
			{
				PillarsByIndex.Remove(index);
				value.completed = true;
				value.ExplodeAndRemove();
			}
		}

		private unsafe void StartEncounter()
		{
			//IL_0020: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			AllExecute();
			OtherMuckAudio.PlayAncientPillar();
			Difficulty difficulty = (Difficulty)((GameManager.gameSettings == null) ? 1 : ((int)GameManager.gameSettings.difficulty));
			int ancientPillarNormalEnemyCount = TheOtherMuckTuningPolicy.GetAncientPillarNormalEnemyCount(difficulty);
			int ancientPillarBruteCount = TheOtherMuckTuningPolicy.GetAncientPillarBruteCount(difficulty);
			mobIds = new int[ancientPillarNormalEnemyCount + ancientPillarBruteCount];
			for (int i = 0; i < mobIds.Length; i++)
			{
				mobIds[i] = -1;
			}
			List<MobType> normalEnemyCandidates = GetNormalEnemyCandidates();
			string[] roster = OtherMuckPillarBalancePolicy.BuildRoster(normalEnemyCandidates.Select((MobType mob) => mob.name), difficulty, () => Random.value);
			int i2;
			for (i2 = 0; i2 < roster.Length; i2++)
			{
				MobType val = normalEnemyCandidates.First((MobType candidate) => candidate.name == roster[i2]);
				bool flag = i2 < ancientPillarBruteCount;
				mobIds[i2] = SpawnEnemy(val, TheOtherMuckRuntime.GetOtherMuckSpawnMultiplier(val) * (flag ? 2f : 1f), flag);
				Debug.Log((object)("[TheOtherMuck] Ancient pillar " + pillarIndex + " spawned " + val.name + ", id=" + mobIds[i2] + ", brute=" + flag + ", difficulty=" + ((object)(*(Difficulty*)(&difficulty))/*cast due to .constrained prefix*/).ToString() + "."));
			}
			((MonoBehaviour)this).InvokeRepeating("CheckMobs", 0.5f, 0.5f);
		}

		private int SpawnEnemy(MobType mob, float multiplier, bool brute)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)mob == (Object)null || (Object)(object)MobSpawner.Instance == (Object)null || (Object)(object)MobManager.Instance == (Object)null)
			{
				return -1;
			}
			if (!TryFindSpawnPosition(out var spawnPosition))
			{
				spawnPosition = ((Component)this).transform.position + Vector3.up * 1f;
			}
			int nextId = MobManager.Instance.GetNextId();
			MobSpawner.Instance.ServerSpawnNewMob(nextId, mob.id, spawnPosition, multiplier, 1f, (BossType)0, -1);
			if (brute)
			{
				TheOtherMuckRuntime.MarkOtherMuckNightBrute(nextId);
			}
			return nextId;
		}

		private List<MobType> GetNormalEnemyCandidates()
		{
			List<MobType> list = new List<MobType>();
			if ((Object)(object)MobSpawner.Instance != (Object)null && MobSpawner.Instance.allMobs != null)
			{
				MobType[] allMobs = MobSpawner.Instance.allMobs;
				foreach (MobType val in allMobs)
				{
					if (IsValidNormalMob(val))
					{
						list.Add(val);
					}
				}
			}
			if (list.Count > 0)
			{
				return list;
			}
			MobType val2 = (((Object)(object)GameLoop.Instance != (Object)null) ? GameLoop.Instance.SelectMobToSpawn(true) : null);
			if (IsValidNormalMob(val2))
			{
				list.Add(val2);
			}
			return list;
		}

		private static bool IsValidNormalMob(MobType mob)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if ((Object)(object)mob == (Object)null || mob.boss || ((int)mob.behaviour != 1 && (int)mob.behaviour != 2))
			{
				return false;
			}
			string text = mob.name ?? string.Empty;
			if (text.IndexOf("Guardian", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Chief", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Gronk", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Chunk", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Bob", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Trader", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Villager", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Woodman", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Smith", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Chef", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Wildcard", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("Woodcutter", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("Archer", StringComparison.OrdinalIgnoreCase) < 0;
			}
			return false;
		}

		private bool TryFindSpawnPosition(out Vector3 spawnPosition)
		{
			//IL_0006: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(((Component)this).transform.position + new Vector3(Random.Range(-1f, 1f) * 15f, 100f, Random.Range(-1f, 1f) * 15f), Vector3.down, ref val, 240f, LayerMask.op_Implicit(whatIsGround)))
			{
				spawnPosition = ((RaycastHit)(ref val)).point;
				return true;
			}
			spawnPosition = Vector3.zero;
			return false;
		}

		private void CheckMobs()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (completed || mobIds == null)
			{
				return;
			}
			for (int i = 0; i < mobIds.Length; i++)
			{
				int num = mobIds[i];
				if (num != -1 && (Object)(object)MobManager.Instance != (Object)null && MobManager.Instance.mobs.ContainsKey(num))
				{
					return;
				}
			}
			completed = true;
			((MonoBehaviour)this).CancelInvoke("CheckMobs");
			TheOtherMuckRuntime.RegisterAncientPillarCompleted(((Component)this).transform.position);
			NetworkCompletedBroadcast?.Invoke(pillarIndex);
			DropReward();
			if (LocalClient.serverOwner && (Object)(object)LocalClient.instance != (Object)null)
			{
				ServerSend.PickupInteract(LocalClient.instance.myId, id);
			}
			if ((Object)(object)ResourceManager.Instance != (Object)null)
			{
				ResourceManager.Instance.RemoveInteractItem(id);
			}
			ExplodeAndRemove();
		}

		private void DropReward()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if (LocalClient.serverOwner && !((Object)(object)ItemManager.Instance == (Object)null))
			{
				Powerup randomPowerup = ItemManager.Instance.GetRandomPowerup(0.3f, 0.2f, 0.1f);
				Transform val = ((Component)this).transform.Find("AncientPillarRewardAnchor");
				Vector3 val2 = (((Object)(object)val != (Object)null) ? val.position : (((Component)this).transform.position + new Vector3(4f, 2.5f, 0f)));
				if ((Object)(object)randomPowerup != (Object)null)
				{
					int nextId = ItemManager.Instance.GetNextId();
					ItemManager.Instance.DropPowerupAtPosition(randomPowerup.id, val2, nextId);
					ServerSend.DropPowerupAtPosition(randomPowerup.id, nextId, val2);
				}
				string gemName = OtherMuckPillarRewardPolicy.GetGemName(GameManager.GetSeed(), TheOtherMuckRuntime.RunGeneration, pillarIndex);
				InventoryItem val3 = ((!string.IsNullOrEmpty(gemName)) ? ItemManager.Instance.GetItemByName(gemName) : null);
				if ((Object)(object)val3 == (Object)null)
				{
					Debug.LogWarning((object)("[TheOtherMuck] Could not drop Ancient Pillar gem for index " + pillarIndex + ": " + (gemName ?? "unassigned") + "."));
				}
				else
				{
					Vector3 val4 = val2 + Vector3.right * 1.35f;
					int nextId2 = ItemManager.Instance.GetNextId();
					ItemManager.Instance.DropItemAtPosition(val3.id, 1, val4, nextId2);
					ServerSend.DropItemAtPosition(val3.id, 1, nextId2, val4);
				}
			}
		}

		private void ExplodeAndRemove()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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)
			//IL_015d: 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_0181: Expected O, but got Unknown
			if (!visualCompleted)
			{
				visualCompleted = true;
				if (pillarIndex >= 0)
				{
					Presentation[pillarIndex] = true;
				}
				completed = true;
				started = true;
				OtherMuckPillarBeacon.Show(((Component)this).gameObject, complete: true);
				TheOtherMuckMapRuntime.MarkPillarCompleted(pillarIndex);
				GameObject val = new GameObject("Other Muck Ancient Pillar Burst");
				val.transform.position = ((Component)this).transform.position + Vector3.up * 2f;
				ParticleSystem val2 = val.AddComponent<ParticleSystem>();
				MainModule main = val2.main;
				((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(2.2f);
				((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(11f);
				((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.7f);
				((MainModule)(ref main)).maxParticles = 180;
				EmissionModule emission = val2.emission;
				((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[3]
				{
					new Burst(0f, (short)90),
					new Burst(0.45f, (short)55),
					new Burst(0.95f, (short)35)
				});
				ShapeModule shape = val2.shape;
				((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
				((ShapeModule)(ref shape)).radius = 2.2f;
				ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
				if ((Object)(object)component != (Object)null)
				{
					((Renderer)component).material = new Material(Shader.Find("Sprites/Default"))
					{
						color = new Color(1f, 0.22f, 0.04f, 1f)
					};
				}
				Object.Destroy((Object)(object)val, 3.2f);
			}
		}
	}
	public sealed class OtherMuckArrivalPresentationPolicy
	{
		private bool landingPrepared;

		private bool completed;

		private bool presented;

		public void PrepareLanding()
		{
			landingPrepared = true;
		}

		public bool TryComplete(TheOtherMuckState state)
		{
			if (!landingPrepared || completed || (state != TheOtherMuckState.Voyaging && state != TheOtherMuckState.OnOtherMuck))
			{
				return false;
			}
			completed = true;
			return true;
		}

		public bool TryPresent()
		{
			if (!completed || presented)
			{
				return false;
			}
			presented = true;
			return true;
		}

		public bool ShouldHoldAtmosphere(TheOtherMuckState state, bool skiesCleared)
		{
			if (!skiesCleared)
			{
				if (state != TheOtherMuckState.Voyaging || !landingPrepared)
				{
					if (state >= TheOtherMuckState.OnOtherMuck)
					{
						return state <= TheOtherMuckState.PortalOpened;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public void Reset()
		{
			landingPrepared = (completed = (presented = false));
		}
	}
	public enum OtherMuckRosterTier
	{
		Common,
		Wolf,
		Elemental,
		Heavy
	}
	public enum SmeagullSupportCategory
	{
		Common,
		Elemental,
		Heavy,
		Boss
	}
	public sealed class OtherMuckArrivalContribution
	{
		public float OffenseScore { get; private set; }

		public float SustainEhp { get; private set; }

		public OtherMuckArrivalContribution(float offenseScore, float sustainEhp)
		{
			OffenseScore = Math.Max(0f, offenseScore);
			SustainEhp = Math.Max(0f, sustainEhp);
		}
	}
	public sealed class OtherMuckDurabilityInputs
	{
		public float MaxHp { get; private set; }

		public float MaxShield { get; private set; }

		public float DefensePercent { get; private set; }

		public float RecoveryHpOverTwentySeconds { get; private set; }

		public OtherMuckDurabilityInputs(float maxHp, float maxShield, float defensePercent, float recoveryHpOverTwentySeconds)
		{
			MaxHp = Math.Max(0f, maxHp);
			MaxShield = Math.Max(0f, maxShield);
			DefensePercent = Math.Max(0f, Math.Min(0.98f, defensePercent));
			RecoveryHpOverTwentySeconds = Math.Max(0f, recoveryHpOverTwentySeconds);
		}
	}
	public sealed class OtherMuckArrivalSnapshot
	{
		public long Generation { get; private set; }

		public Difficulty Difficulty { get; private set; }

		public int ActivePlayers { get; private set; }

		public float MedianOffense { get; private set; }

		public float MedianSustainEhp { get; private set; }

		public float CommonHpAtArrival { get; private set; }

		public float CommonRawDamageAtArrival { get; private set; }

		public OtherMuckArrivalSnapshot(long generation, Difficulty difficulty, int activePlayers, float medianOffense, float medianSustainEhp, float commonHpAtArrival, float commonRawDamageAtArrival)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			Generation = generation;
			Difficulty = difficulty;
			ActivePlayers = Math.Max(1, activePlayers);
			MedianOffense = medianOffense;
			MedianSustainEhp = medianSustainEhp;
			CommonHpAtArrival = commonHpAtArrival;
			CommonRawDamageAtArrival = commonRawDamageAtArrival;
		}
	}
	public static class OtherMuckArrivalScalingPolicy
	{
		public const float CommonReferenceHp = 60f;

		public const float CommonReferenceRawAttackDamage = 10f;

		public const float MommyCommonHpRatio = 60f;

		public const float SmeagullCommonHpRatio = 60f;

		public const float SmeagullBowDamageTakenMultiplier = 0.7f;

		private static readonly int[] EasyMobCaps = new int[10] { 2, 3, 5, 7, 9, 11, 13, 15, 17, 18 };

		private static readonly int[] NormalMobCaps = new int[10] { 2, 4, 7, 10, 13, 16, 18, 20, 22, 24 };

		private static readonly int[] GamerMobCaps = new int[10] { 3, 5, 10, 14, 18, 21, 24, 26, 28, 30 };

		private static readonly int[] EasySmeagullWaves = new int[5] { 4, 6, 8, 10, 15 };

		private static readonly int[] NormalSmeagullWaves = new int[5] { 6, 8, 12, 15, 20 };

		private static readonly int[] GamerSmeagullWaves = new int[5] { 12, 14, 18, 22, 26 };

		private static readonly Dictionary<string, float> VanillaBaseHp = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase)
		{
			["Lil Dave"] = 40f,
			["Goblin"] = 60f,
			["Wolf"] = 60f,
			["Fire Dave"] = 100f,
			["Water Dave"] = 100f,
			["Electric Dave"] = 100f,
			["Wyvern"] = 100f,
			["Golem"] = 150f,
			["Gronk"] = 650f,
			["Guardian"] = 650f,
			["Chief"] = 650f,
			["Big Chunk"] = 700f,
			["Stone Golem"] = 700f,
			["Bob"] = 2500f,
			["Dragon"] = 2500f
		};

		public static float GetPartialMultiplier(float fullMultiplier, float weight)
		{
			return 1f + (Math.Max(0f, fullMultiplier) - 1f) * Math.Max(0f, Math.Min(1f, weight));
		}

		public static float GetExpectedCritMultiplier(float critChance, float critMultiplier)
		{
			return 1f + Math.Max(0f, critChance) * Math.Max(0f, critMultiplier - 1f) * 0.5f;
		}

		public static float GetSustainEhp(OtherMuckDurabilityInputs inputs)
		{
			if (inputs == null)
			{
				return 0f;
			}
			float num = Math.Max(0.02f, 1f - inputs.DefensePercent);
			float num2 = (inputs.MaxHp + inputs.MaxShield) / num;
			float num3 = inputs.RecoveryHpOverTwentySeconds / num;
			return num2 + Math.Min(num2 * 0.35f, num3 * 0.5f);
		}

		public static OtherMuckArrivalSnapshot CreateSnapshot(long generation, Difficulty difficulty, IEnumerable<OtherMuckArrivalContribution> contributions)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: