Decompiled source of Kittys Muck v0.1.87
plugins/Kittys_Muck/Kittys_Muck.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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: