Decompiled source of WKMapLoader v1.0.5
WKMapLoader.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WKMapLoader")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("WKMapLoader")] [assembly: AssemblyTitle("WKMapLoader")] [assembly: AssemblyVersion("1.0.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WKMapLoader { internal static class BoomCourse { private const int Stages = 5; private const float Gap = 3f; private const float T = 0.5f; private const float L = 5f; private const float P = 7f; private const float W = 9f; private const float DefaultPerBar = 3f; public static bool TestMode; public const string NoteText = "Use boom-bars to push off the walls up to next lvl. Reach the top."; public static string Generate(string mapsDir, float perBar) { float ground = perBar; float air = perBar; string how = ((perBar > 0f) ? $"set by hand: {perBar:0.0} m per boom-bar" : null); bool flag = perBar <= 0f && BoomLog.PerBarHeights(out ground, out air, out how); if (how == null) { ground = (air = 3f); how = $"default {3f:0.0} m per boom-bar (no attempts logged)"; } StringBuilder obj = new StringBuilder(); StringBuilder mtl = new StringBuilder(); CultureInfo ic = CultureInfo.InvariantCulture; int vcount = 0; obj.AppendLine("# Boom course - explosive rebar wall tower (WK Map Loader 'boomcourse')"); obj.AppendLine("mtllib boom_course.mtl"); Mat("post", 0.25f, 0.25f, 0.25f); Mat("button", 0.8f, 0.05f, 0.03f); Mat("lamp", 1f, 0.85f, 0.6f); Mat("button_yellow", 0.9f, 0.75f, 0.05f); Mat("save_green", 0.1f, 0.75f, 0.2f); Mat("win_green", 0.15f, 0.9f, 0.3f); Mat("wall", 0.42f, 0.4f, 0.38f); Mat("ground", 0.3f, 0.28f, 0.26f); Box("ground", "ground", -7f, -1f, -11f, 7f, 0f, 6f); Box("spawn", "post", -0.5f, 0.5f, -8.5f, 0.5f, 1.5f, -7.5f); Button("checkpoint_6_rebar_explosive", "button", -3f, 0f, -9f); Button("buddy_button", "button_yellow", -1.8f, 0f, -9f); Box("note", "post", 1f, 0.05f, -8f, 1.4f, 0.15f, -7.6f); float num = 0f; if (TestMode) { ground = (air = 0f); how = "test walls (boomcourse test)"; Box("wall_test_a", "wall", -2.5f, 0f, -4f, -2f, 300f, 4f); Box("wall_test_b", "wall", 2f, 0f, -4f, 2.5f, 300f, 4f); Mat("mark", 0.9f, 0.9f, 0.9f); for (int i = 5; (float)i < 300f; i += 5) { float num2 = ((i % 10 == 0) ? 0.12f : 0.05f); Box($"deco_mark_a_{i}", "mark", -1.99f, (float)i - num2, -4f, -1.97f, (float)i + num2, 4f); Box($"deco_mark_b_{i}", "mark", 1.97f, (float)i - num2, -4f, 1.99f, (float)i + num2, 4f); } for (int j = 10; (float)j < 300f; j += 20) { Box($"light_25.{j:000}", "lamp", -0.15f, j, 5f, 0.15f, (float)j + 0.3f, 5.3f); } num = 300f; } float num3 = 0f; int num4 = 1; for (int k = 0; k < ((!TestMode) ? 5 : 0); k++) { int num5 = k + 2; float num6 = WallHeight(num5); float num7 = (float)k / 4f; string text = "platform_" + (k + 1); Mat(text, 0.75f - 0.4f * num7, 0.5f + 0.1f * num7, 0.3f + 0.45f * num7); Box($"wall_{k + 1}_a", "wall", num3 - (float)num4 * 3f / 2f, num, -2.5f, num3 - (float)num4 * 2f, num + num6, 2.5f); Box($"wall_{k + 1}_b", "wall", num3 + (float)num4 * 3f / 2f, num, -2.5f, num3 + (float)num4 * 2f, num + num6 - 0.5f, 2.5f); Box($"light_20.{k:000}", "lamp", num3 - 0.15f, num + num6 * 0.6f, 3.5f, num3 + 0.15f, num + num6 * 0.6f + 0.3f, 3.8f); float num8 = num + num6; Box(text, text, num3 + (float)num4 * 3f / 2f, num8 - 0.5f, -4.5f, num3 + (float)num4 * 9f, num8, 4.5f); float num9 = num3 + (float)num4 * 5.5f; Box($"light_16.{k:000}", "lamp", num9 - 0.15f, num8 + 5f, -0.15f, num9 + 0.15f, num8 + 5.3f, 0.15f); if (k < 4) { Button($"checkpoint_{num5 + 1}_rebar_explosive", "button", num9, num8, 3.6f); if (k == 1) { Box("save_pad_3", "save_green", num9 - 1f, num8, -4.3f, num9 + 1f, num8 + 0.08f, -2.8f); } } else { Box("exit", "post", num9 - 0.5f, num8 + 0.5f, -1f, num9 + 0.5f, num8 + 1.5f, 0f); Box("smooth_post_win", "post", num9 - 0.12f, num8, 2.4f, num9 + 0.12f, num8 + 1f, 2.64f); Oval("win_button", "win_green", num9, num8 + 1f, 2.52f, 0.35f, 0.22f, 0.12f); } num3 = num9; num = num8; num4 = -num4; } string path = Path.Combine(mapsDir, "boom_course.obj"); File.WriteAllText(path, obj.ToString()); File.WriteAllText(Path.ChangeExtension(path, ".mtl"), mtl.ToString()); File.WriteAllText(Path.Combine(mapsDir, "boom_course_note.txt"), "Use boom-bars to push off the walls up to next lvl. Reach the top."); IEnumerable<string> values = from b in Enumerable.Range(2, 5) select WallHeight(b).ToString("0.0", ic); File.WriteAllText(Path.Combine(mapsDir, "boom_course_report.txt"), (flag ? "calibrated from logged attempts" : "NOT calibrated") + string.Format("\n{0}\nwall heights: {1} m\ntop: {2:0.0} m\n", how, string.Join(", ", values), num)); Plugin.Say(string.Format("Boom course rebuilt - {0}. Walls {1} m, top at {2:0} m.", how, string.Join(", ", values), num)); return "boom_course"; void Box(string name, string mat, float x0, float y0, float z0, float x1, float y1, float z1) { if (x0 > x1) { float num10 = x0; x0 = x1; x1 = num10; } obj.AppendLine("o " + name); obj.AppendLine("usemtl " + mat); float[][] array = new float[8][] { new float[3] { x0, y0, z1 }, new float[3] { x1, y0, z1 }, new float[3] { x1, y1, z1 }, new float[3] { x0, y1, z1 }, new float[3] { x0, y0, z0 }, new float[3] { x1, y0, z0 }, new float[3] { x1, y1, z0 }, new float[3] { x0, y1, z0 } }; foreach (float[] array2 in array) { obj.AppendLine("v " + F(0f - array2[0]) + " " + F(array2[1]) + " " + F(array2[2])); } int[][] array3 = new int[6][] { new int[4] { 2, 1, 4, 3 }, new int[4] { 5, 6, 7, 8 }, new int[4] { 1, 5, 8, 4 }, new int[4] { 6, 2, 3, 7 }, new int[4] { 3, 4, 8, 7 }, new int[4] { 1, 2, 6, 5 } }; foreach (int[] source in array3) { obj.AppendLine("f " + string.Join(" ", source.Select((int num11) => (num11 + vcount).ToString(ic)))); } vcount += 8; } void Button(string name, string mat, float x, float y, float z) { Box("smooth_post_" + name, "post", x - 0.12f, y, z - 0.12f, x + 0.12f, y + 1f, z + 0.12f); Box(name, mat, x - 0.3f, y + 1f, z - 0.3f, x + 0.3f, y + 1.25f, z + 0.3f); } string F(float v) { return v.ToString("0.###", ic); } void Mat(string name, float r, float g, float b) { mtl.AppendLine("newmtl " + name + "\nKd " + F(r) + " " + F(g) + " " + F(b) + "\n"); } void Oval(string name, string mat, float cx, float y0, float cz, float rx, float rz, float h, int seg = 16) { obj.AppendLine("o " + name); obj.AppendLine("usemtl " + mat); for (int l = 0; l < 2; l++) { for (int m = 0; m < seg; m++) { float num10 = (float)m * MathF.PI * 2f / (float)seg; obj.AppendLine("v " + F(0f - (cx + Mathf.Cos(num10) * rx)) + " " + F(y0 + (float)l * h) + " " + F(cz + Mathf.Sin(num10) * rz)); } } obj.AppendLine("v " + F(0f - cx) + " " + F(y0) + " " + F(cz)); obj.AppendLine("v " + F(0f - cx) + " " + F(y0 + h) + " " + F(cz)); int b0 = vcount; int num11 = b0 + 2 * seg + 1; int num12 = b0 + 2 * seg + 2; for (int n = 0; n < seg; n++) { obj.AppendLine($"f {B(n + 1)} {Tp(n + 1)} {Tp(n)} {B(n)}"); obj.AppendLine($"f {num12} {Tp(n)} {Tp(n + 1)}"); obj.AppendLine($"f {num11} {B(n + 1)} {B(n)}"); } vcount += 2 * seg + 2; int B(int num13) { return b0 + 1 + num13 % seg; } int Tp(int num13) { return b0 + 1 + seg + num13 % seg; } } float WallHeight(int bars) { return ground + (float)(bars - 1) * air; } } } internal static class BoomLog { public class Attempt { public bool midAir; public float blastDist; public float angleFromUp; public float launchSpeed; public float rise; public float sideways; public float airtime; } public static readonly List<Attempt> Attempts = new List<Attempt>(); private static Attempt cur; private static Vector3 start; private static Vector3 lastPos; private static float startTime; private static float apex; private static bool sawAir; private static string csvPath; public static void Init(string mapsDir) { csvPath = Path.Combine(mapsDir, "boom_log.csv"); } public static void OnExplosion(UT_Explosion ex) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if (!((Object)(object)playerObject == (Object)null) && !((Object)(object)ex == (Object)null) && !playerObject.noclip) { Vector3 position = ((Component)ex).transform.position; Vector3 position2 = ((Component)playerObject).transform.position; float num = Vector3.Distance(position, position2); if (!(num > ex.maxDistance + 1f)) { Finish(playerObject); Vector3 val = position2 - position; Vector3 normalized = ((Vector3)(ref val)).normalized; cur = new Attempt { midAir = !playerObject.IsGrounded(false), blastDist = num, angleFromUp = Vector3.Angle(normalized, Vector3.up) }; start = (lastPos = position2); apex = position2.y; startTime = Time.time; sawAir = cur.midAir; } } } public static void Track(ENT_Player p) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (cur != null && !((Object)(object)p == (Object)null)) { Vector3 position = ((Component)p).transform.position; float deltaTime = Time.deltaTime; if (Time.time - startTime < 0.25f && deltaTime > 0f) { Attempt attempt = cur; float launchSpeed = cur.launchSpeed; Vector3 val = position - lastPos; attempt.launchSpeed = Mathf.Max(launchSpeed, ((Vector3)(ref val)).magnitude / deltaTime); } lastPos = position; apex = Mathf.Max(apex, position.y); bool flag = p.IsGrounded(false); if (!flag) { sawAir = true; } if ((sawAir && flag && Time.time - startTime > 0.15f) || p.IsHanging() || Time.time - startTime > 6f) { Finish(p); } } } private static void Finish(ENT_Player p) { //IL_001e: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (cur == null) { return; } Vector3 val = (((Object)(object)p != (Object)null) ? ((Component)p).transform.position : lastPos); cur.rise = apex - start.y; Attempt attempt = cur; Vector2 val2 = new Vector2(val.x - start.x, val.z - start.z); attempt.sideways = ((Vector2)(ref val2)).magnitude; cur.airtime = Time.time - startTime; Attempt attempt2 = cur; cur = null; if (attempt2.launchSpeed < 0.5f && attempt2.rise < 0.3f) { return; } Attempts.Add(attempt2); Plugin.Say(string.Format("Boom #{0} ({1}): blast {2:0.0} m away, push {3:0}° from straight up ", Attempts.Count, attempt2.midAir ? "mid-air" : "ground", attempt2.blastDist, attempt2.angleFromUp) + $"-> {attempt2.rise:0.0} m up, {attempt2.sideways:0.0} m sideways, {attempt2.launchSpeed:0.0} m/s"); try { CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (!File.Exists(csvPath)) { File.WriteAllText(csvPath, "time,mode,blast_dist_m,push_angle_from_up_deg,launch_speed_mps,rise_m,sideways_m,airtime_s\n"); } File.AppendAllText(csvPath, string.Join(",", DateTime.Now.ToString("s", invariantCulture), attempt2.midAir ? "air" : "ground", attempt2.blastDist.ToString("0.00", invariantCulture), attempt2.angleFromUp.ToString("0", invariantCulture), attempt2.launchSpeed.ToString("0.00", invariantCulture), attempt2.rise.ToString("0.00", invariantCulture), attempt2.sideways.ToString("0.00", invariantCulture), attempt2.airtime.ToString("0.00", invariantCulture)) + "\n"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("boom_log.csv: " + ex.Message)); } } private static float Percentile(IEnumerable<float> values, float share) { List<float> list = values.OrderBy((float x) => x).ToList(); if (list.Count == 0) { return 0f; } return list[Mathf.Clamp(Mathf.FloorToInt(share * (float)(list.Count - 1) + 0.5f), 0, list.Count - 1)]; } public static bool PerBarHeights(out float ground, out float air, out string how) { List<Attempt> source = Attempts.Where((Attempt a) => a.rise > 1f).ToList(); List<float> list = (from a in source where !a.midAir select a.rise).ToList(); List<float> list2 = (from a in source where a.midAir select a.rise).ToList(); ground = ((list.Count >= 2) ? Percentile(list, 0.25f) : 0f); air = ((list2.Count >= 2) ? Percentile(list2, 0.25f) : 0f); if (ground <= 0f && air > 0f) { ground = air; } if (air <= 0f && ground > 0f) { air = ground; } how = $"{list.Count} ground + {list2.Count} mid-air attempts; 75% of them reached {ground:0.0} m (ground) / {air:0.0} m (mid-air)"; return ground > 0f; } public static void Report() { if (Attempts.Count == 0) { Plugin.Say("No boom attempts logged yet - blast yourself with explosive rebar."); return; } StringBuilder stringBuilder = new StringBuilder($"Boom report ({Attempts.Count} attempts, also in boom_log.csv):\n"); bool[] array = new bool[2] { false, true }; foreach (bool air in array) { List<Attempt> list = Attempts.Where((Attempt a) => a.midAir == air).ToList(); if (list.Count == 0) { continue; } stringBuilder.AppendLine(air ? " MID-AIR blasts" : " GROUND blasts"); int lo; for (lo = 0; lo < 180; lo += 15) { List<Attempt> list2 = list.Where((Attempt a) => a.angleFromUp >= (float)lo && a.angleFromUp < (float)(lo + 15)).ToList(); if (list2.Count != 0) { stringBuilder.AppendLine($" push {lo,3}-{lo + 15,3}° from up: {list2.Count,2}x up avg {list2.Average((Attempt a) => a.rise):0.0} / best {list2.Max((Attempt a) => a.rise):0.0} m, " + $"sideways avg {list2.Average((Attempt a) => a.sideways):0.0} m, speed avg {list2.Average((Attempt a) => a.launchSpeed):0.0} m/s"); } } List<Attempt> list3 = list.Where((Attempt a) => a.rise > 1f).ToList(); if (list3.Count > 0) { stringBuilder.AppendLine($" blast distance: launches that worked were {list3.Min((Attempt a) => a.blastDist):0.0}-{list3.Max((Attempt a) => a.blastDist):0.0} m from the blast"); } } if (PerBarHeights(out var _, out var _, out var how)) { stringBuilder.AppendLine(" Course sizing: " + how); } string[] array2 = stringBuilder.ToString().TrimEnd().Split('\n'); for (int i = 0; i < array2.Length; i++) { Plugin.Say(array2[i]); } } public static void Clear() { Attempts.Clear(); cur = null; Plugin.Say("Boom log cleared (boom_log.csv kept)."); } } [HarmonyPatch(typeof(UT_Explosion), "Explode")] internal static class ExplosionLogPatch { private static void Prefix(UT_Explosion __instance) { try { BoomLog.OnExplosion(__instance); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Boom log: " + ex.Message)); } } } internal static class CustomMenu { private const string TabName = "CUSTOM"; private const string ModeDatabaseId = "wkcustommodes"; internal static readonly Dictionary<M_Gamemode, string> ModeToMap = new Dictionary<M_Gamemode, string>(); private static WKAssetDatabase modeDb; private static readonly HashSet<UI_TabGroup> injected = new HashSet<UI_TabGroup>(); public static void TryInject(UI_TabGroup group) { try { Inject(group); } catch (Exception ex) { Plugin.Log.LogError((object)("CUSTOM tab injection failed: " + ex)); } } private static void Inject(UI_TabGroup group) { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: Unknown result type (might be due to invalid IL or missing references) //IL_0732: Unknown result type (might be due to invalid IL or missing references) //IL_0737: Unknown result type (might be due to invalid IL or missing references) //IL_0742: Unknown result type (might be due to invalid IL or missing references) //IL_074a: Unknown result type (might be due to invalid IL or missing references) //IL_0752: 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_0767: Expected O, but got Unknown //IL_07a2: Unknown result type (might be due to invalid IL or missing references) //IL_07ac: Expected O, but got Unknown //IL_06b3: Unknown result type (might be due to invalid IL or missing references) //IL_06cd: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06a0: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_06f4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)group == (Object)null || group.tabs == null || injected.Contains(group)) { return; } string text = string.Join("/", group.tabs.Select((Tab t) => t.name)); Tab tmpl = ((IEnumerable<Tab>)group.tabs).FirstOrDefault((Func<Tab, bool>)((Tab x) => x.name != null && x.name.ToLowerInvariant().Contains("event"))) ?? ((IEnumerable<Tab>)group.tabs).FirstOrDefault((Func<Tab, bool>)((Tab x) => x.name != null && x.name.ToLowerInvariant().Contains("challenge"))); if (tmpl == null || (Object)(object)tmpl.button == (Object)null || (Object)(object)tmpl.tabObject == (Object)null) { Plugin.Log.LogDebug((object)("Tab group '" + ((Object)group).name + "' [" + text + "] is not the play screen - skipped.")); return; } injected.Add(group); Scene scene = ((Component)group).gameObject.scene; Plugin.Log.LogInfo((object)("Menu tabs: " + text)); List<string> list = (from g in Plugin.Instance.AllMapFiles().GroupBy<string, string>(Path.GetFileNameWithoutExtension, StringComparer.OrdinalIgnoreCase) select g.First() into p orderby Path.GetFileNameWithoutExtension(p) select p).ToList(); Tab val = ((IEnumerable<Tab>)group.tabs).FirstOrDefault((Func<Tab, bool>)((Tab t) => string.Equals(t.name?.Trim(), "custom", StringComparison.OrdinalIgnoreCase))); if (val != null && (Object)(object)val.button != (Object)null && (Object)(object)val.tabObject != (Object)null) { UseBuiltInTab(val, list, scene); return; } bool activeSelf = tmpl.tabObject.activeSelf; tmpl.tabObject.SetActive(false); GameObject val2 = Object.Instantiate<GameObject>(tmpl.tabObject, tmpl.tabObject.transform.parent); tmpl.tabObject.SetActive(activeSelf); ((Object)val2).name = "CUSTOM Page"; UI_Gamemode_Button[] componentsInChildren = val2.GetComponentsInChildren<UI_Gamemode_Button>(true); UI_Gamemode_Button val3 = componentsInChildren.FirstOrDefault(); if ((Object)(object)val3 == (Object)null) { UI_Gamemode_Button val4 = ((IEnumerable<UI_Gamemode_Button>)Resources.FindObjectsOfTypeAll<UI_Gamemode_Button>()).FirstOrDefault((Func<UI_Gamemode_Button, bool>)((UI_Gamemode_Button c) => ((Component)c).gameObject.scene == scene)); if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogWarning((object)"No level card found to copy - CUSTOM tab not added."); Object.Destroy((Object)(object)val2); return; } val3 = Object.Instantiate<UI_Gamemode_Button>(val4, val2.transform); } UI_Gamemode_Button[] array = componentsInChildren; foreach (UI_Gamemode_Button val5 in array) { if ((Object)(object)val5 != (Object)(object)val3) { Object.Destroy((Object)(object)((Component)val5).gameObject); } } TMP_Text[] componentsInChildren2 = val2.GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val6 in componentsInChildren2) { if ((Object)(object)((Component)val6).GetComponentInParent<UI_Gamemode_Button>(true) == (Object)null && val6.text.Trim().Equals(tmpl.name.Trim(), StringComparison.OrdinalIgnoreCase)) { val6.text = "CUSTOM"; } } M_Gamemode gamemode = val3.gamemode; ModeToMap.Clear(); RectTransform component = ((Component)val3).GetComponent<RectTransform>(); bool flag = (Object)(object)((Component)((Component)val3).transform.parent).GetComponent<LayoutGroup>() != (Object)null; Vector2 val7 = (((Object)(object)component != (Object)null) ? component.anchoredPosition : Vector2.zero); float num2; Rect rect; if (!((Object)(object)component != (Object)null)) { num2 = 300f; } else { rect = component.rect; num2 = ((Rect)(ref rect)).width; } float num3 = num2 + 24f; Selectable val8 = null; for (int num4 = 0; num4 < list.Count; num4++) { UI_Gamemode_Button val9 = ((num4 == 0) ? val3 : Object.Instantiate<UI_Gamemode_Button>(val3, ((Component)val3).transform.parent)); ((Object)val9).name = "Card " + Path.GetFileNameWithoutExtension(list[num4]); val9.gamemode = MakeMode(gamemode, list[num4]); if (!flag) { RectTransform component2 = ((Component)val9).GetComponent<RectTransform>(); if (component2 != null) { component2.anchoredPosition = val7 + new Vector2(num3 * (float)num4, 0f); } } if ((Object)(object)val8 == (Object)null) { val8 = ((Component)val9).GetComponent<Selectable>(); } } if (list.Count == 0) { ((Component)val3).gameObject.SetActive(false); } RegisterModes(); Button val10 = (from t in @group.tabs select t.button into b where (Object)(object)b != (Object)null && (Object)(object)((Component)b).transform.parent == (Object)(object)((Component)tmpl.button).transform.parent orderby ((Component)b).transform.GetSiblingIndex() select b).Last(); GameObject val11 = Object.Instantiate<GameObject>(((Component)tmpl.button).gameObject, ((Component)tmpl.button).transform.parent); ((Object)val11).name = "CUSTOM Tab"; val11.transform.SetSiblingIndex(((Component)val10).transform.GetSiblingIndex() + 1); if ((Object)(object)((Component)val11.transform.parent).GetComponent<LayoutGroup>() == (Object)null) { List<RectTransform> list2 = (from t in @group.tabs select t.button into b where (Object)(object)b != (Object)null select ((Component)b).GetComponent<RectTransform>() into rt orderby rt.anchoredPosition.x select rt).ToList(); RectTransform val12 = list2.Last(); float num5; if (list2.Count <= 1) { rect = val12.rect; num5 = ((Rect)(ref rect)).width + 16f; } else { num5 = val12.anchoredPosition.x - list2[list2.Count - 2].anchoredPosition.x; } float num6 = num5; val11.GetComponent<RectTransform>().anchoredPosition = val12.anchoredPosition + new Vector2(num6, 0f); } TMP_Text componentInChildren = val11.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "CUSTOM"; } Button component3 = val11.GetComponent<Button>(); group.tabs.Add(new Tab { name = "CUSTOM", button = component3, tabObject = val2, buttonText = componentInChildren, firstSelect = val8 }); if (typeof(UI_TabGroup).GetField("group", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(group) != null) { ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { group.SelectTab("CUSTOM"); }); } val2.SetActive(false); if ((Object)(object)componentInChildren != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(KeepLabel(componentInChildren)); } Plugin.Log.LogInfo((object)string.Format("{0} tab added with {1} map card(s): {2}", "CUSTOM", list.Count, string.Join(", ", list.Select(Path.GetFileNameWithoutExtension)))); } private static void UseBuiltInTab(Tab tab, List<string> maps, Scene scene) { //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) tab.onlyDev = false; ((Component)tab.button).gameObject.SetActive(true); TMP_Text val = (((Object)(object)tab.buttonText != (Object)null) ? tab.buttonText : ((Component)tab.button).GetComponentInChildren<TMP_Text>(true)); if ((Object)(object)val != (Object)null) { val.text = "CUSTOM"; ((MonoBehaviour)Plugin.Instance).StartCoroutine(KeepLabel(val)); } GameObject tabObject = tab.tabObject; UI_Gamemode_Button[] componentsInChildren = tabObject.GetComponentsInChildren<UI_Gamemode_Button>(true); UI_Gamemode_Button val2 = ((IEnumerable<UI_Gamemode_Button>)componentsInChildren).FirstOrDefault((Func<UI_Gamemode_Button, bool>)((UI_Gamemode_Button c) => (Object)(object)((Component)c).transform.parent != (Object)null && ((Object)((Component)c).transform.parent).name == "Content")) ?? componentsInChildren.FirstOrDefault(); if ((Object)(object)val2 == (Object)null) { UI_Gamemode_Button val3 = ((IEnumerable<UI_Gamemode_Button>)Resources.FindObjectsOfTypeAll<UI_Gamemode_Button>()).FirstOrDefault((Func<UI_Gamemode_Button, bool>)((UI_Gamemode_Button c) => ((Component)c).gameObject.scene == scene)); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"No level card found to copy - CUSTOM tab left empty."); return; } val2 = Object.Instantiate<UI_Gamemode_Button>(val3, tabObject.transform); } foreach (Transform item in ((IEnumerable)((Component)val2).transform.parent).Cast<Transform>().ToList()) { if ((Object)(object)item != (Object)(object)((Component)val2).transform) { Object.Destroy((Object)(object)((Component)item).gameObject); } } tab.firstSelect = FillCards(val2, maps); Plugin.Log.LogInfo((object)string.Format("Built-in Custom tab enabled with {0} map card(s): {1}", maps.Count, string.Join(", ", maps.Select(Path.GetFileNameWithoutExtension)))); } private static Selectable FillCards(UI_Gamemode_Button cardTemplate, List<string> maps) { //IL_0040: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00f5: Unknown result type (might be due to invalid IL or missing references) M_Gamemode gamemode = cardTemplate.gamemode; ModeToMap.Clear(); RectTransform component = ((Component)cardTemplate).GetComponent<RectTransform>(); bool flag = (Object)(object)((Component)((Component)cardTemplate).transform.parent).GetComponent<LayoutGroup>() != (Object)null; Vector2 val = (((Object)(object)component != (Object)null) ? component.anchoredPosition : Vector2.zero); float num; if (!((Object)(object)component != (Object)null)) { num = 300f; } else { Rect rect = component.rect; num = ((Rect)(ref rect)).width; } float num2 = num + 24f; Selectable val2 = null; for (int i = 0; i < maps.Count; i++) { UI_Gamemode_Button val3 = ((i == 0) ? cardTemplate : Object.Instantiate<UI_Gamemode_Button>(cardTemplate, ((Component)cardTemplate).transform.parent)); ((Object)val3).name = "Card " + Path.GetFileNameWithoutExtension(maps[i]); val3.gamemode = MakeMode(gamemode, maps[i]); ((Component)val3).gameObject.SetActive(true); if (!flag) { RectTransform component2 = ((Component)val3).GetComponent<RectTransform>(); if (component2 != null) { component2.anchoredPosition = val + new Vector2(num2 * (float)i, 0f); } } if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val3).GetComponent<Selectable>(); } } if (maps.Count == 0) { ((Component)cardTemplate).gameObject.SetActive(false); } RegisterModes(); return val2; } private static IEnumerator KeepLabel(TMP_Text label) { float until = Time.realtimeSinceStartup + 5f; while ((Object)(object)label != (Object)null && Time.realtimeSinceStartup < until) { if (label.text != "CUSTOM") { label.text = "CUSTOM"; } yield return null; } } private static M_Gamemode MakeMode(M_Gamemode baseMode, string mapPath) { //IL_0233: Unknown result type (might be due to invalid IL or missing references) string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(mapPath); string text = Pretty(fileNameWithoutExtension); string directoryName = Path.GetDirectoryName(mapPath); M_Gamemode val = ((IEnumerable<M_Gamemode>)CL_AssetManager.GetFullCombinedAssetDatabase().gamemodeAssets).FirstOrDefault((Func<M_Gamemode, bool>)((M_Gamemode g) => (Object)(object)g != (Object)null && (((Object)g).name == "GM_Campaign" || g.gamemodeName == "Campaign"))); if ((Object)(object)val != (Object)null) { baseMode = val; } M_Gamemode val2 = Object.Instantiate<M_Gamemode>(baseMode); ((Object)val2).name = "WKMap_" + fileNameWithoutExtension; ((Object)val2).hideFlags = (HideFlags)32; val2.gamemodeName = "Custom Map - " + text; string path = Path.Combine(directoryName, fileNameWithoutExtension + ".txt"); string text2 = (File.Exists(path) ? File.ReadAllText(path).Replace("\r\n", "\n") : null); string text3 = text; if (text2 != null && text2.StartsWith("title:", StringComparison.OrdinalIgnoreCase)) { int num = text2.IndexOf('\n'); text3 = ((num < 0) ? text2.Substring(6) : text2.Substring(6, num - 6)).Trim(); text2 = ((num < 0) ? "" : text2.Substring(num + 1)); if (text3.Length == 0) { text3 = text; } } val2.useCustomCapsuleName = true; val2.capsuleName = text3.ToUpperInvariant(); val2.modeDescription = text2 ?? ("Custom map: " + text + ".\nBuilt in a 3D tool, loaded by WK Map Loader.\nFall off = back to the start. No mass."); val2.introText = text3; val2.newGameText = "Play"; Plugin.Log.LogInfo((object)("[card] '" + text + "' based on '" + baseMode.gamemodeName + "' (scene '" + baseMode.gamemodeScene + "', objects: " + string.Join(", ", from o in baseMode.gamemodeObjects ?? new List<GameObject>() where (Object)(object)o != (Object)null select ((Object)o).name) + ")")); val2.gamemodeScene = "Game-Main"; val2.modeType = (GameType)4; val2.playlistLevelAssets = new List<LevelAssetHolder>(); val2.playlistLevels = new List<M_Level>(); val2.regions = new List<M_Region>(); val2.startItems = new List<SpawnItem>(); val2.gamemodeSettings = new List<GamemodeSetting>(); val2.useGamemodeSettings = false; val2.gamemodeModule = null; val2.modeTags = new List<string> { "custommap" }; val2.isEndless = false; val2.hasRevives = false; val2.hasPerks = false; val2.allowAchievements = false; val2.allowHeightAchievements = false; val2.allowLeaderboardScoring = false; val2.allowCompetitive = false; val2.allowHardmode = false; val2.allowIronKnuckle = false; val2.steamLeaderboardName = ""; val2.roachBankID = "custommap-bank"; val2.showBankAmount = false; val2.saveRoaches = false; val2.gooSpeedMult = 0f; val2.gooSpeedIncreaseMult = 0f; val2.hiddenUntilUnlocked = false; val2.unlockAchievement = ""; val2.unlockHint = ""; val2.devOnly = false; Sprite val3 = LoadSprite(Path.Combine(directoryName, fileNameWithoutExtension + ".png")); if ((Object)(object)val3 != (Object)null) { val2.capsuleArt = val3; val2.screenArt = val3; } ModeToMap[val2] = mapPath; return val2; } private static void RegisterModes() { if ((Object)(object)modeDb == (Object)null) { modeDb = ScriptableObject.CreateInstance<WKAssetDatabase>(); ((Object)modeDb).hideFlags = (HideFlags)32; Plugin.FillNullLists(modeDb); modeDb.id = "wkcustommodes"; CL_AssetManager.AddNewDatabase("wkcustommodes", modeDb); } modeDb.gamemodeAssets.Clear(); modeDb.gamemodeAssets.AddRange(ModeToMap.Keys); CL_AssetManager.RefreshDatabaseList(); } private static Sprite LoadSprite(string png) { //IL_000e: 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_001b: Expected O, but got Unknown //IL_004c: 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) if (!File.Exists(png)) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { filterMode = (FilterMode)0 }; if (!ImageConversion.LoadImage(val, File.ReadAllBytes(png))) { return null; } ((Object)val).hideFlags = (HideFlags)32; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); ((Object)obj).hideFlags = (HideFlags)32; return obj; } private static string Pretty(string id) { return string.Join(" ", from w in id.Replace('_', ' ').Replace('-', ' ').Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries) select char.ToUpperInvariant(w[0]) + w.Substring(1)); } } [HarmonyPatch(typeof(UI_TabGroup), "Start")] internal static class TabGroupStartPatch { private static void Prefix(UI_TabGroup __instance) { CustomMenu.TryInject(__instance); } } [HarmonyPatch(typeof(M_Gamemode), "GetGenerationList")] internal static class CustomModeGenerationPatch { private static void Prefix(M_Gamemode __instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) Plugin.Log.LogInfo((object)($"[card] GetGenerationList on '{__instance?.gamemodeName}' (ours: {CustomMenu.ModeToMap.ContainsKey(__instance)}, " + string.Format("type {0}, player {1})", __instance?.modeType, ((Object)(object)ENT_Player.playerObject != (Object)null) ? "yes" : "no"))); if (!CustomMenu.ModeToMap.TryGetValue(__instance, out var value)) { return; } try { LevelAssetHolder val = Plugin.Instance.BuildHolder(value); if (val != null) { __instance.playlistLevelAssets = new List<LevelAssetHolder> { val }; Plugin.Log.LogInfo((object)("[card] built '" + val.id + "' from " + value)); } else { Plugin.Log.LogError((object)("[card] could not build map '" + value + "'.")); } } catch (Exception ex) { Plugin.Log.LogError((object)("[card] building map failed: " + ex)); } } private static void Postfix(M_Gamemode __instance, List<LevelAssetHolder> __result) { if (CustomMenu.ModeToMap.ContainsKey(__instance)) { Plugin.Log.LogInfo((object)("[card] generation list: " + ((__result == null) ? "null" : string.Join(", ", __result.Select((LevelAssetHolder h) => h?.id ?? "null"))))); } } } [HarmonyPatch(typeof(FXManager), "FXRender")] internal static class FogPatch { public static float MapFogScale = 0.25f; public static bool Active; private static void Postfix() { //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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) if (Active && FXManager.fxData != null && FXManager.showFog) { float num = FXManager.fxData.fogMultiplier * MapFogScale; Color fog = FXManager.fxData.fog; Shader.SetGlobalVector("_FOG", new Vector4(fog.r, fog.g, fog.b, num)); Shader.SetGlobalFloat("_FOGMULT", num); } } } internal class PropSpec { public string Mesh; public Vector3 Forward = Vector3.forward; public Vector3 Up = Vector3.up; public float Scale = 1f; public string Action; public bool Screen; public bool Tree; public float Yaw; public Quaternion Rotation => Quaternion.LookRotation(Forward, Up); public static PropSpec Parse(string name) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) name = Regex.Replace(name, "\\.\\d{3}$", ""); string[] array = name.Split(':'); PropSpec propSpec = new PropSpec { Mesh = ((array.Length > 1) ? array[1] : "") }; foreach (string item in array.Skip(2)) { float result; float result2; Vector3 v; if (item.StartsWith("btn=")) { propSpec.Action = item.Substring(4); } else if (item == "screen") { propSpec.Screen = true; } else if (item == "tree") { propSpec.Tree = true; } else if (item.StartsWith("y") && float.TryParse(item.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { propSpec.Yaw = result; } else if (item.StartsWith("s") && float.TryParse(item.Substring(1), NumberStyles.Float, CultureInfo.InvariantCulture, out result2)) { propSpec.Scale = result2; } else if ((item.StartsWith("f") || item.StartsWith("u")) && TryVec(item.Substring(1), out v)) { if (item[0] == 'f') { propSpec.Forward = v; } else { propSpec.Up = v; } } } return propSpec; } private static bool TryVec(string s, out Vector3 v) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) v = Vector3.zero; string[] array = s.Split(','); if (array.Length != 3) { return false; } CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (!float.TryParse(array[0], NumberStyles.Float, invariantCulture, out var result) || !float.TryParse(array[1], NumberStyles.Float, invariantCulture, out var result2) || !float.TryParse(array[2], NumberStyles.Float, invariantCulture, out var result3)) { return false; } v = new Vector3(result, result2, result3); return ((Vector3)(ref v)).sqrMagnitude > 1E-06f; } } internal static class GameProps { private static readonly string[] SourceLevels = new string[2] { "Training_Level_01", "M3_Habitation_Pier_03" }; private static readonly List<GameObject> sources = new List<GameObject>(); private static readonly List<AsyncOperationHandle<GameObject>> handles = new List<AsyncOperationHandle<GameObject>>(); private static bool sourcesTried; private static readonly Dictionary<string, MeshFilter> cache = new Dictionary<string, MeshFilter>(); public static bool TryGet(string meshName, out Mesh mesh, out Material[] mats, out CL_Button button) { mesh = null; mats = null; button = null; if (!cache.TryGetValue(meshName, out var value) || (Object)(object)value == (Object)null) { LoadSources(); value = sources.SelectMany((GameObject s) => s.GetComponentsInChildren<MeshFilter>(true)).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter m) => (Object)(object)m.sharedMesh != (Object)null && ((Object)m.sharedMesh).name == meshName)) ?? ((IEnumerable<MeshFilter>)Resources.FindObjectsOfTypeAll<MeshFilter>()).FirstOrDefault((Func<MeshFilter, bool>)((MeshFilter m) => (Object)(object)m.sharedMesh != (Object)null && ((Object)m.sharedMesh).name == meshName)); if ((Object)(object)value == (Object)null) { return false; } cache[meshName] = value; Plugin.Log.LogInfo((object)("Prop '" + meshName + "' from '" + ((Object)((Component)value).transform.root).name + "/" + ((Object)value).name + "'")); } mesh = value.sharedMesh; MeshRenderer component = ((Component)value).GetComponent<MeshRenderer>(); mats = (Material[])(((object)((component != null) ? ((Renderer)component).sharedMaterials : null)) ?? ((object)new Material[0])); button = ((Component)value).GetComponent<CL_Button>(); return true; } public static MeshFilter FindTree(string meshName) { LoadSources(); MeshFilter val = (from m in sources.SelectMany((GameObject s) => s.GetComponentsInChildren<MeshFilter>(true)) where (Object)(object)m.sharedMesh != (Object)null && ((Object)m.sharedMesh).name == meshName orderby ((Component)m).GetComponentsInChildren<CL_Button>(true).Length != 0 descending select m).FirstOrDefault(); if ((Object)(object)val != (Object)null) { Plugin.Log.LogInfo((object)("Prop tree '" + meshName + "' from '" + ((Object)((Component)val).transform.root).name + "/" + ((Object)val).name + "'")); } return val; } private static void LoadSources() { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (sourcesTried) { return; } sourcesTried = true; string[] sourceLevels = SourceLevels; foreach (string text in sourceLevels) { try { LevelAssetHolder levelAsset = CL_AssetManager.GetLevelAsset(text, ""); if (levelAsset?.levelAssetReference == null) { Plugin.Log.LogWarning((object)("Prop source level '" + text + "' not in the game's database.")); continue; } AsyncOperationHandle<GameObject> item = Addressables.LoadAssetAsync<GameObject>(((AssetReference)levelAsset.levelAssetReference).RuntimeKey); GameObject val = item.WaitForCompletion(); if ((int)item.Status == 1 && (Object)(object)val != (Object)null) { handles.Add(item); sources.Add(val); } else { Plugin.Log.LogWarning((object)("Prop source level '" + text + "' failed to load: " + item.OperationException?.Message)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Prop source level '" + text + "': " + ex.Message)); } } } } public class MapScreen : MonoBehaviour { internal static readonly List<MapScreen> All = new List<MapScreen>(); private TextMeshPro tmp; private const float PanelW = 0.88f; private const float PanelH = 0.8f; private void OnEnable() { All.Add(this); } private void OnDisable() { All.Remove(this); } private IEnumerator Start() { yield return (object)new WaitForSeconds(0.5f); TMP_FontAsset val = HudFont(); Plugin.Log.LogInfo((object)("Screen: making text with font '" + (((Object)(object)val != (Object)null) ? ((Object)val).name : "none") + "'")); if (!((Object)(object)val == (Object)null)) { MeshFilter component = ((Component)this).GetComponent<MeshFilter>(); Bounds? obj; if (component == null) { obj = null; } else { Mesh sharedMesh = component.sharedMesh; obj = ((sharedMesh != null) ? new Bounds?(sharedMesh.bounds) : ((Bounds?)null)); } Bounds mb = (Bounds)(((??)obj) ?? new Bounds(Vector3.zero, new Vector3(4f, 2f, 0.5f))); MakeBlackPanel(mb); GameObject val2 = new GameObject("screen_text"); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = new Vector3(((Bounds)(ref mb)).center.x, ((Bounds)(ref mb)).center.y, ((Bounds)(ref mb)).max.z + 0.04f); val2.transform.localRotation = Quaternion.Euler(0f, 180f, 0f); tmp = val2.AddComponent<TextMeshPro>(); ((TMP_Text)tmp).font = val; ((TMP_Text)tmp).rectTransform.sizeDelta = new Vector2(((Bounds)(ref mb)).size.x * 0.88f * 0.97f, ((Bounds)(ref mb)).size.y * 0.8f * 0.97f); ((TMP_Text)tmp).enableAutoSizing = true; ((TMP_Text)tmp).fontSizeMin = 1f; ((TMP_Text)tmp).fontSizeMax = 12f; ((TMP_Text)tmp).alignment = (TextAlignmentOptions)513; ((Graphic)tmp).color = new Color(0.55f, 1f, 0.55f); ((TMP_Text)tmp).richText = true; Plugin.Log.LogInfo((object)"Screen: text ready"); GlowGame.RefreshScreens(force: true); Plugin.Log.LogInfo((object)"Screen: first text shown"); } } private void MakeBlackPanel(Bounds mb) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_011d: 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_0131: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: 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_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0213: 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_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: 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_0230: 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_023c: Unknown result type (might be due to invalid IL or missing references) //IL_026b: 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_0282: Unknown result type (might be due to invalid IL or missing references) Material val = (from r in ((Component)((Component)this).transform.root).GetComponentsInChildren<Renderer>() select r.sharedMaterial).FirstOrDefault((Func<Material, bool>)((Material m) => (Object)(object)m != (Object)null && ((Object)m).name.StartsWith("WKMap_Tint_"))); Material val2 = GlowGame.LitMaterial(val, Color.black, dull: true); if (!((Object)(object)val2 == (Object)null)) { Plugin.Log.LogInfo((object)("Screen: black panel from '" + ((Object)val).name + "' (shader '" + ((Object)val.shader).name + "')")); float num = ((Bounds)(ref mb)).size.x * 0.88f / 2f; float num2 = ((Bounds)(ref mb)).size.y * 0.8f / 2f; float num3 = ((Bounds)(ref mb)).max.z + 0.02f; Vector3 center = ((Bounds)(ref mb)).center; Mesh val3 = new Mesh { name = "screen_panel" }; Vector3[] array = (Vector3[])(object)new Vector3[4] { new Vector3(center.x - num, center.y - num2, num3), new Vector3(center.x + num, center.y - num2, num3), new Vector3(center.x + num, center.y + num2, num3), new Vector3(center.x - num, center.y + num2, num3) }; val3.vertices = array.Concat(array).ToArray(); val3.normals = Enumerable.Repeat<Vector3>(Vector3.forward, 4).Concat(Enumerable.Repeat<Vector3>(Vector3.back, 4)).ToArray(); val3.uv = (Vector2[])(object)new Vector2[8] { Vector2.zero, Vector2.right, Vector2.one, Vector2.up, Vector2.zero, Vector2.right, Vector2.one, Vector2.up }; val3.triangles = new int[12] { 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7 }; val3.RecalculateBounds(); GameObject val4 = new GameObject("screen_panel"); val4.transform.SetParent(((Component)this).transform, false); val4.AddComponent<MeshFilter>().sharedMesh = val3; ((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = val2; } } private static TMP_FontAsset HudFont() { TMP_Text[] array = Object.FindObjectsByType<TMP_Text>((FindObjectsSortMode)0); foreach (TMP_Text val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null && ((Behaviour)val).isActiveAndEnabled) { return val.font; } } return null; } internal void SetText(string s) { if ((Object)(object)tmp != (Object)null && ((TMP_Text)tmp).text != s) { ((TMP_Text)tmp).text = s; } } } public class MapGlowHold : MonoBehaviour { public bool glow; public bool pass; public int lane = 1; public int variant = -1; internal bool lit; internal Vector3 home; internal int owner; internal float litAt; internal float litUntil; private CL_Handhold hold; private Renderer rend; private Material gray; private GameObject lamp; internal static readonly List<MapGlowHold> All = new List<MapGlowHold>(); internal bool Held { get { if ((Object)(object)hold != (Object)null) { return hold.GetHolding(); } return false; } } internal bool HasLamp => (Object)(object)lamp != (Object)null; private void OnEnable() { if (glow) { All.Add(this); } } private void OnDisable() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) All.Remove(this); SetLit(on: false); } private void Awake() { //IL_0007: 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) home = ((Component)this).transform.localPosition; } private void Start() { hold = ((Component)this).GetComponent<CL_Handhold>(); rend = ((Component)this).GetComponent<Renderer>(); if (pass) { Collider[] components = ((Component)this).GetComponents<Collider>(); for (int i = 0; i < components.Length; i++) { MakeTrigger(components[i]); } } } internal static void MakeTrigger(Collider c) { MeshCollider val = (MeshCollider)(object)((c is MeshCollider) ? c : null); if (val != null) { val.convex = true; } c.isTrigger = true; } private void Update() { if (!lit && (Object)(object)rend != (Object)null) { gray = rend.sharedMaterial; } if (lit && Held) { GlowGame.OnGrab(this); } } internal void SetLit(bool on, Color color = default(Color)) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rend == (Object)null) { rend = ((Component)this).GetComponent<Renderer>(); } if ((Object)(object)rend == (Object)null || lit == on) { lit = on; return; } if ((Object)(object)gray == (Object)null) { gray = rend.sharedMaterial; } lit = on; if (color == default(Color)) { color = GlowGame.PlayerColors[0]; } rend.sharedMaterial = (on ? GlowGame.LitMaterial(gray, color) : gray); if (on && (Object)(object)lamp == (Object)null && GlowGame.LampCount < 6) { lamp = GlowGame.MakeLamp(((Component)this).transform, color); } if (!on && (Object)(object)lamp != (Object)null) { Object.Destroy((Object)(object)lamp); lamp = null; } } } public class MapLane : MonoBehaviour { public int lane = 1; public int variant = -1; public bool spin; private Vector3 basePos; private Quaternion baseRot; private float dx; private bool started; internal static readonly List<MapLane> All = new List<MapLane>(); private static readonly Dictionary<int, Vector3> axes = new Dictionary<int, Vector3>(); private const float SpinPeriod = 15f; private void Start() { //IL_0007: 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_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_0045: Unknown result type (might be due to invalid IL or missing references) basePos = ((Component)this).transform.localPosition; baseRot = ((Component)this).transform.localRotation; if (((Object)this).name.ToLowerInvariant().Contains("cyl_body")) { axes[lane] = basePos; } started = true; All.Add(this); GlowGame.PlaceLane(this); } private void OnDestroy() { All.Remove(this); } internal void Place(float dx, bool show) { if (started) { this.dx = dx; show &= GlowGame.OnMap(variant); Pose(); if (((Component)this).gameObject.activeSelf != show) { ((Component)this).gameObject.SetActive(show); } } } private void Update() { if (spin) { Pose(); } } private void Pose() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 val = basePos; Quaternion localRotation = baseRot; if (spin && axes.TryGetValue(lane, out var value)) { Quaternion val2 = Quaternion.AngleAxis(Time.time * 360f / 15f, Vector3.right); val = value + val2 * (basePos - value); localRotation = val2 * baseRot; } ((Component)this).transform.localPosition = val + Vector3.right * dx; ((Component)this).transform.localRotation = localRotation; } } public class MapBarrier : MonoBehaviour { public int lane = 1; internal static readonly List<MapBarrier> All = new List<MapBarrier>(); private void Start() { All.Add(this); Set(!GlowGame.IsOpen(lane)); } private void OnDestroy() { All.Remove(this); } internal void Set(bool on) { Collider[] components = ((Component)this).GetComponents<Collider>(); for (int i = 0; i < components.Length; i++) { components[i].enabled = on; } } } internal static class GlowGame { private enum State { Idle, Countdown, Running, Result } private class Lane { public int id; public State state; public float countEnd; public float endTime; public float nextLight; public int lastCount; public bool warned10; public Random rng = new Random(); } private class Score { public int pressed; public int missed; public bool newBest; public readonly List<float> reactions = new List<float>(); } private class Item { public string label; public string value; public Action<int> change; public Color? color; } private static readonly string[] MapNames = new string[2] { "Flat Wall", "Cylinder" }; public static bool Multiplayer; public static bool Coop; public static bool SharedTrail; public static int Players = 2; public static float Lifespan = 3f; public static float Interval = 1f; public static float Duration = 60f; private const float LifeStep = 0.5f; private const float LifeMin = 0.5f; private const float LifeMax = 10f; private const float IntStep = 0.25f; private const float IntMin = 0.25f; private const float IntMax = 5f; private const float DurStep = 15f; private const float DurMin = 15f; private const float DurMax = 600f; public const float LaneOffset = 10.75f; internal const int MaxLamps = 6; internal static readonly Color[] PlayerColors = (Color[])(object)new Color[4] { new Color(0.2f, 1f, 0.3f), new Color(0.25f, 0.55f, 1f), new Color(1f, 0.55f, 0.1f), new Color(1f, 0.3f, 0.8f) }; private static readonly string[] ColorNames = new string[4] { "green", "blue", "orange", "pink" }; private static readonly Lane[] lanes = new Lane[3] { null, new Lane { id = 1 }, new Lane { id = 2 } }; private static readonly Score[] scores = new Score[5] { null, new Score(), new Score(), new Score(), new Score() }; private static int tab; private static int row; private static int map; private static float nextScreen; private static readonly Dictionary<string, int> best = new Dictionary<string, int>(); private static readonly Dictionary<(Material, Color, bool), Material> litCache = new Dictionary<(Material, Color, bool), Material>(); private static readonly Dictionary<Color, Texture2D> colorTex = new Dictionary<Color, Texture2D>(); private const string Dim = "#6FBF6F"; private const string Bright = "#C8FFC8"; private const string Hi = "#FFFFFF"; private static bool TwoWalls { get { if (Multiplayer && !Coop) { return !SharedTrail; } return false; } } private static bool ColoredHolds { get { if (Multiplayer && !Coop) { return SharedTrail; } return false; } } private static int WallCount { get { if (!TwoWalls) { return 1; } return 2; } } private static IEnumerable<Lane> Active => lanes.Skip(1).Take(WallCount); private static int Scorers { get { if (Multiplayer && !Coop) { if (!TwoWalls) { return Players; } return 2; } return 1; } } private static bool Busy => Active.Any((Lane l) => l.state == State.Countdown || l.state == State.Running); public static bool Running => Active.Any((Lane l) => l.state == State.Running); internal static int LampCount => MapGlowHold.All.Count((MapGlowHold h) => h.HasLamp); private static string ModeText { get { if (Multiplayer) { if (!Coop) { if (!SharedTrail) { return "comp, wall each"; } return $"comp x{Players}, shared wall"; } return $"co-op x{Players}"; } return "1 player"; } } private static string Settings => $"{MapNames[map]}, {ModeText}, lifespan {Lifespan:0.#} s, every {Interval:0.##} s, {Duration:0} s"; internal static int VariantOf(string name) { string text = name.ToLowerInvariant(); if (!text.Contains("_cyl")) { if (!text.Contains("_flat")) { return -1; } return 0; } return 1; } internal static bool OnMap(int variant) { if (variant >= 0) { return variant == map; } return true; } internal static bool InPlay(MapGlowHold h, int lane) { if (h.lane == lane) { return OnMap(h.variant); } return false; } private static IEnumerable<int> PlayersOn(int lane) { if (!TwoWalls) { if (!ColoredHolds) { return new int[1] { 1 }; } return Enumerable.Range(1, Players); } return new int[1] { lane }; } private static string ScorerName(int p) { if (Multiplayer) { if (!Coop) { return $"P{p}"; } return "Team"; } return "You"; } internal static bool IsOpen(int lane) { if (lane >= 1 && lane <= 2) { return lanes[lane].state == State.Running; } return false; } private static string Who(Lane l) { if (!TwoWalls) { return ""; } return $"P{l.id} "; } internal static void PlaceLane(MapLane l) { float dx = ((!TwoWalls) ? 0f : ((l.lane == 1) ? (-10.75f) : 10.75f)); l.Place(dx, l.lane == 1 || TwoWalls); } private static void ApplyLayout() { foreach (MapLane item in MapLane.All.ToList()) { if ((Object)(object)item != (Object)null) { PlaceLane(item); } } } private static List<Item> Items() { //IL_033b: Unknown result type (might be due to invalid IL or missing references) List<Item> list = new List<Item> { null }; if (tab == 0) { list.Add(new Item { label = "Map", value = MapNames[map], change = delegate(int d) { map = (map + d + MapNames.Length) % MapNames.Length; } }); list.Add(new Item { label = "Multiplayer", value = (Multiplayer ? "ON" : "OFF"), change = delegate { Multiplayer = !Multiplayer; } }); if (Multiplayer) { list.Add(new Item { label = "Mode", value = (Coop ? "Co-op" : "Comp"), change = delegate { Coop = !Coop; } }); if (!Coop) { list.Add(new Item { label = "Trails", value = (SharedTrail ? "1 shared" : "1 per player"), change = delegate { SharedTrail = !SharedTrail; } }); } if (Coop || SharedTrail) { list.Add(new Item { label = "Player count", value = Players.ToString(), change = delegate(int d) { Players = Mathf.Clamp(Players + d, 2, 4); } }); } } list.Add(new Item { label = "Btn lifespan", value = $"{Lifespan:0.0} s", change = delegate(int d) { Lifespan = Mathf.Clamp(Lifespan + (float)d * 0.5f, 0.5f, 10f); } }); list.Add(new Item { label = "Interval", value = $"{Interval:0.00} s", change = delegate(int d) { Interval = Mathf.Clamp(Interval + (float)d * 0.25f, 0.25f, 5f); } }); list.Add(new Item { label = "Duration", value = $"{Duration:0} s", change = delegate(int d) { Duration = Mathf.Clamp(Duration + (float)d * 15f, 15f, 600f); } }); } else { for (int num = 0; num < PowerUps.Names.Length; num++) { int k = num; list.Add(new Item { label = PowerUps.Shapes[k] + " - " + PowerUps.Names[k], value = (PowerUps.Enabled[k] ? "ON" : "OFF"), color = PowerUps.Colors[k], change = delegate { PowerUps.Enabled[k] = !PowerUps.Enabled[k]; } }); } list.Add(new Item { label = "Max at once", value = PowerUps.MaxAtOnce.ToString(), change = delegate(int d) { PowerUps.MaxAtOnce = Mathf.Clamp(PowerUps.MaxAtOnce + d, 1, 10); } }); list.Add(new Item { label = "Spawn every", value = $"{PowerUps.SpawnEvery:0} s", change = delegate(int d) { PowerUps.SpawnEvery = Mathf.Clamp(PowerUps.SpawnEvery + (float)d * 5f, 5f, 60f); } }); } return list; } public static void Menu(string key) { if (Busy) { return; } foreach (Lane item in Active) { if (item.state == State.Result) { item.state = State.Idle; } } List<Item> list = Items(); row = Mathf.Clamp(row, 0, list.Count - 1); int num = ((key == "left") ? (-1) : ((key == "right") ? 1 : 0)); if (key == "up") { row = (row + list.Count - 1) % list.Count; } else if (key == "down") { row = (row + 1) % list.Count; } else if (num != 0 && row == 0) { tab = 1 - tab; } else if (num != 0) { list[row].change(num); ApplyLayout(); } RefreshScreens(force: true); } public static void StandPressed(int lane) { if (lane >= 1 && lane <= WallCount) { Lane lane2 = lanes[lane]; if (lane2.state != State.Countdown && lane2.state != State.Running) { BeginCountdown(lane); } } } public static void BeginCountdown(int lane, float seconds = 0f) { if (seconds > 0f) { Duration = seconds; } if (!MapGlowHold.All.Any((MapGlowHold h) => InPlay(h, lane))) { MapSession.ShowTitle("No glow holds here"); return; } Lane lane2 = lanes[lane]; foreach (Lane item in Active) { if (item.state == State.Result) { item.state = State.Idle; } } lane2.state = State.Countdown; lane2.countEnd = Time.time + 3f; lane2.lastCount = 4; RefreshScreens(force: true); } private static void Go(Lane l) { l.state = State.Running; foreach (int item in PlayersOn(l.id)) { Score obj = scores[item]; obj.pressed = (obj.missed = 0); obj.reactions.Clear(); obj.newBest = false; } l.warned10 = false; l.endTime = Time.time + Duration; l.nextLight = Time.time + 0.3f; l.rng = new Random(StableHash(Settings)); foreach (MapBarrier item2 in MapBarrier.All) { if (item2.lane == l.id) { item2.Set(on: false); } } PowerUps.StartLane(l.id); MapSession.ShowTitle(Who(l) + "GO!"); Plugin.Say("Glow wall " + Who(l) + ": " + Settings); RefreshScreens(force: true); } public static void Stop(bool showScore) { foreach (Lane item in Active.ToList()) { if (item.state == State.Running && showScore) { Finish(item); } else if (item.state == State.Running || item.state == State.Countdown) { EndRound(item); } } RefreshScreens(force: true); } public static void Reset() { foreach (Lane item in lanes.Skip(1)) { item.state = State.Idle; } PowerUps.Reset(); } private static void EndRound(Lane l) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) l.state = State.Idle; foreach (MapGlowHold item in MapGlowHold.All.ToList()) { if (item.lane == l.id) { item.SetLit(on: false); } } foreach (MapBarrier item2 in MapBarrier.All) { if (item2.lane == l.id) { item2.Set(on: true); } } PowerUps.ClearLane(l.id); MoveOutOfLane(l.id); } private static void MoveOutOfLane(int lane) { //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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_00fd: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { return; } foreach (MapBarrier item in MapBarrier.All) { if (!((Object)(object)item == (Object)null) && item.lane == lane && ((Object)item).name.Contains("front") && ((Component)item).gameObject.activeInHierarchy && !((Object)(object)((Component)item).transform.parent == (Object)null)) { Transform parent = ((Component)item).transform.parent; Vector3 val = parent.InverseTransformPoint(((Component)playerObject).transform.position); Vector3 localPosition = ((Component)item).transform.localPosition; if (!(val.z > localPosition.z) && !(Mathf.Abs(val.x - localPosition.x) > 11.75f)) { ((GameEntity)playerObject).Teleport(parent.TransformPoint(new Vector3(localPosition.x, 1.2f, localPosition.z + 4f)), ((Component)playerObject).transform.rotation, false); break; } } } } private static void Finish(Lane l) { EndRound(l); l.state = State.Result; string settings = Settings; foreach (int item in PlayersOn(l.id)) { Score score = scores[item]; score.newBest = !best.TryGetValue(settings, out var value) || score.pressed > value; if (score.newBest) { best[settings] = score.pressed; } Plugin.Say($"Glow wall {ScorerName(item)}: {score.pressed} pressed, {score.missed} missed, {Pct(score)}, {Rate(score)}, avg reaction {AvgRx(score)}, fastest {BestRx(score)}" + (score.newBest ? ", new best" : "")); } MapSession.ShowTitle("GAME OVER..."); } public static void OnGrab(MapGlowHold h) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Lane l = lanes[Mathf.Clamp(h.lane, 1, 2)]; int owner = h.owner; h.SetLit(on: false); if (l.state != State.Running) { return; } int num = ((Coop || !Multiplayer) ? 1 : Mathf.Clamp(owner, 1, 4)); Score score = scores[num]; score.pressed++; score.reactions.Add(Time.time - h.litAt); MapSession.ShowTitle((Scorers > 1) ? $"{ScorerName(num)}: {score.pressed}" : score.pressed.ToString()); if (!MapGlowHold.All.Any((MapGlowHold x) => x.lane == l.id && x.lit && x.owner == owner)) { LightNext(l, Time.time, owner); if (!ColoredHolds) { l.nextLight = Time.time + Interval; } } RefreshScreens(force: true); } public static void Tick() { //IL_00fc: 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) float time = Time.time; bool flag = false; foreach (Lane item in Active.ToList()) { if (item.state == State.Countdown) { flag = true; int num = Mathf.CeilToInt(item.countEnd - time); if (num != item.lastCount && num > 0) { item.lastCount = num; MapSession.ShowTitle(Who(item) + num); RefreshScreens(force: true); } if (time >= item.countEnd) { Go(item); } } else { if (item.state != State.Running) { continue; } flag = true; foreach (MapGlowHold item2 in MapGlowHold.All.ToList()) { if (item2.lane == item.id && item2.lit && time >= item2.litUntil) { int num2 = ((Coop || !Multiplayer) ? 1 : Mathf.Clamp(item2.owner, 1, 4)); item2.SetLit(on: false); scores[num2].missed++; } } if (time >= item.endTime) { Finish(item); RefreshScreens(force: true); continue; } if (!item.warned10 && Duration > 15f && item.endTime - time <= 10f) { item.warned10 = true; MapSession.ShowTitle(Who(item) + "10 s left"); } if (time < item.nextLight) { continue; } item.nextLight += Interval; if (item.nextLight < time) { item.nextLight = time + Interval; } foreach (int item3 in PlayersOn(item.id)) { LightNext(item, time, ColoredHolds ? item3 : item.id); } } } PowerUps.Tick((from x in Active where x.state == State.Running select x.id).ToList()); if (flag) { RefreshScreens(force: false); } } private static void LightNext(Lane l, float now, int owner) { //IL_00d8: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) List<MapGlowHold> list = (from h in MapGlowHold.All where InPlay(h, l.id) orderby Mathf.Round(h.home.y * 100f), Mathf.Round(h.home.x * 100f), Mathf.Round(h.home.z * 100f) select h).ToList(); if (list.Count == 0) { return; } int num = l.rng.Next(list.Count); Color color = (ColoredHolds ? PlayerColors[Mathf.Clamp(owner - 1, 0, 3)] : PlayerColors[0]); for (int num2 = 0; num2 < list.Count; num2++) { MapGlowHold mapGlowHold = list[(num + num2) % list.Count]; if (!mapGlowHold.lit && !mapGlowHold.Held) { mapGlowHold.owner = owner; mapGlowHold.SetLit(on: true, color); mapGlowHold.litAt = now; mapGlowHold.litUntil = now + Lifespan; break; } } } private static int StableHash(string s) { int num = -2128831035; foreach (char c in s) { num = (num ^ c) * 16777619; } return num & 0x7FFFFFFF; } private static string Clock(float t) { return $"{(int)(t / 60f)}:{t % 60f:00.0}"; } public static void RefreshScreens(bool force) { if (MapScreen.All.Count == 0 || (!force && Time.time < nextScreen)) { return; } nextScreen = Time.time + 0.1f; string text = ScreenText(); foreach (MapScreen item in MapScreen.All) { item.SetText(text); } } private static string Hex(Color c) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(c); } private static string Title(string s) { return "<align=center><size=130%><b>" + s + "</b></size></align>\n"; } private static string Hint(string s) { return "\n<align=center><size=65%><color=#6FBF6F>" + s + "</color></size></align>"; } private static string Row(string label, params string[] values) { StringBuilder stringBuilder = new StringBuilder("<pos=4%><color=#6FBF6F>" + label + "</color><color=#C8FFC8>"); float num = ((values.Length <= 1) ? 52f : 40f); float num2 = ((values.Length <= 1) ? 0f : (58f / (float)values.Length)); for (int i = 0; i < values.Length; i++) { stringBuilder.Append($"<pos={num + (float)i * num2:0}%>{values[i]}"); } return stringBuilder.Append("</color>\n").ToString(); } private static string Pct(Score s) { int num = s.pressed + s.missed; if (num <= 0) { return "-"; } return $"{100f * (float)s.pressed / (float)num:0}%"; } private static string Rate(Score s) { return $"{(float)s.pressed / Duration * 60f:0.0}/min"; } private static string AvgRx(Score s) { if (s.reactions.Count <= 0) { return "-"; } return $"{s.reactions.Average():0.00} s"; } private static string BestRx(Score s) { if (s.reactions.Count <= 0) { return "-"; } return $"{s.reactions.Min():0.00} s"; } private static string TabBar() { return "<align=center><size=90%>" + T(0, "GAME") + " " + T(1, "POWER-UPS") + "</size></align>\n"; static string T(int i, string name) { if (i != tab) { return "<color=#6FBF6F>" + name + "</color>"; } if (row != 0) { return "<color=#FFFFFF><b>" + name + "</b></color>"; } return "<color=#FFFFFF><u><b>" + name + "</b></u></color>"; } } private static string ScreenText() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); List<Lane> source = Active.ToList(); if (source.All((Lane l) => l.state == State.Idle)) { stringBuilder.Append(TabBar()); stringBuilder.Append(Title((tab == 0) ? "GLOW WALL" : "POWER-UPS")); List<Item> list = Items(); row = Mathf.Clamp(row, 0, list.Count - 1); for (int num = 1; num < list.Count; num++) { Item item = list[num]; string text = (item.color.HasValue ? ("<color=" + Hex(item.color.Value) + ">" + item.label + "</color>") : item.label); stringBuilder.Append((num == row) ? ("<pos=4%><color=#FFFFFF><u>" + text + "</u><pos=62%><u>" + item.value + "</u></color>\n") : ("<pos=4%><color=#6FBF6F>" + text + "</color><pos=62%><color=#C8FFC8>" + item.value + "</color>\n")); } if (tab == 0 && ColoredHolds) { stringBuilder.Append(Row("Colors", string.Join(" ", from i in Enumerable.Range(0, Players) select $"<color={Hex(PlayerColors[i])}>P{i + 1} {ColorNames[i]}</color>"))); } string text2 = ((tab == 1) ? "fly through a power-up to use it" : (TwoWalls ? "each player presses the red btn at their wall" : "press the red btn at the wall to start")); stringBuilder.Append(Hint(text2 + "<br>up/down = row left/right = change top row = tabs")); return stringBuilder.ToString(); } bool flag = source.All((Lane l) => l.state == State.Result || l.state == State.Idle); stringBuilder.Append(Title(flag ? "GAME OVER..." : "GLOW WALL")); int scorers = Scorers; List<int> cols = Enumerable.Range(1, scorers).ToList(); if (scorers > 1) { stringBuilder.Append(Row("", V(Name))); } if (!flag) { stringBuilder.Append(Row("Time left", V(delegate(int p) { Lane lane = LaneOf(p); return (lane.state != State.Countdown) ? ((lane.state != State.Running) ? ((lane.state != State.Result) ? "press red btn" : "done") : Clock(Mathf.Max(0f, lane.endTime - Time.time))) : $"<b>{Mathf.Max(1, Mathf.CeilToInt(lane.countEnd - Time.time))}</b>"; }))); } stringBuilder.Append(Row("Missed", V((int p) => (!Played(p)) ? "-" : scores[p].missed.ToString()))); if (source.Any((Lane l) => l.state == State.Result)) { stringBuilder.Append(Row("Accuracy", V((int p) => (!Done(p)) ? "-" : Pct(scores[p])))); stringBuilder.Append(Row("Press rate", V((int p) => (!Done(p)) ? "-" : Rate(scores[p])))); stringBuilder.Append(Row("Avg reaction", V((int p) => (!Done(p)) ? "-" : AvgRx(scores[p])))); stringBuilder.Append(Row("Fastest", V((int p) => (!Done(p)) ? "-" : BestRx(scores[p])))); stringBuilder.Append(Row("Best", V((int p) => Done(p) ? ((!scores[p].newBest) ? ((!best.TryGetValue(Settings, out var value)) ? "-" : value.ToString()) : "NEW!") : "-"))); } string text3 = ((scorers != 1) ? string.Join(" ", cols.Select((int p) => Name(p) + " " + (Played(p) ? scores[p].pressed.ToString() : "-"))) : ((Played(1) ? scores[1].pressed.ToString() : "-") ?? "")); stringBuilder.Append("\n<align=center><size=140%><color=#FFFFFF>Pressed btns - " + text3 + "</color></size></align>\n"); if (flag && scorers > 1 && cols.All(Done) && !Coop) { int top = cols.Max((int p) => scores[p].pressed); List<int> list2 = cols.Where((int p) => scores[p].pressed == top).ToList(); stringBuilder.Append("<align=center><b>" + ((list2.Count > 1) ? "Draw!" : (ScorerName(list2[0]) + " wins!")) + "</b></align>\n"); } stringBuilder.Append(Hint(Settings + ((!Busy) ? "<br>red btn = play again arrows = settings" : ""))); return stringBuilder.ToString(); static bool Done(int p) { return LaneOf(p).state == State.Result; } static Lane LaneOf(int p) { if (!TwoWalls) { return lanes[1]; } return lanes[p]; } static string Name(int p) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!ColoredHolds) { return "<b>" + ScorerName(p) + "</b>"; } return $"<color={Hex(PlayerColors[p - 1])}><b>P{p}</b></color>"; } static bool Played(int p) { return LaneOf(p).state != State.Idle; } string[] V(Func<int, string> f) { return cols.Select(f).ToArray(); } } public static Material LitMaterial(Material gray, Color color, bool dull = false) { //IL_0011: 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_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_0053: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gray == (Object)null) { return null; } if (litCache.TryGetValue((gray, color, dull), out var value) && (Object)(object)value != (Object)null) { return value; } if (!colorTex.TryGetValue(color, out var value2) || (Object)(object)value2 == (Object)null) { value2 = new Texture2D(2, 2) { filterMode = (FilterMode)0 }; value2.SetPixels(Enumerable.Repeat<Color>(color, 4).ToArray()); value2.Apply(); colorTex[color] = value2; } value = new Material(gray) { name = (dull ? "WKMap_GlowDull_" : "WKMap_GlowLit_") + ColorUtility.ToHtmlStringRGB(color) }; string[] texturePropertyNames = value.GetTexturePropertyNames(); foreach (string text in texturePropertyNames) { if (!((Object)(object)value.GetTexture(text) == (Object)null) && !text.ToLowerInvariant().Contains("noise") && !text.ToLowerInvariant().Contains("normal") && !text.ToLowerInvariant().Contains("bump")) { value.SetTexture(text, (Texture)(object)((dull && text.ToLowerInvariant().Contains("emis")) ? Texture2D.blackTexture : value2)); } } if (dull) { texturePropertyNames = value.GetPropertyNames((MaterialPropertyType)2); foreach (string text2 in texturePropertyNames) { if (text2.ToLowerInvariant().Contains("emis")) { value.SetColor(text2, Color.black); } } texturePropertyNames = value.GetPropertyNames((MaterialPropertyType)0); foreach (string text3 in texturePropertyNames) { string text4 = text3.ToLowerInvariant(); if (text4.Contains("emis") || text4.Contains("gloss") || text4.Contains("smooth") || text4.Contains("metal") || text4.Contains("spec")) { value.SetFloat(text3, 0f); } } value.DisableKeyword("_EMISSION"); } if (value.HasProperty("_EmissionMultiplier")) { value.SetFloat("_EmissionMultiplier", dull ? 0f : 3f); } if (value.HasProperty("_ShimmerColor")) { value.SetColor("_ShimmerColor", color); } if (value.HasProperty("_Shimmer")) { value.SetFloat("_Shimmer", dull ? 0f : 1f); } if (value.HasProperty("_ShimmerSpeed")) { value.SetFloat("_ShimmerSpeed", 2f); } if (value.HasProperty("_ShimmerFrequency")) { value.SetFloat("_ShimmerFrequency", 1f); } litCache[(gray, color, dull)] = value; return value; } public static GameObject MakeLamp(Transform hold, Color color) { //IL_0005: 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_0017: 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) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown GameObject val = new GameObject("glow_lamp"); val.transform.SetParent(hold, false); val.transform.position = hold.position + hold.forward * 0.4f + Vector3.up * 0.01f; CL_Lamp obj = val.AddComponent<CL_Lamp>(); obj.lampActive = true; obj.range = (obj.curRange = 2.5f); obj.startColor = (obj.color = color); obj.intensity = 1f; obj.attentuation = 1; obj.emissiveMult = 1f; obj.bypassLightmap = 1f; obj.fadeStart = (obj.fadeTarget = 1f); return val; } } public class MapCheckpoint : MonoBehaviour { public string action = "checkpoint"; public int count = 1; public string item = "rebar"; private void Start() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown CL_Button component = ((Component)this).GetComponent<CL_Button>(); if (!((Object)(object)component == (Object)null)) { if (component.activeEvent == null) { component.activeEvent = new UnityEvent(); } component.activeEvent.AddListener(new UnityAction(Apply)); } } public void Apply() { //IL_0102: 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) if (action.StartsWith("menu_")) { GlowGame.Menu(action.Substring(5)); return; } if (action.StartsWith("glowstart_") && int.TryParse(action.Substring(10), out var result)) { GlowGame.StandPressed(result); return; } switch (action) { case "buddy": MapSession.BuddyOn = !MapSession.BuddyOn; if (MapSession.BuddyOn) { ItemTools.EnsureBuddy(); } else { ItemTools.RemoveBuddy(); } MapSession.ShowTitle(MapSession.BuddyOn ? "Buddy ON" : "Buddy OFF"); return; case "glowgame": GlowGame.StandPressed(1); return; case "win": MapSession.Win(); return; case "tpspawn": MapSession.OnRespawn(); if (MapSession.SavedRespawn.HasValue && (Object)(object)ENT_Player.playerObject != (Object)null) { ((GameEntity)ENT_Player.playerObject).Teleport(MapSession.SavedRespawn.Value, ((Component)ENT_Player.playerObject).transform.rotation, false); MapSession.ShowTitle("Tp to checkpoint"); } else { Plugin.Instance.BackToSpawn(); MapSession.ShowTitle("Tp to spawn"); } return; } if (!ItemTools.ClearInventory()) { Plugin.Log.LogWarning((object)"Could not clear inventory."); } int num = ItemTools.Give(item, count); if (MapSession.BuddyOn) { ItemTools.EnsureBuddy(); } Plugin.Say($"Checkpoint: inventory reset, {num}x {ItemTools.LastResolvedName ?? item}"); if (num > 0) { MapSession.ShowTitle($"+{num} {ItemTools.ShortName(item, num)}"); } } } internal static class MapSession { public static bool BuddyOn; public static bool GodmodeMap; private static bool godmodeSetByUs; public static Vector3? SavedRespawn; public static readonly List<Bounds> PadsLocal = new List<Bounds>(); public static readonly List<(Vector3 pos, string text)> NotesLocal = new List<(Vector3, string)>(); private static readonly List<Bounds> padsWorld = new List<Bounds>(); private static Bounds? lastPad; private static Coroutine fireworks; private const float WinScreenDelay = 10f; public static float WinFlySpeed = 4.2f; private static bool winActive; private static Vector3 lastPos; private static float[] savedSpeeds; public static void ResetForNewMap() { BuddyOn = false; GodmodeMap = false; SavedRespawn = null; PadsLocal.Clear(); NotesLocal.Clear(); GlowGame.Reset(); StopFireworks(); } public static void OnEnterLevel(Transform level) { //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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0095: 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) BuddyOn = false; SavedRespawn = null; lastPad = null; StopFireworks(); padsWorld.Clear(); foreach (Bounds item in PadsLocal) { Bounds current = item; padsWorld.Add(new Bounds(level.TransformPoint(((Bounds)(ref current)).center), ((Bounds)(ref current)).size)); } foreach (var item2 in NotesLocal) { ItemTools.DropNote(level.TransformPoint(item2.pos), item2.text); } ENT_Player playerObject = ENT_Player.playerObject; if (GodmodeMap && (Object)(object)playerObject != (Object)null && !playerObject.GetGodMode()) { playerObject.SetGodMode(true); godmodeSetByUs = true; Plugin.Say("Godmode on for this map."); } } public static void Tick(ENT_Player p) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_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_008a: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)p == (Object)null) { return; } BoostFlight(p); GlowGame.Tick(); if (padsWorld.Count == 0) { return; } Vector3 position = ((Component)p).transform.position; Bounds val = default(Bounds); foreach (Bounds item in padsWorld) { Bounds current = item; ((Bounds)(ref val))..ctor(((Bounds)(ref current)).center + Vector3.up * 1.2f, ((Bounds)(ref current)).size + new Vector3(0.2f, 2.6f, 0.2f)); if (!((Bounds)(ref val)).Contains(position)) { continue; } if (lastPad.HasValue) { Bounds value = lastPad.Value; if (((Bounds)(ref value)).center == ((Bounds)(ref current)).center) { break; } } lastPad =