Decompiled source of MuckReplayable v1.1.11
MuckReplayable.dll
Decompiled 5 days 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.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Xml; using System.Xml.Serialization; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Steamworks; using Steamworks.Data; using TMPro; 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("MuckReplayable")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.11.0")] [assembly: AssemblyInformationalVersion("1.1.11")] [assembly: AssemblyProduct("MuckReplayable")] [assembly: AssemblyTitle("MuckReplayable")] [assembly: AssemblyVersion("1.1.11.0")] namespace MuckReforged; internal static class AccessoryCombatRules { internal static bool Harvesting; internal static bool SpawningProjectileImpact; internal static bool ProjectileDamage; internal static float AttacksPerSecond(bool haste, bool juice) { if (!juice) { if (!haste) { return 3.5f; } return 4f; } if (!haste) { return 5f; } return 5.5f; } } [HarmonyPatch(typeof(LootExtra), "CheckDrop")] internal static class AccessoryHarvestContext { private static void Prefix(out bool __state) { __state = AccessoryCombatRules.Harvesting; AccessoryCombatRules.Harvesting = true; } private static void Finalizer(bool __state) { AccessoryCombatRules.Harvesting = __state; } } internal sealed class DeflectableProjectileImpact : MonoBehaviour { } [HarmonyPatch(typeof(EnemyProjectile), "OnCollisionEnter")] internal static class AccessoryProjectileContext { private static void Prefix(out bool __state) { __state = AccessoryCombatRules.SpawningProjectileImpact; AccessoryCombatRules.SpawningProjectileImpact = true; } private static void Finalizer(bool __state) { AccessoryCombatRules.SpawningProjectileImpact = __state; } } [HarmonyPatch(typeof(ImpactDamage), "SetDamage")] internal static class AccessoryMarkProjectileImpact { private static void Postfix(ImpactDamage __instance) { if (AccessoryCombatRules.SpawningProjectileImpact && (Object)(object)((Component)__instance).GetComponent<DeflectableProjectileImpact>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DeflectableProjectileImpact>(); } } } [HarmonyPatch(typeof(ImpactDamage), "Start")] internal static class AccessoryImpactContext { private static void Prefix(ImpactDamage __instance, out bool __state) { __state = AccessoryCombatRules.ProjectileDamage; AccessoryCombatRules.ProjectileDamage = (Object)(object)((Component)__instance).GetComponent<DeflectableProjectileImpact>() != (Object)null; } private static void Finalizer(bool __state) { AccessoryCombatRules.ProjectileDamage = __state; } } [HarmonyPatch(typeof(ClientSend), "PlayerHit")] internal static class AccessoryProjectileReduction { private static void Prefix(ref int damage, int hurtPlayer) { if (AccessoryCombatRules.ProjectileDamage) { damage = Mathf.CeilToInt((float)damage * (1f - AccessoryNetwork.ValueForPlayer(AccessoryEffect.Deflection, hurtPlayer))); } } } [HarmonyPatch(typeof(Arrow), "OnCollisionEnter")] internal static class AccessoryArrowContext { private static void Prefix(out bool __state) { __state = AccessoryCombatRules.ProjectileDamage; AccessoryCombatRules.ProjectileDamage = true; } private static void Finalizer(bool __state) { AccessoryCombatRules.ProjectileDamage = __state; } } internal enum AccessorySlot { Ring, Necklace } internal enum AccessoryEffect { Strength, Haste, Swiftness, Defense, Deflection, Fortune } internal sealed class ReplayableAccessory { internal string Name; internal AccessorySlot Slot; internal AccessoryEffect Effect; internal string PrimaryMaterial; internal int PrimaryCost; internal string SecondaryMaterial; internal int SecondaryCost; internal float Value; internal Color Color; internal string EffectText; internal InventoryItem Item; } internal static class AccessoryRegistry { private const string AssetPrefix = "MuckReplayable_Accessory_"; private static readonly Dictionary<int, ReplayableAccessory> ById = new Dictionary<int, ReplayableAccessory>(); private static ItemManager installedManager; private static Mesh ringMesh; private static Mesh necklaceMesh; private static readonly ReplayableAccessory[] Definitions = new ReplayableAccessory[6] { Necklace("Necklace Of Greed", AccessoryEffect.Fortune, "AncientCore", 1, "Gold bar", 69, 0.5f, new Color(1f, 0.72f, 0.08f), "+50% harvested resources"), Necklace("Necklace Of Deflection", AccessoryEffect.Deflection, "AncientCore", 1, "Mithril bar", 69, 0.5f, new Color(0.2f, 0.72f, 0.96f), "50% less incoming projectile damage"), Ring("Ring Of Power", AccessoryEffect.Strength, "Fireball", 10, "Chunkium bar", 25, 1f, new Color(0.96f, 0.18f, 0.08f), "+1 effective Massgainer stack"), Ring("Ring Of Speed", AccessoryEffect.Swiftness, "Lightningball", 10, "Chunkium bar", 25, 0.5f, new Color(0.9f, 0.78f, 0.12f), "+50% movement speed"), Ring("Ring Of Haste", AccessoryEffect.Haste, "Wyvern Claws", 1, "Chunkium bar", 25, 0.5f, new Color(0.32f, 0.84f, 0.92f), "+50% attack speed; cap 4 attacks/s (5.5 with Juice)"), Ring("Ring Of Defense", AccessoryEffect.Defense, "Waterball", 10, "Chunkium bar", 25, 10f, new Color(0.12f, 0.42f, 0.96f), "+10 percentage points of defense") }; internal static IEnumerable<ReplayableAccessory> All => Definitions.Where((ReplayableAccessory value) => (Object)(object)value.Item != (Object)null); internal static void Install(ItemManager manager) { //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) if (manager?.allItems == null || manager.allScriptableItems == null || ((Object)(object)installedManager == (Object)(object)manager && Definitions.All((ReplayableAccessory definition) => (Object)(object)definition.Item != (Object)null && manager.allItems.TryGetValue(definition.Item.id, out var value) && value == definition.Item))) { return; } installedManager = manager; ById.Clear(); ReplayableAccessory[] definitions = Definitions; for (int num = 0; num < definitions.Length; num++) { definitions[num].Item = null; } List<InventoryItem> list = manager.allScriptableItems.Where((InventoryItem item) => (Object)(object)item != (Object)null && !(((Object)item).name ?? string.Empty).StartsWith("MuckReplayable_Accessory_", StringComparison.Ordinal)).ToList(); int[] array = (from pair in manager.allItems where (Object)(object)pair.Value != (Object)null && (((Object)pair.Value).name ?? string.Empty).StartsWith("MuckReplayable_Accessory_", StringComparison.Ordinal) select pair.Key).ToArray(); foreach (int key in array) { manager.allItems.Remove(key); } InventoryItem val = Find(manager, "Anvil"); InventoryItem val2 = Find(manager, "Chunkium bar") ?? Find(manager, "Gold bar"); if ((Object)(object)val == (Object)null || (Object)(object)val2?.material == (Object)null) { Plugin.Log.LogWarning((object)"Accessory registration skipped because Anvil or a visual material was unavailable."); return; } ringMesh = (((Object)(object)ringMesh != (Object)null) ? ringMesh : CreateTorusMesh()); necklaceMesh = (((Object)(object)necklaceMesh != (Object)null) ? necklaceMesh : CreatePendantMesh()); int num2 = ItemCatalogUtilities.NextId(manager); definitions = Definitions; foreach (ReplayableAccessory replayableAccessory in definitions) { InventoryItem val3 = Find(manager, replayableAccessory.PrimaryMaterial); InventoryItem val4 = Find(manager, replayableAccessory.SecondaryMaterial); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { Plugin.Log.LogWarning((object)("Skipped " + replayableAccessory.Name + ": " + replayableAccessory.PrimaryMaterial + " or " + replayableAccessory.SecondaryMaterial + " was unavailable.")); continue; } InventoryItem val5 = ScriptableObject.CreateInstance<InventoryItem>(); ((Object)val5).name = "MuckReplayable_Accessory_" + replayableAccessory.Name.Replace(" ", string.Empty); val5.id = num2++; val5.name = replayableAccessory.Name; val5.description = replayableAccessory.EffectText + ". Right-click in your inventory to equip permanently for this run. Only one " + replayableAccessory.Slot.ToString().ToLowerInvariant() + " can be equipped."; val5.type = (ItemType)0; val5.tag = (ItemTag)0; val5.tier = 5; val5.stackable = false; val5.max = 1; val5.amount = 1; val5.craftable = true; val5.craftAmount = 1; val5.unlockWithFirstRequirementOnly = true; val5.stationRequirement = val; val5.requirements = (CraftRequirement[])(object)new CraftRequirement[2] { Requirement(val3, replayableAccessory.PrimaryCost), Requirement(val4, replayableAccessory.SecondaryCost) }; val5.mesh = ((replayableAccessory.Slot == AccessorySlot.Ring) ? ringMesh : necklaceMesh); val5.material = Object.Instantiate<Material>(val2.material); ((Object)val5.material).name = "MuckReplayable_Accessory_" + replayableAccessory.Name + " Material"; if (val5.material.HasProperty("_Color")) { val5.material.color = replayableAccessory.Color; } if (val5.material.HasProperty("_Glossiness")) { val5.material.SetFloat("_Glossiness", 0.72f); } val5.sprite = CreateIcon(replayableAccessory); val5.rotationOffset = ((replayableAccessory.Slot == AccessorySlot.Ring) ? new Vector3(18f, 0f, -22f) : new Vector3(8f, 0f, 0f)); val5.positionOffset = new Vector3(0f, -0.08f, 0.35f); val5.scale = ((replayableAccessory.Slot == AccessorySlot.Ring) ? 0.7f : 0.62f); val5.rarity = (ItemRarity)2; val5.attackTypes = Array.Empty<Weakness>(); Object.DontDestroyOnLoad((Object)(object)val5); Object.DontDestroyOnLoad((Object)(object)val5.material); list.Add(val5); manager.allItems[val5.id] = val5; replayableAccessory.Item = val5; ById[val5.id] = replayableAccessory; } manager.allScriptableItems = list.ToArray(); CraftingUI[] array2 = Resources.FindObjectsOfTypeAll<CraftingUI>(); for (int num = 0; num < array2.Length; num++) { InjectCrafting(array2[num]); } Plugin.Log.LogInfo((object)$"Registered {ById.Count} permanent accessories with anvil recipes."); } internal static bool TryGet(InventoryItem item, out ReplayableAccessory accessory) { return ById.TryGetValue(((Object)(object)item != (Object)null) ? item.id : (-1), out accessory); } internal static ReplayableAccessory FindDefinition(string name) { switch (name) { case "Ruby Ring": name = "Ring Of Power"; break; case "Black Shard Ring": name = "Ring Of Haste"; break; case "Wyvern Ring": name = "Ring Of Speed"; break; case "Dragon Ring": name = "Ring Of Defense"; break; case "Fortune Necklace": name = "Necklace Of Greed"; break; case "Guardian Necklace": name = "Necklace Of Deflection"; break; } return Definitions.FirstOrDefault((ReplayableAccessory value) => string.Equals(value.Name, name, StringComparison.OrdinalIgnoreCase)); } internal static void InjectCrafting(CraftingUI crafting) { if (crafting?.tabs == null || ById.Count == 0 || ((object)OtherInput.Instance?.anvil != crafting && !crafting.tabs.Any((Tab tab) => (tab?.items ?? Array.Empty<InventoryItem>()).Any((InventoryItem item) => (Object)(object)item != (Object)null && item.name == "Gold Sword")))) { return; } int num = Array.FindIndex(crafting.tabs, (Tab tab) => (tab?.items ?? Array.Empty<InventoryItem>()).Any((InventoryItem item) => (Object)(object)item != (Object)null && (int)item.type == 3)); if (num < 0 && crafting.tabs.Length != 0) { num = 0; } if (num >= 0) { crafting.tabs[num].items = (from item in (crafting.tabs[num].items ?? Array.Empty<InventoryItem>()).Concat(All.Select((ReplayableAccessory value) => value.Item)) where (Object)(object)item != (Object)null group item by item.id into @group select @group.First()).ToArray(); } } private static ReplayableAccessory Ring(string name, AccessoryEffect effect, string primary, int primaryCost, string secondary, int secondaryCost, float value, Color color, string text) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) return new ReplayableAccessory { Name = name, Slot = AccessorySlot.Ring, Effect = effect, PrimaryMaterial = primary, PrimaryCost = primaryCost, SecondaryMaterial = secondary, SecondaryCost = secondaryCost, Value = value, Color = color, EffectText = text }; } private static ReplayableAccessory Necklace(string name, AccessoryEffect effect, string primary, int primaryCost, string secondary, int secondaryCost, float value, Color color, string text) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) return new ReplayableAccessory { Name = name, Slot = AccessorySlot.Necklace, Effect = effect, PrimaryMaterial = primary, PrimaryCost = primaryCost, SecondaryMaterial = secondary, SecondaryCost = secondaryCost, Value = value, Color = color, EffectText = text }; } private static InventoryItem Find(ItemManager manager, string name) { return ((IEnumerable<InventoryItem>)manager.allItems.Values).FirstOrDefault((Func<InventoryItem, bool>)((InventoryItem item) => (Object)(object)item != (Object)null && string.Equals(item.name, name, StringComparison.OrdinalIgnoreCase))); } private static CraftRequirement Requirement(InventoryItem item, int amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return new CraftRequirement { item = item, amount = amount }; } private static Mesh CreateTorusMesh() { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: 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_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0178: Expected O, but got Unknown //IL_0179: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[192]; Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length]; int[] array3 = new int[1152]; Vector3 val = default(Vector3); Vector3 val2 = default(Vector3); for (int i = 0; i < 24; i++) { float num = (float)i * (float)Math.PI * 2f / 24f; ((Vector3)(ref val))..ctor(Mathf.Cos(num) * 0.42f, Mathf.Sin(num) * 0.42f, 0f); for (int j = 0; j < 8; j++) { float num2 = (float)j * (float)Math.PI * 2f / 8f; ((Vector3)(ref val2))..ctor(Mathf.Cos(num) * Mathf.Cos(num2), Mathf.Sin(num) * Mathf.Cos(num2), Mathf.Sin(num2)); int num3 = i * 8 + j; array2[num3] = val2; array[num3] = val + val2 * 0.11f; int num4 = (i + 1) % 24 * 8; int num5 = (j + 1) % 8; int num6 = num3 * 6; array3[num6] = num3; array3[num6 + 1] = num4 + j; array3[num6 + 2] = num4 + num5; array3[num6 + 3] = num3; array3[num6 + 4] = num4 + num5; array3[num6 + 5] = i * 8 + num5; } } Mesh val3 = new Mesh { name = "MuckReplayable_Accessory_RingMesh", vertices = array, normals = array2, triangles = array3 }; val3.RecalculateBounds(); Object.DontDestroyOnLoad((Object)val3); return val3; } private static Mesh CreatePendantMesh() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00ed: Expected O, but got Unknown Vector3[] vertices = (Vector3[])(object)new Vector3[6] { new Vector3(0f, 0.55f, 0f), new Vector3(-0.38f, 0.05f, 0f), new Vector3(0f, -0.55f, 0f), new Vector3(0.38f, 0.05f, 0f), new Vector3(0f, 0.05f, 0.2f), new Vector3(0f, 0.05f, -0.2f) }; int[] triangles = new int[24] { 0, 1, 4, 1, 2, 4, 2, 3, 4, 3, 0, 4, 1, 0, 5, 2, 1, 5, 3, 2, 5, 0, 3, 5 }; Mesh val = new Mesh { name = "MuckReplayable_Accessory_NecklaceMesh", vertices = vertices, triangles = triangles }; val.RecalculateNormals(); val.RecalculateBounds(); Object.DontDestroyOnLoad((Object)val); return val; } private static Sprite CreateIcon(ReplayableAccessory definition) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0035: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(96, 96, (TextureFormat)4, false) { name = "MuckReplayable_Accessory_" + definition.Name + " Icon", filterMode = (FilterMode)1, wrapMode = (TextureWrapMode)1 }; Color[] array = Enumerable.Repeat<Color>(new Color(0f, 0f, 0f, 0f), 9216).ToArray(); Color val2 = Color.Lerp(definition.Color, Color.white, 0.42f); for (int i = 0; i < 96; i++) { for (int j = 0; j < 96; j++) { float num = (float)j - 47.5f; float num2 = (float)i - 47.5f; if (definition.Slot == AccessorySlot.Ring) { float num3 = Mathf.Sqrt(num * num + num2 * num2); if (num3 >= 24f && num3 <= 34f) { array[i * 96 + j] = ((num3 < 27f) ? val2 : definition.Color); } if (Mathf.Abs(num) + Mathf.Abs(num2 - 30f) < 13f) { array[i * 96 + j] = val2; } } else { float num4 = Mathf.Abs(Mathf.Sqrt(num * num + (num2 - 8f) * (num2 - 8f) * 0.72f) - 30f); if (num2 > -17f && num4 < 2.2f) { array[i * 96 + j] = val2; } if (Mathf.Abs(num) + Mathf.Abs(num2 + 22f) * 0.72f < 18f) { array[i * 96 + j] = definition.Color; } } } } val.SetPixels(array); val.Apply(false, true); Object.DontDestroyOnLoad((Object)(object)val); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 96f, 96f), new Vector2(0.5f, 0.5f), 96f); ((Object)obj).name = "MuckReplayable_Accessory_" + definition.Name + " Sprite"; Object.DontDestroyOnLoad((Object)(object)obj); return obj; } } internal static class AccessoryState { internal static string Ring { get; private set; } internal static string Necklace { get; private set; } internal static bool Equip(ReplayableAccessory accessory) { if (accessory == null) { return false; } if (accessory.Slot == AccessorySlot.Ring) { if (!string.IsNullOrEmpty(Ring)) { return false; } Ring = accessory.Name; } else { if (!string.IsNullOrEmpty(Necklace)) { return false; } Necklace = accessory.Name; } PlayerStatus instance = PlayerStatus.Instance; if (instance != null) { instance.UpdateStats(); } AccessoryNetwork.SendLocalState(); return true; } internal static bool Has(AccessoryEffect effect) { return Equipped().Any((ReplayableAccessory value) => value.Effect == effect); } internal static float Value(AccessoryEffect effect, int[] playerPowerups = null) { if (playerPowerups != null) { return AccessoryNetwork.ValueForPowerups(effect, playerPowerups); } return (from value in Equipped() where value.Effect == effect select value).Sum((ReplayableAccessory value) => value.Value); } internal static void Reset() { Ring = null; Necklace = null; } internal static void Import(string ring, string necklace) { ReplayableAccessory replayableAccessory = AccessoryRegistry.FindDefinition(ring); ReplayableAccessory replayableAccessory2 = AccessoryRegistry.FindDefinition(necklace); Ring = ((replayableAccessory != null && replayableAccessory.Slot == AccessorySlot.Ring) ? replayableAccessory.Name : null); Necklace = ((replayableAccessory2 != null && replayableAccessory2.Slot == AccessorySlot.Necklace) ? replayableAccessory2.Name : null); } private static IEnumerable<ReplayableAccessory> Equipped() { ReplayableAccessory replayableAccessory = AccessoryRegistry.FindDefinition(Ring); ReplayableAccessory necklace = AccessoryRegistry.FindDefinition(Necklace); if (replayableAccessory != null) { yield return replayableAccessory; } if (necklace != null) { yield return necklace; } } } internal static class AccessoryNetwork { private sealed class Equipment { internal string Ring; internal string Necklace; } internal const int RequestPacketId = 236; internal const int SyncPacketId = 237; private static readonly Dictionary<int, Equipment> Players = new Dictionary<int, Equipment>(); private static readonly MethodInfo ClientSendTcp = AccessTools.Method(typeof(ClientSend), "SendTCPData", new Type[1] { typeof(Packet) }, (Type[])null); private static readonly MethodInfo ServerSendAll = AccessTools.Method(typeof(ServerSend), "SendTCPDataToAll", new Type[1] { typeof(Packet) }, (Type[])null); internal static void Reset() { Players.Clear(); } internal static void Remove(int playerId) { Players.Remove(playerId); } internal static void SendLocalState() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if ((Object)(object)LocalClient.instance == (Object)null || (Object)(object)GameManager.instance == (Object)null) { return; } int myId = LocalClient.instance.myId; if (LocalClient.serverOwner) { SetServer(myId, AccessoryState.Ring, AccessoryState.Necklace); return; } Packet val = new Packet(236); try { val.Write(AccessoryState.Ring ?? string.Empty); val.Write(AccessoryState.Necklace ?? string.Empty); ClientSendTcp?.Invoke(null, new object[1] { val }); } finally { ((IDisposable)val)?.Dispose(); } } internal static void ReceiveRequest(int fromClient, Packet packet) { try { SetServer(fromClient, packet.ReadString(true), packet.ReadString(true)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Rejected accessory state: " + ex.Message)); } } private static void SetServer(int playerId, string requestedRing, string requestedNecklace) { if (Server.clients != null && Server.clients.TryGetValue(playerId, out var value) && value?.player != null) { Players.TryGetValue(playerId, out var value2); string text = Valid(requestedRing, AccessorySlot.Ring); string text2 = Valid(requestedNecklace, AccessorySlot.Necklace); if (!string.IsNullOrEmpty(value2?.Ring) && value2.Ring != text) { text = value2.Ring; } if (!string.IsNullOrEmpty(value2?.Necklace) && value2.Necklace != text2) { text2 = value2.Necklace; } Equipment equipment = new Equipment { Ring = text, Necklace = text2 }; Players[playerId] = equipment; Broadcast(playerId, equipment); } } private static string Valid(string name, AccessorySlot slot) { ReplayableAccessory replayableAccessory = AccessoryRegistry.FindDefinition(name); if (replayableAccessory == null || replayableAccessory.Slot != slot) { return string.Empty; } return replayableAccessory.Name; } private static void Broadcast(int playerId, Equipment state) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Packet val = new Packet(237); try { val.Write(playerId); val.Write(state.Ring ?? string.Empty); val.Write(state.Necklace ?? string.Empty); ServerSendAll?.Invoke(null, new object[1] { val }); Apply(playerId, state.Ring, state.Necklace); } finally { ((IDisposable)val)?.Dispose(); } } internal static void ReceiveSync(Packet packet) { try { Apply(packet.ReadInt(true), packet.ReadString(true), packet.ReadString(true)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Rejected accessory sync: " + ex.Message)); } } private static void Apply(int playerId, string ring, string necklace) { Players[playerId] = new Equipment { Ring = Valid(ring, AccessorySlot.Ring), Necklace = Valid(necklace, AccessorySlot.Necklace) }; if ((Object)(object)LocalClient.instance != (Object)null && playerId == LocalClient.instance.myId) { AccessoryState.Import(ring, necklace); PlayerStatus instance = PlayerStatus.Instance; if (instance != null) { instance.UpdateStats(); } } } internal static float ValueForPowerups(AccessoryEffect effect, int[] playerPowerups) { if (playerPowerups == null || Server.clients == null) { return 0f; } foreach (KeyValuePair<int, Client> client in Server.clients) { if (client.Value?.player?.powerups != null && client.Value.player.powerups == playerPowerups && Players.TryGetValue(client.Key, out var value)) { ReplayableAccessory replayableAccessory = AccessoryRegistry.FindDefinition(value.Ring); ReplayableAccessory replayableAccessory2 = AccessoryRegistry.FindDefinition(value.Necklace); float num = ((replayableAccessory != null && replayableAccessory.Effect == effect) ? replayableAccessory.Value : 0f); if (replayableAccessory2 != null && replayableAccessory2.Effect == effect) { num += replayableAccessory2.Value; } return num; } } return 0f; } internal static float ValueForPlayer(AccessoryEffect effect, int playerId) { if ((Object)(object)LocalClient.instance != (Object)null && playerId == LocalClient.instance.myId) { return AccessoryState.Value(effect); } if (!Players.TryGetValue(playerId, out var value)) { return 0f; } ReplayableAccessory replayableAccessory = AccessoryRegistry.FindDefinition(value.Necklace); if (replayableAccessory == null || replayableAccessory.Effect != effect) { return 0f; } return replayableAccessory.Value; } } internal sealed class AccessoryHud : MonoBehaviour { private GUIStyle title; private GUIStyle text; private void OnGUI() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) InventoryUI instance = InventoryUI.Instance; if (!((Object)(object)instance == (Object)null) && ((Component)instance).gameObject.activeInHierarchy && !((Object)(object)instance.backDrop == (Object)null) && instance.backDrop.activeInHierarchy) { EnsureStyles(); float num = 270f; Rect val = default(Rect); ((Rect)(ref val))..ctor((float)Screen.width - num - 24f, 24f, num, 104f); GUI.Box(val, GUIContent.none); GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 8f, num - 24f, 24f), "PERMANENT ACCESSORIES", title); DrawSlot(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 38f, num - 24f, 25f), "Ring", AccessoryState.Ring); DrawSlot(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 67f, num - 24f, 25f), "Necklace", AccessoryState.Necklace); } } private void DrawSlot(Rect rect, string slot, string equipped) { //IL_0000: 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) GUI.Box(rect, GUIContent.none); GUI.Label(new Rect(((Rect)(ref rect)).x + 8f, ((Rect)(ref rect)).y + 2f, ((Rect)(ref rect)).width - 16f, ((Rect)(ref rect)).height - 4f), slot + ": " + (string.IsNullOrEmpty(equipped) ? "Empty — right-click an accessory" : equipped), text); } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_004e: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (title == null) { title = new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; title.normal.textColor = new Color(1f, 0.72f, 0.25f); text = new GUIStyle(GUI.skin.label) { fontSize = 12, alignment = (TextAnchor)3 }; text.normal.textColor = Color.white; } } } [HarmonyPatch(typeof(ItemManager), "InitAllItems")] [HarmonyPriority(0)] internal static class AccessoryItemRegistrationPatch { private static void Postfix(ItemManager __instance) { AccessoryRegistry.Install(__instance); } } [HarmonyPatch(typeof(CraftingUI), "Awake")] internal static class AccessoryCraftingAwakePatch { private static void Postfix(CraftingUI __instance) { AccessoryRegistry.InjectCrafting(__instance); } } [HarmonyPatch(typeof(CraftingUI), "Start")] internal static class AccessoryCraftingStartPatch { private static void Postfix(CraftingUI __instance) { AccessoryRegistry.InjectCrafting(__instance); } } [HarmonyPatch(typeof(CraftingUI), "UpdateCraftables")] internal static class AccessoryCraftingRefreshPatch { private static void Prefix(CraftingUI __instance) { AccessoryRegistry.InjectCrafting(__instance); } } [HarmonyPatch(typeof(InventoryCell), "OnPointerDown")] internal static class PermanentAccessoryEquipPatch { private static bool Prefix(InventoryCell __instance, PointerEventData eventData) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || eventData == null || (int)eventData.button != 1 || (int)__instance.cellType != 0 || (Object)(object)InventoryUI.Instance == (Object)null || InventoryUI.Instance.HoldingItem() || !AccessoryRegistry.TryGet(__instance.currentItem, out var accessory)) { return true; } if (!AccessoryState.Equip(accessory)) { Notify("Your " + accessory.Slot.ToString().ToLowerInvariant() + " slot is permanent and already occupied."); return false; } __instance.RemoveItem(); Hotbar instance = Hotbar.Instance; if (instance != null) { instance.UpdateHotbar(); } Notify("Equipped " + accessory.Name + " permanently: " + accessory.EffectText + "."); return false; } private static void Notify(string message) { ReforgedRuntime.Instance?.Notify(message, 5f); try { ChatBox instance = ChatBox.Instance; if (instance != null) { instance.AppendMessage(-1, "<color=orange>[Accessory]</color> " + message, string.Empty); } } catch { } } } internal static class AccessoryDefensePatch { [HarmonyPatch(typeof(PowerupInventory), "GetDefenseMultiplier")] [HarmonyPostfix] private static void Apply(int[] playerPowerups, ref float __result) { __result = Mathf.Min(90f, __result + AccessoryState.Value(AccessoryEffect.Defense, playerPowerups)); } } [HarmonyPatch(typeof(PowerupInventory), "GetAttackSpeedMultiplier")] internal static class AccessoryAttackSpeedPatch { [HarmonyPriority(0)] private static void Postfix(int[] playerPowerups, ref float __result) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 __result *= 1f + AccessoryState.Value(AccessoryEffect.Haste, playerPowerups); if (playerPowerups == null && (Object)(object)UseInventory.Instance != (Object)null && (Object)(object)Hotbar.Instance?.currentItem != (Object)null) { InventoryItem currentItem = Hotbar.Instance.currentItem; if ((int)currentItem.type != 9 && (int)currentItem.tag != 2) { float num = (float)AccessTools.Field(typeof(UseInventory), "attackTime").GetValue(UseInventory.Instance); bool haste = AccessoryState.Value(AccessoryEffect.Haste) > 0f; bool juice = ArtifactBalance.JuiceSpeedMultiplier(PowerupInventory.Instance) > 1.01f; __result = Mathf.Min(__result, AccessoryCombatRules.AttacksPerSecond(haste, juice) * Mathf.Max(0.01f, num) / Mathf.Max(0.01f, currentItem.attackSpeed)); } } } } [HarmonyPatch(typeof(PowerupInventory), "GetSpeedMultiplier")] internal static class AccessoryMovementPatch { private static void Postfix(int[] playerPowerups, ref float __result) { __result *= 1f + AccessoryState.Value(AccessoryEffect.Swiftness, playerPowerups); } } [HarmonyPatch(typeof(PowerupInventory), "GetLootMultiplier")] internal static class AccessoryLootPatch { private static void Postfix(int[] playerPowerups, ref float __result) { if (AccessoryCombatRules.Harvesting) { __result *= 1f + AccessoryState.Value(AccessoryEffect.Fortune, playerPowerups); } } } [HarmonyPatch(typeof(Server), "InitializeServerPackets")] internal static class AccessoryServerPacketPatch { private static void Postfix() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (Server.PacketHandlers != null) { Server.PacketHandlers[236] = new PacketHandler(AccessoryNetwork.ReceiveRequest); } } } [HarmonyPatch(typeof(LocalClient), "InitializeClientData")] internal static class AccessoryClientPacketPatch { private static void Postfix() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (LocalClient.packetHandlers != null) { LocalClient.packetHandlers[237] = new PacketHandler(AccessoryNetwork.ReceiveSync); } } } [HarmonyPatch(typeof(ServerHandle), "DisconnectPlayer", new Type[] { typeof(int) })] internal static class AccessoryDisconnectPatch { private static void Postfix(int fromClient) { AccessoryNetwork.Remove(fromClient); } } public sealed class AggroController : MonoBehaviour { private enum AggroState { Idle, Chasing, Searching, Returning } private Mob _mob; private Vector3 _homePosition; private Vector3 _lastSeenPosition; private int _currentPlayerId = -1; private float _lastSeenAt = float.NegativeInfinity; private float _farSince = -1f; private float _returnStartedAt = float.NegativeInfinity; private float _nextBlockingBuildScanAt; private Transform _cachedBlockingBuild; private int _lineOfSightFrame = -1; private int _lineOfSightPlayerId = -1; private bool _lineOfSightResult; private AggroState _state; private bool IsBoss { get { if ((Object)(object)_mob != (Object)null && (Object)(object)_mob.mobType != (Object)null) { return _mob.mobType.boss; } return false; } } private bool IsRanged { get { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 if ((Object)(object)_mob != (Object)null && (Object)(object)_mob.mobType != (Object)null) { if (!_mob.mobType.ranged) { return (int)_mob.mobType.behaviour == 2; } return true; } return false; } } private void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) _mob = ((Component)this).GetComponent<Mob>(); _homePosition = ((Component)this).transform.position; _lastSeenPosition = _homePosition; _state = AggroState.Idle; } internal void MarkDamagedBy(int playerId) { //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 (TryGetLivingPlayer(playerId, out var player)) { _currentPlayerId = playerId; _lastSeenPosition = ((Component)player).transform.position; _lastSeenAt = Time.time; _farSince = -1f; _state = AggroState.Chasing; SetPlayerTarget(player); } } internal Vector3 GetNextDestination() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mob == (Object)null || (Object)(object)_mob.mobType == (Object)null) { return Vector3.zero; } if ((_mob.IsAttacking() && _mob.stopOnAttack) || _mob.knocked || !_mob.ready) { return Vector3.zero; } return (Vector3)(_state switch { AggroState.Idle => TickIdle(), AggroState.Chasing => TickChasing(), AggroState.Searching => TickSearching(), AggroState.Returning => TickReturning(), _ => Vector3.zero, }); } internal float GetNextThinkDelay() { float num; switch (_state) { case AggroState.Chasing: case AggroState.Searching: num = 0.5f; break; case AggroState.Returning: num = 1f; break; default: num = 0.75f; break; } return num + (float)Mathf.Abs(((Object)this).GetInstanceID() % 23) * 0.011f; } private Vector3 TickIdle() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) PlayerManager val = FindClosestVisiblePlayer(AcquireDistance()); if ((Object)(object)val == (Object)null) { ClearTarget(); return Vector3.zero; } BeginChasing(val); return DestinationFor(val); } private Vector3 TickChasing() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (!TryGetLivingPlayer(_currentPlayerId, out var player)) { BeginReturning(); return _homePosition; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position); float num2 = Vector3.Distance(_homePosition, ((Component)this).transform.position); if (num > DisengageDistance() || num2 > HomeLeashDistance()) { if (_farSince < 0f) { _farSince = Time.time; } else if (Time.time - _farSince >= Plugin.Settings.FarTargetGraceSeconds.Value) { BeginReturning(); return _homePosition; } } else { _farSince = -1f; } if (HasLineOfSight(player) || num <= Plugin.Settings.ProximityAcquireDistance.Value) { _lastSeenPosition = ((Component)player).transform.position; _lastSeenAt = Time.time; SetPlayerTarget(player); return DestinationFor(player); } _state = AggroState.Searching; ClearTarget(); return _lastSeenPosition; } private Vector3 TickSearching() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (TryGetLivingPlayer(_currentPlayerId, out var player)) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position); if (num <= AcquireDistance() && (num <= Plugin.Settings.ProximityAcquireDistance.Value || HasLineOfSight(player))) { BeginChasing(player); return DestinationFor(player); } } if (Time.time - _lastSeenAt <= LostSightSeconds()) { ClearTarget(); return _lastSeenPosition; } BeginReturning(); return _homePosition; } private Vector3 TickReturning() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) if (Vector3.Distance(((Component)this).transform.position, _homePosition) <= Plugin.Settings.ReturnArrivalDistance.Value) { _state = AggroState.Idle; _currentPlayerId = -1; _farSince = -1f; ClearTarget(); if ((Object)(object)_mob.agent != (Object)null && _mob.agent.isOnNavMesh) { _mob.agent.ResetPath(); } return Vector3.zero; } if (Time.time - _returnStartedAt >= Plugin.Settings.ReturnReacquireCooldown.Value) { PlayerManager val = FindClosestVisiblePlayer(AcquireDistance()); if ((Object)(object)val != (Object)null && Vector3.Distance(_homePosition, ((Component)val).transform.position) <= HomeLeashDistance()) { BeginChasing(val); return DestinationFor(val); } } ClearTarget(); return _homePosition; } private void BeginChasing(PlayerManager player) { //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) _state = AggroState.Chasing; _currentPlayerId = player.id; _lastSeenPosition = ((Component)player).transform.position; _lastSeenAt = Time.time; _farSince = -1f; SetPlayerTarget(player); } private void BeginReturning() { _state = AggroState.Returning; _returnStartedAt = Time.time; _currentPlayerId = -1; _farSince = -1f; ClearTarget(); } private Vector3 DestinationFor(PlayerManager player) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Settings.AttackBlockingBuildings.Value && TryFindBlockingBuild(player, out var result)) { _mob.target = result; _mob.targetPlayerId = -1; return result.position; } SetPlayerTarget(player); float num = Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position); if (num <= 12f || _mob.mobType.followPlayerAccuracy >= 0.999f) { return ((Component)player).transform.position; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Random.Range(-1f, 1f), 0f, Random.Range(-1f, 1f)); val *= num * (1f - _mob.mobType.followPlayerAccuracy); return ((Component)player).transform.position + val; } private bool TryFindBlockingBuild(PlayerManager player, out Transform result) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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) result = null; if (_mob.mobType.ignoreBuilds || HasLineOfSight(player) || (Object)(object)ResourceManager.Instance == (Object)null || ResourceManager.Instance.builds == null) { _cachedBlockingBuild = null; return false; } float value = Plugin.Settings.BuildingAttackDistance.Value; if ((Object)(object)_cachedBlockingBuild != (Object)null) { Vector3 val = _cachedBlockingBuild.position - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= value * value) { result = _cachedBlockingBuild; return true; } _cachedBlockingBuild = null; } if (Time.time < _nextBlockingBuildScanAt) { return false; } _nextBlockingBuildScanAt = Time.time + 2.1f + (float)Mathf.Abs(((Object)this).GetInstanceID() % 29) * 0.037f; float num = value; Vector3 val2 = ((Component)player).transform.position - ((Component)this).transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; foreach (KeyValuePair<int, GameObject> build in ResourceManager.Instance.builds) { GameObject value2 = build.Value; if (!((Object)(object)value2 == (Object)null)) { Vector3 val3 = value2.transform.position - ((Component)this).transform.position; float magnitude = ((Vector3)(ref val3)).magnitude; if (!(magnitude >= num) && !(Vector3.Dot(normalized, ((Vector3)(ref val3)).normalized) < 0.35f)) { num = magnitude; result = value2.transform; } } } _cachedBlockingBuild = result; return (Object)(object)result != (Object)null; } private PlayerManager FindClosestVisiblePlayer(float maxDistance) { //IL_0046: 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) if (GameManager.players == null) { return null; } PlayerManager result = null; float num = maxDistance; foreach (PlayerManager value in GameManager.players.Values) { if (!((Object)(object)value == (Object)null) && !value.dead && !value.disconnected) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)value).transform.position); if (!(num2 >= num) && (!(num2 > Plugin.Settings.ProximityAcquireDistance.Value) || HasLineOfSight(value))) { result = value; num = num2; } } } return result; } private bool HasLineOfSight(PlayerManager player) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if (CaveNetwork.IsInside(((Component)this).transform.position) && CaveNetwork.IsInside(((Component)player).transform.position)) { return true; } if (_lineOfSightFrame == Time.frameCount && _lineOfSightPlayerId == player.id) { return _lineOfSightResult; } Vector3 val = ((Component)this).transform.position + Vector3.up * 1.2f; Vector3 val2 = ((Component)player).transform.position + Vector3.up * 1.2f - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.01f) { return CacheLineOfSight(player.id, result: true); } int num = -5; if ((Object)(object)MobManager.Instance != (Object)null && ((LayerMask)(ref MobManager.Instance.whatIsRaycastable)).value != 0) { num = ((LayerMask)(ref MobManager.Instance.whatIsRaycastable)).value; } RaycastHit val3 = default(RaycastHit); if (!Physics.Raycast(val, ((Vector3)(ref val2)).normalized, ref val3, magnitude + 0.5f, num, (QueryTriggerInteraction)1)) { return CacheLineOfSight(player.id, result: true); } PlayerManager componentInParent = ((Component)((RaycastHit)(ref val3)).transform).GetComponentInParent<PlayerManager>(); return CacheLineOfSight(player.id, (Object)(object)componentInParent == (Object)(object)player); } private bool CacheLineOfSight(int playerId, bool result) { _lineOfSightFrame = Time.frameCount; _lineOfSightPlayerId = playerId; _lineOfSightResult = result; return result; } private bool TryGetLivingPlayer(int playerId, out PlayerManager player) { player = null; if (playerId < 0 || GameManager.players == null || !GameManager.players.TryGetValue(playerId, out player)) { return false; } if ((Object)(object)player != (Object)null && !player.dead) { return !player.disconnected; } return false; } private void SetPlayerTarget(PlayerManager player) { _mob.target = ((Component)player).transform; _mob.targetPlayerId = player.id; } private void ClearTarget() { _mob.target = null; _mob.targetPlayerId = -1; } private float AcquireDistance() { if (IsBoss) { return Plugin.Settings.BossAcquireDistance.Value; } if (!IsRanged) { return Plugin.Settings.MeleeAcquireDistance.Value; } return Plugin.Settings.RangedAcquireDistance.Value; } private float DisengageDistance() { if (IsBoss) { return Plugin.Settings.BossDisengageDistance.Value; } if (!IsRanged) { return Plugin.Settings.MeleeDisengageDistance.Value; } return Plugin.Settings.RangedDisengageDistance.Value; } private float HomeLeashDistance() { if (IsBoss) { return Plugin.Settings.BossHomeLeash.Value; } if (!IsRanged) { return Plugin.Settings.MeleeHomeLeash.Value; } return Plugin.Settings.RangedHomeLeash.Value; } private float LostSightSeconds() { if (IsBoss) { return Plugin.Settings.BossLostSightSeconds.Value; } if (!IsRanged) { return Plugin.Settings.MeleeLostSightSeconds.Value; } return Plugin.Settings.RangedLostSightSeconds.Value; } } [HarmonyPatch(typeof(MobServerEnemy), "FindNextPosition")] internal static class MobServerEnemyFindNextPositionPatch { private static bool Prefix(MobServerEnemy __instance, ref Vector3 __result) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || Plugin.Settings == null || !Plugin.Settings.EnableAggro.Value) { return true; } AggroController aggroController = ((Component)__instance).GetComponent<AggroController>(); if ((Object)(object)aggroController == (Object)null) { aggroController = ((Component)__instance).gameObject.AddComponent<AggroController>(); } ((MonoBehaviour)__instance).Invoke("SyncFindNextPosition", aggroController.GetNextThinkDelay()); __result = aggroController.GetNextDestination(); return false; } } [HarmonyPatch(typeof(Hitable), "Damage")] internal static class HitableDamageAggroPatch { private static void Prefix(Hitable __instance, int newHp, int fromClient) { if ((Object)(object)__instance == (Object)null || Plugin.Settings == null || !Plugin.Settings.EnableAggro.Value || !LocalClient.serverOwner || newHp >= __instance.hp) { return; } HitableMob val = (HitableMob)(object)((__instance is HitableMob) ? __instance : null); if (!((Object)(object)val == (Object)null)) { AggroController aggroController = ((Component)val).GetComponent<AggroController>(); if ((Object)(object)aggroController == (Object)null) { aggroController = ((Component)val).gameObject.AddComponent<AggroController>(); } aggroController.MarkDamagedBy(fromClient); } } } [HarmonyPatch(typeof(Mob), "SetTarget")] internal static class MobSetTargetPatch { private static bool Prefix(Mob __instance, int targetId) { if ((Object)(object)__instance == (Object)null) { return false; } if ((Object)(object)__instance.agent != (Object)null && __instance.agent.isOnNavMesh && targetId >= 0 && GameManager.players != null && GameManager.players.TryGetValue(targetId, out var value) && (Object)(object)value != (Object)null) { __instance.targetPlayerId = targetId; __instance.target = ((Component)value).transform; return false; } __instance.targetPlayerId = -1; __instance.target = null; return false; } } internal static class ArmorAuditMode { internal static readonly bool Enabled; internal static readonly bool AutoExit; internal static readonly string OutputDirectory; internal static readonly int Seed; static ArmorAuditMode() { string[] commandLineArgs = Environment.GetCommandLineArgs(); Enabled = Array.Exists(commandLineArgs, (string value) => string.Equals(value, "-mr-armor-audit", StringComparison.OrdinalIgnoreCase)); AutoExit = Array.Exists(commandLineArgs, (string value) => string.Equals(value, "-mr-armor-audit-exit", StringComparison.OrdinalIgnoreCase)); OutputDirectory = FindValue(commandLineArgs, "-mr-armor-audit-output="); if (string.IsNullOrWhiteSpace(OutputDirectory)) { OutputDirectory = Path.Combine(Path.GetTempPath(), "MuckReplayable-ArmorAudit"); } if (!int.TryParse(FindValue(commandLineArgs, "-mr-armor-audit-seed="), out var result) || result == 0) { result = 948271; } Seed = result; } internal static void WriteFailure(string message) { if (!Enabled) { return; } try { Directory.CreateDirectory(OutputDirectory); File.WriteAllText(Path.Combine(OutputDirectory, "audit-failed.txt"), message ?? "Unknown armor audit failure"); } catch { } } private static string FindValue(string[] args, string prefix) { return Array.Find(args, (string argument) => argument?.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) ?? false)?.Substring(prefix.Length).Trim(new char[1] { '"' }); } } internal static class ArtifactBalance { private static readonly FieldInfo JuiceSpeed = AccessTools.Field(typeof(PowerupInventory), "juiceSpeed"); internal static int Stacks(int[] powerups, string name) { if (powerups == null && (Object)(object)PowerupInventory.Instance != (Object)null) { powerups = (int[])AccessTools.Field(typeof(PowerupInventory), "powerups")?.GetValue(PowerupInventory.Instance); } if (powerups == null || ItemManager.Instance?.stringToPowerupId == null || !ItemManager.Instance.stringToPowerupId.TryGetValue(name, out var value) || value < 0 || value >= powerups.Length) { return 0; } return Mathf.Max(0, powerups[value]); } internal static float Curve(int stacks, float speed, float maximum) { stacks = Mathf.Max(0, stacks); float num = PowerupInventory.CumulativeDistribution(Mathf.Min(stacks, 12), speed, maximum); if (stacks <= 12) { return num; } float num2 = PowerupInventory.CumulativeDistribution(1, speed, maximum); return num + (float)(stacks - 12) * num2 * 0.18f; } internal static float Defense(int stacks) { return PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.1f, 40f); } internal static float Dumbbell(int stacks) { return 1f + (float)Mathf.Max(0, stacks) * 0.1f; } internal static float Berserk(int stacks, float missingHp) { return 1f + (float)Mathf.Max(0, stacks) * Mathf.Clamp01(missingHp); } internal static float Stamina(int stacks) { return 1f + (float)Mathf.Max(0, stacks) * 0.15f; } internal static float Healing(int stacks) { return Mathf.Min(0.2f, (float)Mathf.Max(0, stacks) * 0.005f); } internal static float Resource(int stacks) { return 1f + PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.3f, 4f); } internal static float Loot(int stacks) { if (stacks > 0) { return 1f + Mathf.Min(1f, 0.2f + (float)Mathf.Max(0, stacks - 1) * 0.1f); } return 1f; } internal static float AttackSpeed(int stacks) { return 1f + (float)Mathf.Max(0, stacks) * 0.05f; } internal static float Hunger(int stacks) { return 1f - PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.2f, 0.5f); } internal static float Juice(int stacks) { if (stacks > 0) { return 1f + Mathf.Min(1.5f, 0.5f + (float)(stacks - 1) * 0.1f); } return 1f; } internal static float JuiceDuration(int stacks) { if (stacks > 0) { return Mathf.Min(3f, 2f + (float)(stacks - 1) * 0.1f); } return 0f; } internal static float Robin(int stacks) { return 1f + PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.06f, 2f); } internal static float Speed(int stacks) { return 1f + (float)Mathf.Max(0, stacks) * 0.05f; } internal static float Adrenaline(int stacks) { if (stacks > 0) { return Mathf.Min(3f, 2f + (float)stacks * 0.1f); } return 1f; } internal static float Crit(int stacks) { return 0.14f + (float)Mathf.Max(0, stacks) * 0.1f; } internal static float Jump(int stacks) { return 1f + PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.075f, 2.5f); } internal static float Wings(int stacks) { if (stacks > 0) { return 1f + PowerupInventory.CumulativeDistribution(stacks, 0.45f, 2.5f); } return 1f; } internal static float Lifesteal(int stacks) { return Mathf.Min(0.8f, Curve(stacks, 0.11f, 0.35f)); } internal static float KnockbackChance(int stacks) { return PowerupInventory.CumulativeDistribution(Mathf.Max(0, stacks), 0.15f, 1f); } internal static float SniperChance(int stacks) { return Mathf.Min(0.1f, (float)Mathf.Max(0, stacks) * 0.01f); } internal static float SniperDamage(int stacks) { if (stacks > 0) { return 5f; } return 1f; } internal static float LightningChance(int stacks) { return Mathf.Min(0.2f, (float)Mathf.Max(0, stacks) * 0.02f); } internal static float LightningDamage(int stacks) { if (stacks > 0) { return Mathf.Min(3f, 2f + (float)(stacks - 1) * 0.1f); } return -1f; } internal static float Enforcer(int stacks, float speed) { if (stacks > 0) { return 1f + PowerupInventory.CumulativeDistribution(stacks, 0.4f, 2f) * Mathf.Clamp01(Mathf.Max(0f, speed) / 20f); } return 1f; } internal static int BonusHp(int stacks) { return Mathf.Clamp(stacks, 0, 50) * 10; } internal static int BonusShield(int stacks) { return Mathf.Clamp(stacks, 0, 50) * 10; } internal static int MaxStacks(string name) { switch (name) { case "Blue Pill": case "Red Pill": return 50; case "Broccoli": return 40; case "Sneaker": return 20; case "Orange Juice": return 40; case "Juice": return 11; case "Piggybank": return 9; case "Sniper Scope": return 10; case "Knuts Hammer": case "Knut's Hammer": return 10; default: return -1; } } internal static float JuiceSpeedMultiplier(PowerupInventory instance) { if (!((Object)(object)instance != (Object)null) || !(JuiceSpeed != null)) { return 1f; } return Mathf.Max(1f, (float)JuiceSpeed.GetValue(instance)); } internal static bool StartJuice(PowerupInventory instance) { if ((Object)(object)instance == (Object)null) { return false; } int num = Stacks(null, "Juice"); if (num <= 0) { return false; } JuiceSpeed?.SetValue(instance, Juice(num)); ((MonoBehaviour)instance).CancelInvoke("StopJuice"); ((MonoBehaviour)instance).Invoke("StopJuice", JuiceDuration(num)); return true; } internal static float LowHpRatio() { PlayerStatus instance = PlayerStatus.Instance; if (!((Object)(object)instance == (Object)null) && instance.maxHp > 0) { return ((float)instance.maxHp - instance.hp) / (float)instance.maxHp; } return 0f; } } [HarmonyPatch(typeof(PowerupInventory), "GetDefenseMultiplier")] internal static class BalancedDefenseArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { float num = ArtifactBalance.Defense(ArtifactBalance.Stacks(playerPowerups, "Danis Milk")) + MythicalArtifactService.AuxiliaryDefense(playerPowerups); __result = Mathf.Min(MythicalArtifactService.DefenseCap(playerPowerups), num); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetStrengthMultiplier")] internal static class BalancedStrengthArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { int num = ArtifactBalance.Stacks(playerPowerups, "Dumbbell"); int num2 = MythicalArtifactService.Stacks(playerPowerups, "Dumbbell") + ((AccessoryState.Value(AccessoryEffect.Strength, playerPowerups) > 0f) ? 1 : 0); float num3 = ((num2 > 0) ? (1f + (float)num * 0.125f * Mathf.Pow(2f, (float)num2)) : ArtifactBalance.Dumbbell(num)); __result = 1.3f * num3 * ArtifactBalance.Berserk(ArtifactBalance.Stacks(playerPowerups, "Berserk"), ArtifactBalance.LowHpRatio()); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetAttackSpeedMultiplier")] internal static class BalancedAttackSpeedArtifactPatch { private static bool Prefix(PowerupInventory __instance, int[] playerPowerups, ref float __result) { float num = (((Object)(object)PlayerStatus.Instance != (Object)null && PlayerStatus.Instance.adrenalineBoost) ? ArtifactBalance.Adrenaline(ArtifactBalance.Stacks(playerPowerups, "Adrenaline")) : 1f); float num2 = ArtifactBalance.AttackSpeed(ArtifactBalance.Stacks(playerPowerups, "Orange Juice")) * MythicalArtifactService.AttackSpeedBonus(playerPowerups) * num * ArtifactBalance.JuiceSpeedMultiplier(__instance) * MythicalArtifactService.AuxiliaryAttackSpeed(playerPowerups); __result = num2; return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetStaminaMultiplier")] internal static class BalancedStaminaArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { float num = (((Object)(object)PlayerStatus.Instance != (Object)null && PlayerStatus.Instance.adrenalineBoost) ? ArtifactBalance.Adrenaline(ArtifactBalance.Stacks(playerPowerups, "Adrenaline")) : 1f); __result = ArtifactBalance.Stamina(ArtifactBalance.Stacks(playerPowerups, "Peanut Butter")) * num * MythicalArtifactService.AuxiliaryStamina(playerPowerups); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetHealingMultiplier")] internal static class BalancedHealingArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Healing(ArtifactBalance.Stacks(playerPowerups, "Broccoli")) + MythicalArtifactService.AuxiliaryHealing(playerPowerups) - 1f; return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetResourceMultiplier")] internal static class BalancedResourceArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 __result = ArtifactBalance.Resource(ArtifactBalance.Stacks(playerPowerups, "Checkered Shirt")) * MythicalArtifactService.AuxiliaryEconomy(playerPowerups); if (WorldModifierState.Active.ResourceBounty) { __result *= 2f; } if (GameManager.gameSettings != null && (int)GameManager.gameSettings.gameMode == 1) { __result += 1.25f; } return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetLootMultiplier")] internal static class BalancedLootArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Loot(ArtifactBalance.Stacks(playerPowerups, "Piggybank")) * MythicalArtifactService.AuxiliaryEconomy(playerPowerups); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetSniperScopeMultiplier")] internal static class BalancedSniperArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { int num = ArtifactBalance.Stacks(playerPowerups, "Sniper Scope"); __result = ((num > 0 && Random.value < ArtifactBalance.SniperChance(num)) ? ArtifactBalance.SniperDamage(num) : 1f); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetSniperScopeDamageMultiplier")] internal static class BalancedSniperDamageArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.SniperDamage(ArtifactBalance.Stacks(playerPowerups, "Sniper Scope")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetLightningMultiplier")] internal static class BalancedLightningArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { int num = ArtifactBalance.Stacks(playerPowerups, "Knuts Hammer"); __result = ((num > 0 && Random.value < ArtifactBalance.LightningChance(num)) ? ArtifactBalance.LightningDamage(num) : (-1f)); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetHpMultiplier")] internal static class BalancedHpArtifactPatch { private static bool Prefix(int[] playerPowerups, ref int __result) { __result = ArtifactBalance.BonusHp(ArtifactBalance.Stacks(playerPowerups, "Red Pill")) + MythicalArtifactService.AuxiliaryMaxHp(playerPowerups); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetShield")] internal static class BalancedShieldArtifactPatch { private static bool Prefix(int[] playerPowerups, ref int __result) { __result = ArtifactBalance.BonusShield(ArtifactBalance.Stacks(playerPowerups, "Blue Pill")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetHungerMultiplier")] internal static class BalancedHungerArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Hunger(ArtifactBalance.Stacks(playerPowerups, "Spooo Bean")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetJuiceMultiplier")] internal static class BalancedJuiceArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Juice(ArtifactBalance.Stacks(playerPowerups, "Juice")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "StartJuice")] internal static class BalancedJuiceDurationPatch { private static bool Prefix(PowerupInventory __instance) { ArtifactBalance.StartJuice(__instance); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetRobinMultiplier")] internal static class BalancedRobinArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Robin(ArtifactBalance.Stacks(playerPowerups, "Robin Hood Hat")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetEnforcerMultiplier")] internal static class BalancedEnforcerArtifactPatch { private static bool Prefix(int[] playerPowerups, float speed, ref float __result) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) float num; if (!(speed >= 0f)) { PlayerMovement instance = PlayerMovement.Instance; if (instance == null) { num = 0f; } else { Vector3 velocity = instance.GetVelocity(); num = ((Vector3)(ref velocity)).magnitude; } } else { num = speed; } float speed2 = num; __result = ArtifactBalance.Enforcer(ArtifactBalance.Stacks(playerPowerups, "Enforcer"), speed2); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetSpeedMultiplier")] internal static class BalancedSpeedArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { float num = (((Object)(object)PlayerStatus.Instance != (Object)null && PlayerStatus.Instance.adrenalineBoost) ? ArtifactBalance.Adrenaline(ArtifactBalance.Stacks(playerPowerups, "Adrenaline")) : 1f); float num2 = PlayerStatus.Instance?.currentSpeedArmorMultiplier ?? 1f; float num3 = ArtifactBalance.Speed(ArtifactBalance.Stacks(playerPowerups, "Sneaker")) * num * num2 * MythicalArtifactService.AuxiliaryMoveSpeed(playerPowerups); MythicalArtifactService.Stacks(playerPowerups, "Sneaker"); __result = Mathf.Min(2f, num3); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetAdrenalineBoost")] internal static class BalancedAdrenalineArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Adrenaline(ArtifactBalance.Stacks(playerPowerups, "Adrenaline")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetCritChance")] internal static class BalancedCritArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { float num = ArtifactBalance.Crit(ArtifactBalance.Stacks(playerPowerups, "Horseshoe")) + MythicalArtifactService.CritBonus(playerPowerups); __result = Mathf.Min(MythicalArtifactService.CritCap(playerPowerups), num); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetJumpMultiplier")] internal static class BalancedJumpArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Jump(ArtifactBalance.Stacks(playerPowerups, "Jetpack")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetExtraJumps")] internal static class BalancedFrogArtifactPatch { private static bool Prefix(int[] playerPowerups, ref int __result) { __result = ArtifactBalance.Stacks(playerPowerups, "Janniks Frog"); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetFallWingsMultiplier")] internal static class BalancedWingsArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Wings(ArtifactBalance.Stacks(playerPowerups, "Wings of Glory")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetKnockbackMultiplier")] internal static class BalancedBulldozerArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ((Random.value < ArtifactBalance.KnockbackChance(ArtifactBalance.Stacks(playerPowerups, "Bulldozer"))) ? 1f : 0f); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetLifestealMultiplier")] internal static class BalancedLifestealArtifactPatch { private static bool Prefix(int[] playerPowerups, ref float __result) { __result = ArtifactBalance.Lifesteal(ArtifactBalance.Stacks(playerPowerups, "Crimson Dagger")); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetMaxDraculaStacks")] internal static class BalancedDraculaCapPatch { private static bool Prefix(ref int __result) { __result = (MythicalArtifactService.HasFang(null) ? int.MaxValue : (ArtifactBalance.Stacks(null, "Dracula") * 25)); return false; } } [HarmonyPatch(typeof(PowerupInventory), "GetHpIncreasePerKill")] internal static class DraculaFangHealingPatch { private static bool Prefix(int[] playerPowerups, ref int __result) { int num = ArtifactBalance.Stacks(playerPowerups, "Dracula"); __result = (MythicalArtifactService.HasFang(playerPowerups) ? Mathf.CeilToInt((float)num * 1.5f) : num); return false; } } internal sealed class ArtifactOffer { internal int ChestId; internal int PlayerId; internal int[] Choices; internal bool Mythical; internal float ExpiresAt; } internal static class ArtifactChoiceService { private sealed class DeterministicRoll { private uint state; internal DeterministicRoll(int seed) { state = ((seed == 0) ? 2738958700u : ((uint)seed)); } internal uint Next() { state ^= state << 13; state ^= state >> 17; state ^= state << 5; return state; } internal int Range(int max) { if (max > 1) { return (int)(Next() % (uint)max); } return 0; } internal float NextFloat() { return (float)(Next() & 0xFFFFFF) / 16777216f; } } internal const int ChoicePacketId = 240; private static readonly Dictionary<long, ArtifactOffer> ServerOffers = new Dictionary<long, ArtifactOffer>(); private static readonly MethodInfo SendTcp = AccessTools.Method(typeof(ClientSend), "SendTCPData", (Type[])null, (Type[])null); private static readonly FieldInfo PowerupsField = AccessTools.Field(typeof(PowerupInventory), "powerups"); internal static int[] GenerateChoices(LootContainerInteract chest, int playerId = -1) { if ((Object)(object)chest == (Object)null || (Object)(object)ItemManager.Instance == (Object)null) { return Array.Empty<int>(); } int[] array = (MythicalArtifactService.IsMythicalChest(chest) ? GenerateMythicalChoices(chest.GetId(), playerId) : GenerateChoices(chest.GetId(), chest.white, chest.blue, chest.gold, playerId)); if (chest.testPowerup && (Object)(object)chest.powerupToTest != (Object)null && array.Length != 0 && ItemManager.Instance.allPowerups != null && ItemManager.Instance.allPowerups.ContainsKey(chest.powerupToTest.id)) { int id = chest.powerupToTest.id; if (IsAtCap(id, playerId)) { return array; } int num = Array.IndexOf(array, id); if (num > 0) { array[num] = array[0]; } array[0] = id; } return array; } private static int[] GenerateMythicalChoices(int chestId, int playerId) { List<int> list = (from id in MythicalArtifactService.GetMythicalChoiceIds() where !IsAtCap(id, playerId) select id).ToList(); if (list == null || list.Count == 0) { return Array.Empty<int>(); } DeterministicRoll deterministicRoll = new DeterministicRoll(GameManager.GetSeed() * 16777619 + chestId * 486187739 + 1597463007); List<int> list2 = new List<int>(Mathf.Min(3, list.Count)); while (list2.Count < Mathf.Min(3, list.Count)) { int item = list[deterministicRoll.Range(list.Count)]; if (!list2.Contains(item)) { list2.Add(item); } } return list2.ToArray(); } internal static int[] GenerateChoices(int chestId, float white, float blue, float gold, int playerId = -1) { Dictionary<int, Powerup> all = ItemManager.Instance?.allPowerups; if (all == null) { return Array.Empty<int>(); } List<int> list = (from pair in all where (Object)(object)pair.Value != (Object)null && !IsAtCap(pair.Key, playerId) select pair.Key into value orderby value select value).ToList(); if (list.Count == 0) { return Array.Empty<int>(); } List<int> white2 = list.Where((int id) => (int)all[id].tier == 0).ToList(); List<int> blue2 = list.Where((int id) => (int)all[id].tier == 1).ToList(); List<int> orange = list.Where((int id) => (int)all[id].tier == 2).ToList(); DeterministicRoll deterministicRoll = new DeterministicRoll(GameManager.GetSeed() * 486187739 + chestId * 16777619 + 219671); List<int> list2 = new List<int>(Mathf.Min(3, list.Count)); for (int num = 0; num < Mathf.Min(3, list.Count); num++) { int num2 = -1; for (int num3 = 0; num3 < 20; num3++) { if (num2 >= 0 && !list2.Contains(num2)) { break; } List<int> list3 = PickTier(deterministicRoll, white2, blue2, orange, white, blue, gold); if (list3.Count > 0) { num2 = list3[deterministicRoll.Range(list3.Count)]; } } if (num2 < 0 || list2.Contains(num2)) { num2 = -1; foreach (int item in list) { if (!list2.Contains(item)) { num2 = item; break; } } } if (num2 < 0) { break; } list2.Add(num2); } return list2.ToArray(); } private static List<int> PickTier(DeterministicRoll random, List<int> white, List<int> blue, List<int> orange, float whiteWeight, float blueWeight, float orangeWeight) { whiteWeight = ((white.Count > 0) ? Mathf.Max(0f, whiteWeight) : 0f); blueWeight = ((blue.Count > 0) ? Mathf.Max(0f, blueWeight) : 0f); orangeWeight = ((orange.Count > 0) ? Mathf.Max(0f, orangeWeight) : 0f); float num = whiteWeight + blueWeight + orangeWeight; if (num <= 0f) { whiteWeight = ((white.Count > 0) ? 1f : 0f); blueWeight = ((blue.Count > 0) ? 1f : 0f); orangeWeight = ((orange.Count > 0) ? 1f : 0f); num = whiteWeight + blueWeight + orangeWeight; } float num2 = random.NextFloat() * num; if (num2 < whiteWeight) { return white; } if (num2 < whiteWeight + blueWeight) { return blue; } return orange; } internal static bool RegisterServerOffer(LootContainerInteract chest, int fromClient) { if ((Object)(object)chest == (Object)null || fromClient < 0) { return false; } int[] array = GenerateChoices(chest, fromClient); if (array.Length == 0) { return false; } long[] array2 = (from pair in ServerOffers where pair.Value.PlayerId == fromClient select pair.Key).ToArray(); foreach (long key in array2) { ServerOffers.Remove(key); } ArtifactOffer artifactOffer = new ArtifactOffer { ChestId = chest.GetId(), PlayerId = fromClient, Choices = array, Mythical = MythicalArtifactService.IsMythicalChest(chest), ExpiresAt = Time.unscaledTime + 1800f }; ServerOffers[OfferKey(fromClient, artifactOffer.ChestId)] = artifactOffer; Plugin.Log.LogInfo((object)string.Format("Artifact offer chest={0}, player={1}, choices={2}", artifactOffer.ChestId, fromClient, string.Join(",", array))); return true; } internal static void RegisterRainbowOffer(int chestId, int playerId, int[] choices) { long[] array = (from pair in ServerOffers where pair.Value.PlayerId == playerId select pair.Key).ToArray(); foreach (long key in array) { ServerOffers.Remove(key); } ServerOffers[OfferKey(playerId, chestId)] = new ArtifactOffer { ChestId = chestId, PlayerId = playerId, Choices = choices, ExpiresAt = Time.unscaledTime + 1800f }; } internal static void Reset() { ServerOffers.Clear(); } internal static void ForgetPlayer(int playerId) { long[] array = (from pair in ServerOffers where pair.Value.PlayerId == playerId select pair.Key).ToArray(); foreach (long key in array) { ServerOffers.Remove(key); } } internal static void SubmitChoice(int chestId, int powerupId) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if ((Object)(object)LocalClient.instance == (Object)null) { return; } if (LocalClient.serverOwner) { HandleChoice(LocalClient.instance.myId, chestId, powerupId); return; } try { Packet val = new Packet(240); try { val.Write(chestId); val.Write(powerupId); SendTcp?.Invoke(null, new object[1] { val }); } finally { ((IDisposable)val)?.Dispose(); } } catch (Exception ex) { Plugin.Log.LogError((object)("Could not send artifact choice: " + ex)); } } internal static void HandleChoicePacket(int fromClient, Packet packet) { try { HandleChoice(fromClient, packet.ReadInt(true), packet.ReadInt(true)); } catch (Exception ex) { Plugin.Log.LogWarning((object)$"Rejected malformed artifact choice from {fromClient}: {ex.Message}"); } } private static void HandleChoice(int fromClient, int chestId, int powerupId) { long key = OfferKey(fromClient, chestId); Client value2; Powerup value3; if (!ServerOffers.TryGetValue(key, out var value) || value.ExpiresAt < Time.unscaledTime || value.Choices == null || !value.Choices.Contains(powerupId)) { Plugin.Log.LogWarning((object)$"Rejected unoffered artifact {powerupId} from player {fromClient}, chest {chestId}"); ServerOffers.Remove(key); } else if (Server.clients == null || !Server.clients.TryGetValue(fromClient, out value2) || value2?.player == null || ItemManager.Instance?.allPowerups == null || !ItemManager.Instance.allPowerups.TryGetValue(powerupId, out value3)) { ServerOffers.Remove(key); } else if (IsAtCap(powerupId, fromClient)) { Plugin.Log.LogWarning((object)$"Rejected capped artifact {powerupId} from player {fromClient}, chest {chestId}"); ServerOffers.Remove(key); } else { ServerOffers.Remove(key); Grant(fromClient, value2.player, value3, value.Mythical); } } private static void Grant(int fromClient, Player serverPlayer, Powerup powerup, bool mythical) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) PlayerManager value; Vector3 val = ((GameManager.players != null && GameManager.players.TryGetValue(fromClient, out value) && (Object)(object)value != (Object)null) ? (((Component)value).transform.position + Vector3.up * 1.2f) : Vector3.zero); int nextId = ItemManager.Instance.GetNextId(); if (mythical) { MythicalArtifactService.RegisterDrop(nextId, powerup.id, broadcast: true); } ItemManager.Instance.DropPowerupAtPosition(powerup.id, val, nextId); ServerSend.DropPowerupAtPosition(powerup.id, nextId, val); if (serverPlayer.powerups != null && powerup.id >= 0 && powerup.id < serverPlayer.powerups.Length) { serverPlayer.powerups[powerup.id] += ((!mythical) ? 1 : 5); } if (mythical) { MythicalArtifactService.RegisterServerPickup(fromClient, powerup.id); } if ((Object)(object)GameManager.instance != (Object)null) { GameManager.instance.powerupsPickedup = true; } if (serverPlayer.stats != null) { serverPlayer.stats.TryGetValue("Powerups", out var value2); serverPlayer.stats["Powerups"] = value2 + 1; } if ((Object)(object)LocalClient.instance != (Object)null && fromClient == LocalClient.instance.myId && (Object)(object)PowerupInventory.Instance != (Object)null) { PowerupInventory.Instance.AddPowerup(powerup.name, powerup.id, nextId); if (mythical) { MythicalArtifactService.ApplyLocalPickup(powerup.id); } } ItemManager.Instance.PickupItem(nextId); ServerSend.PickupItem(fromClient, nextId); MythicalArtifactService.ForgetDrop(nextId); Plugin.Log.LogInfo((object)string.Format("Granted chosen {0}artifact {1} ({2}) to player {3}", mythical ? "mythical " : string.Empty, powerup.name, powerup.id, fromClient)); } internal static int CurrentStacks(int powerupId) { if ((Object)(object)PowerupInventory.Instance == (Object)null || PowerupsField == null) { return 0; } int[] array = (int[])PowerupsField.GetValue(PowerupInventory.Instance); if (array == null || powerupId < 0 || powerupId >= array.Length) { return 0; } return array[powerupId]; } internal static bool IsAtCap(int powerupId, int playerId = -1) { if (ItemManager.Instance?.allPowerups == null || !ItemManager.Instance.allPowerups.TryGetValue(powerupId, out var value) || (Object)(object)value == (Object)null) { return false; } string text = value.name ?? string.Empty; int num = MythicalArtifactService.MaxStacks(text); int num2 = ((playerId >= 0) ? MythicalArtifactService.ServerCount(playerId, powerupId) : MythicalArtifactService.Count(powerupId)); if (num > 0 && num2 >= num) { return true; } int num3 = ArtifactBalance.MaxStacks(text); if (num3 < 0) { return false; } return ((playerId >= 0) ? ServerStackCount(playerId, powerupId) : CurrentStacks(powerupId)) >= num3; } private static int ServerStackCount(int playerId, int powerupId) { if (Server.clients == null || !Server.clients.TryGetValue(playerId, out var value) || value?.player?.powerups == null || powerupId < 0 || powerupId >= value.player.powerups.Length) { return 0; } return Mathf.Max(0, value.player.powerups[powerupId]); } private static long OfferKey(int playerId, int chestId) { return ((long)playerId << 32) ^ (uint)chestId; } } internal sealed class ArtifactChoiceOverlay : MonoBehaviour { private static ArtifactChoiceOverlay instance; private int chestId; private Powerup[] choices; private CursorLockMode previousLock; private bool previousCursor; private bool previousInputActive; private bool inputCaptured; private GUIStyle titleStyle; private GUIStyle nameStyle; private GUIStyle bodyStyle; private GUIStyle tierStyle; private Vector2 compactScroll; private bool mythical; private float rainbowStarted = -1f; private int rainbowCost; private int rainbowWallet; private Powerup[] reelPool; private bool rainbowMode; private RainbowSlotAudio slotAudio; internal static void ShowRainbow(int id, int[] ids, int cost, int wallet) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("Muck Replayable Artifact Choice"); Object.DontDestroyOnLoad((Object)val); instance = val.AddComponent<ArtifactChoiceOverlay>(); } instance.Open(id, ids.Select((int value) => ItemManager.Instance.allPowerups[value]).ToArray(), isMythical: false); instance.rainbowStarted = Time.unscaledTime; instance.rainbowMode = true; instance.slotAudio = ((Component)instance).GetComponent<RainbowSlotAudio>() ?? ((Component)instance).gameObject.AddComponent<RainbowSlotAudio>(); instance.slotAudio.Begin(); instance.rainbowCost = cost; instance.rainbowWallet = wallet; instance.reelPool = ItemManager.Instance.allPowerups.Values.Where((Powerup value) => (Object)(object)value != (Object)null).ToArray(); } internal static void Show(LootContainerInteract chest) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown if ((Object)(object)chest == (Object)null || (Object)(object)ItemManager.Instance == (Object)null) { return; } int playerId = (((Object)(object)LocalClient.instance != (Object)null) ? LocalClient.instance.myId : (-1)); int[] array = ArtifactChoiceService.GenerateChoices(chest, playerId); if (array.Length == 0) { return; } if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("Muck Replayable Artifact Choice"); Object.DontDestroyOnLoad((Object)val); instance = val.AddComponent<ArtifactChoiceOverlay>(); } Dictionary<int, Powerup> allPowerups = ItemManager.Instance.allPowerups; if (allPowerups == null) { return; } List<Powerup> list = new List<Powerup>(Mathf.Min(3, array.Length)); int[] array2 = array; foreach (int key in array2) { if (!allPowerups.TryGetValue(key, out var value) || (Object)(object)value == (Object)null) { return; } list.Add(value); } instance.Open(chest.GetId(), list.ToArray(), MythicalArtifactService.IsMythicalChest(chest)); } private void Open(int id, Powerup[] offered, bool isMythical) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (offered != null && offered.Length != 0 && offered.Length <= 3 && !offered.Any((Powerup powerup) => (Object)(object)powerup == (Object)null)) { if (!inputCaptured) { previousLock = Cursor.lockState; previousCursor = Cursor.visible; previousInputActive = (Object)(object)PlayerInput.Instance != (Object)null && PlayerInput.Instance.active; inputCaptured = true; } chestId = id; slotAudio?.End(); choices = offered; mythical = isMythical; rainbowStarted = -1f; rainbowMode = false; compactScroll = Vector2.zero; UiOverlayInputBlocker.SetBlocked(925111, blocked: true); if ((Object)(object)PlayerInput.Instance != (Object)null) { PlayerInput.Instance.active = false; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private void Update() { if (choices != null && (Object)(object)GameManager.instance == (Object)null) { Close(); } else if (choices != null && (Object)(object)PlayerInput.Instance != (Object)null && PlayerInput.Instance.active) { PlayerInput.Instance.active = false; } } private void OnGUI() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: 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_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) if (choices == null || choices.Length == 0) { return; } Powerup[] array = choices; LocalizationService.ApplyGuiFont(); ReforgedGuiTheme.Ensure(); EnsureStyles(); GUI.depth = -2000; ReforgedGuiTheme.DrawDim(); float num = Mathf.Min(Mathf.Max(220f, (float)Screen.width - 24f), 1280f); float num2 = Mathf.Min(Mathf.Max(190f, (float)Screen.height - 24f), 690f); Rect val = default(Rect); ((Rect)(ref val))..ctor(((float)Screen.width - num) * 0.5f, ((float)Screen.height - num2) * 0.5f, num, num2); GUI.Box(val, GUIContent.none, ReforgedGuiTheme.Window); bool flag = rainbowMode; float num3 = ((rainbowStarted >= 0f) ? (Time.unscaledTime - rainbowStarted) : (-1f)); float num4 = (flag ? 140f : 92f); float num5 = ((Rect)(ref val)).width - 40f; GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 18f, ((Rect)(ref val)).width - 48f, 44f), flag ? "RAINBOW CHEST" : Header(), titleStyle); if (flag) { RainbowSlotPresentation.Lamps(val, num3); int num6 = ((num3 >= 0f && num3 < 2.65f) ? RainbowChestRules.RollCost(rainbowWallet, (uint)(num3 * 17321f)) : rainbowCost); string text = ((num3 < 2.65f) ? ("COST " + num6.ToString("N0") + " GOLD • ROLLING") : ("PAID " + rainbowCost.ToString("N0") + " GOLD")); GUI.Box(new Rect(((Rect)(ref val)).x + 22f, ((Rect)(ref val)).y + 65f, num5 - 4f, 34f), GUIContent.none); GUI.Label(new Rect(((Rect)(ref val)).x + 28f, ((Rect)(ref val)).y + 69f, num5 - 16f, 28f), text, nameStyle); string text2 = ((num3 < 5.15f) ? "Reels slowing down..." : ("GOLD LEFT " + (rainbowWallet - rainbowCost).ToString("N0") + " • CHOOSE ONE ARTIFACT")); GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 106f, num5 - 8f, 30f), text2, bodyStyle); } else { GUI.Label(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 59f, ((Rect)(ref val)).width - 48f, 26f), Subtitle(), bodyStyle); } float num7 = 14f; if (((Rect)(ref val)).width < 760f || ((Rect)(ref val)).height < 430f) { Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 20f, ((Rect)(ref val)).y + num4, num5, Mathf.Max(70f, ((Rect)(ref val)).height - num4 - 20f)); float num8 = 260f; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(0f, 0f, Mathf.Max(180f, ((Rect)(ref val2)).width - 18f), num8 * (float)array.Length + num7 * (float)Mathf.Max(0, array.Length - 1)); compactScroll = GUI.BeginScrollView(val2, compactScroll, val3); for (int i = 0; i < array.Length; i++) { DrawCard(new Rect(0f, (float)i * (num8 + num7), ((Rect)(ref val3)).width, num8), array[i]); if (choices == null) { GUI.EndScrollView(); return; } } GUI.EndScrollView(); return; } float num9 = (num5 - num7 * (float)(array.Length - 1)) / (float)array.Length; Rect card = default(Rect); for (int j = 0; j < array.Length; j++) { ((Rect)(ref card))..ctor(((Rect)(ref val)).x + 20f + (float)j * (num9 + num7), ((Rect)(ref val)).y + num4, num9, ((Rect)(ref val)).height - num4 - 20f); DrawCard(card, array[j]); if (choices == null) { break; } } } private void DrawCard(Rect card, Powerup powerup) { //IL_007f: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00c1: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: