Decompiled source of Expanded v1.1.26
BepInEx/plugins/SlipAndSkid.Expanded/SlipAndSkid.Expanded.dll
Decompiled 3 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.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using BepInEx.Unity.Mono; using CameraUtils; using Effects; using Effects.MotionEasing; using Game; using Game.Levels; using Game.Scores; using Game.UnlockableContent; using HarmonyLib; using Menus; using Menus.UI; using Menus.UI.Rules; using Microsoft.CodeAnalysis; using Obstacles; using Obstacles.ObstacleAffixes; using Obstacles.ObstacleGenerationContexts; using Player; using SlipAndSkid.Expanded; using SlipAndSkid.ExtendedCore; using SlipSkid.ChaosCards; using SlipSkid.ChaosSystems; using SlipSkid.RaceWorkshop; using SlipSkid.TankCards; using Sounds.SplitScreenAudio; using TMPro; using UI; using UI.TabsSystem; using UI.VectorGraphics; using Unity.Netcode; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Localization; using UnityEngine.Localization.Tables; using UnityEngine.Rendering; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; using Utils; using Utils.Networking; using World; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.1.26.0")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("1.1.25.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 SlipSkid.RaceWorkshop { public sealed class NukeChargeEffect : MonoBehaviour { private readonly List<Transform> motes = new List<Transform>(); private readonly List<Renderer> renderers = new List<Renderer>(); private readonly List<LineRenderer> arcs = new List<LineRenderer>(); private readonly List<Material> arcMaterials = new List<Material>(); private float start; private const float Duration = 1.6f; private Light glow; private Transform halo; private Renderer haloRenderer; internal static NukeChargeEffect Spawn(Transform parent) { //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) GameObject val = new GameObject("Nuke Cherenkov charge visuals"); val.transform.SetParent(parent, false); NukeChargeEffect nukeChargeEffect = val.AddComponent<NukeChargeEffect>(); nukeChargeEffect.Initialize(); return nukeChargeEffect; } private static void Colorize(Renderer r, Color color) { //IL_0030: 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) if (Object.op_Implicit((Object)(object)r) && Object.op_Implicit((Object)(object)r.sharedMaterial)) { Material sharedMaterial = r.sharedMaterial; if (sharedMaterial.HasProperty("_BaseColor")) { sharedMaterial.SetColor("_BaseColor", color); } if (sharedMaterial.HasProperty("_Color")) { sharedMaterial.SetColor("_Color", color); } } } private void Initialize() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_002e: 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_00a9: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0181: 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_01db: Unknown result type (might be due to invalid IL or missing references) start = Time.unscaledTime; GameObject val = new GameObject("Blue charge illumination"); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.zero; glow = val.AddComponent<Light>(); glow.type = (LightType)2; glow.color = new Color(0.08f, 0.65f, 1f); glow.range = 7f; glow.intensity = 0f; GameObject val2 = WorkshopVisual.Shape((PrimitiveType)0, "Charge aura", new Color(0.05f, 0.55f, 1f, 0.05f), Vector3.one); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = Vector3.zero; halo = val2.transform; haloRenderer = val2.GetComponent<Renderer>(); DisableColliders(val2); for (int i = 0; i < 20; i++) { GameObject val3 = WorkshopVisual.Shape((PrimitiveType)0, "Orbiting blue radiation", new Color(0.16f, 0.78f, 1f, 0.8f), Vector3.one * 0.14f); val3.transform.SetParent(((Component)this).transform, false); DisableColliders(val3); motes.Add(val3.transform); renderers.Add(val3.GetComponent<Renderer>()); } for (int j = 0; j < 4; j++) { GameObject val4 = new GameObject("Charge electrical arc"); val4.transform.SetParent(((Component)this).transform, false); LineRenderer val5 = val4.AddComponent<LineRenderer>(); val5.useWorldSpace = false; val5.positionCount = 6; float startWidth = (val5.endWidth = 0.055f); val5.startWidth = startWidth; Material item = (((Renderer)val5).sharedMaterial = WorkshopVisual.Material(new Color(0.25f, 0.83f, 1f, 0.85f))); arcMaterials.Add(item); arcs.Add(val5); } } private static void DisableColliders(GameObject obj) { Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].enabled = false; } } private void Update() { //IL_006a: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) float num = Time.unscaledTime - start; float num2 = Mathf.Clamp01(num / 1.6f); if (num >= 1.6f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num3 = num2 * num2; if (Object.op_Implicit((Object)(object)glow)) { glow.intensity = 0.25f + num3 * 3.2f; } if (Object.op_Implicit((Object)(object)halo)) { halo.localScale = Vector3.one * (2.1f + num2 * 1.2f); Colorize(haloRenderer, new Color(0.07f, 0.6f, 1f, 0.045f + num3 * 0.23f)); } for (int i = 0; i < motes.Count; i++) { float num4 = (float)i * 2.399963f + num * (3f + 13f * num3) * ((i % 2 == 0) ? 1f : (-1f)); float num5 = Mathf.Lerp(2.1f, 0.55f, num2) + 0.18f * Mathf.Sin(num * 9f + (float)i); float num6 = -1.1f + (float)(i % 7) * 0.37f + 0.15f * Mathf.Sin(num4 * 1.8f); motes[i].localPosition = new Vector3(Mathf.Cos(num4) * num5, num6, Mathf.Sin(num4) * num5); motes[i].localScale = Vector3.one * (0.09f + num3 * 0.17f); Colorize(renderers[i], new Color(0.25f + 0.5f * num2, 0.75f + 0.2f * num2, 1f, 0.4f + 0.55f * num2)); } for (int j = 0; j < arcs.Count; j++) { LineRenderer val = arcs[j]; if (((Renderer)val).enabled = num2 > 0.45f && Mathf.Sin(num * (11f + (float)j * 2f) + (float)j * 2.2f) > 0.75f - 0.65f * num2) { float num7 = (float)j * MathF.PI * 0.5f + num * 5f; for (int k = 0; k < 6; k++) { float num8 = (float)k / 5f; float num9 = 1.1f + 0.2f * Mathf.Sin(num * 38f + (float)j * 8f + (float)k * 5f); val.SetPosition(k, new Vector3(Mathf.Cos(num7 + num8 * 1.6f) * num9, -1.15f + num8 * 2.3f, Mathf.Sin(num7 + num8 * 1.6f) * num9)); } } } } private void OnDestroy() { foreach (Material arcMaterial in arcMaterials) { if (Object.op_Implicit((Object)(object)arcMaterial)) { Object.Destroy((Object)(object)arcMaterial); } } } } internal static class WorkshopArtwork { internal static readonly string[] Files = new string[16] { "cargo-pickup", "cargo-delivery", "dash-refill", "pit-stop", "one-way-barrier", "timed-bridge", "relocate", "random-roadworks", "stunt-hoop", "flipper-platform", "portal-pads", "duplicate", "traffic-light", "revolving-door", "nuke", "vertigo" }; internal static Texture2D Load(int index, string pluginLocation, Func<Texture2D> fallback, Action<string> warn) { //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown Texture2D val = null; string text = Path.Combine(Path.GetDirectoryName(pluginLocation), "artwork", Files[index] + ".png"); try { if (!File.Exists(text)) { return fallback(); } FileInfo fileInfo = new FileInfo(text); if (fileInfo.Length < 33 || fileInfo.Length > 8388608) { throw new InvalidDataException("PNG must be between 33 bytes and 8 MiB."); } byte[] array = File.ReadAllBytes(text); byte[] array2 = new byte[8] { 137, 80, 78, 71, 13, 10, 26, 10 }; for (int i = 0; i < array2.Length; i++) { if (array[i] != array2[i]) { throw new InvalidDataException("Not a PNG file."); } } if (ReadUInt(array, 8) != 13 || array[12] != 73 || array[13] != 72 || array[14] != 68 || array[15] != 82) { throw new InvalidDataException("Missing PNG image header."); } uint num = ReadUInt(array, 16); uint num2 = ReadUInt(array, 20); if (num == 0 || num2 == 0 || num > 2048 || num2 > 2048) { throw new InvalidDataException("PNG dimensions must be 1–2048 pixels."); } val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, array, true)) { throw new InvalidDataException("Unity could not decode PNG."); } ((Object)val).name = Files[index] + " artwork"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; return val; } catch (Exception ex) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)val); } warn("Card artwork skipped: " + text + " (" + ex.Message + "). Using default icon."); return fallback(); } } private static uint ReadUInt(byte[] bytes, int offset) { return (uint)((bytes[offset] << 24) | (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3]); } } public static class WorkshopBarrierRules { public static bool BlockedCrossing(double ax, double ay, double az, double bx, double by, double bz, double radius) { if (!WorkshopRules.Finite(ax) || !WorkshopRules.Finite(ay) || !WorkshopRules.Finite(az) || !WorkshopRules.Finite(bx) || !WorkshopRules.Finite(by) || !WorkshopRules.Finite(bz) || !WorkshopRules.Finite(radius) || radius < 0.0) { return false; } double num = radius + 0.4; if (az < num || bz >= num || az <= bz) { return false; } double num2 = (az - num) / (az - bz); double num3 = ax + (bx - ax) * num2; double num4 = ay + (by - ay) * num2; if (num3 >= -2.5 - radius && num3 <= 2.5 + radius && num4 >= 0.0 - radius) { return num4 <= 3.0 + radius; } return false; } } public static class WorkshopBridgeRules { public static double Angle(double elapsed, double down, double up, double move) { if (!WorkshopRules.Finite(elapsed) || down < 0.0 || up < 0.0 || move <= 0.0) { return 0.0; } double num = down + up + 2.0 * move; double num2 = Math.Max(0.0, elapsed) % num; if (num2 < down) { return 0.0; } num2 -= down; if (num2 < move) { return 90.0 * num2 / move; } num2 -= move; if (num2 < up) { return 90.0; } num2 -= up; return Math.Max(0.0, 90.0 * (1.0 - num2 / move)); } } internal static class WorkshopCardArtwork { private sealed class Artwork { internal Texture2D texture; internal Sprite sprite; } private static readonly Dictionary<ObstacleDescription, Artwork> backgrounds = new Dictionary<ObstacleDescription, Artwork>(); private static bool OwnCard(ObstacleDescription description) { string text = ((object)description.id).ToString(); if ((!Object.op_Implicit((Object)(object)WorkshopPlugin.Instance) || WorkshopPlugin.Instance.CardIndex(text) < 0) && (!Object.op_Implicit((Object)(object)TankPlugin.Instance) || !TankPlugin.Instance.HandlesCard(text)) && (!Object.op_Implicit((Object)(object)SlipSkid.ChaosSystems.ChaosPlugin.Instance) || SlipSkid.ChaosSystems.ChaosPlugin.Instance.CardIndex(text) < 0)) { return SlipSkid.ChaosCards.ChaosPlugin.Ids.Contains(text); } return true; } internal static void Apply(ObstacleDescription description) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)description) || !Object.op_Implicit((Object)(object)description.thumbnail) || !OwnCard(description) || !Object.op_Implicit((Object)(object)description.overrideBackGroundMaterial) || (!description.isFullArt && !Object.op_Implicit((Object)(object)description.overrideBackGroundMaterialTexture) && (int)description.type != 4)) { return; } if (!backgrounds.TryGetValue(description, out var value) || (Object)(object)value.texture != (Object)(object)description.thumbnail || !Object.op_Implicit((Object)(object)value.sprite)) { if (value != null && Object.op_Implicit((Object)(object)value.sprite)) { Object.Destroy((Object)(object)value.sprite); } Texture2D thumbnail = description.thumbnail; Sprite val = Sprite.Create(thumbnail, new Rect(0f, 0f, (float)((Texture)thumbnail).width, (float)((Texture)thumbnail).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ((Object)val).name = ((Object)description).name + " custom full-card artwork"; value = new Artwork { texture = thumbnail, sprite = val }; backgrounds[description] = value; } description.overrideBackGroundMaterialTexture = value.sprite; } internal static void Clear() { foreach (Artwork value in backgrounds.Values) { if (Object.op_Implicit((Object)(object)value.sprite)) { Object.Destroy((Object)(object)value.sprite); } } backgrounds.Clear(); } } [HarmonyPatch(typeof(ObstacleSelectionElement), "SetStyle")] internal static class WorkshopCardArtworkPatch { [HarmonyPrefix] private static void Prefix(ObstacleDescription __1) { WorkshopCardArtwork.Apply(__1); } } public static class WorkshopCardIdentity { public static string Id(int index) { switch (index) { case 15: return "3a15066d-2e89-42e6-b0fc-a38e43ec149d"; default: throw new ArgumentOutOfRangeException("index", "Assign new cards an independent permanent ID."); case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: return "fe17a165-7340-4b18-a079-08413a001" + (200 + index); } } public static int? LegacyTag(int index) { Id(index); if (index != 15) { return -918000 - index; } return null; } } internal static class WorkshopCompatibility { private static object Plugin(string guid) { return ExpandedModules.Find(guid); } private static object Get(object obj, string field) { if (obj == null) { return null; } FieldInfo fieldInfo = AccessTools.Field(obj.GetType(), field); if (!(fieldInfo == null)) { return fieldInfo.GetValue(obj); } return null; } private static void Remove(object obj, string name, object key) { if (Get(obj, name) is IDictionary dictionary) { dictionary.Remove(key); } } internal static bool GateCrossed(Obstacle obstacle, Vector3 from, Vector3 to, float radius) { //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_00f5: 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) Type type = Plugin("slipskid.chaossystems")?.GetType().Assembly.GetType("SlipSkid.ChaosSystems.ChaosPlaced"); object obj = Get((type == null || !Object.op_Implicit((Object)(object)obstacle)) ? null : ((Component)obstacle).GetComponent(type), "gateGeometry"); if (obj == null) { return false; } PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), "Valid"); if (propertyInfo == null || !(bool)propertyInfo.GetValue(obj, null)) { return false; } MethodInfo methodInfo = AccessTools.Method(obj.GetType(), "Local", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(obj.GetType(), "Crossed", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return false; } return (bool)methodInfo2.Invoke(obj, new object[3] { (object)(Vector3)methodInfo.Invoke(obj, new object[1] { from }), (object)(Vector3)methodInfo.Invoke(obj, new object[1] { to }), radius }); } internal static void GateFeedback(int player, string text) { PlayerData val = WorkshopPlugin.Player(player); if (Object.op_Implicit((Object)(object)val) && ((NetworkBehaviour)val).IsOwner) { Type type = Plugin("slipskid.chaossystems")?.GetType().Assembly.GetType("SlipSkid.ChaosSystems.ChaosFeedback"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "Notify", (Type[])null, (Type[])null)); if (methodInfo != null) { methodInfo.Invoke(null, new object[2] { player, text }); } else { WorkshopOverlay.Notice(text); } } } internal static void PortalTravel(int player) { object obj = Get(Plugin("slipskid.chaossystems"), "World"); Remove(obj, "frames", player); Remove(obj, "history", player); Remove(obj, "trailLast", player); } internal static void Refill(int player) { object obj = Plugin("slipskid.tankcards"); Remove(Get(obj, "rules"), "spentAmmo", player); object obj2 = Get(obj, "Suite"); if (obj2 == null && obj != null) { PropertyInfo propertyInfo = AccessTools.Property(obj.GetType(), "Suite"); if (propertyInfo != null) { obj2 = propertyInfo.GetValue(obj, null); } } object obj3 = Get(obj2, "Rules"); for (int i = 0; i < 4; i++) { Remove(obj3, "used", player * 4 + i); } object obj4 = Plugin("slipskid.chaossystems"); if (Get(Get(obj4, "Rules"), "used") is IDictionary dictionary) { object[] array = (from object k in dictionary.Keys where k.ToString().StartsWith(player + ":", StringComparison.Ordinal) select k).ToArray(); foreach (object key in array) { dictionary.Remove(key); } } Remove(obj4, "charges", player); Remove(obj4, "cardCharges", player); } internal static void Leave(int player) { object obj = Plugin("slipskid.tankcards"); object obj2 = Get(obj, "rules"); if (obj2 != null) { AccessTools.Method(obj2.GetType(), "RemovePlayer", (Type[])null, (Type[])null).Invoke(obj2, new object[1] { player }); } object obj3 = Get((obj == null) ? null : AccessTools.Property(obj.GetType(), "Suite")?.GetValue(obj, null), "Rules"); if (obj3 != null) { AccessTools.Method(obj3.GetType(), "Remove", (Type[])null, (Type[])null).Invoke(obj3, new object[1] { player }); } object obj4 = Get(Plugin("slipskid.chaossystems"), "Rules"); if (obj4 != null) { AccessTools.Method(obj4.GetType(), "Remove", (Type[])null, (Type[])null).Invoke(obj4, new object[1] { player }); } } internal static void Reset() { } internal static void NewNetwork() { object obj = Get(Plugin("slipskid.chaossystems"), "Rules"); if (obj != null && !(bool)Get(obj, "RoundActive")) { AccessTools.Field(obj.GetType(), "Epoch").SetValue(obj, 0); } } } internal sealed class DepotDraft { internal ulong tool; internal ulong first; internal ulong client; internal int player; } internal sealed class WorkshopDepots { private readonly WorkshopPlugin p; private readonly Dictionary<ulong, ulong> routes = new Dictionary<ulong, ulong>(); private readonly Dictionary<ulong, DepotDraft> drafts = new Dictionary<ulong, DepotDraft>(); private readonly Dictionary<ulong, int> control = new Dictionary<ulong, int>(); internal bool committing; private bool Placement => CoreGame.IsState((GameState)8); internal WorkshopDepots(WorkshopPlugin plugin) { p = plugin; } internal bool Pending(Obstacle tool) { if (Object.op_Implicit((Object)(object)tool)) { return drafts.ContainsKey(((NetworkBehaviour)tool).NetworkObjectId); } return false; } internal bool Defers(Obstacle tool) { if (Object.op_Implicit((Object)(object)tool)) { if (tool.affixIndex.Value != -918000) { return Pending(tool); } return true; } return false; } internal ulong Destination(ulong pickup) { if (!routes.TryGetValue(pickup, out var value)) { return 0uL; } return value; } internal ulong Partner(ulong id) { if (routes.TryGetValue(id, out var value)) { return value; } foreach (KeyValuePair<ulong, ulong> route in routes) { if (route.Value == id) { return route.Key; } } return 0uL; } internal void LinkCopies(Dictionary<ulong, ulong> copies) { if (!p.Host) { return; } KeyValuePair<ulong, ulong>[] array = routes.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<ulong, ulong> keyValuePair = array[i]; if (copies.TryGetValue(keyValuePair.Key, out var value) && copies.TryGetValue(keyValuePair.Value, out var value2)) { p.Emit(new WorkshopPacket { kind = "depotpair", objectId = value, target = value2 }); } } } internal void Placed(Obstacle tool, bool inScene) { //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (!p.Host || inScene || !Placement || !Defers(tool) || !Object.op_Implicit((Object)(object)tool.playerInfos) || (Object)(object)tool.playerInfos.currentObstacle != (Object)(object)tool) { return; } PlayerData playerInfos = tool.playerInfos; if (!drafts.TryGetValue(((NetworkBehaviour)tool).NetworkObjectId, out var value)) { ObstacleDescription val = p.Description("bed8133d-50d9-43f9-a313-d5331e2727a6"); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.prefab)) { Vector3 val2 = (Vector3)AccessTools.Field(typeof(Obstacle), "_placeScale").GetValue(tool); Vector3 localScale = ((Component)val.prefab).transform.localScale; Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(val2.x / Mathf.Max(0.001f, Mathf.Abs(localScale.x)), val2.y / Mathf.Max(0.001f, Mathf.Abs(localScale.y)), val2.z / Mathf.Max(0.001f, Mathf.Abs(localScale.z))); try { Obstacle val4 = val.Spawn(playerInfos, ((Component)tool).transform.position, ((Component)tool).transform.rotation, val3, true, -918000); if (!Object.op_Implicit((Object)(object)val4)) { Invalid(tool, "Could not create pickup; try again."); return; } p.Emit(new WorkshopPacket { kind = "depotstage", objectId = ((NetworkBehaviour)tool).NetworkObjectId, target = ((NetworkBehaviour)val4).NetworkObjectId, player = playerInfos.playerIndex.Value }); return; } catch (Exception ex) { p.Note("Cargo pickup spawn failed: " + ex.Message); Invalid(tool, "Cargo placement failed; try again."); return; } } Invalid(tool, "Cargo template unavailable; try again."); } else { Obstacle val5 = WorkshopRelocate.Obstacle(value.first); if (!Object.op_Implicit((Object)(object)val5) || val5.Destroyed) { Cancel(value); return; } if (Vector3.Distance(((Component)val5).transform.position, ((Component)tool).transform.position) < (float)p.Settings["CargoRouteMin"]) { Invalid(tool, "Place delivery at least " + p.Settings["CargoRouteMin"] + " metres from pickup."); return; } p.Emit(new WorkshopPacket { kind = "depotpair", objectId = value.first, target = value.tool }); p.Emit(new WorkshopPacket { kind = "depotfinish", objectId = value.tool, player = value.player, target = value.client, position = ((Component)tool).transform.position, rotation = ((Component)tool).transform.rotation, scale = (Vector3)AccessTools.Field(typeof(Obstacle), "_placeScale").GetValue(tool) }); } } private void Invalid(Obstacle tool, string text) { p.Emit(new WorkshopPacket { kind = "depotinvalid", objectId = ((NetworkBehaviour)tool).NetworkObjectId, player = tool.playerInfosIndex.Value, text = text }); } private void Schedule(ulong id) { control[id] = Time.frameCount + 1; } private void Delivery(Obstacle tool) { if (Object.op_Implicit((Object)(object)tool)) { if (p.Host && tool.affixIndex.Value != -918001) { tool.affixIndex.Value = -918001; } tool.description = p.Cards[1]; WorkshopObject component = ((Component)tool).GetComponent<WorkshopObject>(); if (Object.op_Implicit((Object)(object)component) && component.kind != 1) { component.SetDepotKind(1); } } } private void Control(Obstacle tool) { //IL_004e: 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_006b: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)tool)) { Delivery(tool); ObstacleManager.RemoveFromTile(tool); object? value = AccessTools.Field(typeof(Obstacle), "_invisibleTarget").GetValue(tool); Transform val = (Transform)((value is Transform) ? value : null); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).gameObject); } Transform transform = new GameObject("Cargo delivery movement target").transform; transform.SetPositionAndRotation(((Component)tool).transform.position, ((Component)tool).transform.rotation); AccessTools.Field(typeof(Obstacle), "_invisibleTarget").SetValue(tool, transform); tool.positionEase.target = transform; tool.rotationEase.target = transform; AccessTools.Method(typeof(Obstacle), "SetState", (Type[])null, (Type[])null).Invoke(tool, new object[1] { (object)(ObstacleState)(((NetworkBehaviour)tool).IsOwner ? 1 : 2) }); tool.EnableInputs(); } } internal void Tick() { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Invalid comparison between Unknown and I4 KeyValuePair<ulong, int>[] array = control.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<ulong, int> keyValuePair = array[i]; if (Time.frameCount >= keyValuePair.Value) { control.Remove(keyValuePair.Key); Obstacle val = WorkshopRelocate.Obstacle(keyValuePair.Key); if (Object.op_Implicit((Object)(object)val) && Placement) { Control(val); } } } DepotDraft[] array2 = drafts.Values.ToArray(); foreach (DepotDraft depotDraft in array2) { PlayerData val2 = WorkshopPlugin.Player(depotDraft.player); Obstacle val3 = WorkshopRelocate.Obstacle(depotDraft.tool); if (!Placement || !Object.op_Implicit((Object)(object)val2) || ((NetworkBehaviour)val2).OwnerClientId != depotDraft.client || !Object.op_Implicit((Object)(object)val3)) { if (p.Host) { Cancel(depotDraft); continue; } drafts.Remove(depotDraft.tool); control.Remove(depotDraft.tool); continue; } Delivery(val3); if ((int)val3.state == 3 && !control.ContainsKey(depotDraft.tool)) { Schedule(depotDraft.tool); } if (((NetworkBehaviour)val2).IsOwner && Keyboard.current != null && ((ButtonControl)Keyboard.current.backspaceKey).wasPressedThisFrame) { p.Request(new WorkshopPacket { kind = "depotcancel", objectId = depotDraft.tool, player = depotDraft.player }); } } if (!p.Host) { return; } KeyValuePair<ulong, ulong>[] array3 = routes.ToArray(); for (int i = 0; i < array3.Length; i++) { KeyValuePair<ulong, ulong> keyValuePair2 = array3[i]; if (!Object.op_Implicit((Object)(object)WorkshopRelocate.Obstacle(keyValuePair2.Key)) || !Object.op_Implicit((Object)(object)WorkshopRelocate.Obstacle(keyValuePair2.Value))) { Deleted((!Object.op_Implicit((Object)(object)WorkshopRelocate.Obstacle(keyValuePair2.Key))) ? keyValuePair2.Key : keyValuePair2.Value); } } } internal void CancelRequest(PlayerData player, WorkshopPacket packet) { if (Placement && drafts.TryGetValue(packet.objectId, out var value) && value.player == player.playerIndex.Value && value.client == ((NetworkBehaviour)player).OwnerClientId) { Cancel(value); } } private void Cancel(DepotDraft draft) { if (p.Host) { p.Emit(new WorkshopPacket { kind = "depotfinish", objectId = draft.tool, player = draft.player, target = draft.client, text = "cancel" }); Obstacle val = WorkshopRelocate.Obstacle(draft.first); Obstacle val2 = WorkshopRelocate.Obstacle(draft.tool); if (Object.op_Implicit((Object)(object)val)) { ObstacleManager.Delete(val); } if (Object.op_Implicit((Object)(object)val2)) { ObstacleManager.Delete(val2); } } } internal bool CanDelete(Obstacle obj) { if (!p.Host || !Object.op_Implicit((Object)(object)obj)) { return true; } KeyValuePair<ulong, ulong> keyValuePair = routes.FirstOrDefault((KeyValuePair<ulong, ulong> x) => x.Key == ((NetworkBehaviour)obj).NetworkObjectId || x.Value == ((NetworkBehaviour)obj).NetworkObjectId); if (keyValuePair.Key == 0L) { return true; } Obstacle val = WorkshopRelocate.Obstacle((keyValuePair.Key == ((NetworkBehaviour)obj).NetworkObjectId) ? keyValuePair.Value : keyValuePair.Key); if (Object.op_Implicit((Object)(object)val)) { return !p.Relocate.Reserved(val); } return true; } internal void Deleted(ulong id) { if (!p.Host) { return; } KeyValuePair<ulong, ulong> keyValuePair = routes.FirstOrDefault((KeyValuePair<ulong, ulong> x) => x.Key == id || x.Value == id); if (keyValuePair.Key != 0L) { p.Emit(new WorkshopPacket { kind = "depotunlink", objectId = keyValuePair.Key }); Obstacle val = WorkshopRelocate.Obstacle((keyValuePair.Key == id) ? keyValuePair.Value : keyValuePair.Key); if (Object.op_Implicit((Object)(object)val)) { ObstacleManager.Delete(val); } } DepotDraft[] array = drafts.Values.Where((DepotDraft d) => d.tool == id || d.first == id).ToArray(); foreach (DepotDraft draft in array) { Cancel(draft); } } internal void Snapshot(WorkshopPacket packet) { packet.depotPickup = routes.Keys.ToArray(); packet.depotDelivery = packet.depotPickup.Select((ulong x) => routes[x]).ToArray(); } internal void Synchronize(WorkshopPacket packet) { if (!p.Host && packet.depotPickup != null && packet.depotDelivery != null && packet.depotPickup.Length == packet.depotDelivery.Length) { routes.Clear(); for (int i = 0; i < packet.depotPickup.Length; i++) { routes[packet.depotPickup[i]] = packet.depotDelivery[i]; } } } internal void Event(WorkshopPacket packet) { //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) if (packet.kind == "depotstage") { PlayerData val = WorkshopPlugin.Player(packet.player); if (Object.op_Implicit((Object)(object)val)) { drafts[packet.objectId] = new DepotDraft { tool = packet.objectId, first = packet.target, player = packet.player, client = ((NetworkBehaviour)val).OwnerClientId }; Schedule(packet.objectId); if (((NetworkBehaviour)val).IsOwner) { WorkshopOverlay.Notice("Pickup placed. Now place its delivery point. Backspace cancels both."); } } } else if (packet.kind == "depotinvalid") { Schedule(packet.objectId); PlayerData val2 = WorkshopPlugin.Player(packet.player); if (Object.op_Implicit((Object)(object)val2) && ((NetworkBehaviour)val2).IsOwner) { WorkshopOverlay.Notice(packet.text); } } else if (packet.kind == "depotpair") { routes[packet.objectId] = packet.target; } else if (packet.kind == "depotunlink") { routes.Remove(packet.objectId); } else { if (packet.kind != "depotfinish") { return; } drafts.Remove(packet.objectId); control.Remove(packet.objectId); PlayerData val3 = WorkshopPlugin.Player(packet.player); Obstacle val4 = WorkshopRelocate.Obstacle(packet.objectId); if (packet.text != "cancel" && Object.op_Implicit((Object)(object)val4)) { Delivery(val4); WorkshopRelocate.Pose(packet.objectId, packet.position, packet.rotation, packet.scale); AccessTools.Method(typeof(Obstacle), "SetState", (Type[])null, (Type[])null).Invoke(val4, new object[1] { (object)(ObstacleState)3 }); } if (!Object.op_Implicit((Object)(object)val3) || !((NetworkBehaviour)val3).IsOwner || ((NetworkBehaviour)val3).OwnerClientId != packet.target) { return; } committing = true; try { if (Object.op_Implicit((Object)(object)val4)) { val3.PlaceObstacle(val4, false, false); return; } val3.placedObstacle.Value = true; val3.UnBindFromObstacle(); } finally { committing = false; } } } internal void Reset() { routes.Clear(); drafts.Clear(); control.Clear(); } } [HarmonyPatch(typeof(PlayerData), "PlaceObstacle")] internal static class WorkshopDepotPlayerPlacePatch { [HarmonyPrefix] private static bool Prefix(Obstacle obstacle, bool inScene, bool delete) { WorkshopPlugin instance = WorkshopPlugin.Instance; if (!(!Object.op_Implicit((Object)(object)instance) || inScene || delete) && !instance.Depots.committing) { return !instance.Depots.Defers(obstacle); } return true; } } public sealed class WorkshopDrawbridge : MonoBehaviour { private WorkshopObject bridge; private Transform hinge; private BoxCollider deck; private WorkshopSolid solid; internal void Init(WorkshopObject owner) { //IL_000d: 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_0086: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) bridge = owner; hinge = new GameObject("Drawbridge hinge").transform; hinge.SetParent(((Component)this).transform, false); hinge.localPosition = new Vector3(0f, 0.25f, -5f); GameObject val = GameObject.CreatePrimitive((PrimitiveType)3); ((Object)val).name = "Solid drawbridge deck"; val.transform.SetParent(hinge, false); val.transform.localPosition = new Vector3(0f, 0f, 5f); val.transform.localScale = new Vector3(5f, 0.5f, 10f); deck = val.GetComponent<BoxCollider>(); ((Collider)deck).enabled = false; Object.Destroy((Object)(object)deck); solid = WorkshopSolid.Create("Drawbridge physics", new Vector3(5f, 0.5f, 10f)); Material val2 = WorkshopVisual.Material(new Color(0.8f, 0.55f, 0.2f)); val.GetComponent<Renderer>().sharedMaterial = val2; val.AddComponent<WorkshopMaterials>().owned.Add(val2); GameObject obj = WorkshopVisual.Shape((PrimitiveType)2, "Drawbridge axle", new Color(0.3f, 0.32f, 0.35f), new Vector3(0.25f, 2.75f, 0.25f)); obj.transform.SetParent(((Component)this).transform, false); obj.transform.localPosition = new Vector3(0f, 0.25f, -5f); obj.transform.localRotation = Quaternion.Euler(0f, 0f, 90f); WorkshopObject.Arrow(((Component)this).transform, new Vector3(0f, 0.52f, -4f), new Color(0.2f, 1f, 0.5f), reverse: false); } private void FixedUpdate() { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0104: Unknown result type (might be due to invalid IL or missing references) WorkshopPlugin instance = WorkshopPlugin.Instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)bridge) && solid != null) { bool flag = bridge.Placed && !bridge.obstacle.IsCurrentlyBeingPlaced && !instance.Relocate.Reserved(bridge.obstacle); float num = ((flag && instance.Rules.active) ? ((float)WorkshopBridgeRules.Angle(instance.World.Elapsed, instance.Settings["BridgeOn"], instance.Settings["BridgeOff"], instance.Settings["BridgeMove"])) : 0f); hinge.localRotation = Quaternion.Euler(0f - num, 0f, 0f); solid.Sync(hinge.TransformPoint(new Vector3(0f, 0f, 5f)), hinge.rotation, flag); } } private void OnDisable() { if (solid != null && Object.op_Implicit((Object)(object)solid.box)) { ((Collider)solid.box).enabled = false; } } private void OnDestroy() { if (solid != null) { solid.Dispose(); } } } internal static class WorkshopDuplicate { private static ulong Partner(WorkshopPlugin p, ulong id) { PortalPair portalPair = p.Portals.Pair(id); if (portalPair == null) { return p.Depots.Partner(id); } if (portalPair.a != id) { return portalPair.a; } return portalPair.b; } private static bool Eligible(WorkshopPlugin p, Obstacle tool, Obstacle obj, Func<Obstacle, bool> reserved) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)obj) || (Object)(object)obj == (Object)(object)tool || obj is ObstacleDelete || (int)obj.state != 3 || obj.Destroyed || reserved(obj) || WorkshopRelocate.IsTemporary(obj)) { return false; } if (p.Settings["DuplicateOthers"] == 0 && obj.playerInfosIndex.Value != tool.playerInfosIndex.Value) { return false; } ObstacleDescription val = (Object.op_Implicit((Object)(object)obj.description) ? p.Description(SerializableGuid.op_Implicit(obj.description.id)) : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.prefab) || (int)val.type == 4) { return false; } int num = -918000 - obj.affixIndex.Value; if ((num == 0 || num == 1 || num == 10) && Partner(p, ((NetworkBehaviour)obj).NetworkObjectId) == 0L) { return false; } return true; } internal static Obstacle[] Select(WorkshopPlugin p, Obstacle tool, IEnumerable<Obstacle> neighbours, Func<Obstacle, bool> reserved) { return WorkshopDuplicateRules.Select(from o in neighbours where Object.op_Implicit((Object)(object)o) orderby Vector3.Distance(((Component)tool).transform.position, ((Component)o).transform.position) select ((NetworkBehaviour)o).NetworkObjectId, (ulong id) => Eligible(p, tool, WorkshopRelocate.Obstacle(id), reserved), (ulong id) => Partner(p, id), p.Settings["DuplicateCount"]).Select(WorkshopRelocate.Obstacle).ToArray(); } internal static bool Commit(WorkshopPlugin p, MoveGroup group, out string error) { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_021a: 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_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) error = "Could not duplicate this group; originals are unchanged. Try again or cancel."; if (!p.Host || !group.duplicate || group.items.Count == 0 || group.items.Count > p.Settings["DuplicateCount"]) { return false; } PlayerData val = WorkshopPlugin.Player(group.player); if (!Object.op_Implicit((Object)(object)val) || ((NetworkBehaviour)val).OwnerClientId != group.client) { return false; } Dictionary<ulong, Obstacle> dictionary = new Dictionary<ulong, Obstacle>(); foreach (MoveItem item in group.items) { Obstacle val2 = WorkshopRelocate.Obstacle(item.id); if (!Object.op_Implicit((Object)(object)val2) || val2.Destroyed || val2 is ObstacleDelete || !Object.op_Implicit((Object)(object)val2.description) || !Object.op_Implicit((Object)(object)p.Description(SerializableGuid.op_Implicit(val2.description.id))) || !Object.op_Implicit((Object)(object)p.Description(SerializableGuid.op_Implicit(val2.description.id)).prefab)) { return false; } if (p.Settings["DuplicateOthers"] == 0 && val2.playerInfosIndex.Value != group.player) { return false; } ulong partner = Partner(p, item.id); if (partner != 0L && !group.items.Any((MoveItem i) => i.id == partner)) { return false; } dictionary[item.id] = val2; } List<Obstacle> list = new List<Obstacle>(); Dictionary<ulong, ulong> dictionary2 = new Dictionary<ulong, ulong>(); Quaternion val3 = group.destinationRotation * Quaternion.Inverse(group.rotation); try { Vector3 val6 = default(Vector3); foreach (MoveItem item2 in group.items) { Obstacle val4 = dictionary[item2.id]; ObstacleDescription val5 = p.Description(SerializableGuid.op_Implicit(val4.description.id)); Vector3 localScale = ((Component)val5.prefab).transform.localScale; if (Mathf.Abs(localScale.x) < 0.0001f || Mathf.Abs(localScale.y) < 0.0001f || Mathf.Abs(localScale.z) < 0.0001f) { throw new InvalidOperationException("Prefab has zero scale."); } ((Vector3)(ref val6))..ctor(item2.scale.x / localScale.x, item2.scale.y / localScale.y, item2.scale.z / localScale.z); Vector3 val7 = group.destination + val3 * (item2.position - group.origin); Quaternion val8 = val3 * item2.rotation; Obstacle val9 = val5.Spawn(val, val7, val8, val6, true, val4.affixIndex.Value); if (!Object.op_Implicit((Object)(object)val9)) { throw new InvalidOperationException("Native spawn returned no object: " + ((Object)val5).name); } list.Add(val9); dictionary2[item2.id] = ((NetworkBehaviour)val9).NetworkObjectId; } p.Depots.LinkCopies(dictionary2); p.Portals.LinkCopies(dictionary2); foreach (MoveItem item3 in group.items) { p.Emit(new WorkshopPacket { kind = "relocatedpose", objectId = dictionary2[item3.id], position = group.destination + val3 * (item3.position - group.origin), rotation = val3 * item3.rotation, scale = item3.scale }); } p.State(); p.Note("Duplicate placed: player=" + group.player + " copies=" + list.Count); error = null; return true; } catch (Exception ex) { foreach (Obstacle item4 in list) { if (Object.op_Implicit((Object)(object)item4)) { ObstacleManager.Delete(item4); } } p.Note("Duplicate group rolled back: " + ex.Message); return false; } } } public static class WorkshopDuplicateRules { public static ulong[] Select(IEnumerable<ulong> candidates, Func<ulong, bool> eligible, Func<ulong, ulong> partner, int limit) { List<ulong> list = new List<ulong>(); HashSet<ulong> hashSet = new HashSet<ulong>(); if (candidates == null || limit <= 0) { return list.ToArray(); } foreach (ulong candidate in candidates) { if (hashSet.Contains(candidate) || !eligible(candidate)) { continue; } ulong num = partner(candidate); if (num == candidate || (num != 0L && (!eligible(num) || partner(num) != candidate))) { continue; } int num2 = 1 + ((num != 0L && !hashSet.Contains(num)) ? 1 : 0); if (list.Count + num2 <= limit) { list.Add(candidate); hashSet.Add(candidate); if (num2 == 2) { list.Add(num); hashSet.Add(num); } } } return list.ToArray(); } } public enum FlipperPhase { Resting, Rising, Raised, Returning } public sealed class WorkshopFlipperCycle { public const double RiseTime = 0.18; public const double MaxAngle = 85.0; public readonly int serial; public readonly double start; public readonly double hold; public readonly double lower; public WorkshopFlipperCycle(int serial, double start, double hold, double lower) { if (serial <= 0 || !WorkshopRules.Finite(start) || start < 0.0 || !WorkshopRules.Finite(hold) || hold < 0.0 || hold > 10.0 || !WorkshopRules.Finite(lower) || lower < 1.0 || lower > 10.0) { throw new ArgumentOutOfRangeException("Invalid flipper cycle"); } this.serial = serial; this.start = start; this.hold = hold; this.lower = lower; } public FlipperPhase Phase(double now) { if (!WorkshopRules.Finite(now)) { return FlipperPhase.Raised; } double num = now - start; if (num < 0.18) { return FlipperPhase.Rising; } if (num < 0.18 + hold) { return FlipperPhase.Raised; } if (num < 0.18 + hold + lower) { return FlipperPhase.Returning; } return FlipperPhase.Resting; } public double Angle(double now) { FlipperPhase flipperPhase = Phase(now); double num = now - start; return flipperPhase switch { FlipperPhase.Resting => 0.0, FlipperPhase.Raised => 85.0, FlipperPhase.Rising => 85.0 * Ease(num / 0.18), _ => 85.0 * (1.0 - Ease((num - 0.18 - hold) / lower)), }; } private static double Ease(double value) { value = Math.Max(0.0, Math.Min(1.0, value)); return value * value * (3.0 - 2.0 * value); } } public sealed class WorkshopFlipperEntries { private readonly HashSet<string> inside = new HashSet<string>(); public bool Observe(ulong platform, int player, bool contains, bool crossed) { string item = platform + ":" + player; bool num = inside.Contains(item); if (contains) { inside.Add(item); } else { inside.Remove(item); } return !num && crossed; } public void Reset() { inside.Clear(); } } public static class WorkshopFlipperRules { public const double HalfWidth = 2.0; public const double HalfLength = 2.5; public const double Top = 0.31; public const double Tolerance = 0.4; public static bool Contains(WorkshopMath.Point point, double radius) { return Crosses(point, point, radius); } public static bool Crosses(WorkshopMath.Point from, WorkshopMath.Point to, double radius) { if (!WorkshopRules.Finite(radius) || radius <= 0.0 || radius > 10.0 || !Finite(from) || !Finite(to)) { return false; } double near = 0.0; double far = 1.0; if (Slab(from.x, to.x, -2.0 - radius * 0.35, 2.0 + radius * 0.35, ref near, ref far) && Slab(from.y, to.y, 0.31 + radius - 0.4, 0.31 + radius + 0.4, ref near, ref far)) { return Slab(from.z, to.z, -2.5 - radius * 0.35, 2.5 + radius * 0.35, ref near, ref far); } return false; } private static bool Finite(WorkshopMath.Point p) { if (WorkshopRules.Finite(p.x) && WorkshopRules.Finite(p.y)) { return WorkshopRules.Finite(p.z); } return false; } private static bool Slab(double from, double to, double min, double max, ref double near, ref double far) { double num = to - from; if (Math.Abs(num) < 1E-09) { if (from >= min) { return from <= max; } return false; } double num2 = (min - from) / num; double num3 = (max - from) / num; if (num2 > num3) { double num4 = num2; num2 = num3; num3 = num4; } near = Math.Max(near, num2); far = Math.Min(far, num3); return near <= far; } } internal sealed class WorkshopFlippers { private readonly WorkshopPlugin p; private readonly Dictionary<ulong, WorkshopFlipperCycle> cycles = new Dictionary<ulong, WorkshopFlipperCycle>(); private readonly Dictionary<int, Vector3> previous = new Dictionary<int, Vector3>(); private readonly Dictionary<string, int> impulses = new Dictionary<string, int>(); private readonly WorkshopFlipperEntries entries = new WorkshopFlipperEntries(); private int serial; private int epoch = -1; private float tickAt; internal WorkshopFlippers(WorkshopPlugin plugin) { p = plugin; } private void EnsureRound() { if (epoch != p.Rules.epoch) { Reset(); epoch = p.Rules.epoch; } } internal WorkshopFlipperCycle Cycle(ulong id) { EnsureRound(); if (!cycles.TryGetValue(id, out var value)) { return null; } return value; } internal void Reset() { cycles.Clear(); previous.Clear(); impulses.Clear(); entries.Reset(); serial = 0; epoch = -1; tickAt = 0f; } private bool Alive(PlayerData player) { if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)player.controller) && Object.op_Implicit((Object)(object)player.controller.sphereRigidbody) && !player.isDead.Value) { return !player.finishedRace.Value; } return false; } internal void Tick() { //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) if (!p.Rules.active) { Reset(); return; } EnsureRound(); if (!p.Host || !p.Racing || Time.unscaledTime < tickAt) { return; } tickAt = Time.unscaledTime + 0.02f; float elapsed = p.World.Elapsed; KeyValuePair<ulong, WorkshopFlipperCycle>[] array = cycles.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<ulong, WorkshopFlipperCycle> keyValuePair = array[i]; if (keyValuePair.Value.Phase(elapsed) == FlipperPhase.Resting) { cycles.Remove(keyValuePair.Key); } } PlayerData[] array2 = (from x in GameManager.Players.Where(Alive) orderby x.playerIndex.Value select x).ToArray(); WorkshopObject[] array3 = p.World.objects.Where((WorkshopObject o) => Object.op_Implicit((Object)(object)o) && o.kind == 9 && o.Placed && Object.op_Implicit((Object)(object)((NetworkBehaviour)o.obstacle).NetworkObject) && ((NetworkBehaviour)o.obstacle).NetworkObject.IsSpawned && !o.obstacle.IsCurrentlyBeingPlaced && !p.Relocate.Reserved(o.obstacle)).ToArray(); PlayerData[] array4 = array2; foreach (PlayerData val in array4) { int value = val.playerIndex.Value; Vector3 position = val.controller.sphereRigidbody.position; Vector3 val2; if (previous.TryGetValue(value, out var value2)) { val2 = position - value2; if (!(((Vector3)(ref val2)).sqrMagnitude > 625f)) { goto IL_017c; } } value2 = position; goto IL_017c; IL_017c: previous[value] = position; WorkshopObject[] array5 = array3; foreach (WorkshopObject workshopObject in array5) { ulong networkObjectId = ((NetworkBehaviour)workshopObject.obstacle).NetworkObjectId; float sphereRadius = val.controller.SphereRadius; WorkshopMath.Point point = Point(workshopObject.Area.InverseTransformPoint(value2)); WorkshopMath.Point point2 = Point(workshopObject.Area.InverseTransformPoint(position)); if (!entries.Observe(networkObjectId, value, WorkshopFlipperRules.Contains(point2, sphereRadius), WorkshopFlipperRules.Crosses(point, point2, sphereRadius)) || cycles.ContainsKey(networkObjectId)) { continue; } WorkshopFlipperCycle workshopFlipperCycle = new WorkshopFlipperCycle(++serial, elapsed, p.Settings["FlipperHold"], p.Settings["FlipperReturn"]); cycles[networkObjectId] = workshopFlipperCycle; p.Emit(new WorkshopPacket { kind = "flipperstate", objectId = networkObjectId, id = workshopFlipperCycle.serial, number = (float)workshopFlipperCycle.start, volume = (float)workshopFlipperCycle.hold, scale = new Vector3((float)workshopFlipperCycle.lower, 0f, 0f) }); PlayerData[] array6 = array2; foreach (PlayerData val3 in array6) { bool num3 = (Object)(object)val3 == (Object)(object)val; Vector3 value3 = workshopObject.Area.InverseTransformPoint(val3.controller.sphereRigidbody.position); if (num3 || WorkshopFlipperRules.Contains(Point(value3), val3.controller.SphereRadius)) { Transform area = workshopObject.Area; val2 = new Vector3(0f, 1f, 1f); Vector3 velocity = area.TransformDirection(((Vector3)(ref val2)).normalized) * (float)p.Settings["FlipperStrength"]; p.Emit(new WorkshopPacket { kind = "flipperlaunch", objectId = networkObjectId, id = workshopFlipperCycle.serial, player = val3.playerIndex.Value, velocity = velocity }); } } } } } private static WorkshopMath.Point Point(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return new WorkshopMath.Point(value.x, value.y, value.z); } internal void Snapshot(WorkshopPacket packet) { EnsureRound(); KeyValuePair<ulong, WorkshopFlipperCycle>[] source = (p.Rules.active ? (from x in cycles where x.Value.Phase(p.World.Elapsed) != FlipperPhase.Resting orderby x.Key select x).ToArray() : new KeyValuePair<ulong, WorkshopFlipperCycle>[0]); packet.flipperObjects = source.Select((KeyValuePair<ulong, WorkshopFlipperCycle> x) => x.Key).ToArray(); packet.flipperSerials = source.Select((KeyValuePair<ulong, WorkshopFlipperCycle> x) => x.Value.serial).ToArray(); packet.flipperStarts = source.Select((KeyValuePair<ulong, WorkshopFlipperCycle> x) => (float)x.Value.start).ToArray(); packet.flipperHolds = source.Select((KeyValuePair<ulong, WorkshopFlipperCycle> x) => (float)x.Value.hold).ToArray(); packet.flipperReturns = source.Select((KeyValuePair<ulong, WorkshopFlipperCycle> x) => (float)x.Value.lower).ToArray(); } internal void Synchronize(WorkshopPacket packet) { if (p.Host) { return; } if (!packet.active) { Reset(); return; } EnsureRound(); int num = ((packet.flipperObjects != null) ? packet.flipperObjects.Length : 0); if (packet.flipperSerials == null || packet.flipperStarts == null || packet.flipperHolds == null || packet.flipperReturns == null || packet.flipperSerials.Length != num || packet.flipperStarts.Length != num || packet.flipperHolds.Length != num || packet.flipperReturns.Length != num) { return; } Dictionary<ulong, WorkshopFlipperCycle> dictionary = new Dictionary<ulong, WorkshopFlipperCycle>(); for (int i = 0; i < num; i++) { try { dictionary[packet.flipperObjects[i]] = new WorkshopFlipperCycle(packet.flipperSerials[i], packet.flipperStarts[i], packet.flipperHolds[i], packet.flipperReturns[i]); } catch (ArgumentOutOfRangeException) { return; } } cycles.Clear(); foreach (KeyValuePair<ulong, WorkshopFlipperCycle> item in dictionary) { cycles[item.Key] = item.Value; } } internal void Event(WorkshopPacket packet) { //IL_00a3: 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) if (!p.Rules.active) { return; } EnsureRound(); if (packet.kind == "flipperstate") { WorkshopFlipperCycle workshopFlipperCycle = Cycle(packet.objectId); if (workshopFlipperCycle == null || workshopFlipperCycle.serial < packet.id) { try { cycles[packet.objectId] = new WorkshopFlipperCycle(packet.id, packet.number, packet.volume, packet.scale.x); } catch (ArgumentOutOfRangeException) { } } } else { if (packet.kind != "flipperlaunch" || packet.id <= 0 || !WorkshopPlugin.Valid(packet.velocity) || ((Vector3)(ref packet.velocity)).magnitude > 81f) { return; } PlayerData val = WorkshopPlugin.Player(packet.player); if (Alive(val) && ((NetworkBehaviour)val).IsOwner && p.Racing) { string key = packet.objectId + ":" + packet.player; if (!impulses.TryGetValue(key, out var value) || value < packet.id) { impulses[key] = packet.id; val.controller.sphereRigidbody.AddForce(packet.velocity, (ForceMode)2); } } } } } public sealed class WorkshopFlipper : MonoBehaviour { private WorkshopObject platform; private Transform hinge; private Rigidbody body; private BoxCollider flap; private BoxCollider baseCollider; private TMP_Text label; internal void Init(WorkshopObject owner) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0227: 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_023d: Expected O, but got Unknown //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) platform = owner; GameObject val = WorkshopVisual.Shape((PrimitiveType)3, "Flipper base", new Color(0.16f, 0.18f, 0.2f), new Vector3(4.4f, 0.12f, 5.4f)); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.up * 0.04f; baseCollider = val.AddComponent<BoxCollider>(); ((Collider)baseCollider).enabled = false; hinge = new GameObject("Flipper hinge").transform; hinge.SetParent(((Component)this).transform, false); hinge.localPosition = new Vector3(0f, 0.185f, -2.5f); GameObject val2 = WorkshopVisual.Shape((PrimitiveType)3, "Flipper flap", new Color(1f, 0.55f, 0.12f), new Vector3(4f, 0.25f, 5f)); val2.transform.SetParent(hinge, false); val2.transform.localPosition = new Vector3(0f, 0f, 2.5f); flap = val2.AddComponent<BoxCollider>(); ((Collider)flap).enabled = false; body = ((Component)hinge).gameObject.AddComponent<Rigidbody>(); body.isKinematic = true; body.useGravity = false; body.interpolation = (RigidbodyInterpolation)1; GameObject obj = WorkshopVisual.Shape((PrimitiveType)2, "Hinge axle", new Color(0.35f, 0.4f, 0.45f), new Vector3(0.18f, 2.2f, 0.18f)); obj.transform.SetParent(((Component)this).transform, false); obj.transform.localPosition = new Vector3(0f, 0.185f, -2.5f); obj.transform.localRotation = Quaternion.Euler(0f, 0f, 90f); WorkshopObject.Arrow(hinge, new Vector3(0f, 0.135f, 3f), new Color(0.2f, 1f, 0.5f), reverse: false); GameObject val3 = new GameObject("Flipper status"); val3.transform.SetParent(((Component)this).transform, false); val3.transform.localPosition = new Vector3(-2.5f, 1.3f, -1.6f); label = (TMP_Text)(object)val3.AddComponent<TextMeshPro>(); label.fontSize = 3f; label.alignment = (TextAlignmentOptions)514; label.rectTransform.sizeDelta = new Vector2(4f, 1.5f); if (!Object.op_Implicit((Object)(object)GameManager.instance)) { return; } int num = LayerMask.op_Implicit(GameManager.instance.floorLayer); for (int i = 0; i < 32; i++) { if ((num & (1 << i)) != 0) { int layer = (val2.layer = i); val.layer = layer; break; } } } private WorkshopFlipperCycle Current() { WorkshopPlugin instance = WorkshopPlugin.Instance; if (!Object.op_Implicit((Object)(object)instance) || !instance.Rules.active || !Object.op_Implicit((Object)(object)platform) || !Object.op_Implicit((Object)(object)platform.obstacle) || !Object.op_Implicit((Object)(object)((NetworkBehaviour)platform.obstacle).NetworkObject)) { return null; } return instance.Flippers.Cycle(((NetworkBehaviour)platform.obstacle).NetworkObjectId); } private void Update() { WorkshopPlugin instance = WorkshopPlugin.Instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)platform) && Object.op_Implicit((Object)(object)flap)) { bool flag = platform.Placed && !platform.obstacle.IsCurrentlyBeingPlaced && !instance.Relocate.Reserved(platform.obstacle); WorkshopFlipperCycle workshopFlipperCycle = Current(); FlipperPhase flipperPhase = workshopFlipperCycle?.Phase(instance.World.Elapsed) ?? FlipperPhase.Resting; ((Collider)baseCollider).enabled = flag; ((Collider)flap).enabled = flag && flipperPhase != FlipperPhase.Rising; if (Object.op_Implicit((Object)(object)label)) { label.text = flipperPhase switch { FlipperPhase.Raised => "BLOCK " + Mathf.CeilToInt((float)(workshopFlipperCycle.start + 0.18 + workshopFlipperCycle.hold - (double)instance.World.Elapsed)) + "s", FlipperPhase.Rising => "FLIP!", FlipperPhase.Resting => "READY", _ => "RESET", }; } } } private void FixedUpdate() { //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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) WorkshopPlugin instance = WorkshopPlugin.Instance; if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)platform) && Object.op_Implicit((Object)(object)body)) { WorkshopFlipperCycle workshopFlipperCycle = Current(); float num = ((workshopFlipperCycle == null) ? 0f : ((float)workshopFlipperCycle.Angle(instance.World.Elapsed))); if (!platform.Placed || platform.obstacle.IsCurrentlyBeingPlaced || instance.Relocate.Reserved(platform.obstacle)) { num = 0f; } body.position = ((Component)this).transform.TransformPoint(new Vector3(0f, 0.185f, -2.5f)); body.rotation = ((Component)this).transform.rotation * Quaternion.Euler(0f - num, 0f, 0f); } } } [HarmonyPatch] internal static class WorkshopHistoryCameraInputPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(CinemachineOrbitalInputBind).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "Zoom" || methodInfo.Name == "RotateX" || methodInfo.Name == "RotateY" || methodInfo.Name == "HandleMouseOrbitalInputs") { yield return methodInfo; } } } [HarmonyPrefix] private static bool Prefix(object[] __args) { if (!WorkshopOverlay.CapturesInput) { return true; } if (__args.Length == 1 && __args[0] is float) { __args[0] = 0f; return true; } return false; } } [HarmonyPatch(typeof(CinemachineOrbitalInputBind), "Update")] internal static class WorkshopHistoryCameraUpdatePatch { private static readonly FieldInfo zoom = AccessTools.Field(typeof(CinemachineOrbitalInputBind), "_zoomInput"); private static readonly MethodInfo clear = AccessTools.Method(typeof(CinemachineOrbitalInputBind), "ClearRotation", (Type[])null, (Type[])null); [HarmonyPrefix] private static bool Prefix(CinemachineOrbitalInputBind __instance) { if (!WorkshopOverlay.CapturesInput) { return true; } zoom.SetValue(__instance, 0f); clear.Invoke(__instance, null); return false; } } [HarmonyPatch] internal static class WorkshopHistorySteeringPatch { private static IEnumerable<MethodBase> TargetMethods() { MethodInfo[] methods = typeof(SphereCarController).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "SetSteer" || methodInfo.Name == "SetVerticalSteer" || methodInfo.Name == "HandleMouseVerticalSteerInputs") { yield return methodInfo; } } } [HarmonyPrefix] private static bool Prefix(SphereCarController __instance, object[] __args) { if (!WorkshopOverlay.CapturesInput || !Object.op_Implicit((Object)(object)__instance.player) || !((NetworkBehaviour)__instance.player).IsOwner) { return true; } if (__args.Length == 1 && __args[0] is float) { __args[0] = 0f; return true; } __instance.SetSteer(0f); __instance.SetVerticalSteer(0f); return false; } } public static class WorkshopHistoryScroll { public static double Move(double offset, double content, double viewport, double pixels) { if (!Finite(offset) || !Finite(content) || !Finite(viewport) || !Finite(pixels)) { return 0.0; } double val = Math.Max(0.0, content - Math.Max(0.0, viewport)); return Math.Max(0.0, Math.Min(val, offset + pixels)); } public static double Stick(double value) { if (!Finite(value)) { return 0.0; } double num = Math.Min(1.0, Math.Abs(value)); if (!(num <= 0.2)) { return (double)Math.Sign(value) * (num - 0.2) / 0.8; } return 0.0; } private static bool Finite(double n) { if (!double.IsNaN(n)) { return !double.IsInfinity(n); } return false; } } internal static class WorkshopIcons { private static readonly Color[] colors = (Color[])(object)new Color[17] { new Color(1f, 0.6f, 0.1f), new Color(1f, 0.4f, 0.05f), new Color(0.8f, 0.25f, 1f), new Color(0.2f, 1f, 0.45f), new Color(0.2f, 0.85f, 1f), new Color(0.1f, 0.9f, 1f), new Color(0.5f, 1f, 0.4f), new Color(0.5f, 0.8f, 1f), new Color(1f, 0.8f, 0.3f), new Color(1f, 0.55f, 0.1f), new Color(0.2f, 0.85f, 1f), new Color(0.85f, 0.4f, 1f), new Color(1f, 0.15f, 0.1f), new Color(0.3f, 0.85f, 0.95f), new Color(1f, 0.35f, 0.1f), new Color(0.8f, 0.12f, 0.12f), new Color(0.65f, 0.25f, 0.95f) }; internal static Texture2D Create(int kind) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_05d9: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Unknown result type (might be due to invalid IL or missing references) //IL_05ff: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[16384]; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { bool flag = false; array[i * 128 + j] = (Color)((kind switch { 0 => Circle(j, i, 60, 56, 30) || Line(j, i, 69, 85, 85, 105, 5) || Circle(j, i, 89, 107, 6), 1 => Line(j, i, 28, 20, 28, 107, 7) || Line(j, i, 100, 20, 100, 107, 7) || Line(j, i, 28, 107, 100, 107, 7) || (j > 36 && j < 92 && i > 28 && i < 96 && (j + i) % 15 < 4), 2 => Line(j, i, 30, 95, 30, 46, 10) || Line(j, i, 98, 95, 98, 46, 10) || Line(j, i, 30, 46, 48, 26, 10) || Line(j, i, 48, 26, 80, 26, 10) || Line(j, i, 80, 26, 98, 46, 10), 3 => Arrow(j, i, 25, 43, 100, 43) || Arrow(j, i, 100, 85, 25, 85), 4 => Car(j, i, 43, 78) || Car(j, i, 82, 43), 5 => Line(j, i, 15, 25, 58, 25, 5) || Line(j, i, 58, 25, 58, 70, 5) || Line(j, i, 58, 70, 110, 70, 5) || Car(j, i, 100, 99), 6 => Circle(j, i, 33, 64, 22) || Circle(j, i, 95, 64, 22) || Line(j, i, 54, 64, 74, 64, 6), 7 => (j > 36 && j < 94 && i > 25 && i < 65) || Line(j, i, 40, 55, 40, 93, 6) || Line(j, i, 55, 55, 55, 104, 6) || Line(j, i, 70, 55, 70, 109, 6) || Line(j, i, 85, 55, 85, 100, 6) || Line(j, i, 38, 35, 22, 55, 7), 9 => Line(j, i, 20, 26, 105, 26, 5) || Line(j, i, 25, 30, 84, 96, 7) || Arrow(j, i, 40, 52, 83, 95), 10 => (Circle(j, i, 32, 64, 24) && !Circle(j, i, 32, 64, 15)) || (Circle(j, i, 96, 64, 24) && !Circle(j, i, 96, 64, 15)) || Arrow(j, i, 45, 100, 84, 100) || Arrow(j, i, 84, 28, 45, 28), 15 => Line(j, i, 20, 26, 108, 26, 4) || Line(j, i, 20, 26, 20, 100, 4) || Line(j, i, 108, 26, 108, 100, 4) || Line(j, i, 20, 100, 108, 100, 4) || Line(j, i, 43, 84, 85, 84, 5) || Line(j, i, 43, 84, 52, 56, 5) || Line(j, i, 85, 84, 76, 56, 5) || Line(j, i, 52, 56, 76, 56, 5) || Circle(j, i, 48, 92, 6) || Circle(j, i, 80, 92, 6), 14 => Circle(j, i, 64, 64, 38) || Circle(j, i, 64, 64, 12) || Line(j, i, 64, 15, 64, 113, 5), 13 => Circle(j, i, 64, 64, 33) || Line(j, i, 64, 24, 64, 104, 5) || Line(j, i, 24, 64, 104, 64, 5), 12 => Line(j, i, 64, 20, 64, 110, 6) || Circle(j, i, 64, 88, 15) || Circle(j, i, 64, 52, 15), 11 => Line(j, i, 25, 25, 75, 25, 4) || Line(j, i, 25, 25, 25, 75, 4) || Line(j, i, 25, 75, 75, 75, 4) || Line(j, i, 75, 25, 75, 75, 4) || Line(j, i, 53, 53, 103, 53, 4) || Line(j, i, 53, 53, 53, 103, 4) || Line(j, i, 53, 103, 103, 103, 4) || Line(j, i, 103, 53, 103, 103, 4), _ => Circle(j, i, 64, 96, 14) || Circle(j, i, 30, 40, 14) || Circle(j, i, 98, 40, 14) || Line(j, i, 59, 78, 39, 57, 4) || Line(j, i, 69, 78, 89, 57, 4) || Line(j, i, 47, 40, 81, 40, 4), }) ? colors[(kind >= 0 && kind < colors.Length) ? kind : (colors.Length - 1)] : new Color(0.035f, 0.055f, 0.085f)); } } val.SetPixels(array); val.Apply(); return val; } private static bool Circle(int x, int y, int cx, int cy, int r) { return (x - cx) * (x - cx) + (y - cy) * (y - cy) < r * r; } private static bool Line(int x, int y, int ax, int ay, int bx, int by, int width) { return WorkshopMath.SegmentDistanceSquared(new WorkshopMath.Point(x, y, 0.0), new WorkshopMath.Point(ax, ay, 0.0), new WorkshopMath.Point(bx, by, 0.0)) < (double)(width * width); } private static bool Arrow(int x, int y, int ax, int ay, int bx, int by) { int num = ((bx > ax) ? 1 : (-1)); if (!Line(x, y, ax, ay, bx, by, 5) && !Line(x, y, bx, by, bx - num * 18, by - 15, 5)) { return Line(x, y, bx, by, bx - num * 18, by + 15, 5); } return true; } private static bool Car(int x, int y, int cx, int cy) { if (x <= cx - 15 || x >= cx + 15 || y <= cy - 21 || y >= cy + 21) { if (x > cx - 21 && x < cx + 21) { if (y <= cy - 18 || y >= cy - 10) { if (y > cy + 10) { return y < cy + 18; } return false; } return true; } return false; } return true; } } internal static class WorkshopKillCredit { [ThreadStatic] internal static int CurrentToken; internal static int Authorize(int attacker, string cause) { WorkshopPlugin instance = WorkshopPlugin.Instance; if (!Object.op_Implicit((Object)(object)instance) || instance.World == null) { return 0; } return instance.World.AuthorizeAttack(attacker, cause); } internal static void Run(int token, Action death) { int currentToken = CurrentToken; try { CurrentToken = token; death(); } finally { CurrentToken = currentToken; } } } public sealed class WorkshopLobbyOption : GameRulesOption { internal int index; private WorkshopOption Option => WorkshopPlugin.Instance.Settings.options[index]; public override void PreviousValue(ref CustomGameRules rules) { WorkshopPlugin.Instance.Setting(index, -1); } public override void NextValue(ref CustomGameRules rules) { WorkshopPlugin.Instance.Setting(index, 1); } public override void ValidateValue(ref CustomGameRules rules) { } public override void ApplyValue(ref CustomGameRules rules) { } public override string ValueLabel(CustomGameRules rules) { if (Option.key == "DraftCard") { if (Option.value != 0) { return WorkshopPlugin.Names[Option.value - 1]; } return "Off"; } if (Option.key == "SpawnPool") { if (Option.value != 0) { if (Option.value != 1) { return "Both"; } return "Safe props"; } return "Hazards"; } if (Option.max == 1) { if (Option.value != 1) { return "Off"; } return "On"; } return Option.value.ToString(); } public override int CompareToDefaultValue(CustomGameRules rules) { return Option.value.CompareTo(Option.defaultValue); } public override void UpdateNameLabel(string text) { base.nameLabel.text = "Workshop: " + Option.title; } public override void UpdateRules(CustomGameRules rules) { ((GameRulesOption)this).UpdateStyle(); } } internal static class WorkshopLobby { internal static void Ensure(GameRulesValuesMenu menu) { //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) if ((Object.op_Implicit((Object)(object)menu) && ((Object)menu).name == "SlipSkid Mod Settings") || (Object.op_Implicit((Object)(object)GameRulesMenu.instance) && ((Component)GameRulesMenu.instance).GetComponentsInChildren<GameRulesOption>(true).Any((GameRulesOption o) => o is WorkshopLobbyOption))) { return; } WorkshopPlugin instance = WorkshopPlugin.Instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)menu) || menu.options == null) { return; } GameRulesOptionList val = ((IEnumerable<GameRulesOptionList>)menu.options).FirstOrDefault((Func<GameRulesOptionList, bool>)((GameRulesOptionList x) => x != null && x.gameRulesOptionList != null && x.gameRulesOptionList.Any((GameRulesOption o) => Object.op_Implicit((Object)(object)o)))); if (val == null || val.gameRulesOptionList.Any((GameRulesOption x) => x is WorkshopLobbyOption)) { return; } GameRulesOption val2 = ((IEnumerable<GameRulesOption>)val.gameRulesOptionList).FirstOrDefault((Func<GameRulesOption, bool>)((GameRulesOption x) => Object.op_Implicit((Object)(object)x) && !((object)x).GetType().Namespace.StartsWith("SlipSkid."))); if (!Object.op_Implicit((Object)(object)val2)) { return; } GameObject val3 = new GameObject("Workshop Rules Staging"); val3.SetActive(false); List<WorkshopLobbyOption> list = new List<WorkshopLobbyOption>(); try { Transform parent = ((Component)val2).transform.parent; for (int num = 0; num < instance.Settings.options.Count; num++) { GameObject obj = Object.Instantiate<GameObject>(((Component)val2).gameObject, val3.transform); obj.SetActive(false); ((Object)obj).name = "Workshop lobby rule " + num; GameRulesOption component = obj.GetComponent<GameRulesOption>(); WorkshopLobbyOption workshopLobbyOption = obj.AddComponent<WorkshopLobbyOption>(); FieldInfo[] fields = typeof(GameRulesOption).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(workshopLobbyOption, fieldInfo.GetValue(component)); } ((GameRulesOption)workshopLobbyOption).optionDisplayName = null; workshopLobbyOption.index = num; ((GameRulesOption)workshopLobbyOption).customButton.onEnter = new UnityEvent(); ((GameRulesOption)workshopLobbyOption).customButton.onSubmit = new UnityEvent(); ((GameRulesOption)workshopLobbyOption).previousButton.onSubmit = new UnityEvent(); ((GameRulesOption)workshopLobbyOption).nextButton.onSubmit = new UnityEvent(); Object.DestroyImmediate((Object)(object)component); list.Add(workshopLobbyOption); } Transform transform = ((Component)val2).transform; RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null); RectTransform val5 = (from r in val.gameRulesOptionList.Where((GameRulesOption o) => Object.op_Implicit((Object)(object)o) && (Object)(object)((Component)o).transform.parent == (Object)(object)parent).Select(delegate(GameRulesOption o) { Transform transform2 = ((Component)o).transform; return (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); }) where Object.op_Implicit((Object)(object)r) orderby r.anchoredPosition.y select r).FirstOrDefault(); foreach (WorkshopLobbyOption item in list) { ((Component)item).transform.SetParent(parent, false); } if (Object.op_Implicit((Object)(object)val4) && Object.op_Implicit((Object)(object)val5) && !Object.op_Implicit((Object)(object)((Component)parent).GetComponent<LayoutGroup>()) && Object.op_Implicit((Object)(object)val2.scrollRect) && (Object)(object)val2.scrollRect.content == (Object)(object)parent) { Rect rect = val4.rect; float num3 = Mathf.Max(((Rect)(ref rect)).height, 40f); for (int num4 = 0; num4 < list.Count; num4++) { ((RectTransform)((Component)list[num4]).transform).anchoredPosition = val5.anchoredPosition - new Vector2(0f, num3 * (float)(num4 + 1)); } RectTransform content = val2.scrollRect.content; content.sizeDelta += new Vector2(0f, num3 * (float)list.Count); } val.gameRulesOptionList = val.gameRulesOptionList.Concat(list.Cast<GameRulesOption>()).ToArray(); foreach (WorkshopLobbyOption item2 in list) { ((Component)item2).gameObject.SetActive(true); } instance.Note("Added " + list.Count + " Workshop settings to lobby rules."); } catch (Exception ex) { foreach (WorkshopLobbyOption item3 in list) { if (Object.op_Implicit((Object)(object)item3)) { Object.Destroy((Object)(object)((Component)item3).gameObject); } } instance.Note("Workshop lobby UI failed: " + ex); } finally { Object.Destroy((Object)(object)val3); } } internal static void Refresh() { GameRulesMenu instance = GameRulesMenu.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.canvas) || !((Behaviour)instance.canvas).enabled) { return; } GameRulesOption[] componentsInChildren = ((Component)instance).GetComponentsInChildren<GameRulesOption>(true); foreach (GameRulesOption val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeInHierarchy && val is WorkshopLobbyOption) { val.UpdateStyle(); } } } } [HarmonyPatch(typeof(GameRulesValuesMenu), "BuildUI")] internal static class WorkshopRulesUiPatch { [HarmonyPrefix] [HarmonyAfter(new string[] { "slipskid.tankcards" })] private static void Prefix(GameRulesValuesMenu __instance) { WorkshopLobby.Ensure(__instance); } } [HarmonyPatch(typeof(GameRulesMenu), "ResetRules")] internal static class WorkshopRulesResetPatch { [HarmonyPostfix] private static void Postfix() { if (Object.op_Implicit((Object)(object)WorkshopPlugin.Instance)) { WorkshopPlugin.Instance.Defaults(); } } } public sealed class WorkshopMatchHistory { private sealed class Round { internal int epoch; internal int number; internal string text; } private readonly List<Round> rounds = new List<Round>(); public int Revision { get; private set; } public bool Contains(int epoch) { return rounds.Any((Round r) => r.epoch == epoch); } public bool Add(int epoch, int number, string text) { if (rounds.Any((Round r) => r.epoch == epoch)) { return false; } rounds.Add(new Round { epoch = epoch, number = number, text = (text ?? "") }); Revision++; return true; } public string Render(string totals) { if (rounds.Count == 0) { return "No completed rounds yet."; } return "COMPLETED ROUNDS: " + rounds.Count + "\nNewest round first. Times are completed start-to-finish runs.\n\n" + string.Join("\n\n", from r in rounds orderby r.epoch descending select r.text) + "\n\n" + totals; } public void Clear() { rounds.Clear(); Revision = 0; } } public sealed class WorkshopHistoryTransfer { public const int ChunkSize = 2400; private string[] parts; private int revision; private int received; public int AppliedRevision { get; private set; } public static string[] Split(string report) { List<string> list = new List<string>(); report = report ?? ""; int num; for (int i = 0; i < report.Length; i += num) { num = Math.Min(2400, report.Length - i); if (i + num < report.Length && char.IsHighSurrogate(report[i + num - 1]) && char.IsLowSurrogate(report[i + num])) { num--; } list.Add(report.Substring(i, num)); } if (list.Count == 0) { list.Add(""); } return list.ToArray(); } public bool Accept(int version, int index, int count, string text, out string report) { report = null; if (version <= AppliedRevision || version < revision || count < 1 || count > 4096 || index < 0 || index >= count || text == null || text.Length > 2400) { return false; } if (version > revision) { revision = version; parts = new string[count]; received = 0; } if (parts == null || parts.Length != count) { return false; } if (parts[index] != null) { return false; } parts[index] = text; received++; if (received != parts.Length) { return false; } report = string.Concat(parts); AppliedRevision = version; parts = null; return true; } public void Clear() { parts = null; int num = (AppliedRevision = 0); revision = (received = num); } } public sealed class WorkshopCombatRules { private readonly Dictionary<int, int> dashSerial = new Dictionary<int, int>(); private readonly Dictionary<int, int> deaths = new Dictionary<int, int>(); private readonly Dictionary<int, double> dashUntil = new Dictionary<int, double>(); private readonly HashSet<string> hits = new HashSet<string>(); public bool Dash(int player, int serial, double now) { if (player < 0 || serial <= 0 || !WorkshopRules.Finite(now) || (dashSerial.TryGetValue(player, out var value) && serial <= value)) { return false; } dashSerial[player] = serial; dashUntil[player] = now + 0.65; return true; } public bool Hit(int attacker, int victim, double now) { if (attacker >= 0 && victim >= 0 && attacker != victim && WorkshopRules.Finite(now) && dashUntil.TryGetValue(attacker, out var value) && now <= value && now >= value - 0.65 && dashSerial.TryGetValue(attacker, out var value2)) { return hits.Add(attacker + ":" + value2 + ":" + victim); } return false; } public bool Death(int victim, int serial) { if (victim < 0 || serial <= 0 || (deaths.TryGetValue(victim, out var value) && serial <= value)) { return false; } deaths[victim] = serial; return true; } public void Clear() { dashSerial.Clear(); dashUntil.Clear(); deaths.Clear(); hits.Clear(); } } public sealed class WorkshopAttackCredits { private sealed class Attack { internal int attacker; internal string cause; internal readonly HashSet<int> victims = new HashSet<int>(); } private readonly Dictionary<int, Attack> attacks = new Dictionary<int, Attack>(); private int sequence; public int Authorize(int attacker, string cause) { if (attacker < 0) { return 0; } int num = ++sequence; attacks[num] = new Attack { attacker = attacker, cause = cause }; return num; } public bool Consume(int token, int victim, out int attacker, out string cause) { attacker = -1; cause = null; if (victim < 0 || !attacks.TryGetValue(token, out var value) || value.attacker == victim || !value.victims.Add(victim)) { return false; } attacker = value.attacker; cause = value.cause; return true; } public void Clear() { attacks.Clear(); } } public static class WorkshopMath { public struct Point { public double x; public double y; public double z; public Point(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } public static Point operator -(Point a, Point b) { return new Point(a.x - b.x, a.y - b.y, a.z - b.z); } public static Point operator +(Point a, Point b) { return new Point(a.x + b.x, a.y + b.y, a.z + b.z); } public static Point operator *(Point a, double t) { return new Point(a.x * t, a.y * t, a.z * t); } } public static bool IsLandingContact(bool vehicle, bool supportingSurface, double upNormal) { if (!vehicle && supportingSurface && !double.IsNaN(upNormal) && !double.IsInfinity(upNormal)) { return upNormal >= 0.5; } return false; } public static double Dot(Point a, Point b) { return a.x * b.x + a.y * b.y + a.z * b.z; } private static double Clamp(double n, double min, double max) { return Math.Max(min, Math.Min(max, n)); } public static double ClosingSpeed(Point offset, Point relativeVelocity) { double num = Math.Sqrt(Dot(offset, offset)); if (!(num < 1E-09)) { return Dot(offset, relativeVelocity) / num; } return 0.0; } public static double LateralDelta(double sideSpeed, double projection, double polarity, double strength, double dt, double cap) { double num = projection * polarity * strength * dt; return Clamp(sideSpeed + num, 0.0 - cap, cap) - Clamp(sideSpeed, 0.0 - cap, cap); } public static double SegmentDistanceSquared(Point p, Point a, Point b) { Point point = b - a; double num = Dot(point, point); double num2 = ((num < 1E-09) ? 0.0 : Clamp(Dot(p - a, point) / num, 0.0, 1.0)); Point point2 = p - (a + point * num2); return Dot(point2, point2); } public static double SegmentsDistanceSquared(Point p1, Point q1, Point p2, Point q2) { Point point = q1 - p1; Point point2 = q2 - p2; Point point3 = p1 - p2; double num = Dot(point, point); double num2 = Dot(point2, point2); double num3 = Dot(point2, point3); if (num < 1E-09 && num2 < 1E-09) { return Dot(point3, point3); } double num4; double num5; if (num < 1E-09) { num4 = 0.0; num5 = Clamp(num3 / num2, 0.0, 1.0); } else { double num6 = Dot(point, point3); if (num2 < 1E-09) { num5 = 0.0; num4 = Clamp((0.0 - num6) / num, 0.0, 1.0); } else { double num7 = Dot(point, point2); double num8 = num * num2 - num7 * num7; num4 = ((Math.Abs(num8) > 1E-09) ? Clamp((num7 * num3 - num6 * num2) / num8, 0.0, 1.0) : 0.0); num5 = (num7 * num4 + num3) / num2; if (num5 < 0.0) { num5 = 0.0; num4 = Clamp((0.0 - num6) / num, 0.0, 1.0); } else if (num5 > 1.0) { num5 = 1.0; num4 = Clamp((num7 - num6) / num, 0.0, 1.0); } } } Point point4 = p1 + point * num4 - (p2 + point2 * num5); return Dot(point4, point4); } } internal static class WorkshopModTab { internal const string PageName = "SlipSkid Mod Settings"; private static bool creating; private static GameRulesValuesMenu captured; private static readonly Dictionary<RectTransform, Vector2> positions = new Dictionary<RectTransform, Vector2>(); private static readonly Dictionary<RectTransform, Vector2> sizes = new Dictionary<RectTransform, Vector2>(); internal static void Capture(GameRulesValuesMenu menu) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)menu) || ((Object)menu).name == "SlipSkid Mod Settings" || (Object)(object)captured == (Object)(object)menu) { return; } captured = menu; positions.Clear(); sizes.Clear(); foreach (GameRulesOption item in from o in menu.options.SelectMany((GameRulesOptionList l) => l.gameRulesOptionList) where Object.op_Implicit((Object)(object)o) && !Mod(o) select o) { Transform transform = ((Component)item).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (Object.op_Implicit((Object)(object)val)) { positions[val] = val.anchoredPosition; } if (Object.op_Implicit((Object)(object)item.scrollRect) && Object.op_Implicit((Object)(object)item.scrollRect.content)) { sizes[item.scrollRect.content] = item.scrollRect.content.sizeDelta; } } } private static bool Mod(GameRulesOption option) { if (Object.op_Implicit((Object)(object)option)) { return (((object)option).GetType().Namespace ?? "").StartsWith("SlipSkid.", StringComparison.Ordinal); } return false; } private static T Map<T>(T item, Transform original, Transform copy) where T : Component { if (!Object.op_Implicit((Object)(object)item)) { return default(T); } Stack<int> stack = new Stack<int>(); Transform val = ((Component)item).transform; while ((Object)(object)val != (Object)(object)original) { stack.Push(val.GetSiblingIndex()); val = val.parent; if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("Tab reference outside its header"); } } while (stack.Count > 0) { copy = copy.GetChild(stack.Pop()); } return ((Component)copy).GetComponent<T>(); } private static Image Gradient(Transform parent, string name, bool top) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown re