using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.Json; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Game.AI; using Game.Combat; using Game.Data; using Game.LevelOperations; using Game.PlayerOperations; using Game.UI; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using SaveSystem; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FrankMods")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Quest board, XP progression and unlockable equipment finishes for Inferno Protocol.")] [assembly: AssemblyFileVersion("0.5.0.0")] [assembly: AssemblyInformationalVersion("0.5.0+477d00f8c6e6102e4d9ad948d3169f90685e9781")] [assembly: AssemblyProduct("ContentPlus")] [assembly: AssemblyTitle("InfernoProtocol.FieldQuests")] [assembly: AssemblyVersion("0.5.0.0")] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.All)] internal sealed class NullableAttribute : Attribute { public NullableAttribute(byte value) { } public NullableAttribute(byte[] value) { } } [AttributeUsage(AttributeTargets.All)] internal sealed class NullableContextAttribute : Attribute { public NullableContextAttribute(byte value) { } } } namespace InfernoProtocol.FieldQuests { internal static class BoardHouseSite { internal static bool TryFind(out Vector3 position, out Vector3 facing, out string description) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_010a: 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) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: 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_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); val = (position = (facing = val)); description = "Waiting for the outdoor trader and porch"; foreach (TradeController item in Object.FindObjectsOfType()) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).GetComponentInParent() != (Object)null || (Object)(object)((Component)item).GetComponentInParent() != (Object)null) { continue; } Vector3 position2 = ((Component)item).transform.position; if ((Object)(object)Player.localPlayer == (Object)null || Player.isInMaze || !BoardSiteRules.IsOutdoorAnchor(position2.y - ((Component)Player.localPlayer).transform.position.y, Vector3.Distance(position2, ((Component)Player.localPlayer).transform.position))) { continue; } if (!TryHouse(position2, out var center, out var outward, out var landmark)) { description = $"Outdoor trader at {position2}; waiting for nearby house geometry"; continue; } val = Vector3.Cross(outward, Vector3.up); Vector3 normalized = ((Vector3)(ref val)).normalized; float num = BoardSiteRules.OppositeTraderOffset(Vector3.Dot(position2 - center, normalized)); float num2 = Vector3.Dot(position2 - center, outward); float[] array = new float[3] { 0.65f, 1f, 1.35f }; foreach (float num3 in array) { float[] array2 = new float[3] { 0f, 0.35f, 0.7f }; foreach (float num4 in array2) { float num5 = num + num4; if (BoardSiteRules.ClearsEntrance(num5)) { Vector3 candidate = center + normalized * num5 + outward * (num2 + num3); candidate.y = position2.y; if (TryGround(candidate, outward, out var feet)) { position = feet; facing = feet + outward; description = $"outdoor house front-right porch opposite trader at {position2}; {landmark}; house center={center}"; return true; } } } } description = "Outdoor porch found (" + landmark + "), but the marked side has no clear board footprint"; } return false; } private static bool TryHouse(Vector3 trader, out Vector3 center, out Vector3 outward, out string landmark) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0403: 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_0411: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) center = (outward = default(Vector3)); landmark = ""; HashSet hashSet = new HashSet(); float num = float.MaxValue; foreach (Collider item in (Il2CppArrayBase)(object)Physics.OverlapSphere(trader + Vector3.up, 12f, -5, (QueryTriggerInteraction)1)) { Transform val = ((Component)item).transform; while ((Object)(object)val != (Object)null) { if (hashSet.Add(((Object)val).GetInstanceID())) { string text = ((Object)val).name.ToLowerInvariant(); if ((text.Contains("house") || text.Contains("cabin") || text.Contains("building") || text.Contains("shop") || text.Contains("trade")) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val).GetComponentInParent() != (Object)null)) { bool flag = false; Bounds val2 = default(Bounds); foreach (Renderer componentsInChild in ((Component)val).GetComponentsInChildren()) { if (componentsInChild.enabled) { if (!flag) { val2 = componentsInChild.bounds; flag = true; } else { ((Bounds)(ref val2)).Encapsulate(componentsInChild.bounds); } } } if (flag && !(((Bounds)(ref val2)).size.y < 2.5f) && !(((Bounds)(ref val2)).size.y > 15f) && !(((Bounds)(ref val2)).size.x > 30f) && !(((Bounds)(ref val2)).size.z > 30f) && !(Mathf.Max(((Bounds)(ref val2)).size.x, ((Bounds)(ref val2)).size.z) < 4f)) { float num2 = Vector3.Distance(((Bounds)(ref val2)).ClosestPoint(trader), trader); if (!(num2 > 7f) && !(num2 >= num)) { Vector3 val3 = trader - ((Bounds)(ref val2)).center; val3.y = 0f; Vector3 forward = val.forward; forward.y = 0f; ((Vector3)(ref forward)).Normalize(); Vector3 right = val.right; right.y = 0f; ((Vector3)(ref right)).Normalize(); Vector3 val4 = ((Mathf.Abs(Vector3.Dot(val3, forward)) >= Mathf.Abs(Vector3.Dot(val3, right))) ? forward : right); if (!(((Vector3)(ref val4)).sqrMagnitude < 0.5f)) { if (Vector3.Dot(val4, val3) < 0f) { val4 = -val4; } center = ((Bounds)(ref val2)).center; center.y = trader.y; outward = val4; landmark = ((Object)val).name; num = num2; } } } } } val = val.parent; } } if (num < float.MaxValue) { return true; } foreach (HandledPhysicalDoor item2 in Object.FindObjectsOfType()) { if ((Object)(object)((Component)item2).GetComponentInParent() != (Object)null || (Object)(object)((Component)item2).GetComponentInParent() != (Object)null) { continue; } Vector3 val5; if (!((Object)(object)item2.objectRenderer != (Object)null)) { val5 = ((Component)item2).transform.position; } else { Bounds bounds = item2.objectRenderer.bounds; val5 = ((Bounds)(ref bounds)).center; } Vector3 val6 = val5; float num3 = Vector3.Distance(val6, trader); if (num3 > 9f || num3 >= num || Mathf.Abs(val6.y - trader.y) > 3f) { continue; } Vector3 val7 = ((Component)item2).transform.forward; val7.y = 0f; if (!(((Vector3)(ref val7)).sqrMagnitude < 0.1f)) { ((Vector3)(ref val7)).Normalize(); if (Vector3.Dot(val7, trader - val6) < 0f) { val7 = -val7; } center = val6; center.y = trader.y; outward = val7; landmark = "outdoor physical door " + ((Object)item2).name; num = num3; } } return num < float.MaxValue; } private static bool TryGround(Vector3 candidate, Vector3 outward, out Vector3 feet) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0130: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) feet = default(Vector3); List list = new List(); foreach (RaycastHit item in (Il2CppArrayBase)(object)Physics.RaycastAll(candidate + Vector3.up * 2.5f, Vector3.down, 6f, -5, (QueryTriggerInteraction)1)) { list.Add(item); } list.Sort((RaycastHit a, RaycastHit b) => Mathf.Abs(((RaycastHit)(ref a)).point.y - candidate.y).CompareTo(Mathf.Abs(((RaycastHit)(ref b)).point.y - candidate.y))); RaycastHit val3 = default(RaycastHit); foreach (RaycastHit item2 in list) { RaycastHit current2 = item2; if (!(((RaycastHit)(ref current2)).normal.y < 0.97f) && !(Mathf.Abs(((RaycastHit)(ref current2)).point.y - candidate.y) > 2.5f) && (!((Object)(object)((RaycastHit)(ref current2)).collider.attachedRigidbody != (Object)null) || ((RaycastHit)(ref current2)).collider.attachedRigidbody.isKinematic)) { Vector3 val = ((RaycastHit)(ref current2)).point + Vector3.up * 0.04f; Quaternion val2 = Quaternion.LookRotation(outward); if (!Physics.CheckBox(val + Vector3.up * 1.2f, new Vector3(1.08f, 1.14f, 0.4f), val2, -5, (QueryTriggerInteraction)1) && Physics.Raycast(val + outward * 1.4f + Vector3.up, Vector3.down, ref val3, 2f, -5, (QueryTriggerInteraction)1) && !(Mathf.Abs(((RaycastHit)(ref val3)).point.y - val.y) > 0.3f) && !Physics.CheckCapsule(((RaycastHit)(ref val3)).point + Vector3.up * 0.4f, ((RaycastHit)(ref val3)).point + Vector3.up * 1.5f, 0.32f, -5, (QueryTriggerInteraction)1)) { feet = val; return true; } } } return false; } } internal static class BoardPlacement { internal const float X = -23.165f; internal const float Y = 0.199f; internal const float Z = -20.094f; internal const float Yaw = 3.526f; } internal static class BoardSiteRules { internal static (float X, float Z) Offset(float outwardX, float outwardZ, float right, float front) { return (X: (0f - outwardZ) * right + outwardX * front, Z: outwardX * right + outwardZ * front); } internal static bool ClearsEntrance(float right) { return right - 1.08f >= 2f; } internal static bool IsOutdoorAnchor(float heightDifference, float distance) { if (Math.Abs(heightDifference) <= 12f) { return distance <= 100f; } return false; } internal static float OppositeTraderOffset(float traderSide) { return Math.Max(3.2f, Math.Abs(traderSide)); } } public static class FinishPattern { public readonly struct Ink { public readonly float R; public readonly float G; public readonly float B; public Ink(float r, float g, float b) { R = r; G = g; B = b; } } private static float Hash(int x, int y) { int num = x * 374761393 + y * 668265263; int num2 = (num ^ (num >>> 13)) * 1274126177; return (float)(uint)(num2 ^ (num2 >>> 16)) / 4.2949673E+09f; } private static float Noise(float x, float y) { int num = (int)MathF.Floor(x); int num2 = (int)MathF.Floor(y); float num3 = x - (float)num; float num4 = y - (float)num2; num3 = num3 * num3 * (3f - 2f * num3); num4 = num4 * num4 * (3f - 2f * num4); float num5 = Hash(num, num2) * (1f - num3) + Hash(num + 1, num2) * num3; float num6 = Hash(num, num2 + 1) * (1f - num3) + Hash(num + 1, num2 + 1) * num3; return num5 * (1f - num4) + num6 * num4; } private static float Frac(float x) { return x - MathF.Floor(x); } public static Ink Sample(int finish, float u, float v) { switch (finish) { case 1: { float num5 = Noise(u * 15f, v * 15f) * 0.7f + Noise(u * 37f, v * 37f) * 0.3f; if (!(num5 < 0.36f)) { if (!(num5 < 0.5f)) { if (!(num5 < 0.64f)) { return new Ink(0.68f, 0.65f, 0.43f); } return new Ink(0.43f, 0.49f, 0.25f); } return new Ink(0.22f, 0.32f, 0.13f); } return new Ink(0.08f, 0.12f, 0.07f); } case 2: { float num6 = Frac((u + v * 0.55f) * 9f); if (num6 < 0.055f) { return new Ink(0.82f, 0.91f, 0.94f); } if (Frac(v * 8f) < 0.04f) { return new Ink(0.09f, 0.16f, 0.23f); } if (!(num6 < 0.38f)) { return new Ink(0.025f, 0.08f, 0.18f); } return new Ink(0.09f, 0.32f, 0.65f); } case 3: { float num8 = u * 12f; float num9 = v * 12f; float num10 = 100f; float num11 = 100f; int num12 = (int)MathF.Floor(num8); int num13 = (int)MathF.Floor(num9); for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { float num14 = (float)(num12 + i) + Hash(num12 + i, num13 + j) - num8; float num15 = (float)(num13 + j) + Hash(num12 + i + 71, num13 + j + 39) - num9; float num16 = num14 * num14 + num15 * num15; if (num16 < num10) { num11 = num10; num10 = num16; } else if (num16 < num11) { num11 = num16; } } } float num17 = MathF.Sqrt(num11) - MathF.Sqrt(num10); if (!(num17 < 0.045f)) { if (!(num17 < 0.095f)) { return new Ink(0.065f, 0.05f, 0.045f); } return new Ink(0.42f, 0.065f, 0.02f); } return new Ink(0.96f, 0.38f, 0.06f); } case 4: { float num24 = Frac((u + v) * 14f); float num25 = Frac((u - v) * 14f); if (num24 < 0.065f || num25 < 0.065f) { return new Ink(0.75f, 0.56f, 0.24f); } if (num24 < 0.12f || num25 < 0.12f) { return new Ink(0.08f, 0.055f, 0.025f); } return new Ink(0.32f, 0.21f, 0.1f); } case 5: { float num22 = Noise(MathF.Floor(u * 48f) / 3f, MathF.Floor(v * 48f) / 3f); if (!(num22 < 0.35f)) { if (!(num22 < 0.51f)) { if (!(num22 < 0.66f)) { return new Ink(0.93f, 0.95f, 0.91f); } return new Ink(0.73f, 0.8f, 0.83f); } return new Ink(0.46f, 0.57f, 0.64f); } return new Ink(0.13f, 0.21f, 0.29f); } case 6: if (Frac(v * 6f) < 0.075f) { return new Ink(0.72f, 0.74f, 0.69f); } if (!(Frac((u + v) * 10f) < 0.48f)) { return new Ink(0.055f, 0.06f, 0.055f); } return new Ink(0.95f, 0.7f, 0.045f); case 7: { float num18 = Frac(u * 13f + MathF.Sin(v * 28f) * 0.24f + Noise(u * 9f, v * 19f) * 1.4f); if (!(num18 < 0.26f)) { if (!(num18 < 0.36f)) { return new Ink(0.62f, 0.3f, 0.085f); } return new Ink(0.84f, 0.68f, 0.35f); } return new Ink(0.06f, 0.045f, 0.025f); } case 8: { float num21 = Frac(u * 5f); if (num21 < 0.12f) { return new Ink(0.88f, 0.86f, 0.78f); } if (num21 < 0.31f) { if (((int)(u * 80f) + (int)(v * 80f)) % 2 != 0) { return new Ink(0.035f, 0.035f, 0.045f); } return new Ink(0.83f, 0.81f, 0.74f); } return new Ink(0.56f, 0.025f, 0.055f); } case 9: { float num23 = Frac(v * 12f + MathF.Sin(u * 25f) * 0.35f + MathF.Sin(u * 49f) * 0.1f); if (!(num23 < 0.1f)) { if (!(num23 < 0.39f)) { if (!(num23 < 0.52f)) { return new Ink(0.025f, 0.09f, 0.17f); } return new Ink(0.08f, 0.26f, 0.36f); } return new Ink(0.055f, 0.57f, 0.61f); } return new Ink(0.86f, 0.93f, 0.86f); } case 10: { float num7 = Frac((Noise(u * 7f, v * 7f) * 0.75f + Noise(u * 19f, v * 19f) * 0.25f) * 23f); if (!(num7 < 0.14f)) { if (!(num7 < 0.23f)) { return new Ink(0.055f, 0.15f, 0.12f); } return new Ink(0.29f, 0.44f, 0.3f); } return new Ink(0.78f, 0.84f, 0.55f); } case 11: { float num19 = Frac((u + v) * 18f); float num20 = Frac((u - v) * 18f); if (num19 < 0.16f) { if (!(num20 < 0.16f)) { return new Ink(0.53f, 0.36f, 0.12f); } return new Ink(0.91f, 0.72f, 0.3f); } if (num20 < 0.16f) { return new Ink(0.74f, 0.57f, 0.23f); } if (((int)(u * 100f) + (int)(v * 100f)) % 2 != 0) { return new Ink(0.11f, 0.025f, 0.18f); } return new Ink(0.22f, 0.055f, 0.31f); } case 12: { float num = u * 16f; float num2 = v * 16f; int num3 = (int)num; int y = (int)num2; float num4 = Hash(num3 * 2 + ((Frac(num) + Frac(num2) > 1f) ? 1 : 0), y); if (!(num4 < 0.25f)) { if (!(num4 < 0.5f)) { if (!(num4 < 0.75f)) { return new Ink(0.88f, 0.79f, 0.58f); } return new Ink(0.73f, 0.57f, 0.36f); } return new Ink(0.52f, 0.35f, 0.21f); } return new Ink(0.23f, 0.17f, 0.12f); } default: return new Ink(1f, 1f, 1f); } } } internal static class FinishTextures { internal static Texture2D Create(int finish, Texture source = null) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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_00ba: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(512, 512, (TextureFormat)4, true); RenderTexture val2 = null; RenderTexture active = RenderTexture.active; try { Color32[] array = null; if ((Object)(object)source != (Object)null) { val2 = RenderTexture.GetTemporary(512, 512, 0, (RenderTextureFormat)0); Graphics.Blit(source, val2); RenderTexture.active = val2; val.ReadPixels(new Rect(0f, 0f, 512f, 512f), 0, 0); array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)val.GetPixels32()); } Color32[] array2 = (Color32[])(object)new Color32[262144]; for (int i = 0; i < 512; i++) { for (int j = 0; j < 512; j++) { int num = i * 512 + j; FinishPattern.Ink ink = FinishPattern.Sample(finish, (float)j / 512f, (float)i / 512f); Color32 val3 = (Color32)((array == null) ? new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue) : array[num]); float num2 = ((array == null) ? 1f : (0.35f + 0.65f * ((float)(int)val3.r * 0.2126f + (float)(int)val3.g * 0.7152f + (float)(int)val3.b * 0.0722f) / 255f)); array2[num] = new Color32((byte)(ink.R * num2 * 255f), (byte)(ink.G * num2 * 255f), (byte)(ink.B * num2 * 255f), val3.a); } } val.SetPixels32(Il2CppStructArray.op_Implicit(array2)); val.Apply(true, true); ((Object)val).name = "FieldQuests_Finish_" + finish; ((Texture)val).wrapMode = (TextureWrapMode)(((Object)(object)source != (Object)null) ? ((int)source.wrapMode) : 0); ((Texture)val).filterMode = (FilterMode)2; return val; } catch { Object.Destroy((Object)(object)val); throw; } finally { RenderTexture.active = active; if ((Object)(object)val2 != (Object)null) { RenderTexture.ReleaseTemporary(val2); } } } internal static Texture2D Apply(Material material, int finish) { string text = (material.HasProperty("_BaseMap") ? "_BaseMap" : (material.HasProperty("_BaseColorMap") ? "_BaseColorMap" : (material.HasProperty("_MainTex") ? "_MainTex" : null))); if (text == null) { return null; } Texture2D val = Create(finish, material.GetTexture(text)); material.SetTexture(text, (Texture)(object)val); return val; } } internal sealed class QuestBoard : IDisposable { private readonly List _materials = new List(); internal GameObject Root { get; private set; } internal Vector3 Position => Root.transform.position; internal Vector3 CosmeticPosition => Root.transform.TransformPoint(new Vector3(1.65f, 0f, 0f)); internal string WaitingReason { get; private set; } = "Preparing the quest board"; internal bool Create(Vector3? hostPosition = null, float hostYaw = 0f) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Root != (Object)null) { return true; } Vector3 position = (Vector3)(((??)hostPosition) ?? new Vector3(-23.165f, 0.199f, -20.094f)); float num = (hostPosition.HasValue ? hostYaw : 3.526f); string text = (hostPosition.HasValue ? "host-selected location" : "saved ground position (no trader lookup)"); try { Root = new GameObject("FieldQuests_QuestBoard"); Root.layer = 2; Root.SetActive(false); Root.transform.position = position; Root.transform.rotation = Quaternion.Euler(0f, num, 0f); Build(); Root.SetActive(true); WaitingReason = ""; ManualLogSource logSource = QuestPlugin.LogSource; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Quest Board ready at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Position); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; static wood-and-paper board, no NPC model or animation."); } logSource.LogInfo(val); return true; } catch { Dispose(); throw; } } private void Build() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00b4: 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_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0126: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0493: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Expected O, but got Unknown //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_0689: Unknown result type (might be due to invalid IL or missing references) //IL_06ab: Unknown result type (might be due to invalid IL or missing references) //IL_06bf: Unknown result type (might be due to invalid IL or missing references) //IL_06f3: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Unknown result type (might be due to invalid IL or missing references) //IL_0745: Unknown result type (might be due to invalid IL or missing references) //IL_0788: Unknown result type (might be due to invalid IL or missing references) //IL_07eb: Unknown result type (might be due to invalid IL or missing references) //IL_07ff: Unknown result type (might be due to invalid IL or missing references) //IL_07b5: Unknown result type (might be due to invalid IL or missing references) Material material = Material(new Color(0.19f, 0.105f, 0.052f)); Material val = Material(new Color(0.32f, 0.205f, 0.11f)); Material val2 = Material(new Color(0.28f, 0.17f, 0.085f)); Material material2 = Material(new Color(0.08f, 0.1f, 0.105f)); Material val3 = Material(new Color(0.86f, 0.8f, 0.64f)); Material val4 = Material(new Color(0.75f, 0.79f, 0.72f)); Material val5 = Material(new Color(0.18f, 0.2f, 0.18f)); Material val6 = Material(new Color(0.3f, 0.57f, 0.49f)); Part("FinishCabinet", new Vector3(1.65f, 0.46f, 0f), new Vector3(0.68f, 0.92f, 0.44f), material); Part("FinishCounter", new Vector3(1.65f, 0.96f, 0f), new Vector3(0.82f, 0.09f, 0.57f), material2); Collider(new Vector3(1.65f, 0.5f, 0f), new Vector3(0.72f, 1f, 0.5f)); for (int i = 1; i < 5; i++) { Part("FinishSample", new Vector3(1.32f + (float)i * 0.13f, 1.08f, 0f), new Vector3(0.09f, 0.16f, 0.13f), Material(SkinVisuals.ColorFor(i))); } float[] array = new float[2] { -1f, 1f }; foreach (float num in array) { BoardText("FINISHES", new Vector3(1.65f, 0.73f, num * 0.227f), num, new Vector2(590f, 140f), 65f, new Color(0.94f, 0.9f, 0.77f)); } array = new float[2] { -0.88f, 0.88f }; foreach (float num2 in array) { Part("TimberPost", new Vector3(num2, 1.12f, 0f), new Vector3(0.16f, 2.24f, 0.18f), material); Part("PostFoot", new Vector3(num2, 0.15f, 0f), new Vector3(0.185f, 0.3f, 0.205f), material2); Collider(new Vector3(num2, 1.12f, 0f), new Vector3(0.16f, 2.24f, 0.18f)); } for (int k = 0; k < 6; k++) { Part("BackingPlank", new Vector3(0f, 0.89f + (float)k * 0.185f, 0f), new Vector3(1.64f, 0.18f, 0.1f), (k % 2 == 0) ? val : val2); } Part("LowerRail", new Vector3(0f, 0.76f, 0f), new Vector3(1.98f, 0.13f, 0.18f), material); Part("Header", new Vector3(0f, 2.055f, 0f), new Vector3(1.98f, 0.3f, 0.2f), material); Part("RainCap", new Vector3(0f, 2.245f, 0f), new Vector3(2.08f, 0.075f, 0.34f), material2); array = new float[2] { -0.78f, 0.78f }; foreach (float num3 in array) { Part("InsetSideTrim", new Vector3(num3, 1.38f, 0.07f), new Vector3(0.035f, 1.08f, 0.045f), material); } Collider(new Vector3(0f, 1.47f, 0f), new Vector3(1.8f, 1.5f, 0.2f)); array = new float[2] { 1f, -1f }; foreach (float num4 in array) { BoardText("QUEST BOARD", new Vector3(0f, 2.09f, num4 * 0.108f), num4, new Vector2(1740f, 160f), 105f, new Color(0.94f, 0.9f, 0.77f)); BoardText("FIELD ASSIGNMENTS", new Vector3(0f, 1.963f, num4 * 0.109f), num4, new Vector2(1600f, 70f), 38f, new Color(0.65f, 0.76f, 0.64f)); float[] array2 = new float[2] { -0.88f, 0.88f }; foreach (float num5 in array2) { float[] array3 = new float[2] { 0.76f, 2.055f }; foreach (float num6 in array3) { Part("IronFastener", new Vector3(num5, num6, num4 * 0.106f), new Vector3(0.042f, 0.042f, 0.016f), material2); } } for (int n = 0; n < 3; n++) { float num7 = (float)(n - 1) * 0.49f; GameObject val7 = new GameObject("PinnedNotice"); val7.layer = 2; val7.transform.SetParent(Root.transform, false); val7.transform.localPosition = new Vector3(num7, (n == 1) ? 0.025f : 0f, 0f); val7.transform.localRotation = Quaternion.Euler(0f, 0f, n switch { 2 => 1.2f, 0 => -1.5f, _ => 0f, }); Part("PostedAssignment", new Vector3(0f, 1.37f, num4 * 0.066f), new Vector3(0.415f, 0.64f, 0.014f), (n == 1) ? val4 : val3, val7.transform); Part("PaperPin", new Vector3(0f, 1.65f, num4 * 0.08f), new Vector3(0.027f, 0.027f, 0.013f), material2, val7.transform); Part("NoticeHeading", new Vector3(0f, 1.53f, num4 * 0.077f), new Vector3(0.29f, 0.045f, 0.009f), (n == 1) ? val6 : val5, val7.transform); for (int num8 = 0; num8 < 4; num8++) { Part("NoticeWriting", new Vector3(0f, 1.4f - (float)num8 * 0.064f, num4 * 0.077f), new Vector3((num8 == 3) ? 0.18f : ((num8 % 2 == 0) ? 0.29f : 0.24f), 0.009f, 0.008f), val5, val7.transform); } Part("RewardSeal", new Vector3(0.125f, 1.12f, num4 * 0.079f), new Vector3(0.055f, 0.055f, 0.012f), val6, val7.transform); } } } private Material Material(Color color) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) Shader obj = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default"); if ((Object)(object)obj == (Object)null) { throw new InvalidOperationException("Quest board shader unavailable."); } Material val = new Material(obj) { name = "FieldQuests_BoardMaterial", color = color }; if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", color); } if (val.HasProperty("_Smoothness")) { val.SetFloat("_Smoothness", 0.18f); } _materials.Add(val); return val; } private void Part(string name, Vector3 position, Vector3 size, Material material, Transform parent = null) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)obj).name = name; obj.layer = 2; obj.transform.SetParent(((Object)(object)parent != (Object)null) ? parent : Root.transform, false); obj.transform.localPosition = position; obj.transform.localScale = size; Collider component = obj.GetComponent(); component.enabled = false; Object.Destroy((Object)(object)component); Renderer component2 = obj.GetComponent(); component2.sharedMaterial = material; if (size.z < 0.04f) { component2.shadowCastingMode = (ShadowCastingMode)0; } } private void Collider(Vector3 center, Vector3 size) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) BoxCollider obj = Root.AddComponent(); obj.center = center; obj.size = size; } private void BoardText(string text, Vector3 position, float side, Vector2 size, float fontSize, Color color) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_007b: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_014e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("BoardTitle", (Type[])(object)new Type[2] { Il2CppType.Of(), Il2CppType.Of() }); val.transform.SetParent(Root.transform, false); val.layer = 2; val.GetComponent().renderMode = (RenderMode)2; RectTransform component = val.GetComponent(); component.sizeDelta = size; ((Transform)component).localPosition = position; ((Transform)component).localRotation = Quaternion.Euler(0f, (float)((side > 0f) ? 180 : 0), 0f); ((Transform)component).localScale = Vector3.one * 0.001f; GameObject val2 = new GameObject("Title", (Type[])(object)new Type[3] { Il2CppType.Of(), Il2CppType.Of(), Il2CppType.Of() }); val2.transform.SetParent((Transform)(object)component, false); val2.layer = 2; TextMeshProUGUI component2 = val2.GetComponent(); ((TMP_Text)component2).text = text; ((TMP_Text)component2).fontSize = fontSize; ((Graphic)component2).color = color; ((TMP_Text)component2).fontStyle = (FontStyles)1; ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).enableWordWrapping = false; ((Graphic)component2).raycastTarget = false; ((TMP_Text)component2).rectTransform.anchorMin = Vector2.zero; ((TMP_Text)component2).rectTransform.anchorMax = Vector2.one; ((TMP_Text)component2).rectTransform.offsetMin = Vector2.zero; ((TMP_Text)component2).rectTransform.offsetMax = Vector2.zero; } internal bool CanRead(bool cosmetics = false) { //IL_0036: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0065: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Root == (Object)null || (Object)(object)Player.mainCamera == (Object)null || (Object)(object)Player.localPlayer == (Object)null) { return false; } Vector3 val = (cosmetics ? CosmeticPosition : Position); if (Vector3.Distance(((Component)Player.localPlayer).transform.position, val) >= (cosmetics ? 2.1f : 3.8f)) { return false; } Vector3 val2 = val + Vector3.up * (cosmetics ? 1f : 1.4f); Vector3 position = ((Component)Player.mainCamera).transform.position; Vector3 val3 = val2 - position; val3.y = 0f; Vector3 forward = ((Component)Player.mainCamera).transform.forward; forward.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude > 0.25f && Vector3.Dot(((Vector3)(ref forward)).normalized, ((Vector3)(ref val3)).normalized) < 0.35f) { return false; } Vector3 val4 = val2 - position; foreach (RaycastHit item in (Il2CppArrayBase)(object)Physics.RaycastAll(position, ((Vector3)(ref val4)).normalized, ((Vector3)(ref val4)).magnitude, -5, (QueryTriggerInteraction)1)) { RaycastHit current = item; Transform transform = ((RaycastHit)(ref current)).transform; if (!((Object)(object)transform == (Object)null) && !transform.IsChildOf(Root.transform) && !transform.IsChildOf(((Component)Player.localPlayer).transform) && !transform.IsChildOf(((Component)Player.mainCamera).transform)) { return false; } } return true; } public void Dispose() { if ((Object)(object)Root != (Object)null) { Object.Destroy((Object)(object)Root); } foreach (Material material in _materials) { if ((Object)(object)material != (Object)null) { Object.Destroy((Object)(object)material); } } _materials.Clear(); Root = null; } } public sealed class QuestController : MonoBehaviour { private const string RequestChannel = "FrankMods.FieldQuests.Request.v1"; private const string ResponseChannel = "FrankMods.FieldQuests.Response.v1"; private NetworkManager _network; private CustomMessagingManager _messages; private HandleNamedMessageDelegate _requestHandler; private HandleNamedMessageDelegate _responseHandler; private Action _saveHandler; private readonly Dictionary _lastRequest = new Dictionary(); private readonly QuestBoard _board = new QuestBoard(); private QuestPanel _ui; private readonly SkinVisuals _skins = new SkinVisuals(); private bool _skinFailed; internal QuestService Service; private float _nextCheck; private float _nextPoll; private float _nextBoardAttempt; private float _nextHudPoll; private bool _failed; private bool _wasListening; private readonly QuestInteraction _talk = new QuestInteraction(); private float _nextSpawnWarning; private QuestBoardLocation _hostLocation; private string _placementStatus = "Preparing the quest board"; private PropertyInfo _carpetMounted; private bool _checkedCarpet; internal bool BlockingInput { get { if (_ui != null) { return _ui.BlockingInput; } return false; } } public QuestController(IntPtr ptr) : base(ptr) { } private void Update() { try { Tick(); } catch (Exception ex) { if (!_failed) { QuestPlugin.LogSource.LogError((object)("FieldQuests runtime: " + ex)); } _failed = true; _ui?.Dispose(); _ui = null; _talk.Dispose(); } } private void Tick() { //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Invalid comparison between Unknown and I4 //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_05bb: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= _nextCheck) { _nextCheck = Time.unscaledTime + 0.5f; NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening) { if (_wasListening) { Cleanup(); } return; } if (!Player.isLocalPlayerLoaded) { _ui?.Close(); _ui?.Tick(); if (!BlockingInput) { _talk.Release(); } return; } if ((Object)(object)_network != (Object)(object)singleton || !_wasListening) { Cleanup(); _network = singleton; _messages = singleton.CustomMessagingManager; _requestHandler = DelegateSupport.ConvertDelegate((Delegate)new Action(OnRequest)); _responseHandler = DelegateSupport.ConvertDelegate((Delegate)new Action(OnResponse)); _messages.RegisterNamedMessageHandler("FrankMods.FieldQuests.Request.v1", _requestHandler); _messages.RegisterNamedMessageHandler("FrankMods.FieldQuests.Response.v1", _responseHandler); _wasListening = true; QuestService.ValidateCatalog(); if (singleton.IsServer) { Service = new QuestService(); Service.Load(); _saveHandler = DelegateSupport.ConvertDelegate((Delegate)(Action)delegate { try { Service?.SaveWithWorld(); } catch (Exception ex3) { QuestPlugin.LogSource.LogError((object)("Quest save failed: " + ex3)); } }); SaveManager.onSaveComplete += _saveHandler; } _ui = new QuestPanel(Send); } } if (!_wasListening || _failed) { return; } if (!Player.isLocalPlayerLoaded || (Object)(object)Player.localPlayer == (Object)null) { _ui?.Close(); _ui?.Tick(); if (!BlockingInput) { _talk.Release(); } return; } if ((Object)(object)_board.Root == (Object)null && Time.unscaledTime >= _nextBoardAttempt) { _nextBoardAttempt = Time.unscaledTime + 3f; try { if (_network.IsServer) { _board.Create(); _placementStatus = _board.WaitingReason; } else { QuestBoardLocation hostLocation = _hostLocation; if (hostLocation != null && hostLocation.IsValid) { _board.Create((Vector3?)new Vector3(_hostLocation.X, _hostLocation.Y, _hostLocation.Z), _hostLocation.Yaw); _placementStatus = _board.WaitingReason; } else { _placementStatus = "Waiting for the host's quest board (host needs ContentPlus)"; SendText("FrankMods.FieldQuests.Request.v1", NetworkManager.ServerClientId, "locate:"); } } } catch (Exception ex) { _placementStatus = "Quest board could not be created; retrying (details in game log)"; if (Time.unscaledTime >= _nextSpawnWarning) { QuestPlugin.LogSource.LogWarning((object)("Quest board placement: " + ex)); } } if ((Object)(object)_board.Root == (Object)null && Time.unscaledTime >= _nextSpawnWarning) { _nextSpawnWarning = Time.unscaledTime + 30f; QuestPlugin.LogSource.LogWarning((object)("Quest board: " + _placementStatus)); } } bool flag = Application.isFocused && (!Cursor.visible || (int)Cursor.lockState == 1) && !PlayerInventoryUI.isOpen && !SkillWheelManager.isOpen && !((ANetworkEntity)Player.localPlayer).isDead; bool flag2 = flag && _board.CanRead(); bool flag3 = flag && _board.CanRead(cosmetics: true) && Vector3.Distance(Player.localTransform.position, _board.CosmeticPosition) < Vector3.Distance(Player.localTransform.position, _board.Position); flag2 = flag2 || flag3; if (!_skinFailed) { try { _skins.Tick(); } catch (Exception ex2) { _skinFailed = true; QuestPlugin.LogSource.LogWarning((object)("Cosmetic rendering paused for this session: " + ex2)); try { _skins.Dispose(); } catch { } } } if (flag && !_ui.IsOpen && Time.unscaledTime >= _nextHudPoll) { _nextHudPoll = Time.unscaledTime + 5f; Send("progress", ""); } bool flag4 = IsRidingCarpet(); int num; if (flag2) { num = ((!flag4) ? 1 : 0); if (num != 0 && !BlockingInput) { _talk.Reserve(); goto IL_04ce; } } else { num = 0; } if (!BlockingInput) { _talk.Release(); } goto IL_04ce; IL_04ce: _ui.SetPrompt(flag2, ((Object)(object)_board.Root != (Object)null) ? _board.Position : Vector3.zero, flag4, _talk.Label, (Object)(object)_board.Root != (Object)null, _placementStatus, flag, flag3); bool pressed = _talk.Pressed; if (((uint)num & (pressed ? 1u : 0u)) != 0 && !BlockingInput) { _ui.Open(flag3); Send(_ui.IsCosmetics ? "wardrobe" : "view", ""); _nextPoll = Time.unscaledTime + 1f; } if (_ui.IsOpen && (((ANetworkEntity)Player.localPlayer).isDead || (Object)(object)_board.Root == (Object)null || Vector3.Distance(Player.localTransform.position, _board.Position) > 5.5f)) { _ui.Close(); } _ui.Tick(); if (_ui.IsOpen && Time.unscaledTime >= _nextPoll) { Send(_ui.IsCosmetics ? "wardrobe" : "view", ""); _nextPoll = Time.unscaledTime + 1f; } } private bool IsRidingCarpet() { if (!_checkedCarpet) { _checkedCarpet = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType("InfernoProtocol.MagicCarpet.MagicCarpetController", throwOnError: false); if (type != null) { _carpetMounted = type.GetProperty("IsMounted", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } } } object obj = _carpetMounted?.GetValue(null); if (obj is bool) { return (bool)obj; } return false; } private void Send(string verb, string id) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_network == (Object)null) && (!((Object)(object)_board.Root == (Object)null) || !(verb != "progress"))) { if (_network.IsServer) { QuestView view = Service.Execute(Player.localPlayer, verb, id, ((Object)(object)_board.Root != (Object)null) ? _board.Position : Vector3.zero); _skins.Receive(view); _ui.Receive(view); } else { SendText("FrankMods.FieldQuests.Request.v1", NetworkManager.ServerClientId, verb + ":" + id); } } } private void OnRequest(ulong sender, FastBufferReader reader) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_network == (Object)null || !_network.IsServer || Service == null || ((FastBufferReader)(ref reader)).Length > 512) { return; } float unscaledTime = Time.unscaledTime; if (_lastRequest.TryGetValue(sender, out var value) && unscaledTime - value < 0.15f) { return; } _lastRequest[sender] = unscaledTime; string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, true); if (text == null || text.Length > 80) { return; } string[] array = text.Split(':'); NetworkClient val = default(NetworkClient); if (array.Length != 2 || !_network.ConnectedClients.TryGetValue(sender, ref val)) { return; } if (array[0] == "locate") { QuestBoardLocation location = (((Object)(object)_board.Root == (Object)null) ? null : new QuestBoardLocation { X = _board.Position.x, Y = _board.Position.y, Z = _board.Position.z, Yaw = _board.Root.transform.eulerAngles.y }); SendText("FrankMods.FieldQuests.Response.v1", sender, JsonSerializer.Serialize(new QuestView { LocationOnly = true, Location = location, Message = _placementStatus })); } else { if ((Object)(object)_board.Root == (Object)null && array[0] != "progress") { return; } Player val2 = (((Object)(object)val.PlayerObject != (Object)null) ? ((Component)val.PlayerObject).GetComponent() : null); if ((Object)(object)val2 == (Object)null) { foreach (Player item in Object.FindObjectsOfType()) { if (((NetworkBehaviour)item).IsSpawned && ((NetworkBehaviour)item).OwnerClientId == sender) { val2 = item; break; } } } if (!((Object)(object)val2 == (Object)null)) { QuestView value2 = Service.Execute(val2, array[0], array[1], ((Object)(object)_board.Root != (Object)null) ? _board.Position : Vector3.zero); SendText("FrankMods.FieldQuests.Response.v1", sender, JsonSerializer.Serialize(value2)); } } } catch (Exception ex) { QuestPlugin.LogSource.LogWarning((object)("Quest request rejected: " + ex.Message)); } } private void OnResponse(ulong sender, FastBufferReader reader) { try { if ((Object)(object)_network == (Object)null || _network.IsServer || sender != NetworkManager.ServerClientId || ((FastBufferReader)(ref reader)).Length > 20000) { return; } string json = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref json, true); QuestView questView = JsonSerializer.Deserialize(json); if (questView == null || questView.Protocol != 1 || questView.Rows == null || questView.Rows.Count > QuestCatalog.All.Length) { return; } if (questView.LocationOnly) { QuestBoardLocation location = questView.Location; if (location != null && location.IsValid) { _hostLocation = questView.Location; } if (!string.IsNullOrEmpty(questView.Message)) { _placementStatus = questView.Message; } return; } HashSet hashSet = new HashSet(); foreach (QuestRow row in questView.Rows) { if (row == null || QuestCatalog.Find(row.Id) == null || !hashSet.Add(row.Id)) { return; } } _skins.Receive(questView); _ui?.Receive(questView); } catch (Exception ex) { QuestPlugin.LogSource.LogWarning((object)("Quest response rejected: " + ex.Message)); } } private void SendText(string channel, ulong target, string value) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) int num = value.Length * 2 + 32; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num, (Allocator)2, num); try { ((FastBufferWriter)(ref val)).WriteValueSafe(value, true); _messages.SendNamedMessage(channel, target, val, (NetworkDelivery)4); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } internal void Cleanup() { if ((Delegate)(object)_saveHandler != (Delegate)null) { SaveManager.onSaveComplete -= _saveHandler; } _saveHandler = null; _ui?.Dispose(); _ui = null; _skins.Dispose(); _skinFailed = false; _talk.Dispose(); _board.Dispose(); if (_messages != null) { try { _messages.UnregisterNamedMessageHandler("FrankMods.FieldQuests.Request.v1"); _messages.UnregisterNamedMessageHandler("FrankMods.FieldQuests.Response.v1"); } catch { } } Service = null; _messages = null; _network = null; _hostLocation = null; _placementStatus = "Preparing the quest board"; _nextHudPoll = 0f; _nextBoardAttempt = 0f; _nextSpawnWarning = 0f; _lastRequest.Clear(); _wasListening = false; _failed = false; } private void OnDestroy() { Cleanup(); } } internal sealed class QuestInteraction : IDisposable { private readonly List _buttons = new List(); private readonly List _disabled = new List(); private bool _active; internal bool Pressed { get { if (!_active || !_buttons.Exists((ButtonControl b) => b.wasPressedThisFrame)) { Keyboard current = Keyboard.current; if (current == null) { return false; } return ((ButtonControl)current.f9Key).wasPressedThisFrame; } return true; } } internal string Label { get { bool playingWithGamepad = PlayerInputDispatcher.playingWithGamepad; foreach (ButtonControl button in _buttons) { if (((Il2CppObjectBase)((InputControl)button).device).TryCast() != null == playingWithGamepad) { return ((InputControl)button).displayName; } } return "F9"; } } internal void Reserve() { if (_active) { return; } PlayerActionContainer actions = PlayerInputDispatcher.actions; InputAction val = ((actions != null) ? actions.interact : null); if (val == null || !val.enabled) { return; } _buttons.Clear(); Enumerator enumerator = val.controls.GetEnumerator(); while (enumerator.MoveNext()) { ButtonControl val2 = ((Il2CppObjectBase)enumerator.Current).TryCast(); if (val2 != null) { _buttons.Add(val2); } } InputActionAsset inputActionsAsset = PlayerInputDispatcher.inputActionsAsset; ReadOnlyArray val3 = ((inputActionsAsset != null) ? inputActionsAsset.actionMaps : null); if (val3 != null) { Enumerator enumerator2 = val3.GetEnumerator(); while (enumerator2.MoveNext()) { Enumerator enumerator3 = enumerator2.Current.actions.GetEnumerator(); while (enumerator3.MoveNext()) { InputAction current = enumerator3.Current; if (!current.enabled) { continue; } bool flag = false; enumerator = current.controls.GetEnumerator(); while (enumerator.MoveNext()) { InputControl control = enumerator.Current; if (_buttons.Exists((ButtonControl b) => ((InputControl)b).path == control.path)) { flag = true; break; } } if (flag) { _disabled.Add(current); } } } } foreach (InputAction item in _disabled) { item.Disable(); } _active = true; } internal void Release(bool force = false) { if (!force && _buttons.Exists((ButtonControl b) => b.isPressed)) { return; } foreach (InputAction item in _disabled) { if (item.actionMap == null || item.actionMap.enabled) { item.Enable(); } } _disabled.Clear(); _buttons.Clear(); _active = false; } public void Dispose() { Release(force: true); } } public sealed class Quest { public readonly string Id; public readonly string Title; public readonly string Description; public readonly string Target; public readonly string Reward; public readonly int Amount; public readonly int Xp; public readonly int Level; public readonly bool Hunt; public Quest(string id, string title, string description, string target, int amount, string reward, int xp, int level, bool hunt) { Id = id; Title = title; Description = description; Target = target; Amount = amount; Reward = reward; Xp = xp; Level = level; Hunt = hunt; } } public static class QuestCatalog { public static readonly Quest[] All = new Quest[24] { new Quest("s01", "A place to begin", "A good camp starts with solid timber. Bring logs for the supply reserve.", "Log", 8, "LeatherShoes", 100, 1, hunt: false), new Quest("s02", "Firm foundations", "We need stone to reinforce the paths around camp.", "Stone", 12, "WoodenSpear", 120, 1, hunt: false), new Quest("s03", "Light the way", "Help us keep the perimeter lit after sundown.", "Torch", 3, "Flashlight", 140, 1, hunt: false), new Quest("s04", "First-aid reserve", "A small medical reserve can save a life. Stock the infirmary.", "Bandage", 3, "LeatherFlaskEmpty", 150, 1, hunt: false), new Quest("s05", "A warm welcome", "Bring drinking water for the next arrivals.", "WaterBottleFilled", 2, "StonePickaxe", 130, 1, hunt: false), new Quest("s06", "Field dressings", "Supply clean cloth for field dressings. Earn protective headgear for your next expedition.", "ClothPiece", 6, "ScrapHelmet", 180, 2, hunt: false), new Quest("s07", "A proper workshop", "Deliver planks so we can expand the work area.", "Plank", 8, "ScrapAxe", 220, 2, hunt: false), new Quest("s08", "Keep it together", "Tape is always in short supply at the repair bench.", "Tape", 3, "ScrapPickaxe", 240, 2, hunt: false), new Quest("s09", "Copper prospect", "Bring copper ore for the camp's first metalwork trials.", "CopperOre", 8, "BronzeHammer", 280, 3, hunt: false), new Quest("s10", "The other half", "Tin will let us put that copper to better use.", "TinOre", 8, "BronzeAxe", 280, 3, hunt: false), new Quest("s11", "Bronze standard", "A batch of finished ingots will get the new workshop running.", "BronzeIngot", 4, "MiningHelmet", 360, 4, hunt: false), new Quest("s12", "Power reserve", "Deliver spare batteries for our night patrols.", "Battery", 3, "GasMask", 360, 4, hunt: false), new Quest("h01", "Small trouble", "Thin out the rats around our supply routes. Only your kills after accepting count.", "Rat", 5, "NailBat", 150, 1, hunt: true), new Quest("h02", "Shambling company", "Keep the walking dead away from our newcomers.", "Zombie", 5, "ScrapMachete", 180, 1, hunt: true), new Quest("h03", "Larger teeth", "Giant rats have been tearing through the supply trails.", "GiantRat", 3, "Crossbow", 240, 2, hunt: true), new Quest("h04", "Night watch", "Clear a larger group of zombies so our scouts can get through.", "Zombie", 15, "ScrapHelmet", 320, 2, hunt: true), new Quest("h05", "Scavenger patrol", "Trash eaters keep following our supply parties.", "TrashEater", 5, "ScrapMachete", 320, 2, hunt: true), new Quest("h06", "Unwanted company", "Put down the meat slimes blocking our route.", "MeatSlime", 5, "ScrapPant", 360, 3, hunt: true), new Quest("h07", "Forest sentries", "The leaf hunters have made the treeline dangerous.", "LeafHunter", 5, "ScrapShirt", 400, 3, hunt: true), new Quest("h08", "A quieter night", "Hunt the ghouls before another patrol goes missing.", "Ghoul", 4, "IronSpear", 420, 3, hunt: true), new Quest("h09", "Broken ambush", "Stop the goblin fighters stalking the outer paths.", "GoblinMelee", 8, "BronzeMachete", 440, 4, hunt: true), new Quest("h10", "Buzz off", "Giant flies are making the nearby routes miserable.", "GiantFly", 6, "GasMask", 460, 4, hunt: true), new Quest("h11", "Hold the line", "Prove the camp can rely on you against a sustained zombie threat.", "Zombie", 30, "Colt1911", 600, 5, hunt: true), new Quest("h12", "Veteran hunter", "Take down the stitchers threatening our expeditions.", "Stitcher", 5, "Katana", 750, 5, hunt: true) }; public static Quest Find(string id) { return All.FirstOrDefault((Quest q) => q.Id == id); } public static Dictionary Unavailable(Func itemExists, Func creatureExists) { Dictionary dictionary = new Dictionary(); Quest[] all = All; foreach (Quest quest in all) { try { if (!itemExists(quest.Reward)) { dictionary[quest.Id] = "Missing reward: " + quest.Reward; } else if (!(quest.Hunt ? creatureExists(quest.Target) : itemExists(quest.Target))) { dictionary[quest.Id] = "Missing objective: " + quest.Target; } } catch (Exception ex) { dictionary[quest.Id] = "Asset lookup failed: " + ex.Message; } } return dictionary; } public static int Level(int xp) { int i; for (i = 1; i < 100 && xp >= Threshold(i + 1); i++) { } return i; } public static int Threshold(int level) { return checked(100 * (level - 1) * level); } } public sealed class Progress { public int Xp { get; set; } public Dictionary Active { get; set; } = new Dictionary(); public HashSet Completed { get; set; } = new HashSet(); public Dictionary Skins { get; set; } = new Dictionary(); public string Accept(Quest quest) { if (quest == null) { return "Unknown assignment."; } if (Completed.Contains(quest.Id)) { return "Already completed."; } if (Active.ContainsKey(quest.Id)) { return "Already in your journal."; } if (QuestCatalog.Level(Xp) < quest.Level) { return $"Requires level {quest.Level}."; } if (Active.Count >= 6) { return "Your journal holds six active quests. Finish or abandon one first."; } Active.Add(quest.Id, 0); return "Quest accepted."; } public void Kill(string creature) { Quest[] all = QuestCatalog.All; foreach (Quest quest in all) { if (quest.Hunt && quest.Target == creature && Active.TryGetValue(quest.Id, out var value)) { Active[quest.Id] = Math.Min(quest.Amount, value + 1); } } } public void Complete(Quest quest) { if (!Active.ContainsKey(quest.Id) || Completed.Contains(quest.Id)) { throw new InvalidOperationException("Quest is not claimable."); } int xp = checked(Xp + quest.Xp); Completed.Add(quest.Id); Active.Remove(quest.Id); Xp = xp; } } public readonly struct StackData : IEquatable { public readonly string Item; public readonly int Count; public readonly byte Durability; public readonly byte Var1; public readonly byte Var2; public StackData(string item, int count, byte durability = 0, byte var1 = 0, byte var2 = 0) { Item = item; Count = count; Durability = durability; Var1 = var1; Var2 = var2; } public StackData WithCount(int count) { return new StackData(Item, count, Durability, Var1, Var2); } public bool Equals(StackData other) { if (Count == other.Count) { if (Count != 0) { if (Item == other.Item && Durability == other.Durability && Var1 == other.Var1) { return Var2 == other.Var2; } return false; } return true; } return false; } public override bool Equals(object obj) { if (obj is StackData other) { return Equals(other); } return false; } public override int GetHashCode() { if (Count != 0) { return HashCode.Combine(Item, Count, Durability, Var1, Var2); } return 0; } public static bool operator ==(StackData a, StackData b) { return a.Equals(b); } public static bool operator !=(StackData a, StackData b) { return !a.Equals(b); } } public sealed class Slot { public string Container { get; init; } public int Index { get; init; } public bool RewardDestination { get; init; } public StackData Before { get; init; } public StackData After { get; set; } } public static class TurnInPlanner { public static bool Plan(List slots, Quest quest, StackData reward, out string error) { foreach (Slot slot2 in slots) { slot2.After = slot2.Before; } int num = ((!quest.Hunt) ? quest.Amount : 0); foreach (Slot slot3 in slots) { if (num == 0) { break; } if (!(slot3.Before.Item != quest.Target) && slot3.Before.Count > 0) { int num2 = Math.Min(num, slot3.Before.Count); slot3.After = slot3.Before.WithCount(slot3.Before.Count - num2); num -= num2; } } if (num != 0) { error = "Not enough materials. Nothing was consumed."; return false; } Slot slot = slots.FirstOrDefault((Slot s) => s.RewardDestination && s.After.Count == 0); if (slot == null) { error = "Free one inventory or backpack slot for your reward."; return false; } slot.After = reward; error = ""; return true; } } public static class SlotTransaction { public static void Commit(List changed, Func read, Action write) { foreach (Slot item3 in changed) { if (read(item3) != item3.Before) { throw new InvalidOperationException("An inventory changed. Try again."); } } int num = 0; try { foreach (Slot item4 in changed) { if (read(item4) != item4.Before) { throw new InvalidOperationException("An inventory changed during turn-in."); } num++; write(item4, item4.After); if (read(item4) != item4.After) { throw new InvalidOperationException("Inventory write did not stick."); } } } catch (Exception item) { List list = new List(); for (int num2 = num - 1; num2 >= 0; num2--) { try { write(changed[num2], changed[num2].Before); if (read(changed[num2]) != changed[num2].Before) { throw new InvalidOperationException("Rollback verification failed."); } } catch (Exception item2) { list.Add(item2); } } if (list.Count > 0) { list.Insert(0, item); throw new AggregateException("Inventory rollback failed.", list); } throw; } } } public sealed class QuestRow { public string Id { get; set; } public int Count { get; set; } public int Carried { get; set; } public int Stored { get; set; } public string State { get; set; } } public sealed class QuestView { public int Protocol { get; set; } = 1; public string Message { get; set; } = ""; public int Xp { get; set; } public List Rows { get; set; } = new List(); public bool LocationOnly { get; set; } public bool ProgressOnly { get; set; } public Dictionary Skins { get; set; } = new Dictionary(); public List SkinUnlocks { get; set; } = new List(); public QuestBoardLocation Location { get; set; } } public sealed class QuestBoardLocation { public float X { get; set; } public float Y { get; set; } public float Z { get; set; } public float Yaw { get; set; } public bool IsValid { get { if (float.IsFinite(X) && float.IsFinite(Y) && float.IsFinite(Z) && float.IsFinite(Yaw) && Math.Abs(X) < 1000000f && Math.Abs(Y) < 1000000f) { return Math.Abs(Z) < 1000000f; } return false; } } } internal sealed class QuestPanel : IDisposable { private sealed class ActionBox { internal Image Image; internal TextMeshProUGUI Label; internal Action Click; internal bool Enabled = true; internal Color BaseColor; } private readonly Action _send; private readonly List _buttons = new List(); private readonly List _disabledMaps = new List(); private readonly List _previouslyDisabledActions = new List(); private readonly List _visible = new List(); private readonly ActionBox[] _tabs = new ActionBox[5]; private readonly ActionBox[] _rows = new ActionBox[6]; private readonly Image[] _rowIcons = (Image[])(object)new Image[6]; private readonly TextMeshProUGUI[] _rowStatus = (TextMeshProUGUI[])(object)new TextMeshProUGUI[6]; private readonly string[] _filters = new string[5] { "All assignments", "My journal", "Hunts", "Supplies", "Completed" }; private GameObject _canvas; private GameObject _window; private Image _scrim; private Image _xpFill; private Image _objectiveFill; private Image _rewardIcon; private Image _targetIcon; private TextMeshProUGUI _prompt; private TextMeshProUGUI _level; private TextMeshProUGUI _xp; private TextMeshProUGUI _title; private TextMeshProUGUI _description; private TextMeshProUGUI _objective; private TextMeshProUGUI _sources; private TextMeshProUGUI _reward; private TextMeshProUGUI _rewardXp; private TextMeshProUGUI _status; private TextMeshProUGUI _pagination; private TextMeshProUGUI _listTitle; private ActionBox _primary; private ActionBox _abandon; private QuestView _view; private Color _accent = new Color(0.45f, 0.88f, 0.8f, 1f); private readonly Color _ink = new Color(0.88f, 0.93f, 0.93f, 1f); private readonly Color _muted = new Color(0.56f, 0.65f, 0.68f, 1f); private readonly Color _panel = new Color(0.045f, 0.065f, 0.075f, 0.96f); private int _filter; private int _selection; private string _confirmation; private string _pendingClaim; private float _pendingSince; private float _receiptUntil; private float _displayXp = -1f; private TextMeshProUGUI _receipt; private GameObject _levelHud; private TextMeshProUGUI _hudLevel; private Image _hudFill; private int _hudXp = -1; private float _nextHudTheme; private GameObject _dialog; private TextMeshProUGUI _dialogTitle; private TextMeshProUGUI _dialogBody; private TextMeshProUGUI _dialogReward; private Image _dialogIcon; private ActionBox _dialogConfirm; private ActionBox _dialogCancel; private bool _dialogResult; private bool _dialogCancelSelected; private float _dialogOpened; private bool _cosmetics; private readonly Dictionary _finishPreviews = new Dictionary(); private TextMeshProUGUI _brand; private TextMeshProUGUI _sidebarTitle; private TextMeshProUGUI _welcome; private ActionBox _finishPrevious; private ActionBox _finishNext; private TextMeshProUGUI _briefingTitle; private TextMeshProUGUI _finishPage; private TextMeshProUGUI _collection; private Image _objectiveTrack; private Image _levelTrack; private int _savedFinish; private int _savedEquipment; private bool _releasePending; private bool _savedCursor; private bool _lookWasEnabled; private CursorLockMode _savedLock; private float _openTime; private float _repeatAt; private float _messageUntil; private float _lastResponse; private float _nextAction; private int _navHeld; internal bool IsCosmetics => _cosmetics; internal bool IsOpen { get; private set; } internal bool BlockingInput { get { if (!IsOpen) { return _releasePending; } return true; } } private QuestRow Selected { get { if (_visible.Count <= _selection) { return null; } return _visible[_selection]; } } internal QuestPanel(Action send) { //IL_00a5: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) _send = send; Build(); } internal void Open(bool cosmetics = false) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (BlockingInput) { return; } _cosmetics = cosmetics; _filter = (cosmetics ? _savedFinish : 0); _selection = (cosmetics ? _savedEquipment : 0); ((TMP_Text)_brand).text = (cosmetics ? "FINISHES / EQUIPMENT COSMETICS" : "FIELD NOTES / QUEST BOARD"); ((TMP_Text)_sidebarTitle).text = (cosmetics ? "CHOOSE A FINISH" : "THE QUEST BOARD"); ((Component)_welcome).gameObject.SetActive(!cosmetics); ((Component)_finishPrevious.Image).gameObject.SetActive(cosmetics); ((Component)_finishNext.Image).gameObject.SetActive(cosmetics); LayoutFinishes(cosmetics); LoadTheme(); _savedCursor = Cursor.visible; _savedLock = Cursor.lockState; _disabledMaps.Clear(); _previouslyDisabledActions.Clear(); PlayerActionContainer actions = PlayerInputDispatcher.actions; int lookWasEnabled; if (actions == null) { lookWasEnabled = 0; } else { InputAction look = actions.look; lookWasEnabled = ((((look != null) ? new bool?(look.enabled) : ((bool?)null)) == true) ? 1 : 0); } _lookWasEnabled = (byte)lookWasEnabled != 0; InputActionAsset inputActionsAsset = PlayerInputDispatcher.inputActionsAsset; ReadOnlyArray val = ((inputActionsAsset != null) ? inputActionsAsset.actionMaps : null); if (val != null) { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { InputActionMap current = enumerator.Current; if (!current.enabled) { continue; } Enumerator enumerator2 = current.actions.GetEnumerator(); while (enumerator2.MoveNext()) { InputAction current2 = enumerator2.Current; if (!current2.enabled) { _previouslyDisabledActions.Add(current2); } } _disabledMaps.Add(current); current.Disable(); } } PlayerInputDispatcher.SetEnableLookInput(false); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; _window.SetActive(true); ((Component)_scrim).gameObject.SetActive(true); _levelHud.SetActive(false); ((Component)_prompt).gameObject.SetActive(false); IsOpen = true; _confirmation = null; _openTime = Time.unscaledTime; _pendingClaim = null; _dialog.SetActive(false); _receiptUntil = 0f; _displayXp = _view?.Xp ?? 0; _lastResponse = Time.unscaledTime; ((TMP_Text)_status).text = "Loading quest board..."; Refresh(); } internal void Close() { if (IsOpen) { if (_cosmetics) { _savedFinish = _filter; _savedEquipment = _selection; } IsOpen = false; _releasePending = true; _window.SetActive(false); ((Component)_scrim).gameObject.SetActive(false); _confirmation = null; _dialog.SetActive(false); } } private void RestoreInput() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) foreach (InputActionMap disabledMap in _disabledMaps) { if (disabledMap != null) { disabledMap.Enable(); } } _disabledMaps.Clear(); foreach (InputAction previouslyDisabledAction in _previouslyDisabledActions) { if (previouslyDisabledAction != null) { previouslyDisabledAction.Disable(); } } _previouslyDisabledActions.Clear(); PlayerInputDispatcher.SetEnableLookInput(_lookWasEnabled); Cursor.lockState = _savedLock; Cursor.visible = _savedCursor; _releasePending = false; } internal void Receive(QuestView view) { //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) if (view == null) { return; } if (view.ProgressOnly || view.Rows.Count > 0 || _cosmetics) { UpdateLevelHud(view.Xp); } if (view.ProgressOnly) { return; } bool flag = _pendingClaim != null; string selectedId = Selected?.Id; Quest quest = ((_view == null || view.Xp <= _view.Xp) ? null : QuestCatalog.All.FirstOrDefault((Quest q) => _view.Rows.Any((QuestRow r) => r.Id == q.Id && r.State != "COMPLETED") && view.Rows.Any((QuestRow r) => r.Id == q.Id && r.State == "COMPLETED"))); if (quest != null && IsOpen) { int num = QuestCatalog.Level(_view.Xp); int num2 = QuestCatalog.Level(view.Xp); ((TMP_Text)_receipt).text = $"REWARD RECEIVED / {Name(quest.Reward)} x1 / +{quest.Xp} XP" + ((num2 > num) ? $" / LEVEL UP: {num2}" : ""); ((Graphic)_receipt).color = _accent; _receiptUntil = Time.unscaledTime + 6f; if (SkinCatalog.RewardFor(quest.Id).Length > 0) { TextMeshProUGUI receipt = _receipt; ((TMP_Text)receipt).text = ((TMP_Text)receipt).text + " / " + SkinCatalog.RewardFor(quest.Id); } } if (_pendingClaim != null && (view.Rows.Any((QuestRow r) => r.Id == _pendingClaim && r.State == "COMPLETED") || !string.IsNullOrEmpty(view.Message))) { _pendingClaim = null; } _view = view; _lastResponse = Time.unscaledTime; if (IsOpen && flag && _pendingClaim == null) { _dialogResult = true; ((TMP_Text)_dialogTitle).text = ((quest != null) ? "ASSIGNMENT COMPLETE" : "TURN-IN UPDATE"); ((TMP_Text)_dialogBody).text = ((quest != null) ? (quest.Title + "\nYour reward has been delivered.") : view.Message); if (quest != null) { ((TMP_Text)_dialogReward).text = Name(quest.Reward) + $" x1 / +{quest.Xp} XP"; } else { ((TMP_Text)_dialogReward).text = "No success confirmed. Check your assignment before retrying."; ((Behaviour)_dialogIcon).enabled = false; } if (quest != null && SkinCatalog.RewardFor(quest.Id).Length > 0) { TextMeshProUGUI dialogReward = _dialogReward; ((TMP_Text)dialogReward).text = ((TMP_Text)dialogReward).text + "\n" + SkinCatalog.RewardFor(quest.Id); } _dialogConfirm.Enabled = false; ((Component)_dialogConfirm.Image).gameObject.SetActive(false); ((TMP_Text)_dialogCancel.Label).text = "CONTINUE / B or Esc"; _dialog.SetActive(true); } if (!string.IsNullOrEmpty(view.Message)) { ((TMP_Text)_status).text = view.Message; _messageUntil = Time.unscaledTime + 8f; if (_cosmetics) { ((TMP_Text)_receipt).text = view.Message; ((Graphic)_receipt).color = _accent; _receiptUntil = Time.unscaledTime + 6f; } } Refresh(); int num3 = _visible.FindIndex((QuestRow r) => r.Id == selectedId); if (num3 >= 0 && num3 != _selection) { _selection = num3; Refresh(); } } internal void SetPrompt(bool visible, Vector3 boardPosition, bool riding, string talkButton, bool boardReady, string placementStatus, bool gameplay, bool cosmetics = false) { _levelHud.SetActive(gameplay && !BlockingInput && _hudXp >= 0); if (gameplay && Time.unscaledTime >= _nextHudTheme) { _nextHudTheme = Time.unscaledTime + 5f; LoadTheme(); } ((Component)_prompt).gameObject.SetActive(visible && !BlockingInput); if (visible) { ((TMP_Text)_prompt).text = (riding ? "QUEST BOARD\nDismount your carpet to read the board" : (cosmetics ? ("FINISHES / COSMETIC STATION\n[" + talkButton + "] Customize equipment") : ("QUEST BOARD / FIELD ASSIGNMENTS\n[" + talkButton + "] Read board / Browse quests"))); } } internal void Tick() { //IL_0146: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_0665: Unknown result type (might be due to invalid IL or missing references) //IL_066e: Unknown result type (might be due to invalid IL or missing references) //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0716: Unknown result type (might be due to invalid IL or missing references) //IL_0720: Unknown result type (might be due to invalid IL or missing references) //IL_0707: Unknown result type (might be due to invalid IL or missing references) if (!Application.isFocused || !Player.isLocalPlayerLoaded || (Object)(object)Player.localPlayer == (Object)null || ((ANetworkEntity)Player.localPlayer).isDead) { _levelHud.SetActive(false); } if (_releasePending) { if (Released()) { RestoreInput(); } } else { if (!IsOpen) { return; } if (_pendingClaim != null && Time.unscaledTime - _pendingSince > 8f) { _pendingClaim = null; if (_dialog.activeSelf) { _dialogResult = true; ((TMP_Text)_dialogTitle).text = "CONFIRMATION DELAYED"; ((TMP_Text)_dialogBody).text = "The host has not confirmed the turn-in. Check the refreshed quest state before retrying."; ((Component)_dialogConfirm.Image).gameObject.SetActive(false); ((TMP_Text)_dialogCancel.Label).text = "BACK"; } ((TMP_Text)_status).text = "No confirmation received. Refresh the board before retrying."; _messageUntil = Time.unscaledTime + 6f; Refresh(); } if (Time.unscaledTime > _receiptUntil) { ((TMP_Text)_receipt).text = (_cosmetics ? "Earn it through quests. Save your look. Equip it whenever you like." : "A safer camp. A stronger survivor. One assignment at a time."); ((Graphic)_receipt).color = _muted; } else { ((Graphic)_receipt).color = Color.Lerp(_muted, _accent, Mathf.Clamp01((_receiptUntil - Time.unscaledTime) / 0.6f)); } if (_view != null) { _displayXp = ((_displayXp < 0f) ? ((float)_view.Xp) : Mathf.MoveTowards(_displayXp, (float)_view.Xp, Math.Max(120f, Math.Abs((float)_view.Xp - _displayXp) * 5f) * Time.unscaledDeltaTime)); int num = QuestCatalog.Level((int)_displayXp); int num2 = QuestCatalog.Threshold(num); int num3 = QuestCatalog.Threshold(num + 1); ((Graphic)_xpFill).rectTransform.anchorMax = new Vector2(Mathf.Clamp01((_displayXp - (float)num2) / (float)(num3 - num2)), 1f); ((TMP_Text)_level).text = $"LEVEL {num:00}"; ((TMP_Text)_xp).text = $"{(int)_displayXp - num2:N0} / {num3 - num2:N0} XP\n{_view.Rows.Count((QuestRow r) => r.State == "COMPLETED")} assignments completed"; } if (!Application.isFocused) { Close(); return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; PlayerInputDispatcher.SetEnableLookInput(false); foreach (InputActionMap disabledMap in _disabledMaps) { if (disabledMap.enabled) { disabledMap.Disable(); } } if (Time.unscaledTime - _lastResponse > 6f) { ((TMP_Text)_status).text = "Waiting for the host. The host must have ContentPlus installed."; } else if (Time.unscaledTime > _messageUntil && _confirmation == null) { ((TMP_Text)_status).text = ((!_cosmetics) ? ((Gamepad.current != null) ? "D-pad: browse / filter | A: action | X: abandon | LB/RB: page | B: back" : "Click: select / action | Wheel: browse | Arrow keys: browse / filter | Enter: action | Esc: back") : ((Gamepad.current != null) ? "D-pad left/right: finish | Up/down: equipment | LB/RB: equipment page | A: apply | B: close" : "Click to select | Wheel: equipment | Left/right: finish | Up/down: equipment | Enter: apply | Esc: close")); } if (Time.unscaledTime - _openTime < 0.25f) { return; } Keyboard current2 = Keyboard.current; Gamepad current3 = Gamepad.current; if (_dialog.activeSelf) { TickDialog(current2, current3); return; } if ((current2 != null && ((ButtonControl)current2.escapeKey).wasPressedThisFrame) || (current3 != null && current3.buttonEast.wasPressedThisFrame)) { if (_confirmation != null) { _confirmation = null; Refresh(); } else { Close(); } return; } int num4 = (_cosmetics ? SkinCatalog.Names.Length : _filters.Length); if ((current3 != null && current3.dpad.left.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.leftArrowKey).wasPressedThisFrame)) { Filter((_filter + num4 - 1) % num4); } if ((current3 != null && current3.dpad.right.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.rightArrowKey).wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.tabKey).wasPressedThisFrame)) { Filter((_filter + 1) % num4); } int num5 = (((current3 != null && current3.dpad.down.isPressed) || (current2 != null && ((ButtonControl)current2.downArrowKey).isPressed)) ? 1 : 0) - (((current3 != null && current3.dpad.up.isPressed) || (current2 != null && ((ButtonControl)current2.upArrowKey).isPressed)) ? 1 : 0); if (num5 != 0 && (num5 != _navHeld || Time.unscaledTime >= _repeatAt)) { Select(_selection + num5); _repeatAt = Time.unscaledTime + ((num5 != _navHeld) ? 0.32f : 0.12f); } _navHeld = num5; if ((current3 != null && current3.leftShoulder.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.pageUpKey).wasPressedThisFrame)) { Select(_selection - 6); } if ((current3 != null && current3.rightShoulder.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.pageDownKey).wasPressedThisFrame)) { Select(_selection + 6); } if ((current3 != null && current3.buttonSouth.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.enterKey).wasPressedThisFrame)) { Primary(); } if (_dialog.activeSelf) { return; } if ((current3 != null && current3.buttonWest.wasPressedThisFrame) || (current2 != null && ((ButtonControl)current2.deleteKey).wasPressedThisFrame)) { Abandon(); } if (_dialog.activeSelf) { return; } Mouse current4 = Mouse.current; if (current4 == null) { return; } Vector2 val = ((InputControl)(object)((Pointer)current4).position).ReadValue(); if (Mathf.Abs(((InputControl)(object)current4.scroll).ReadValue().y) > 0.1f) { Select(_selection + ((((InputControl)(object)current4.scroll).ReadValue().y < 0f) ? 1 : (-1))); } foreach (ActionBox button in _buttons) { if (((Component)button.Image).gameObject.activeInHierarchy && button.Enabled) { bool flag = RectTransformUtility.RectangleContainsScreenPoint(((Graphic)button.Image).rectTransform, val, (Camera)null); ((Graphic)button.Image).color = (flag ? Color.Lerp(button.BaseColor, _accent, 0.18f) : button.BaseColor); if (flag && current4.leftButton.wasPressedThisFrame) { button.Click(); break; } } } } } private static bool Released() { //IL_00c7: 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) Keyboard current = Keyboard.current; Gamepad current2 = Gamepad.current; if (current == null || !((ButtonControl)current.anyKey).isPressed) { Mouse current3 = Mouse.current; if (current3 == null || !current3.leftButton.isPressed) { Mouse current4 = Mouse.current; if (current4 == null || !current4.rightButton.isPressed) { Mouse current5 = Mouse.current; if ((current5 == null || !current5.middleButton.isPressed) && (current2 == null || !current2.buttonSouth.isPressed) && (current2 == null || !current2.buttonEast.isPressed) && (current2 == null || !current2.buttonWest.isPressed) && (current2 == null || !current2.buttonNorth.isPressed)) { if (current2 != null) { Vector2 val = ((InputControl)(object)current2.dpad).ReadValue(); if (((Vector2)(ref val)).sqrMagnitude > 0.01f) { goto IL_0140; } } if ((current2 == null || !current2.leftShoulder.isPressed) && (current2 == null || !current2.rightShoulder.isPressed) && (current2 == null || !current2.selectButton.isPressed) && (current2 == null || !current2.leftTrigger.isPressed) && (current2 == null || !current2.rightTrigger.isPressed)) { return current2 == null || !current2.startButton.isPressed; } } } } } goto IL_0140; IL_0140: return false; } private void Filter(int filter) { _filter = filter; if (!_cosmetics) { _selection = 0; } _confirmation = null; Refresh(); } private void Select(int selected) { _selection = Mathf.Clamp(selected, 0, Math.Max(0, (_cosmetics ? SkinCatalog.Items.Length : _visible.Count) - 1)); _confirmation = null; Refresh(); } private void Primary() { if (_pendingClaim != null || Time.unscaledTime < _nextAction) { return; } _nextAction = Time.unscaledTime + 0.35f; if (_cosmetics) { int value = 0; _view?.Skins?.TryGetValue(SkinCatalog.Items[_selection], out value); if (_primary.Enabled && value != _filter) { QuestView view = _view; if (view != null && view.SkinUnlocks?.Contains(_filter) == true) { _send("skin", SkinCatalog.Items[_selection] + "|" + _filter); } } return; } QuestRow selected = Selected; if (selected == null) { return; } if (selected.State == "AVAILABLE") { _send("accept", selected.Id); } else if (!(selected.State != "READY")) { if (_confirmation != "claim:" + selected.Id) { _confirmation = "claim:" + selected.Id; ShowDialog(selected, abandon: false); Quest quest = QuestCatalog.Find(selected.Id); ((TMP_Text)_status).text = (quest.Hunt ? "Confirm completion to receive the displayed reward and XP." : $"Consume {quest.Amount} {Name(quest.Target)}: {Math.Min(quest.Amount, selected.Carried)} carried + {Math.Max(0, quest.Amount - selected.Carried)} stored. Confirm turn-in?"); _messageUntil = Time.unscaledTime + 30f; Refresh(); } else { _confirmation = null; _pendingClaim = selected.Id; _pendingSince = Time.unscaledTime; ((TMP_Text)_status).text = "Turning in assignment... waiting for host confirmation."; _messageUntil = Time.unscaledTime + 8f; Refresh(); _send("claim", selected.Id); } } } private void Abandon() { if (_cosmetics || _pendingClaim != null || Time.unscaledTime < _nextAction) { return; } _nextAction = Time.unscaledTime + 0.35f; QuestRow selected = Selected; if (selected != null && (!(selected.State != "ACTIVE") || !(selected.State != "READY") || !(selected.State != "UNAVAILABLE"))) { if (_confirmation != "abandon:" + selected.Id) { _confirmation = "abandon:" + selected.Id; ShowDialog(selected, abandon: true); ((TMP_Text)_status).text = "Abandon this assignment? Hunt progress will reset. Press Abandon again to confirm."; _messageUntil = Time.unscaledTime + 30f; Refresh(); } else { _confirmation = null; _send("abandon", selected.Id); } } } private void CancelDialog() { _confirmation = null; _dialog.SetActive(false); _nextAction = Time.unscaledTime + 0.3f; Refresh(); } private void ShowDialog(QuestRow row, bool abandon) { Quest quest = QuestCatalog.Find(row.Id); _dialogResult = false; _dialogCancelSelected = abandon; _dialogOpened = Time.unscaledTime; ((TMP_Text)_dialogTitle).text = (abandon ? "ABANDON ASSIGNMENT?" : "READY TO TURN IN?"); ((TMP_Text)_dialogBody).text = quest.Title + "\n\n" + (abandon ? "This removes the assignment from your journal. Hunt progress will reset. No items will be taken." : (quest.Hunt ? "Hunt complete. No items will be consumed." : $"DELIVER {quest.Amount} {Name(quest.Target)}\n{Math.Min(quest.Amount, row.Carried)} carried + {Math.Max(0, quest.Amount - row.Carried)} from built storage\nThese materials will be consumed.")); ((TMP_Text)_dialogReward).text = (abandon ? "You can accept this assignment again later." : $"YOU RECEIVE\n{Name(quest.Reward)} x1 / +{quest.Xp} XP"); if (!abandon && SkinCatalog.RewardFor(quest.Id).Length > 0) { TextMeshProUGUI dialogReward = _dialogReward; ((TMP_Text)dialogReward).text = ((TMP_Text)dialogReward).text + "\n" + SkinCatalog.RewardFor(quest.Id); } SetIcon(_dialogIcon, quest.Reward); ((Behaviour)_dialogIcon).enabled = !abandon; ((Component)_dialogConfirm.Image).gameObject.SetActive(true); _dialogConfirm.Enabled = true; ((TMP_Text)_dialogConfirm.Label).text = (abandon ? "ABANDON" : "CONFIRM TURN-IN"); ((TMP_Text)_dialogCancel.Label).text = "CANCEL / B or Esc"; _dialog.SetActive(true); } private void ConfirmDialog() { if (_dialogResult || _pendingClaim != null || _confirmation == null || Time.unscaledTime - _dialogOpened < 0.3f) { return; } string[] action = _confirmation.Split(':'); QuestRow questRow = _view?.Rows.FirstOrDefault((QuestRow r) => r.Id == action[1]); bool flag = action[0] == "claim"; if (questRow != null) { bool num; if (!flag) { if (!(questRow.State != "ACTIVE") || !(questRow.State != "READY")) { goto IL_0128; } num = questRow.State != "UNAVAILABLE"; } else { num = questRow.State != "READY"; } if (!num) { goto IL_0128; } } _dialogResult = true; _confirmation = null; ((TMP_Text)_dialogTitle).text = "ASSIGNMENT CHANGED"; ((TMP_Text)_dialogBody).text = "This action is no longer available. Return to the board to review the current requirements."; ((Component)_dialogConfirm.Image).gameObject.SetActive(false); ((TMP_Text)_dialogCancel.Label).text = "BACK"; return; IL_0128: _confirmation = null; if (flag) { _pendingClaim = questRow.Id; _pendingSince = Time.unscaledTime; ((TMP_Text)_dialogTitle).text = "TURNING IN..."; ((TMP_Text)_dialogBody).text = "Waiting for the host to confirm your materials and deliver your reward."; _dialogConfirm.Enabled = false; ((Component)_dialogConfirm.Image).gameObject.SetActive(false); ((TMP_Text)_dialogCancel.Label).text = "BACK (does not cancel request)"; } else { _dialog.SetActive(false); } _nextAction = Time.unscaledTime + 0.35f; Refresh(); _send(action[0], questRow.Id); } private void TickDialog(Keyboard k, Gamepad g) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) if ((k != null && ((ButtonControl)k.escapeKey).wasPressedThisFrame) || (g != null && g.buttonEast.wasPressedThisFrame)) { CancelDialog(); } else { if (Time.unscaledTime - _dialogOpened < 0.3f) { return; } if ((g != null && g.dpad.left.wasPressedThisFrame) || (k != null && ((ButtonControl)k.leftArrowKey).wasPressedThisFrame)) { _dialogCancelSelected = true; } if ((g != null && g.dpad.right.wasPressedThisFrame) || (k != null && ((ButtonControl)k.rightArrowKey).wasPressedThisFrame)) { _dialogCancelSelected = false; } if (k != null && ((ButtonControl)k.tabKey).wasPressedThisFrame) { _dialogCancelSelected = !_dialogCancelSelected; } if ((g != null && g.buttonSouth.wasPressedThisFrame) || (k != null && ((ButtonControl)k.enterKey).wasPressedThisFrame)) { if (_dialogCancelSelected || _dialogResult || !_dialogConfirm.Enabled) { CancelDialog(); } else { ConfirmDialog(); } return; } Mouse current = Mouse.current; for (int i = 0; i < 2; i++) { ActionBox actionBox = ((i == 0) ? _dialogCancel : _dialogConfirm); if (((Component)actionBox.Image).gameObject.activeSelf) { bool flag = current != null && RectTransformUtility.RectangleContainsScreenPoint(((Graphic)actionBox.Image).rectTransform, ((InputControl)(object)((Pointer)current).position).ReadValue(), (Camera)null); bool flag2 = actionBox == (_dialogCancelSelected ? _dialogCancel : _dialogConfirm); ((Graphic)actionBox.Image).color = Color.Lerp(_panel, _accent, (flag || flag2) ? 0.38f : 0.14f); if (flag && current.leftButton.wasPressedThisFrame && actionBox.Enabled) { actionBox.Click(); break; } } } } } private void RefreshSkins() { //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_042e: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Unknown result type (might be due to invalid IL or missing references) //IL_075a: Unknown result type (might be due to invalid IL or missing references) //IL_079b: Unknown result type (might be due to invalid IL or missing references) //IL_0785: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Unknown result type (might be due to invalid IL or missing references) _visible.Clear(); ((TMP_Text)_finishPage).text = $"{_filter / 5 + 1} / {(SkinCatalog.Names.Length + 4) / 5}"; ((TMP_Text)_collection).text = $"{Math.Max(0, (_view?.SkinUnlocks?.Count ?? 1) - 1)} / {SkinCatalog.Names.Length - 1} FINISHES UNLOCKED\nEarn new designs through quests."; _selection = Mathf.Clamp(_selection, 0, SkinCatalog.Items.Length - 1); for (int i = 0; i < _tabs.Length; i++) { int finish = _filter / 5 * 5 + i; ((Component)_tabs[i].Image).gameObject.SetActive(finish < SkinCatalog.Names.Length); if (finish < SkinCatalog.Names.Length) { QuestView view = _view; bool flag = view != null && view.SkinUnlocks?.Contains(finish) == true; _tabs[i].Click = delegate { Filter(finish); }; ((TMP_Text)_tabs[i].Label).text = ((finish == _filter) ? "> " : "") + SkinCatalog.Names[finish] + (flag ? "" : "\nLocked"); ((Graphic)_tabs[i].Image).color = ((finish == _filter) ? Color.Lerp(_panel, SkinVisuals.ColorFor(finish), 0.3f) : _panel); ((Graphic)_tabs[i].Label).color = (flag ? _ink : _muted); } } int num = _selection / 6; ((TMP_Text)_pagination).text = $"{num + 1} / {(SkinCatalog.Items.Length + 5) / 6}"; ((TMP_Text)_listTitle).text = "2 / CHOOSE EQUIPMENT"; for (int num2 = 0; num2 < _rows.Length; num2++) { int num3 = num * 6 + num2; ((Component)_rows[num2].Image).gameObject.SetActive(num3 < SkinCatalog.Items.Length); if (num3 < SkinCatalog.Items.Length) { string text = SkinCatalog.Items[num3]; int value = 0; _view?.Skins?.TryGetValue(text, out value); value = Mathf.Clamp(value, 0, SkinCatalog.Names.Length - 1); ((TMP_Text)_rows[num2].Label).text = Name(text); ((Graphic)_rows[num2].Label).color = _ink; ((TMP_Text)_rowStatus[num2]).text = "Current: " + SkinCatalog.Names[value]; ((Graphic)_rowStatus[num2]).color = ((value == _filter) ? _accent : _muted); SetIcon(_rowIcons[num2], text); ((Graphic)_rows[num2].Image).color = ((num3 == _selection) ? Color.Lerp(_panel, _accent, 0.22f) : _panel); int capture = num3; _rows[num2].Click = delegate { Select(capture); }; } } string text2 = SkinCatalog.Items[_selection]; QuestView view2 = _view; bool flag2 = view2 != null && view2.SkinUnlocks?.Contains(_filter) == true; int value2 = 0; _view?.Skins?.TryGetValue(text2, out value2); value2 = Mathf.Clamp(value2, 0, SkinCatalog.Names.Length - 1); bool flag3 = value2 == _filter; ((TMP_Text)_title).text = SkinCatalog.Names[_filter]; TextMeshProUGUI description = _description; ((TMP_Text)description).text = _filter switch { 1 => "Layered olive, sand and dark woodland camouflage. Original texture detail remains underneath.", 2 => "Deep-blue panels with diagonal enamel bands and pale technical pinstripes.", 3 => "Charcoal fragments split by ember-orange fissures. Painted cracks, not added glow or bloom.", 4 => "An interlocking brass diamond lattice over dark brown panels, with recessed-looking borders.", 5 => "Stepped snow-white, slate and ice-blue digital camouflage blocks.", 6 => "Industrial yellow-and-black diagonal warning bands with pale divider rails.", 7 => "Broken, winding dark tiger stripes with sand edging over burnt orange.", 8 => "Crimson racing panels, cream pinstripes and a narrow checkered lane.", 9 => "Rolling turquoise and navy wave bands edged with pale seafoam.", 10 => "Fine map-like contour lines tracing irregular green terrain fields.", 11 => "Interlaced gold ribbons over a finely textured royal-purple ground.", 12 => "Angular sand, ochre and dark-earth splinter camouflage.", _ => "Restore the original game materials. No items are required to save an appearance.", }; ((TMP_Text)_objective).text = (flag3 ? "CURRENT FINISH" : (flag2 ? "READY TO APPLY" : "LOCKED FINISH")) + "\nPattern swatch"; ((TMP_Text)_sources).text = (flag2 ? "No item needed. Applies when you equip it.\nSaved in this world; visible only to you." : ("Complete this quest to unlock:\n" + (QuestCatalog.Find(SkinCatalog.Quests[_filter])?.Title ?? "Waiting for quest data"))); ((TMP_Text)_reward).text = Name(text2); ((TMP_Text)_rewardXp).text = "Current: " + SkinCatalog.Names[value2]; ((TMP_Text)_rewardXp).fontSizeMax = 17f; ((TMP_Text)_rewardXp).fontSizeMin = 14f; SetIcon(_rewardIcon, text2); SetFinishPreview(_targetIcon, _filter); if (_filter == 0) { SetIcon(_targetIcon, text2); } ((Graphic)_objectiveFill).rectTransform.anchorMax = new Vector2((float)(flag2 ? 1 : 0), 1f); _primary.Enabled = flag2 && !flag3; ((TMP_Text)_primary.Label).text = ((!flag2) ? "UNLOCK THROUGH QUESTS" : (flag3 ? "APPLIED" : ((_filter == 0) ? "RESTORE ORIGINAL" : "APPLY TO THIS EQUIPMENT"))); ((Graphic)_primary.Image).color = (_primary.Enabled ? _accent : _panel); ((Graphic)_primary.Label).color = (Color)(_primary.Enabled ? new Color(0.025f, 0.06f, 0.065f) : _muted); ((Component)_abandon.Image).gameObject.SetActive(false); foreach (ActionBox button in _buttons) { button.BaseColor = ((Graphic)button.Image).color; } } private void SetFinishPreview(Image image, int finish) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) ((Behaviour)image).enabled = finish > 0; if (finish == 0) { return; } if (!_finishPreviews.TryGetValue(finish, out var value)) { Texture2D val = FinishTextures.Create(finish); try { value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } catch { Object.Destroy((Object)(object)val); throw; } _finishPreviews[finish] = value; } image.sprite = value; ((Graphic)image).color = Color.white; image.preserveAspect = true; } private void LayoutFinishes(bool enabled) { ((TMP_Text)_sidebarTitle).text = (enabled ? "1 / CHOOSE FINISH" : "THE QUEST BOARD"); ((TMP_Text)_briefingTitle).text = (enabled ? "3 / PREVIEW & APPLY" : "ASSIGNMENT BRIEF"); ((Component)_finishPage).gameObject.SetActive(enabled); ((Component)_collection).gameObject.SetActive(enabled); ((Component)_level).gameObject.SetActive(!enabled); ((Component)_xp).gameObject.SetActive(!enabled); ((Component)_levelTrack).gameObject.SetActive(!enabled); ((Component)_objectiveTrack).gameObject.SetActive(!enabled); ((TMP_Text)_rewardXp).fontSizeMax = 23f; ((TMP_Text)_rewardXp).fontSizeMin = 18f; Place(((Graphic)_targetIcon).rectTransform, 0.06f, enabled ? 0.46f : 0.51f, enabled ? 0.43f : 0.2f, enabled ? 0.7f : 0.64f); Place(((TMP_Text)_objective).rectTransform, enabled ? 0.48f : 0.24f, enabled ? 0.46f : 0.505f, 0.94f, enabled ? 0.7f : 0.64f); Place(((TMP_Text)_description).rectTransform, 0.06f, enabled ? 0.71f : 0.65f, 0.94f, 0.82f); Place(((TMP_Text)_sources).rectTransform, 0.06f, 0.35f, 0.94f, enabled ? 0.445f : 0.477f); } private void Refresh() { //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_0761: Unknown result type (might be due to invalid IL or missing references) //IL_0777: Unknown result type (might be due to invalid IL or missing references) //IL_0796: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_0907: Unknown result type (might be due to invalid IL or missing references) //IL_07d2: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0bf2: Unknown result type (might be due to invalid IL or missing references) //IL_0bea: Unknown result type (might be due to invalid IL or missing references) //IL_0c30: Unknown result type (might be due to invalid IL or missing references) //IL_0c15: Unknown result type (might be due to invalid IL or missing references) //IL_0cdf: Unknown result type (might be due to invalid IL or missing references) //IL_0ce4: Unknown result type (might be due to invalid IL or missing references) if (_cosmetics) { RefreshSkins(); return; } _visible.Clear(); if (_view != null) { foreach (QuestRow row in _view.Rows) { Quest quest = QuestCatalog.Find(row.Id); if (quest != null && ((_filter == 0 && row.State != "COMPLETED") || (_filter == 1 && (row.State == "ACTIVE" || row.State == "READY" || row.State == "UNAVAILABLE")) || (_filter == 2 && quest.Hunt && row.State != "COMPLETED") || (_filter == 3 && !quest.Hunt && row.State != "COMPLETED") || (_filter == 4 && row.State == "COMPLETED"))) { _visible.Add(row); } } } _selection = Mathf.Clamp(_selection, 0, Math.Max(0, _visible.Count - 1)); int num = _view?.Xp ?? 0; int num2 = QuestCatalog.Level(num); int num3 = QuestCatalog.Threshold(num2); int num4 = QuestCatalog.Threshold(num2 + 1); ((TMP_Text)_level).text = $"LEVEL {num2:00}"; ((TMP_Text)_xp).text = $"{num - num3:N0} / {num4 - num3:N0} XP\n{_view?.Rows.Count((QuestRow r) => r.State == "COMPLETED") ?? 0} assignments completed"; for (int num5 = 0; num5 < _tabs.Length; num5++) { ((Component)_tabs[num5].Image).gameObject.SetActive(true); int tab = num5; _tabs[num5].Click = delegate { Filter(tab); }; ((TMP_Text)_tabs[num5].Label).text = _filters[num5]; ((Graphic)_tabs[num5].Image).color = (Color)((num5 == _filter) ? new Color(_accent.r * 0.23f, _accent.g * 0.23f, _accent.b * 0.23f, 1f) : _panel); ((Graphic)_tabs[num5].Label).color = ((num5 == _filter) ? _accent : _muted); } int num6 = _selection / 6; ((TMP_Text)_pagination).text = ((_visible.Count == 0) ? "NO ASSIGNMENTS" : $"{num6 + 1} / {(_visible.Count + 5) / 6}"); ((TMP_Text)_listTitle).text = _filters[_filter].ToUpperInvariant() + $" / {_visible.Count}"; for (int num7 = 0; num7 < _rows.Length; num7++) { int num8 = num6 * 6 + num7; ((Component)_rows[num7].Image).gameObject.SetActive(num8 < _visible.Count); if (num8 < _visible.Count) { QuestRow questRow = _visible[num8]; Quest quest2 = QuestCatalog.Find(questRow.Id); ((TMP_Text)_rows[num7].Label).text = quest2.Title; ((Graphic)_rows[num7].Label).color = ((questRow.State == "LOCKED") ? _muted : _ink); ((Graphic)_rows[num7].Image).color = (Color)((num8 == _selection) ? new Color(_accent.r * 0.21f, _accent.g * 0.21f, _accent.b * 0.21f, 1f) : _panel); ((TMP_Text)_rowStatus[num7]).text = $"{questRow.State} / LV {quest2.Level}" + ((questRow.State == "ACTIVE" || questRow.State == "READY") ? $" / {Math.Min(questRow.Count, quest2.Amount)}/{quest2.Amount}" : ""); ((Graphic)_rowStatus[num7]).color = ((questRow.State == "READY") ? _accent : _muted); SetIcon(_rowIcons[num7], quest2.Reward); int capture = num8; _rows[num7].Click = delegate { Select(capture); }; } } QuestRow selected = Selected; if (selected == null) { ((TMP_Text)_title).text = ((_filter == 1) ? "Your next adventure awaits" : "Nothing here yet"); ((TMP_Text)_description).text = "Browse All assignments and accept a contract to begin. Every assignment rewards experience."; ((TMP_Text)_objective).text = ""; ((TMP_Text)_sources).text = ""; ((TMP_Text)_reward).text = ""; ((TMP_Text)_rewardXp).text = ""; ((Behaviour)_rewardIcon).enabled = false; ((Behaviour)_targetIcon).enabled = false; _primary.Enabled = false; ((TMP_Text)_primary.Label).text = "Select an assignment"; ((Graphic)_primary.Image).color = _panel; ((Graphic)_primary.Label).color = _muted; ((Graphic)_objectiveFill).rectTransform.anchorMax = new Vector2(0f, 1f); ((Component)_abandon.Image).gameObject.SetActive(false); { foreach (ActionBox button in _buttons) { button.BaseColor = ((Graphic)button.Image).color; } return; } } Quest quest3 = QuestCatalog.Find(selected.Id); ((TMP_Text)_title).text = quest3.Title; ((TMP_Text)_description).text = quest3.Description; if (selected.State == "UNAVAILABLE") { ((TMP_Text)_description).text = "This assignment needs an item or creature missing from this game build. You can abandon it to free a journal slot; no materials will be taken."; } ((TMP_Text)_objective).text = $"{(quest3.Hunt ? "DEFEAT" : "DELIVER")} {Name(quest3.Target)}\n{Math.Min(selected.Count, quest3.Amount)} / {quest3.Amount}"; ((Graphic)_objectiveFill).rectTransform.anchorMax = new Vector2(Mathf.Clamp01((float)selected.Count / (float)quest3.Amount), 1f); ((TMP_Text)_sources).text = (quest3.Hunt ? "Your confirmed kills after accepting this quest." : $"CARRIED {selected.Carried} BUILT STORAGE {selected.Stored}\nCarried items first; then eligible loaded storage.\nHost: shared built storage. Guests: own placements."); ((TMP_Text)_reward).text = Name(quest3.Reward) + " x1"; ((TMP_Text)_rewardXp).text = $"+{quest3.Xp} XP"; string text = SkinCatalog.RewardFor(quest3.Id); ((TMP_Text)_rewardXp).fontSize = ((text.Length != 0) ? 18 : 23); if (text.Length != 0) { TextMeshProUGUI rewardXp = _rewardXp; ((TMP_Text)rewardXp).text = ((TMP_Text)rewardXp).text + "\nSKIN: " + SkinCatalog.Names[Array.IndexOf(SkinCatalog.Quests, quest3.Id)]; } SetIcon(_rewardIcon, quest3.Reward); SetIcon(_targetIcon, quest3.Hunt ? quest3.Reward : quest3.Target); ((Behaviour)_targetIcon).enabled = !quest3.Hunt; _primary.Enabled = _pendingClaim == null && (selected.State == "AVAILABLE" || selected.State == "READY"); TextMeshProUGUI label = _primary.Label; ((TMP_Text)label).text = selected.State switch { "AVAILABLE" => "ACCEPT ASSIGNMENT", "READY" => (_confirmation == "claim:" + selected.Id) ? "CONFIRM TURN-IN" : "COMPLETE & COLLECT", "LOCKED" => $"UNLOCKS AT LEVEL {quest3.Level}", "COMPLETED" => "REWARD COLLECTED", "UNAVAILABLE" => "UNAVAILABLE IN THIS GAME BUILD", _ => "IN PROGRESS", }; if (_pendingClaim != null) { ((TMP_Text)_primary.Label).text = "PROCESSING TURN-IN..."; } ((Graphic)_primary.Image).color = (_primary.Enabled ? _accent : _panel); ((Graphic)_primary.Label).color = (Color)(_primary.Enabled ? new Color(0.025f, 0.06f, 0.065f, 1f) : _muted); ((Component)_abandon.Image).gameObject.SetActive(selected.State == "ACTIVE" || selected.State == "READY" || selected.State == "UNAVAILABLE"); ((TMP_Text)_abandon.Label).text = ((_confirmation == "abandon:" + selected.Id) ? "CONFIRM ABANDON" : "Abandon assignment"); foreach (ActionBox button2 in _buttons) { button2.BaseColor = ((Graphic)button2.Image).color; } } private static string Name(string item) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse(item, out Items result) && ItemDatabase.GetItemInfo(result) != null) { string itemName = ItemDatabase.GetItemName(result); if (!string.IsNullOrWhiteSpace(itemName)) { return itemName; } } return Regex.Replace(item, "([a-z])([A-Z])", "$1 $2"); } private static void SetIcon(Image image, string item) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) object sprite; if (!Enum.TryParse(item, out Items result)) { sprite = null; } else { ItemDatabaseEntry itemInfo = ItemDatabase.GetItemInfo(result); sprite = ((itemInfo != null) ? itemInfo.icon : null); } image.sprite = (Sprite)sprite; ((Behaviour)image).enabled = (Object)(object)image.sprite != (Object)null; ((Graphic)image).color = Color.white; image.preserveAspect = true; } private void LoadTheme() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) try { string path = Path.Combine(Paths.ConfigPath, "com.holden.infernoprotocol.betterui.cfg"); if (File.Exists(path)) { string[] array = File.ReadAllLines(path); foreach (string text in array) { if (text.TrimStart().StartsWith("ColorPalette =", StringComparison.Ordinal) && int.TryParse(text.Split('=')[1].Trim(), out var result)) { _accent = (Color)(result switch { 0 => new Color(0.43f, 1f, 0.52f), 1 => new Color(0.43f, 0.68f, 1f), 2 => new Color(0.35f, 0.91f, 0.93f), 3 => new Color(0.77f, 0.57f, 1f), _ => new Color(1f, 0.76f, 0.39f), }); } } } } catch { } ((Graphic)_xpFill).color = _accent; ((Graphic)_objectiveFill).color = _accent; ((Graphic)_rewardXp).color = _accent; ((Graphic)_hudFill).color = _accent; ((Graphic)_hudLevel).color = _ink; } private void UpdateLevelHud(int xp) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (xp >= 0 && xp <= 10000000 && xp != _hudXp) { _hudXp = xp; int num = QuestCatalog.Level(xp); int num2 = QuestCatalog.Threshold(num); int num3 = QuestCatalog.Threshold(num + 1); ((TMP_Text)_hudLevel).text = "LV " + num; ((Graphic)_hudFill).rectTransform.anchorMax = new Vector2((num >= 100) ? 1f : Mathf.Clamp01((float)(xp - num2) / (float)(num3 - num2)), 1f); } } private void Build() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0588: Unknown result type (might be due to invalid IL or missing references) //IL_0768: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_0817: Unknown result type (might be due to invalid IL or missing references) //IL_0853: Unknown result type (might be due to invalid IL or missing references) //IL_088f: Unknown result type (might be due to invalid IL or missing references) //IL_08c0: Unknown result type (might be due to invalid IL or missing references) //IL_08fb: Unknown result type (might be due to invalid IL or missing references) //IL_093a: Unknown result type (might be due to invalid IL or missing references) //IL_0970: Unknown result type (might be due to invalid IL or missing references) //IL_09ab: Unknown result type (might be due to invalid IL or missing references) //IL_09ea: Unknown result type (might be due to invalid IL or missing references) //IL_0a17: Unknown result type (might be due to invalid IL or missing references) //IL_0a52: Unknown result type (might be due to invalid IL or missing references) //IL_0a8e: Unknown result type (might be due to invalid IL or missing references) //IL_0b43: Unknown result type (might be due to invalid IL or missing references) //IL_0b83: Unknown result type (might be due to invalid IL or missing references) //IL_0bd6: Unknown result type (might be due to invalid IL or missing references) //IL_0c10: Unknown result type (might be due to invalid IL or missing references) //IL_0c3d: Unknown result type (might be due to invalid IL or missing references) //IL_0c74: Unknown result type (might be due to invalid IL or missing references) //IL_0cb0: Unknown result type (might be due to invalid IL or missing references) //IL_0cef: Unknown result type (might be due to invalid IL or missing references) //IL_0d1c: Unknown result type (might be due to invalid IL or missing references) //IL_0d57: Unknown result type (might be due to invalid IL or missing references) //IL_0e25: Unknown result type (might be due to invalid IL or missing references) //IL_0e6a: Unknown result type (might be due to invalid IL or missing references) //IL_0eae: Unknown result type (might be due to invalid IL or missing references) //IL_0edc: Unknown result type (might be due to invalid IL or missing references) //IL_06ad: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) _canvas = new GameObject("FieldQuests_Canvas", (Type[])(object)new Type[3] { Il2CppType.Of(), Il2CppType.Of(), Il2CppType.Of() }); Canvas component = _canvas.GetComponent(); component.renderMode = (RenderMode)0; component.sortingOrder = 32000; CanvasScaler component2 = _canvas.GetComponent(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1920f, 1080f); component2.screenMatchMode = (ScreenMatchMode)1; _scrim = Box("Backdrop", _canvas.transform, 0f, 0f, 1f, 1f, new Color(0f, 0f, 0f, 0.54f)); Image val = Box("Journal", _canvas.transform, 0.04f, 0.055f, 0.96f, 0.945f, new Color(0.027f, 0.04f, 0.052f, 0.98f)); _window = ((Component)val).gameObject; _brand = Label("Brand", ((Component)val).transform, 0.025f, 0.91f, 0.85f, 0.98f, "FIELD NOTES / QUEST BOARD", 31f, _ink, bold: true); _receipt = Label("Subtitle", ((Component)val).transform, 0.026f, 0.858f, 0.975f, 0.906f, "A safer camp. A stronger survivor. One assignment at a time.", 19f, _muted, bold: true); Button("Close", ((Component)val).transform, 0.88f, 0.9f, 0.975f, 0.965f, "CLOSE [B]", Close); Box("Divider", ((Component)val).transform, 0.025f, 0.85f, 0.975f, 0.852f, _muted * 0.4f); Image val2 = Box("Sidebar", ((Component)val).transform, 0.02f, 0.13f, 0.235f, 0.825f, _panel); _sidebarTitle = Label("Agent", ((Component)val2).transform, 0.09f, 0.84f, 0.91f, 0.96f, "THE QUEST BOARD", 21f, _ink, bold: true); _welcome = Label("Welcome", ((Component)val2).transform, 0.09f, 0.69f, 0.91f, 0.84f, "Bring what the camp needs.\nTake what keeps you alive.", 18f, _muted); _finishPrevious = Button("PreviousFinishes", ((Component)val2).transform, 0.045f, 0.71f, 0.3f, 0.79f, "<", delegate { Filter(SkinCatalog.PageStart(_filter, -1)); }); _finishNext = Button("NextFinishes", ((Component)val2).transform, 0.7f, 0.71f, 0.955f, 0.79f, ">", delegate { Filter(SkinCatalog.PageStart(_filter, 1)); }); _finishPage = Label("FinishPage", ((Component)val2).transform, 0.32f, 0.71f, 0.68f, 0.79f, "", 17f, _muted); ((TMP_Text)_finishPage).alignment = (TextAlignmentOptions)514; _collection = Label("Collection", ((Component)val2).transform, 0.09f, 0.025f, 0.91f, 0.18f, "", 16f, _muted); ((Component)_finishPrevious.Image).gameObject.SetActive(false); ((Component)_finishNext.Image).gameObject.SetActive(false); for (int num = 0; num < 5; num++) { int tab = num; _tabs[num] = Button("Filter" + num, ((Component)val2).transform, 0.045f, 0.58f - 0.09f * (float)num, 0.955f, 0.66f - 0.09f * (float)num, _filters[num], delegate { Filter(tab); }); } _level = Label("Level", ((Component)val2).transform, 0.09f, 0.12f, 0.9f, 0.2f, "LEVEL 01", 25f, _ink, bold: true); _xpFill = Box("XPFill", ((Component)(_levelTrack = Box("XPTrack", ((Component)val2).transform, 0.09f, 0.092f, 0.91f, 0.105f, new Color(0.16f, 0.2f, 0.22f)))).transform, 0f, 0f, 0f, 1f, _accent); _xp = Label("XPText", ((Component)val2).transform, 0.09f, 0.01f, 0.95f, 0.085f, "", 15f, _muted); Image val3 = Box("Assignments", ((Component)val).transform, 0.248f, 0.13f, 0.598f, 0.825f, Color.clear); _listTitle = Label("ListTitle", ((Component)val3).transform, 0.025f, 0.91f, 0.99f, 1f, "ALL ASSIGNMENTS", 20f, _ink, bold: true); for (int num2 = 0; num2 < 6; num2++) { _rows[num2] = Button("Quest" + num2, ((Component)val3).transform, 0.01f, 0.79f - 0.132f * (float)num2, 0.99f, 0.912f - 0.132f * (float)num2, "", delegate { }); Place(((TMP_Text)_rows[num2].Label).rectTransform, 0.17f, 0.42f, 0.97f, 0.89f); ((TMP_Text)_rows[num2].Label).alignment = (TextAlignmentOptions)4097; ((TMP_Text)_rows[num2].Label).fontSize = 21f; _rowStatus[num2] = Label("State", ((Component)_rows[num2].Image).transform, 0.17f, 0.08f, 0.97f, 0.4f, "", 13f, _muted); _rowIcons[num2] = Box("RewardPreview", ((Component)_rows[num2].Image).transform, 0.015f, 0.12f, 0.145f, 0.88f, Color.white); } Button("Previous", ((Component)val3).transform, 0.02f, 0.005f, 0.22f, 0.08f, "< PREV", delegate { Select(_selection - 6); }); _pagination = Label("Pages", ((Component)val3).transform, 0.28f, 0.005f, 0.72f, 0.08f, "", 15f, _muted); ((TMP_Text)_pagination).alignment = (TextAlignmentOptions)514; Button("Next", ((Component)val3).transform, 0.78f, 0.005f, 0.98f, 0.08f, "NEXT >", delegate { Select(_selection + 6); }); Image val4 = Box("Briefing", ((Component)val).transform, 0.615f, 0.13f, 0.98f, 0.825f, _panel); _briefingTitle = Label("BriefingTitle", ((Component)val4).transform, 0.06f, 0.92f, 0.94f, 0.99f, "ASSIGNMENT BRIEF", 14f, _accent, bold: true); _title = Label("Title", ((Component)val4).transform, 0.06f, 0.82f, 0.94f, 0.925f, "", 29f, _ink, bold: true); _description = Label("Description", ((Component)val4).transform, 0.06f, 0.65f, 0.94f, 0.82f, "", 19f, _muted); _targetIcon = Box("TargetIcon", ((Component)val4).transform, 0.06f, 0.51f, 0.2f, 0.64f, Color.white); _objective = Label("Objective", ((Component)val4).transform, 0.24f, 0.505f, 0.94f, 0.64f, "", 21f, _ink, bold: true); _objectiveFill = Box("Progress", ((Component)(_objectiveTrack = Box("ObjectiveTrack", ((Component)val4).transform, 0.06f, 0.482f, 0.94f, 0.492f, new Color(0.16f, 0.2f, 0.22f)))).transform, 0f, 0f, 0f, 1f, _accent); _sources = Label("Sources", ((Component)val4).transform, 0.06f, 0.35f, 0.94f, 0.477f, "", 16f, _muted); Image val5 = Box("Reward", ((Component)val4).transform, 0.045f, 0.205f, 0.955f, 0.34f, new Color(0.065f, 0.1f, 0.12f)); _rewardIcon = Box("Icon", ((Component)val5).transform, 0.035f, 0.06f, 0.2f, 0.94f, Color.white); _reward = Label("Name", ((Component)val5).transform, 0.23f, 0.45f, 0.98f, 0.95f, "", 19f, _ink, bold: true); _rewardXp = Label("Experience", ((Component)val5).transform, 0.23f, 0.05f, 0.98f, 0.48f, "", 23f, _accent, bold: true); _primary = Button("Primary", ((Component)val4).transform, 0.06f, 0.095f, 0.94f, 0.183f, "", Primary); _abandon = Button("Abandon", ((Component)val4).transform, 0.15f, 0.012f, 0.85f, 0.082f, "", Abandon); _status = Label("Status", ((Component)val).transform, 0.025f, 0.018f, 0.975f, 0.1f, "", 17f, _muted); _prompt = Label("Prompt", _canvas.transform, 0.3f, 0.18f, 0.7f, 0.27f, "", 22f, _ink, bold: true); ((TMP_Text)_prompt).alignment = (TextAlignmentOptions)514; Image val6 = Box("ConfirmationShade", ((Component)val).transform, 0f, 0f, 1f, 1f, new Color(0f, 0f, 0f, 0.75f)); _dialog = ((Component)val6).gameObject; Image val7 = Box("ConfirmationCard", ((Component)val6).transform, 0.25f, 0.2f, 0.75f, 0.8f, _panel); Box("AccentRule", ((Component)val7).transform, 0f, 0.986f, 1f, 1f, _accent); _dialogTitle = Label("Heading", ((Component)val7).transform, 0.065f, 0.81f, 0.935f, 0.96f, "", 30f, _ink, bold: true); _dialogBody = Label("Details", ((Component)val7).transform, 0.065f, 0.4f, 0.935f, 0.8f, "", 23f, _ink); Image val8 = Box("Receipt", ((Component)val7).transform, 0.05f, 0.21f, 0.95f, 0.39f, new Color(0.075f, 0.105f, 0.12f)); _dialogIcon = Box("RewardIcon", ((Component)val8).transform, 0.025f, 0.08f, 0.17f, 0.92f, Color.white); _dialogReward = Label("Reward", ((Component)val8).transform, 0.2f, 0.06f, 0.97f, 0.94f, "", 22f, _ink, bold: true); _dialogCancel = Button("Cancel", ((Component)val7).transform, 0.065f, 0.055f, 0.475f, 0.17f, "CANCEL", CancelDialog); _dialogConfirm = Button("Confirm", ((Component)val7).transform, 0.505f, 0.055f, 0.935f, 0.17f, "CONFIRM", ConfirmDialog); _dialog.SetActive(false); Image val9 = Box("ExplorationLevel", _canvas.transform, 0.025f, 0.911f, 0.1f, 0.947f, new Color(0.025f, 0.04f, 0.052f, 0.28f)); _levelHud = ((Component)val9).gameObject; _hudLevel = Label("LevelNumber", ((Component)val9).transform, 0.065f, 0.25f, 0.95f, 0.95f, "LV 1", 18f, _ink, bold: true); Image val10 = Box("Track", ((Component)val9).transform, 0.07f, 0.15f, 0.93f, 0.2f, new Color(0.15f, 0.19f, 0.21f, 0.65f)); _hudFill = Box("Fill", ((Component)val10).transform, 0f, 0f, 0f, 1f, _accent); _levelHud.SetActive(false); _window.SetActive(false); ((Component)_scrim).gameObject.SetActive(false); ((Component)_prompt).gameObject.SetActive(false); } private ActionBox Button(string name, Transform parent, float x0, float y0, float x1, float y1, string text, Action click) { //IL_000a: 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) Image val = Box(name, parent, x0, y0, x1, y1, _panel); ActionBox actionBox = new ActionBox { Image = val, Click = click, Label = Label("Text", ((Component)val).transform, 0.035f, 0.06f, 0.965f, 0.94f, text, 17f, _ink, bold: true) }; ((TMP_Text)actionBox.Label).alignment = (TextAlignmentOptions)514; _buttons.Add(actionBox); return actionBox; } private static Image Box(string name, Transform parent, float x0, float y0, float x1, float y1, Color color) { //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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, (Type[])(object)new Type[3] { Il2CppType.Of(), Il2CppType.Of(), Il2CppType.Of() }); val.transform.SetParent(parent, false); Image component = val.GetComponent(); ((Graphic)component).color = color; ((Graphic)component).raycastTarget = false; Place(((Graphic)component).rectTransform, x0, y0, x1, y1); return component; } private static TextMeshProUGUI Label(string name, Transform parent, float x0, float y0, float x1, float y1, string text, float size, Color color, bool bold = false) { //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) //IL_0064: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, (Type[])(object)new Type[3] { Il2CppType.Of(), Il2CppType.Of(), Il2CppType.Of() }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent(); ((TMP_Text)component).text = text; ((TMP_Text)component).fontSize = size; ((TMP_Text)component).fontSizeMax = size; ((TMP_Text)component).fontSizeMin = size * 0.78f; ((TMP_Text)component).enableAutoSizing = true; ((Graphic)component).color = color; ((TMP_Text)component).fontStyle = (FontStyles)(bold ? 1 : 0); ((TMP_Text)component).enableWordWrapping = true; ((TMP_Text)component).alignment = (TextAlignmentOptions)4097; ((Graphic)component).raycastTarget = false; ((TMP_Text)component).richText = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)1; Place(((TMP_Text)component).rectTransform, x0, y0, x1, y1); return component; } private static void Place(RectTransform rect, float x0, float y0, float x1, float y1) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(x0, y0); rect.anchorMax = new Vector2(x1, y1); Vector2 offsetMin = (rect.offsetMax = Vector2.zero); rect.offsetMin = offsetMin; } public void Dispose() { foreach (Sprite value in _finishPreviews.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value.texture); Object.Destroy((Object)(object)value); } } _finishPreviews.Clear(); if (BlockingInput) { RestoreInput(); } IsOpen = false; if ((Object)(object)_canvas != (Object)null) { Object.Destroy((Object)(object)_canvas); } _canvas = null; } } [BepInPlugin("com.holden.infernoprotocol.fieldquests", "ContentPlus", "0.5.0")] public sealed class QuestPlugin : BasePlugin { [HarmonyPatch] private static class Hooks { [HarmonyPostfix] [HarmonyPatch(typeof(ANPC), "OnDeathServer_InternalServer")] private static void Death(ANPC __instance, ref DamageData __0) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) try { Controller?.Service?.Death(__instance, __0); } catch (Exception ex) { LogSource.LogWarning((object)("Quest kill tracking: " + ex.Message)); } } [HarmonyPostfix] [HarmonyPatch(typeof(ANPC), "OnNetworkSpawn")] private static void Spawn(ANPC __instance) { Controller?.Service?.Respawn(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Player), "ApplyMovement")] private static bool Move() { if (!((Object)(object)Controller == (Object)null)) { return !Controller.BlockingInput; } return true; } } internal static ManualLogSource LogSource; internal static QuestController Controller; private Harmony _harmony; public override void Load() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown LogSource = ((BasePlugin)this).Log; Controller = ((BasePlugin)this).AddComponent(); _harmony = new Harmony("com.holden.infernoprotocol.fieldquests"); _harmony.PatchAll(typeof(Hooks)); ((BasePlugin)this).Log.LogInfo((object)"ContentPlus 0.5.0 loaded. Quest board, XP progression and equipment finishes. Use Interact to read the board (F9 also works)."); } public override bool Unload() { Controller?.Cleanup(); if ((Object)(object)Controller != (Object)null) { Object.Destroy((Object)(object)Controller); } Controller = null; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } return true; } } internal sealed class QuestService { private sealed class Container { internal string Key; internal NetworkList Inventory; internal bool Carried; } private Dictionary _players = new Dictionary(); private string _saveFile; private bool _faulted; private readonly HashSet _deaths = new HashSet(); private static Dictionary _unavailable = new Dictionary(); internal bool Ready { get { if (_saveFile != null) { return !_faulted; } return false; } } internal void Load() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown string saveFile = SaveManager.GetSaveFile("FieldQuests.v1.json"); if (string.IsNullOrWhiteSpace(saveFile)) { throw new InvalidOperationException("No world save path."); } if (File.Exists(saveFile)) { _players = JsonSerializer.Deserialize>(File.ReadAllText(saveFile)) ?? throw new InvalidDataException("Empty quest save."); foreach (Progress value in _players.Values) { if (value == null || value.Active == null || value.Completed == null || value.Xp < 0 || value.Xp > 10000000) { throw new InvalidDataException("Invalid quest progress."); } } } _saveFile = saveFile; ManualLogSource logSource = QuestPlugin.LogSource; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Quest save loaded: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(saveFile); } logSource.LogInfo(val); } internal void SaveWithWorld() { if (Ready) { string text = _saveFile + ".tmp"; Directory.CreateDirectory(Path.GetDirectoryName(_saveFile)); File.WriteAllText(text, JsonSerializer.Serialize(_players)); if (File.Exists(_saveFile)) { File.Replace(text, _saveFile, _saveFile + ".bak"); } else { File.Move(text, _saveFile); } } } private Progress Get(Player player) { string key = player.platformId.ToString(CultureInfo.InvariantCulture); if (!_players.TryGetValue(key, out var value)) { _players.Add(key, value = new Progress()); } return value; } internal void Respawn(ANPC npc) { _deaths.Remove(((Object)npc).GetInstanceID()); } internal void Death(ANPC npc, DamageData damage) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) NetworkBehaviour val = default(NetworkBehaviour); if (Ready && ((NetworkBehaviour)npc).IsServer && !_deaths.Contains(((Object)npc).GetInstanceID()) && ((NetworkBehaviourReference)(ref damage.source)).TryGet(ref val, NetworkManager.Singleton)) { Player val2 = ((Il2CppObjectBase)val).TryCast(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).GetComponentInParent(); } if (!((Object)(object)val2 == (Object)null) && ((NetworkBehaviour)val2).IsSpawned && HasPersistentIdentity(val2)) { _deaths.Add(((Object)npc).GetInstanceID()); Get(val2).Kill(((object)npc.npcId/*cast due to .constrained prefix*/).ToString()); } } } internal QuestView Execute(Player player, string verb, string id, Vector3 npcPosition) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) if (!Ready) { return new QuestView { Message = "Quest save unavailable. Check the game log." }; } if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsSpawned || ((ANetworkEntity)player).isDead) { return new QuestView { Message = "Player unavailable." }; } if (!HasPersistentIdentity(player)) { return new QuestView { Message = "A persistent platform ID is required for multiplayer quest progress." }; } Progress progress = Get(player); Progress progress2 = progress; if (progress2.Skins == null) { Dictionary dictionary = (progress2.Skins = new Dictionary()); } switch (verb) { case "progress": return Appearance(progress, new QuestView { ProgressOnly = true, Xp = progress.Xp }); case "wardrobe": return Appearance(progress, new QuestView { Xp = progress.Xp }); case "skin": { if (Vector3.Distance(((Component)player).transform.position, npcPosition) > 5f) { return View(player, "Return to the cosmetic station."); } string[] array = id.Split('|'); if (SaveManager.isBusy || array.Length != 2 || !int.TryParse(array[1], out var result) || !SkinCatalog.Select(progress.Skins, progress.Completed, array[0], result)) { return View(player, "That finish is unavailable or locked."); } SaveWithWorld(); return Appearance(progress, new QuestView { Xp = progress.Xp, Message = ((result == 0) ? "Original appearance restored." : "Appearance saved. Applies when you equip this item.") }); } default: { string message = ""; if (verb != "view") { if (Vector3.Distance(((Component)player).transform.position, npcPosition) > 5f) { return View(player, "Return to the quest board to manage assignments."); } if (SaveManager.isBusy) { return View(player, "The world is saving. Try again in a moment."); } Quest quest = QuestCatalog.Find(id); if (quest == null) { return View(player, "Unknown assignment."); } if (_unavailable.ContainsKey(id) && verb != "abandon") { return View(player, "This assignment is unavailable in this game build. No items were taken."); } message = verb switch { "accept" => progress.Accept(quest), "abandon" => progress.Active.Remove(quest.Id) ? "Quest abandoned. Its hunt progress was cleared." : "Quest is not active.", "claim" => Claim(player, progress, quest), _ => "Unknown action.", }; } return View(player, message); } } } private static bool HasPersistentIdentity(Player player) { if (player.platformId == 0L) { if (NetworkManager.Singleton.IsServer && ((Il2CppObjectBase)NetworkManager.Singleton.ConnectedClientsList).Cast>().Count == 1) { return ((NetworkBehaviour)player).OwnerClientId == NetworkManager.Singleton.LocalClientId; } return false; } return true; } private List Containers(Player player, bool includeStorage = true) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Invalid comparison between Unknown and I4 //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Invalid comparison between Unknown and I4 List list = new List { new Container { Key = "inventory", Inventory = player.inventory, Carried = true } }; if ((Object)(object)player.cachedBackpack != (Object)null && ((NetworkBehaviour)player.cachedBackpack).IsSpawned) { list.Add(new Container { Key = "backpack", Inventory = player.cachedBackpack.inventory, Carried = true }); } if (!includeStorage) { return list; } HashSet hashSet = new HashSet(); foreach (Container item in list) { hashSet.Add(((Il2CppObjectBase)item.Inventory).Pointer); } bool localHost = NetworkManager.Singleton.IsServer && ((NetworkBehaviour)player).OwnerClientId == NetworkManager.Singleton.LocalClientId; if (ItemStash.allStashes != null) { Enumerator enumerator2 = ItemStash.allStashes.GetEnumerator(); while (enumerator2.MoveNext()) { ItemStash current2 = enumerator2.Current; if ((Object)(object)current2 == (Object)null || !((NetworkBehaviour)current2).IsSpawned || current2.inventory == null) { continue; } APlacable attachedPlacable = ((ANetworkPlacable)current2).attachedPlacable; if (!((Object)(object)attachedPlacable == (Object)null)) { bool playerChest = (int)attachedPlacable.placableItem == 280 || (int)attachedPlacable.placableItem == 367; if (StorageAccess.CanUse(attachedPlacable.placedByPlatformId, player.platformId, localHost, attachedPlacable.loadedFromSave, playerChest, attachedPlacable.placableId, (Object)(object)((Il2CppObjectBase)current2).TryCast() != (Object)null) && hashSet.Add(((Il2CppObjectBase)current2.inventory).Pointer)) { list.Add(new Container { Key = "storage-" + ((Object)current2).GetInstanceID(), Inventory = current2.inventory }); } } } } return list.OrderBy((Container c) => (!c.Carried) ? 1 : 0).ThenBy((Container c) => c.Key, StringComparer.Ordinal).ToList(); } private unsafe static StackData Pack(ItemData d) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new StackData(((object)(*(Items*)(&d.item))/*cast due to .constrained prefix*/).ToString(), d.count, d.durability, d.customVar1, d.customVar2); } private static ItemData Unpack(StackData d) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001d: 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 (d.Count != 0) { return new ItemData { item = Enum.Parse(d.Item), count = checked((byte)d.Count), durability = d.Durability, customVar1 = d.Var1, customVar2 = d.Var2 }; } return ItemData.empty; } private string Claim(Player player, Progress p, Quest q) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) if (p.Completed.Contains(q.Id)) { return "Already rewarded."; } if (!p.Active.TryGetValue(q.Id, out var value)) { return "Accept this assignment first."; } if (q.Hunt && value < q.Amount) { return "The hunt is still in progress."; } if (p.Xp > int.MaxValue - q.Xp) { return "XP limit reached. Nothing was consumed."; } List list = Containers(player, !q.Hunt); List list2 = new List(); foreach (Container item in list) { for (int i = 0; i < item.Inventory.Count; i++) { list2.Add(new Slot { Container = item.Key, Index = i, RewardDestination = item.Carried, Before = Pack(item.Inventory[i]) }); } } ItemData val = ItemData.Create(Enum.Parse(q.Reward), (byte)1); if (val.count == 0 || val.item != Enum.Parse(q.Reward)) { return "Reward unavailable. Nothing was consumed."; } string itemName = ItemDatabase.GetItemName(val.item); if (!TurnInPlanner.Plan(list2, q, Pack(val), out var error)) { return error; } List changed = list2.Where((Slot s) => s.Before != s.After).ToList(); Dictionary> inventories = list.ToDictionary((Container c) => c.Key, (Container c) => c.Inventory); try { SlotTransaction.Commit(changed, (Slot s) => Pack(inventories[s.Container][s.Index]), delegate(Slot s, StackData data) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) inventories[s.Container][s.Index] = Unpack(data); }); p.Complete(q); return $"Completed: {q.Title} / +{q.Xp} XP / {itemName}"; } catch (Exception ex) { if (ex is AggregateException) { _faulted = true; QuestPlugin.LogSource.LogError((object)"Quest inventory rollback failed; claims disabled."); } QuestPlugin.LogSource.LogError((object)("Quest turn-in failed: " + ex)); return "Turn-in failed; see the game log. No XP granted."; } } private unsafe QuestView View(Player player, string message) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Progress progress = Get(player); QuestView questView = new QuestView { Xp = progress.Xp, Message = message }; Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); foreach (Container item in Containers(player)) { for (int i = 0; i < item.Inventory.Count; i++) { ItemData val = item.Inventory[i]; if (val.count != 0) { Dictionary obj = (item.Carried ? dictionary : dictionary2); string key = ((object)(*(Items*)(&val.item))/*cast due to .constrained prefix*/).ToString(); obj.TryGetValue(key, out var value); obj[key] = value + val.count; } } } Quest[] all = QuestCatalog.All; foreach (Quest quest in all) { if (!_unavailable.ContainsKey(quest.Id) || progress.Active.ContainsKey(quest.Id) || progress.Completed.Contains(quest.Id)) { dictionary.TryGetValue(quest.Target, out var value2); dictionary2.TryGetValue(quest.Target, out var value3); int value4; bool flag = progress.Active.TryGetValue(quest.Id, out value4); int num = (quest.Hunt ? value4 : (value2 + value3)); string state = (progress.Completed.Contains(quest.Id) ? "COMPLETED" : (_unavailable.ContainsKey(quest.Id) ? "UNAVAILABLE" : ((!flag) ? ((QuestCatalog.Level(progress.Xp) < quest.Level) ? "LOCKED" : "AVAILABLE") : ((num >= quest.Amount) ? "READY" : "ACTIVE")))); questView.Rows.Add(new QuestRow { Id = quest.Id, State = state, Count = num, Carried = value2, Stored = value3 }); } } return Appearance(progress, questView); } private static QuestView Appearance(Progress p, QuestView view) { view.Skins = new Dictionary(p.Skins ?? new Dictionary()); view.SkinUnlocks = (from i in Enumerable.Range(0, SkinCatalog.Names.Length) where SkinCatalog.Unlocked(i, p.Completed) select i).ToList(); return view; } internal static void ValidateCatalog() { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown HashSet hashSet = new HashSet(); Quest[] all = QuestCatalog.All; foreach (Quest quest in all) { if (!hashSet.Add(quest.Id) || quest.Xp <= 0 || quest.Amount <= 0) { throw new InvalidDataException("Invalid quest: " + quest.Id); } } _unavailable = QuestCatalog.Unavailable((string name) => Enum.TryParse(name, out NPCs result) && ItemDatabase.GetItemInfo(result) != null, (string name) => Enum.TryParse(name, out result) && NPCDatabase.GetNPCInfo(result) != null); bool flag = default(bool); foreach (KeyValuePair item in _unavailable) { ManualLogSource logSource = QuestPlugin.LogSource; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(40, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Assignment "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" hidden for this game build: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item.Value); } logSource.LogWarning(val); } ManualLogSource logSource2 = QuestPlugin.LogSource; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(51, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("FieldQuests catalog ready: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(QuestCatalog.All.Length - _unavailable.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(QuestCatalog.All.Length); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" assignments available."); } logSource2.LogInfo(val2); } } public static class SkinCatalog { public static readonly string[] Items = new string[12] { "WoodenSpear", "NailBat", "ScrapAxe", "ScrapPickaxe", "ScrapMachete", "BronzeAxe", "IronSpear", "Katana", "LeatherShoes", "ScrapHelmet", "ScrapShirt", "ScrapPant" }; public static readonly string[] Names = new string[13] { "Original", "Woodland", "Blue Circuit", "Embercrack", "Brasswork", "Arctic Digital", "Hazard", "Tigerstripe", "Crimson Rally", "Tidebreaker", "Topographic", "Royal Weave", "Desert Shards" }; public static readonly string[] Quests = new string[13] { "", "s01", "s02", "h02", "s07", "h03", "s08", "h07", "h09", "s05", "s09", "h12", "h05" }; public static int PageStart(int selected, int direction) { int num = (Names.Length + 4) / 5; return (selected / 5 + direction + num) % num * 5; } public static bool Unlocked(int finish, HashSet completed) { if (finish >= 0 && finish < Names.Length) { if (finish != 0) { return completed.Contains(Quests[finish]); } return true; } return false; } public static bool Select(Dictionary choices, HashSet completed, string item, int finish) { if (!Items.Contains(item) || !Unlocked(finish, completed)) { return false; } if (finish == 0) { choices.Remove(item); } else { choices[item] = finish; } return true; } public static string RewardFor(string quest) { int num = Array.IndexOf(Quests, quest); if (num <= 0) { return ""; } return Names[num] + " finish unlocked"; } } internal sealed class SkinVisuals : IDisposable { private sealed class Applied { internal Renderer Renderer; internal Material[] Original; internal Material[] Clones; internal string Key; internal readonly List Textures = new List(); } private readonly Dictionary _applied = new Dictionary(); private readonly Dictionary _choices = new Dictionary(); private float _next; internal static Color ColorFor(int finish) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) return (Color)(finish switch { 1 => new Color(0.45f, 0.67f, 0.36f), 2 => new Color(0.3f, 0.55f, 0.9f), 3 => new Color(0.88f, 0.35f, 0.18f), 4 => new Color(0.76f, 0.57f, 0.28f), 5 => new Color(0.73f, 0.83f, 0.9f), 6 => new Color(0.95f, 0.7f, 0.045f), 7 => new Color(0.8f, 0.44f, 0.15f), 8 => new Color(0.8f, 0.12f, 0.19f), 9 => new Color(0.1f, 0.7f, 0.74f), 10 => new Color(0.6f, 0.74f, 0.4f), 11 => new Color(0.65f, 0.35f, 0.8f), 12 => new Color(0.82f, 0.68f, 0.45f), _ => Color.white, }); } internal void Receive(QuestView view) { if (view.Skins == null) { return; } _choices.Clear(); foreach (KeyValuePair skin in view.Skins) { if (SkinCatalog.Items.Contains(skin.Key) && skin.Value > 0 && skin.Value < SkinCatalog.Names.Length) { _choices[skin.Key] = skin.Value; } } } internal unsafe void Tick() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _next) { return; } _next = Time.unscaledTime + 0.25f; HashSet wanted = new HashSet(); Player localPlayer = Player.localPlayer; if ((Object)(object)localPlayer != (Object)null) { PackedMeshRenderer staticItemRenderer = localPlayer.staticItemRenderer; Renderer renderer = ((staticItemRenderer != null) ? staticItemRenderer.meshRenderer : null); ItemData currentItemData = localPlayer.currentItemData; Apply(renderer, ((object)(*(Items*)(¤tItemData.item))/*cast due to .constrained prefix*/).ToString(), wanted); PlayerClothing[] array = (PlayerClothing[])(object)new PlayerClothing[7] { localPlayer.HatVisual, localPlayer.TopVisual, localPlayer.BottomVisual, localPlayer.ShoesVisual, localPlayer.GlovesVisual, localPlayer.AccessoryVisual, localPlayer.BackpackVisual }; foreach (PlayerClothing val in array) { if ((Object)(object)val != (Object)null) { Apply(val.clothingRenderer, ((object)val.variantKey/*cast due to .constrained prefix*/).ToString(), wanted); } } } int[] array2 = _applied.Keys.Where((int k) => !wanted.Contains(k)).ToArray(); foreach (int id in array2) { Remove(id); } } private void Apply(Renderer renderer, string item, HashSet wanted) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown if ((Object)(object)renderer == (Object)null || !_choices.TryGetValue(item, out var value)) { return; } int instanceID = ((Object)renderer).GetInstanceID(); wanted.Add(instanceID); string text = item + ":" + value; if (_applied.TryGetValue(instanceID, out var existing)) { Il2CppReferenceArray current = renderer.sharedMaterials; if (existing.Key == text && ((Il2CppArrayBase)(object)current).Length == existing.Clones.Length && Enumerable.Range(0, ((Il2CppArrayBase)(object)current).Length).All((int i) => (Object)(object)((Il2CppArrayBase)(object)current)[i] == (Object)(object)existing.Clones[i])) { return; } Remove(instanceID); } Material[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)renderer.sharedMaterials); Material[] array2 = (Material[])(object)new Material[array.Length]; Applied applied = new Applied { Renderer = renderer, Original = array, Clones = array2, Key = text }; _applied[instanceID] = applied; for (int num = 0; num < array.Length; num++) { if (!((Object)(object)array[num] == (Object)null)) { array2[num] = new Material(array[num]); Texture2D val = FinishTextures.Apply(array2[num], value); if ((Object)(object)val != (Object)null) { applied.Textures.Add(val); } } } renderer.sharedMaterials = Il2CppReferenceArray.op_Implicit(array2); } private void Remove(int id) { Applied applied = _applied[id]; if ((Object)(object)applied.Renderer != (Object)null) { Material[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)applied.Renderer.sharedMaterials); for (int i = 0; i < Math.Min(array.Length, applied.Clones.Length); i++) { if ((Object)(object)array[i] == (Object)(object)applied.Clones[i]) { array[i] = applied.Original[i]; } } applied.Renderer.sharedMaterials = Il2CppReferenceArray.op_Implicit(array); } Material[] clones = applied.Clones; foreach (Material val in clones) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } foreach (Texture2D texture in applied.Textures) { if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); } } _applied.Remove(id); } public void Dispose() { int[] array = _applied.Keys.ToArray(); foreach (int id in array) { Remove(id); } _choices.Clear(); } } internal static class StorageAccess { internal static bool CanUse(ulong owner, ulong player, bool localHost, bool saved, bool playerChest, ulong placementId, bool loot) { if (!playerChest && (loot || placementId == 0L)) { return false; } if (localHost && (placementId != 0 || saved || owner != 0L)) { return true; } if (owner != 0L) { return owner == player; } return false; } } }