Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Stoneveil v0.4.4
plugins/Stoneveil/Stoneveil.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Stoneveil")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.4.4.0")] [assembly: AssemblyInformationalVersion("0.4.4")] [assembly: AssemblyProduct("Stoneveil")] [assembly: AssemblyTitle("Stoneveil")] [assembly: AssemblyVersion("0.4.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Secret { internal sealed class AutomaticCloseRequest { private bool pending; private float expires; private float nextAttempt; internal void Request(float now) { if (!pending) { pending = true; expires = now + 60f; nextAttempt = now; } } internal void Cancel() { pending = false; } internal bool ShouldAttempt(float now, bool owner, DoorState state) { if (!owner || !state.Enabled || !state.Open || now >= expires) { Cancel(); return false; } if (!pending || now < nextAttempt) { return false; } nextAttempt = now + 0.25f; return true; } internal static bool AcceptRpc(long sender, long owner, bool isOwner, DoorState state) { if (isOwner && sender == owner && state.Enabled) { return state.Open; } return false; } internal static bool AcceptStateWrite(int observed, int published, bool isOwner, DoorState state) { if (isOwner && state.Enabled && state.Open && observed == 0) { return published != 0; } return false; } internal static int NativeState(DoorState state) { if (!state.Enabled || !state.Open) { return 0; } return 1; } } internal enum DoorCommand { Convert, Remove, Toggle, CycleMotion, Reverse, ToggleConcealment } internal enum DoorMotion { HingeLeft, HingeRight, SlideLeft, SlideRight } internal enum PanelKind { Wall, Hatch } internal readonly struct DoorState { private const int EnabledBit = 1; private const int OpenBit = 2; private const int ConcealedBit = 4; private const int ReverseBit = 8; private const int StackedStoneBit = 64; internal readonly int Value; internal bool Enabled => (Value & 1) != 0; internal bool Open => (Value & 2) != 0; internal bool Concealed => (Value & 4) != 0; internal bool Reverse => (Value & 8) != 0; internal bool StackedStone => (Value & 0x40) != 0; internal DoorMotion Motion => (DoorMotion)((Value >> 4) & 3); internal DoorState(int value) { Value = ((value >= 0 && value <= 127 && (value == 0 || (value & 1) != 0)) ? value : 0); } internal DoorState Apply(DoorCommand command, bool stackStone = false) { switch (command) { case DoorCommand.Convert: if (!Enabled) { return new DoorState(1 | (stackStone ? 64 : 0)); } return this; case DoorCommand.Remove: return new DoorState(0); default: if (!Enabled) { return this; } switch (command) { case DoorCommand.Toggle: return new DoorState(Value ^ 2); case DoorCommand.ToggleConcealment: return new DoorState(Value ^ 4); case DoorCommand.Reverse: if (!Open) { return new DoorState(Value ^ 8); } break; case DoorCommand.CycleMotion: if (!Open) { return new DoorState((Value & -49) | ((int)(Motion + 1) % 4 << 4)); } break; } return this; } } } internal static class GameAccess { internal static readonly Func<Player, bool> TakeInput = AccessTools.MethodDelegate<Func<Player, bool>>(AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null), (object)null, true); internal static readonly Action<WearNTear> SetupColliders = AccessTools.MethodDelegate<Action<WearNTear>>(AccessTools.Method(typeof(WearNTear), "SetupColliders", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef<List<PrivateArea>> Areas = AccessTools.StaticFieldRefAccess<List<PrivateArea>>(AccessTools.Field(typeof(PrivateArea), "m_allAreas")); private static readonly Func<PrivateArea, bool> IsEnabled = AccessTools.MethodDelegate<Func<PrivateArea, bool>>(AccessTools.Method(typeof(PrivateArea), "IsEnabled", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<PrivateArea, Vector3, float, bool> IsInside = AccessTools.MethodDelegate<Func<PrivateArea, Vector3, float, bool>>(AccessTools.Method(typeof(PrivateArea), "IsInside", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<PrivateArea, long, bool> IsPermitted = AccessTools.MethodDelegate<Func<PrivateArea, long, bool>>(AccessTools.Method(typeof(PrivateArea), "IsPermitted", (Type[])null, (Type[])null), (object)null, true); internal static Player ResolveSender(long sender) { foreach (Player allPlayer in Player.GetAllPlayers()) { ZNetView component = ((Component)allPlayer).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.GetZDO().GetOwner() == sender) { return allPlayer; } } return null; } internal static bool HasWardAccess(Vector3 point, long playerId) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) bool flag = false; foreach (PrivateArea item in Areas.Invoke()) { if (Object.op_Implicit((Object)(object)item) && IsEnabled(item) && IsInside(item, point, 0f)) { flag = true; if (((Component)item).GetComponent<Piece>().GetCreator() == playerId || IsPermitted(item, playerId)) { return true; } } } return !flag; } } internal static class LinkedSwitchAccess { private static readonly HashSet<int> SwitchPrefabs = new HashSet<int> { StringExtensionMethods.GetStableHashCode("doorswitch_wood"), StringExtensionMethods.GetStableHashCode("doorswitch_iron"), StringExtensionMethods.GetStableHashCode("doorswitch_rune"), StringExtensionMethods.GetStableHashCode("doorswitch_bookshelf") }; internal static bool CanUse(Player player, ZDO source, ZDO target, bool open) { return GetDenialReason(player, source, target, open) == null; } internal static string GetDenialReason(Player player, ZDO source, ZDO target, bool open) { return GetLinkDenialReason(source, target, open) ?? GetInteractionDenialReason(player, source, target, open); } internal static string GetLinkDenialReason(ZDO source, ZDO target, bool open) { string targetDenialReason = GetTargetDenialReason(source, target, open); if (targetDenialReason != null) { return targetDenialReason; } if (!LinkedSwitchPolicy.HasReference(source.GetString("doorswitch_links", ""), target.GetString("latchlink_identity", ""))) { return "The switch's link to this door is missing on this peer"; } return null; } internal static string GetInteractionDenialReason(Player player, ZDO source, ZDO target, bool open) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return "The requesting player is not loaded"; } if (((Character)player).IsDead()) { return "The requesting player is dead"; } string targetDenialReason = GetTargetDenialReason(source, target, open); if (targetDenialReason != null) { return targetDenialReason; } if (!GameAccess.HasWardAccess(source.GetPosition(), player.GetPlayerID())) { return "Ward access denied at the linked switch"; } if (!GameAccess.HasWardAccess(target.GetPosition(), player.GetPlayerID())) { return "Ward access denied at the door"; } int mode = source.GetInt("doorswitch_mode", 0); float num = Vector3.Distance(((Component)player).transform.position, source.GetPosition()); if (!LinkedSwitchPolicy.Allows(mode, open, num, player.m_maxInteractDistance, linked: true, permitted: true, enabled: true)) { return $"Too far from the linked switch ({num:0.0} m; limit {player.m_maxInteractDistance + 2f:0.0} m)"; } return null; } private static string GetTargetDenialReason(ZDO source, ZDO target, bool open) { if (source == null) { return "The linked switch data is not available on this peer"; } if (target == null) { return "The door data is not available on this peer"; } if (!Chainloader.PluginInfos.ContainsKey("com.tomtom.latchlink")) { return "LatchLink is not loaded on this peer"; } if (!SwitchPrefabs.Contains(source.GetPrefab())) { return "The request source is not a LatchLink switch"; } if (!new DoorState(target.GetInt("com.tomtom.secret.state.v1", 0)).Enabled) { return "This panel's Stoneveil hinge is disabled"; } int num = source.GetInt("doorswitch_mode", 0); if (num < 0 || num > 2) { return "The linked switch has an invalid mode"; } if ((num == 1 && !open) || (num == 2 && open)) { return "The requested action conflicts with the switch mode"; } return null; } } internal static class LinkedSwitchPolicy { internal static bool HasReference(string references, string identity) { if (!Guid.TryParseExact(identity, "N", out var _)) { return false; } string[] array = (references ?? "").Split(';'); for (int i = 0; i < array.Length; i++) { if (array[i] == "g:" + identity) { return true; } } return false; } internal static bool Allows(int mode, bool open, float playerDistance, float interactDistance, bool linked, bool permitted, bool enabled) { if (enabled && linked && permitted && playerDistance >= 0f && interactDistance >= 0f && !float.IsInfinity(playerDistance) && !float.IsInfinity(interactDistance) && playerDistance <= interactDistance + 2f) { if (mode != 0 && !(mode == 1 && open)) { if (mode == 2) { return !open; } return false; } return true; } return false; } } internal static class LinkedSwitchRpc { private sealed class Pending { internal SecretDoor Door; internal long Player; internal ZDOID Source; internal ZDOID Target; internal bool Open; internal float Expires; } [CompilerGenerated] private static class <>O { public static CoroutineHandler <0>__OnServerReceive; public static CoroutineHandler <1>__OnClientReceive; } private const byte Request = 0; private const byte Response = 1; private static CustomRPC rpc; private static readonly Dictionary<long, Pending> Requests = new Dictionary<long, Pending>(); private static long nextRequest; private static float nextCleanup; private static ZNet session; internal static void Initialize() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown NetworkManager instance = NetworkManager.Instance; object obj = <>O.<0>__OnServerReceive; if (obj == null) { CoroutineHandler val = OnServerReceive; <>O.<0>__OnServerReceive = val; obj = (object)val; } object obj2 = <>O.<1>__OnClientReceive; if (obj2 == null) { CoroutineHandler val2 = OnClientReceive; <>O.<1>__OnClientReceive = val2; obj2 = (object)val2; } rpc = instance.AddRPC("Stoneveil_LinkAuthorization", (CoroutineHandler)obj, (CoroutineHandler)obj2); } internal static void Authorize(SecretDoor door, long player, ZDOID source, ZDOID target, bool open) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) Update(); long server = GetServer(); if (rpc == null || server == 0L || Requests.Count >= 256) { door.CompleteSwitchAuthorization(player, source, target, open, "Switch authorization is unavailable; try again"); return; } foreach (Pending value in Requests.Values) { if ((Object)(object)value.Door == (Object)(object)door) { return; } } long num = ++nextRequest; Requests.Add(num, new Pending { Door = door, Player = player, Source = source, Target = target, Open = open, Expires = Time.unscaledTime + 5f }); ZPackage val = new ZPackage(); val.Write((byte)0); val.Write(num); val.Write(source); val.Write(target); val.Write(open); rpc.SendPackage(server, val); } private static IEnumerator OnServerReceive(long sender, ZPackage package) { byte b = package.ReadByte(); if (b == 1 && sender == ZNet.GetUID()) { ReceiveResponse(package); } else if (b == 0 && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { long num = package.ReadLong(); ZDOMan instance = ZDOMan.instance; ZDO source = ((instance != null) ? instance.GetZDO(package.ReadZDOID()) : null); ZDOMan instance2 = ZDOMan.instance; ZDO val = ((instance2 != null) ? instance2.GetZDO(package.ReadZDOID()) : null); bool open = package.ReadBool(); string text = ((val == null || val.GetOwner() != sender) ? "Door ownership changed while authorizing the switch; try again" : LinkedSwitchAccess.GetLinkDenialReason(source, val, open)); ZPackage val2 = new ZPackage(); val2.Write((byte)1); val2.Write(num); val2.Write(text ?? ""); rpc.SendPackage(sender, val2); } yield break; } private static IEnumerator OnClientReceive(long sender, ZPackage package) { long server = GetServer(); if (server != 0L && sender == server && package.ReadByte() == 1) { ReceiveResponse(package); } yield break; } private static void ReceiveResponse(ZPackage package) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) long key = package.ReadLong(); string text = package.ReadString(); if (!Requests.TryGetValue(key, out var value)) { return; } Requests.Remove(key); if (Object.op_Implicit((Object)(object)value.Door)) { if (Time.unscaledTime >= value.Expires) { text = "Switch authorization timed out; try again"; } value.Door.CompleteSwitchAuthorization(value.Player, value.Source, value.Target, value.Open, string.IsNullOrEmpty(text) ? null : text); } } private static long GetServer() { if (!((Object)(object)ZNet.instance == (Object)null)) { if (!ZNet.instance.IsServer()) { return ZNet.instance.GetServerPeer()?.m_uid ?? 0; } return ZNet.GetUID(); } return 0L; } internal static void Update() { //IL_00fe: 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) if ((Object)(object)session != (Object)(object)ZNet.instance) { Requests.Clear(); session = ZNet.instance; nextCleanup = 0f; } if (Time.unscaledTime < nextCleanup) { return; } nextCleanup = Time.unscaledTime + 1f; List<long> list = new List<long>(); foreach (KeyValuePair<long, Pending> request in Requests) { if (!Object.op_Implicit((Object)(object)request.Value.Door) || Time.unscaledTime >= request.Value.Expires) { list.Add(request.Key); } } foreach (long item in list) { Pending pending = Requests[item]; Requests.Remove(item); if (Object.op_Implicit((Object)(object)pending.Door)) { pending.Door.CompleteSwitchAuthorization(pending.Player, pending.Source, pending.Target, pending.Open, "Switch authorization timed out; try again"); } } } } public sealed class StoneveilDoor : Door { public bool InteractFromSwitch(Humanoid user, ZDOID switchId, bool open) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) return NativeDoorAdapter.Panel((Door)(object)this)?.InteractFromSwitch(user, switchId, open) ?? false; } public string GetSwitchFailure() { return NativeDoorAdapter.Panel((Door)(object)this)?.LastSwitchFailure; } private void Awake() { Piece component = ((Component)this).GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component)) { base.m_name = component.m_name; } NativeDoorAdapter.AwakeMethod.Invoke(this, null); } private void UpdateState() { NativeDoorAdapter.UpdateMethod.Invoke(this, null); } } internal static class NativeDoorAdapter { internal static readonly MethodInfo AwakeMethod = AccessTools.Method(typeof(Door), "Awake", (Type[])null, (Type[])null); internal static readonly MethodInfo UpdateMethod = AccessTools.Method(typeof(Door), "UpdateState", (Type[])null, (Type[])null); private static readonly MethodInfo UseMethod = AccessTools.Method(typeof(Door), "RPC_UseDoor", (Type[])null, (Type[])null); internal static void Use(Door door, long sender) { UseMethod.Invoke(door, new object[2] { sender, false }); } internal static SecretDoor Panel(Door door) { if (!(door is StoneveilDoor)) { return null; } return ((Component)door).GetComponent<SecretDoor>(); } internal static void LogInteractionPatches() { Patches patchInfo = Harmony.GetPatchInfo((MethodBase)AccessTools.Method(typeof(Door), "Interact", (Type[])null, (Type[])null)); if (patchInfo != null) { SecretPlugin.Warn("Door.Interact prefixes: " + string.Join(", ", patchInfo.Prefixes.Select((Patch p) => p.owner + ":" + p.PatchMethod.DeclaringType?.FullName + "." + p.PatchMethod.Name))); } } } [HarmonyPatch(typeof(Door), "UpdateState")] internal static class NativeDoorUpdatePatch { private static void Prefix(Door __instance) { NativeDoorAdapter.Panel(__instance)?.PollNativeState(); } } [HarmonyPatch(typeof(Door), "SetState")] internal static class NativeDoorStatePatch { private static bool Prefix(Door __instance, int state) { if (!(__instance is StoneveilDoor)) { return true; } NativeDoorAdapter.Panel(__instance)?.ObserveNativeState(state); return false; } } [HarmonyPatch(typeof(Door), "CanInteract")] internal static class NativeDoorCanInteractPatch { private static bool Prefix(Door __instance, ref bool __result) { if (!(__instance is StoneveilDoor)) { return true; } __result = NativeDoorAdapter.Panel(__instance)?.CanOperate ?? false; return false; } } [HarmonyPatch(typeof(Door), "Interact")] [HarmonyPriority(0)] [HarmonyAfter(new string[] { "com.tomtom.latchlink", "Harmony.Azumatt.WardIsLove" })] internal static class NativeDoorInteractPatch { private static bool Prefix(Door __instance, Humanoid character, bool hold, bool alt, ref bool __result) { if (!(__instance is StoneveilDoor)) { return true; } __result = NativeDoorAdapter.Panel(__instance)?.InteractPanel(character, hold, alt) ?? false; return false; } } [HarmonyPatch(typeof(Door), "RPC_UseDoor")] internal static class NativeDoorUsePatch { private static bool Prefix(Door __instance, long uid) { if (!(__instance is StoneveilDoor)) { return true; } NativeDoorAdapter.Panel(__instance)?.HandleNativeUse(uid); return false; } } [HarmonyPatch(typeof(Door), "Open")] internal static class NativeDoorOpenPatch { private static bool Prefix(Door __instance) { if (!(__instance is StoneveilDoor)) { return true; } SecretDoor secretDoor = NativeDoorAdapter.Panel(__instance); if (Object.op_Implicit((Object)(object)secretDoor) && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { secretDoor.InteractPanel((Humanoid)(object)Player.m_localPlayer, hold: false, alt: false); } return false; } } [HarmonyPatch(typeof(Door), "UseItem")] internal static class NativeDoorItemPatch { private static bool Prefix(Door __instance, ref bool __result) { if (!(__instance is StoneveilDoor)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Door), "GetHoverText")] internal static class NativeDoorHoverPatch { private static bool Prefix(Door __instance, ref string __result) { if (!(__instance is StoneveilDoor)) { return true; } __result = NativeDoorAdapter.Panel(__instance)?.GetHoverText() ?? ""; return false; } } [HarmonyPatch(typeof(Door), "GetHoverName")] internal static class NativeDoorNamePatch { private static bool Prefix(Door __instance, ref string __result) { if (!(__instance is StoneveilDoor)) { return true; } __result = NativeDoorAdapter.Panel(__instance)?.GetHoverName() ?? ""; return false; } } internal static class PanelCollision { internal static bool Blocks(Collider panel, Collider candidate) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)panel) || !Object.op_Implicit((Object)(object)candidate) || !panel.enabled || !candidate.enabled || panel.isTrigger || candidate.isTrigger || !Object.op_Implicit((Object)(object)((Component)candidate).GetComponentInParent<Character>())) { return false; } if (!SupportsPenetration(panel) && !SupportsPenetration(candidate)) { return true; } Vector3 val = default(Vector3); float num = default(float); if (Physics.ComputePenetration(candidate, ((Component)candidate).transform.position, ((Component)candidate).transform.rotation, panel, ((Component)panel).transform.position, ((Component)panel).transform.rotation, ref val, ref num)) { return num > 0.005f; } return false; } private static bool SupportsPenetration(Collider collider) { if (!(collider is BoxCollider) && !(collider is CapsuleCollider) && !(collider is SphereCollider)) { MeshCollider val = (MeshCollider)(object)((collider is MeshCollider) ? collider : null); if (val != null) { return val.convex; } return false; } return true; } } internal static class PanelMotion { internal static void Evaluate(Vector3 min, Vector3 max, PanelKind kind, DoorState state, float progress, out Vector3 pivot, out Quaternion rotation, out Vector3 translation, float? nearEdgeHeight = null, float? farEdgeHeight = null) { progress = Math.Clamp(progress, 0f, 1f); progress = progress * progress * (3f - 2f * progress); pivot = Vector3.Zero; rotation = Quaternion.Identity; translation = Vector3.Zero; if (state.Motion == DoorMotion.SlideLeft || state.Motion == DoorMotion.SlideRight) { float num = ((state.Motion == DoorMotion.SlideLeft) ? (-1f) : 1f); translation = Vector3.UnitX * ((max.X - min.X + 0.1f) * num * progress); return; } bool flag = state.Motion == DoorMotion.HingeRight; Vector3 axis; if (kind == PanelKind.Wall) { pivot = new Vector3(flag ? max.X : min.X, min.Y, (min.Z + max.Z) * 0.5f); axis = Vector3.UnitY; } else { float y = ((!flag) ? (nearEdgeHeight ?? min.Y) : (farEdgeHeight ?? max.Y)); pivot = new Vector3((min.X + max.X) * 0.5f, y, flag ? max.Z : min.Z); axis = Vector3.UnitX; } float num2 = (flag ? (-1f) : 1f) * (state.Reverse ? (-1f) : 1f); rotation = Quaternion.CreateFromAxisAngle(axis, num2 * MathF.PI * 0.5f * progress); } } internal sealed class PanelRig : IDisposable { private readonly List<(Transform node, Vector3 position, Quaternion rotation)> parts = new List<(Transform, Vector3, Quaternion)>(); private readonly List<(Collider original, Collider copy, bool wasEnabled)> rootColliders = new List<(Collider, Collider, bool)>(); private readonly Transform root; private readonly WearNTear wear; private readonly float nearEdgeHeight; private readonly float farEdgeHeight; private StoneStack stack; internal bool StackedStone { get; } internal Bounds Bounds { get; private set; } internal PanelRig(Transform root, bool stackedStone = false, bool checkClearance = false) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Expected O, but got Unknown //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Expected O, but got Unknown //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_0503: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) this.root = root; StackedStone = stackedStone; wear = ((Component)root).GetComponent<WearNTear>(); Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(true); if (!Object.op_Implicit((Object)(object)wear) || Object.op_Implicit((Object)(object)((Component)root).GetComponent<Renderer>()) || ((Component)root).GetComponentsInChildren<Rigidbody>(true).Length != 0 || ((Component)root).GetComponentsInChildren<ZNetView>(true).Length != 1) { throw new InvalidOperationException("This piece has an unsupported component layout."); } bool flag = true; List<Vector3> list = new List<Vector3>(); Bounds val = default(Bounds); Collider[] array = componentsInChildren; Bounds bounds = default(Bounds); foreach (Collider val2 in array) { if (val2.isTrigger) { continue; } BoxCollider val3 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null); if (val3 != null) { ((Bounds)(ref bounds))..ctor(val3.center, val3.size); } else { MeshCollider val4 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null); if (val4 == null || !Object.op_Implicit((Object)(object)val4.sharedMesh)) { throw new InvalidOperationException("Only box and mesh panel colliders are supported."); } bounds = val4.sharedMesh.bounds; } for (int j = 0; j < 8; j++) { Vector3 val5 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val6 = root.InverseTransformPoint(((Component)val2).transform.TransformPoint(val5)); list.Add(val6); if (flag) { ((Bounds)(ref val))..ctor(val6, Vector3.zero); flag = false; } else { ((Bounds)(ref val)).Encapsulate(val6); } } } if (flag) { throw new InvalidOperationException("This piece has no solid panel geometry."); } Bounds = val; if (stackedStone && checkClearance) { CheckUpperClearance(root, val); } float num = 0f; float num2 = 0f; int num3 = 0; int num4 = 0; foreach (Vector3 item in list) { if (Mathf.Abs(item.z - ((Bounds)(ref val)).min.z) < 0.01f) { num += item.y; num3++; } if (Mathf.Abs(item.z - ((Bounds)(ref val)).max.z) < 0.01f) { num2 += item.y; num4++; } } nearEdgeHeight = num / (float)num3; farEdgeHeight = num2 / (float)num4; foreach (Transform item2 in root) { Transform val7 = item2; if (((Component)val7).GetComponentsInChildren<Renderer>(true).Length == 0 && ((Component)val7).GetComponentsInChildren<Collider>(true).Length == 0) { continue; } Transform[] componentsInChildren2 = ((Component)val7).GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { if (((Component)componentsInChildren2[i]).CompareTag("snappoint")) { throw new InvalidOperationException("This piece mixes snap points with moving geometry."); } } parts.Add((val7, val7.localPosition, val7.localRotation)); } try { array = ((Component)root).GetComponents<Collider>(); foreach (Collider val8 in array) { if (!val8.isTrigger) { GameObject val9 = new GameObject("Secret_Collider"); val9.layer = ((Component)root).gameObject.layer; val9.transform.SetParent(root, false); BoxCollider val10 = (BoxCollider)(object)((val8 is BoxCollider) ? val8 : null); Collider val11; if (val10 != null) { BoxCollider obj = val9.AddComponent<BoxCollider>(); obj.center = val10.center; obj.size = val10.size; val11 = (Collider)(object)obj; } else { MeshCollider val12 = (MeshCollider)val8; MeshCollider obj2 = val9.AddComponent<MeshCollider>(); obj2.sharedMesh = val12.sharedMesh; obj2.convex = val12.convex; val11 = (Collider)(object)obj2; } val11.sharedMaterial = val8.sharedMaterial; val11.contactOffset = val8.contactOffset; val11.enabled = val8.enabled; rootColliders.Add((val8, val11, val8.enabled)); val8.enabled = false; parts.Add((val9.transform, Vector3.zero, Quaternion.identity)); } } if (stackedStone) { List<Transform> list2 = new List<Transform>(); foreach (var part in parts) { list2.Add(part.node); } stack = new StoneStack(root, list2); parts.Add((stack.Upper, stack.Upper.localPosition, Quaternion.identity)); Bounds val13 = val; ((Bounds)(ref val13)).center = ((Bounds)(ref val13)).center + stack.Upper.localPosition; ((Bounds)(ref val)).Encapsulate(val13); Bounds = val; } Physics.SyncTransforms(); GameAccess.SetupColliders(wear); } catch { Dispose(); throw; } } private static void CheckUpperClearance(Transform root, Bounds lower) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Vector3 upperOffset = StoneStackLayout.UpperOffset; Vector3 val = root.TransformPoint(((Bounds)(ref lower)).center + new Vector3(upperOffset.X, upperOffset.Y, upperOffset.Z)); Vector3 lossyScale = root.lossyScale; ((Vector3)(ref lossyScale))..ctor(Mathf.Abs(lossyScale.x), Mathf.Abs(lossyScale.y), Mathf.Abs(lossyScale.z)); Vector3 val2 = Vector3.Max(Vector3.Scale(((Bounds)(ref lower)).extents, lossyScale) - Vector3.one * 0.025f, Vector3.one * 0.01f); Physics.SyncTransforms(); Collider[] array = Physics.OverlapBox(val, val2, root.rotation, -1, (QueryTriggerInteraction)1); foreach (Collider val3 in array) { if (!((Component)val3).transform.IsChildOf(root) && ((Component)val3).gameObject.layer != LayerMask.NameToLayer("ghost")) { throw new InvalidOperationException("Clear the space above this wall before adding its 2x2 secret hinge."); } } } internal void SyncVisuals() { stack?.SyncVisuals(); } internal void Apply(PanelKind kind, DoorState state, float progress) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (progress == 0f) { foreach (var part in parts) { if (Object.op_Implicit((Object)(object)part.node)) { part.node.localPosition = part.position; part.node.localRotation = part.rotation; } } return; } Bounds bounds = Bounds; Vector3 min = ToNumerics(((Bounds)(ref bounds)).min); bounds = Bounds; PanelMotion.Evaluate(min, ToNumerics(((Bounds)(ref bounds)).max), kind, state, progress, out var pivot, out var rotation, out var translation, nearEdgeHeight, farEdgeHeight); Quaternion val = default(Quaternion); ((Quaternion)(ref val))..ctor(rotation.X, rotation.Y, rotation.Z, rotation.W); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(pivot.X, pivot.Y, pivot.Z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(translation.X, translation.Y, translation.Z); foreach (var part2 in parts) { if (Object.op_Implicit((Object)(object)part2.node)) { part2.node.localPosition = val2 + val * (part2.position - val2) + val3; part2.node.localRotation = val * part2.rotation; } } } internal bool ContainsCharacter() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Collider[] componentsInChildren = ((Component)root).GetComponentsInChildren<Collider>(); foreach (Collider val in componentsInChildren) { if (!val.enabled || val.isTrigger) { continue; } Bounds bounds = val.bounds; Vector3 val2 = Vector3.Max(((Bounds)(ref bounds)).extents, Vector3.one * 0.01f); Collider[] array = Physics.OverlapBox(((Bounds)(ref bounds)).center, val2, Quaternion.identity, -1, (QueryTriggerInteraction)1); foreach (Collider candidate in array) { if (PanelCollision.Blocks(val, candidate)) { return true; } } } return false; } internal static Vector3 ToNumerics(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new Vector3(value.x, value.y, value.z); } public void Dispose() { Apply(PanelKind.Wall, default(DoorState), 0f); stack?.Dispose(); stack = null; foreach (var rootCollider in rootColliders) { if (Object.op_Implicit((Object)(object)rootCollider.original)) { rootCollider.original.enabled = rootCollider.wasEnabled; } if (Object.op_Implicit((Object)(object)rootCollider.copy)) { rootCollider.copy.enabled = false; StoneStack.RemoveTemporary(((Component)rootCollider.copy).gameObject); } } rootColliders.Clear(); parts.Clear(); if (Object.op_Implicit((Object)(object)wear)) { GameAccess.SetupColliders(wear); } } } public sealed class SecretDoor : MonoBehaviour, Hoverable, Interactable { private const string StateKey = "com.tomtom.secret.state.v1"; private const string CommandRpc = "Secret_Command"; private const string ReplyRpc = "Secret_Reply"; private const string SwitchRpc = "Stoneveil_LinkedSwitch"; internal static readonly HashSet<SecretDoor> MovingPanels = new HashSet<SecretDoor>(); private ZNetView view; private Piece piece; private PanelKind kind; private PanelRig rig; private DoorState state; private float progress; private float nextPoll; private float nextOperation; private float nextBlockedLog; private bool initialized; private bool failed; private StoneveilDoor nativeDoor; private int publishedNativeState; private bool manualNativeUse; private bool adapterUnavailable; private bool lastAdapterOwner; private bool switchInteraction; private bool switchOpen; private ZDOID interactionSwitch; private bool switchPipelineReached; private readonly AutomaticCloseRequest automaticClose = new AutomaticCloseRequest(); internal string LastSwitchFailure { get; private set; } private bool IsStackableStone => view.GetZDO().GetPrefab() == StringExtensionMethods.GetStableHashCode("stone_wall_2x1"); internal bool CanOperate { get { if (initialized && Object.op_Implicit((Object)(object)view) && view.IsValid() && new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)).Enabled && rig != null && !failed && Time.unscaledTime >= nextOperation) { return Mathf.Approximately(progress, state.Open ? 1f : 0f); } return false; } } private void Start() { view = ((Component)this).GetComponent<ZNetView>(); piece = ((Component)this).GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)view) && view.IsValid() && SecretPlugin.Supported.TryGetValue(view.GetZDO().GetPrefab(), out kind)) { view.Register<int>("Secret_Command", (Action<long, int>)ReceiveCommand); view.Register<string>("Secret_Reply", (Action<long, string>)ReceiveReply); view.Register<ZPackage>("Stoneveil_LinkedSwitch", (Action<long, ZPackage>)ReceiveSwitchCommand); initialized = true; Sync(initial: true); } } private void Update() { if (!initialized || !view.IsValid()) { return; } if (Time.unscaledTime >= nextPoll) { nextPoll = Time.unscaledTime + 0.1f; Sync(initial: false); } PollNativeState(); TryAutomaticClose(); if (rig != null) { rig.SyncVisuals(); progress = Mathf.MoveTowards(progress, state.Open ? 1f : 0f, Time.deltaTime / 0.75f); rig.Apply(kind, state, progress); if (progress > 0f) { MovingPanels.Add(this); } else { MovingPanels.Remove(this); } } } private void Sync(bool initial) { state = new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)); if (!state.Enabled) { automaticClose.Cancel(); PublishNativeState(); rig?.Dispose(); rig = null; failed = false; progress = 0f; MovingPanels.Remove(this); return; } bool flag = state.StackedStone && IsStackableStone; if (rig != null && rig.StackedStone != flag) { rig.Dispose(); rig = null; } if (rig == null && !failed) { try { rig = new PanelRig(((Component)this).transform, flag); } catch (Exception ex) { failed = true; SecretPlugin.Warn("Cannot animate " + ((Object)this).name + ": " + ex.Message); } } if (initial && rig != null) { progress = (state.Open ? 1f : 0f); rig.Apply(kind, state, progress); if (progress > 0f) { MovingPanels.Add(this); } } EnsureNativeDoor(); } internal void Request(Player player, DoorCommand command) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (initialized && view.IsValid() && PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { if (command != DoorCommand.Toggle && piece.GetCreator() != player.GetPlayerID()) { SecretPlugin.Tell("Only the piece's builder can change its secret hinge."); return; } view.InvokeRPC("Secret_Command", new object[1] { (int)command }); } } private void ReceiveCommand(long sender, int value) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) if (!view.IsValid() || !view.IsOwner() || !Enum.IsDefined(typeof(DoorCommand), value)) { return; } Player val = GameAccess.ResolveSender(sender); if (!Object.op_Implicit((Object)(object)val) || ((Character)val).IsDead() || !piece.IsPlacedByPlayer()) { return; } bool flag = value != 2; if ((flag && (piece.GetCreator() != val.GetPlayerID() || !SecretPlugin.HasHammer(val))) || !GameAccess.HasWardAccess(((Component)this).transform.position, val.GetPlayerID())) { Reply(sender, "You do not have access to this hinge."); return; } float num = (flag ? 8f : (val.m_maxInteractDistance + 2f)); if (Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position) > num) { return; } Sync(initial: false); if (Time.unscaledTime < nextOperation) { return; } if (value == 1 && failed) { view.GetZDO().Set("com.tomtom.secret.state.v1", 0); Sync(initial: false); Reply(sender, "Secret hinge removed."); return; } if ((value == 1 || value == 3 || value == 4) && (state.Open || progress > 0f)) { Reply(sender, "Close the panel before changing or removing its hinge."); return; } if (!state.Enabled && value != 0) { Reply(sender, "This piece has no secret hinge."); return; } if (failed) { Reply(sender, "The panel cannot animate. Remove its hinge and check the log."); return; } if (value == 2) { if (Object.op_Implicit((Object)(object)nativeDoor)) { manualNativeUse = true; try { NativeDoorAdapter.Use((Door)(object)nativeDoor, sender); return; } finally { manualNativeUse = false; } } TogglePanel(sender); return; } DoorState doorState = state.Apply((DoorCommand)value, IsStackableStone); if (value == 0 && rig == null) { if (doorState.StackedStone && !GameAccess.HasWardAccess(((Component)this).transform.TransformPoint(Vector3.up), val.GetPlayerID())) { Reply(sender, "You do not have access to the space above this wall."); return; } try { rig = new PanelRig(((Component)this).transform, doorState.StackedStone && IsStackableStone, checkClearance: true); } catch (Exception ex) { Reply(sender, ex.Message); return; } } if (doorState.Value != state.Value) { view.GetZDO().Set("com.tomtom.secret.state.v1", doorState.Value); nextOperation = Time.unscaledTime + 0.2f; Sync(initial: false); PublishNativeState(); switch (value) { case 0: Reply(sender, state.StackedStone ? "2x2 secret stone door created." : "Secret hinge added."); break; case 1: Reply(sender, "Secret hinge removed."); break; case 3: Reply(sender, $"Motion: {state.Motion}"); break; case 4: Reply(sender, state.Reverse ? "Swing reversed." : "Swing restored."); break; case 5: Reply(sender, state.Concealed ? "Interaction prompt concealed." : "Interaction prompt visible."); break; case 2: break; } } } internal bool InteractFromSwitch(Humanoid user, ZDOID switchId, bool open) { //IL_00ba: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) LastSwitchFailure = null; if (!Object.op_Implicit((Object)(object)nativeDoor) || ((ZDOID)(ref switchId)).IsNone()) { return RejectSwitch("Stoneveil door adapter or source switch is unavailable", switchId, "client"); } bool flag = switchInteraction; bool flag2 = switchOpen; bool flag3 = switchPipelineReached; ZDOID val = interactionSwitch; switchInteraction = true; switchPipelineReached = false; interactionSwitch = switchId; switchOpen = open; try { bool num = ((Door)nativeDoor).Interact(user, false, false); if (!num && LastSwitchFailure == null) { RejectSwitch(switchPipelineReached ? "Stoneveil interaction did not submit a request" : "Door interaction was stopped before Stoneveil handled it; check mod patches", switchId, "client"); if (!switchPipelineReached) { NativeDoorAdapter.LogInteractionPatches(); } } return num; } finally { switchInteraction = flag; interactionSwitch = val; switchOpen = flag2; switchPipelineReached = flag3; } } private void ReceiveSwitchCommand(long sender, ZPackage package) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (initialized && view.IsValid() && view.IsOwner()) { ZDOID val; bool open; try { val = package.ReadZDOID(); open = package.ReadBool(); } catch (Exception) { return; } Player player = GameAccess.ResolveSender(sender); ZDOMan instance = ZDOMan.instance; ZDO source = ((instance != null) ? instance.GetZDO(val) : null); string text = ((!piece.IsPlacedByPlayer()) ? "The panel is not a player-built piece" : LinkedSwitchAccess.GetInteractionDenialReason(player, source, view.GetZDO(), open)); if (text != null) { RejectSwitch(text, val, "owner"); Reply(sender, text); } else { LinkedSwitchRpc.Authorize(this, sender, val, view.GetZDO().m_uid, open); } } } internal void CompleteSwitchAuthorization(long sender, ZDOID sourceId, ZDOID targetId, bool open, string denial) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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 (!initialized || !Object.op_Implicit((Object)(object)view) || !view.IsValid() || !view.IsOwner() || view.GetZDO().m_uid != targetId) { return; } if (denial == null) { object obj; if (piece.IsPlacedByPlayer()) { Player player = GameAccess.ResolveSender(sender); ZDOMan instance = ZDOMan.instance; obj = LinkedSwitchAccess.GetInteractionDenialReason(player, (instance != null) ? instance.GetZDO(sourceId) : null, view.GetZDO(), open); } else { obj = "The panel is not a player-built piece"; } denial = (string)obj; } if (denial != null) { RejectSwitch(denial, sourceId, "authorization"); Reply(sender, denial); return; } Sync(initial: false); if (state.Open == open) { return; } if (!CanOperate) { LogBlockedOperation("The panel is still moving or unavailable."); Reply(sender, "The panel is still moving or unavailable."); return; } if (Object.op_Implicit((Object)(object)nativeDoor)) { manualNativeUse = true; try { NativeDoorAdapter.Use((Door)(object)nativeDoor, sender); return; } finally { manualNativeUse = false; } } TogglePanel(sender); } private void EnsureNativeDoor() { if (Object.op_Implicit((Object)(object)nativeDoor) || adapterUnavailable || rig == null || failed) { return; } if (Object.op_Implicit((Object)(object)((Component)this).GetComponent<Door>())) { adapterUnavailable = true; SecretPlugin.Warn("Another mod already supplied a Door on " + ((Object)this).name + "; skipping the Stoneveil adapter."); return; } publishedNativeState = AutomaticCloseRequest.NativeState(state); lastAdapterOwner = view.IsOwner(); if (view.IsOwner()) { view.GetZDO().Set(ZDOVars.s_state, publishedNativeState, false); } nativeDoor = ((Component)this).gameObject.AddComponent<StoneveilDoor>(); ((Door)nativeDoor).m_name = piece.m_name; } private void PublishNativeState() { if (Object.op_Implicit((Object)(object)nativeDoor) && Object.op_Implicit((Object)(object)view) && view.IsValid()) { publishedNativeState = AutomaticCloseRequest.NativeState(state); if (view.IsOwner()) { view.GetZDO().Set(ZDOVars.s_state, publishedNativeState, false); } } } internal void PollNativeState() { if (initialized && Object.op_Implicit((Object)(object)view) && view.IsValid() && Object.op_Implicit((Object)(object)nativeDoor)) { state = new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)); if (lastAdapterOwner != view.IsOwner()) { lastAdapterOwner = view.IsOwner(); automaticClose.Cancel(); PublishNativeState(); } else { ObserveNativeState(view.GetZDO().GetInt(ZDOVars.s_state, 0)); } } } internal void ObserveNativeState(int observed) { if (initialized && Object.op_Implicit((Object)(object)view) && view.IsValid() && Object.op_Implicit((Object)(object)nativeDoor)) { if (AutomaticCloseRequest.AcceptStateWrite(observed, publishedNativeState, view.IsOwner(), state)) { automaticClose.Request(Time.unscaledTime); } PublishNativeState(); } } internal void HandleNativeUse(long sender) { if (initialized && Object.op_Implicit((Object)(object)view) && view.IsValid() && view.IsOwner()) { state = new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)); if (manualNativeUse) { TogglePanel(sender); } else if (AutomaticCloseRequest.AcceptRpc(sender, view.GetZDO().GetOwner(), isOwner: true, state)) { automaticClose.Request(Time.unscaledTime); TryAutomaticClose(); } } } private void TogglePanel(long sender) { bool open = !state.Open; if (!TryCommitOperation(open, out var denial)) { Reply(sender, denial); } } private void TryAutomaticClose() { if (automaticClose.ShouldAttempt(Time.unscaledTime, view.IsOwner(), state)) { TryCommitOperation(open: false, out var _); } } private bool TryCommitOperation(bool open, out string denial) { denial = null; if (!CanOperate) { denial = "The panel is still moving or unavailable."; } else if (!PathClear(open)) { denial = "Someone is in the panel's path; move clear and try again."; } if (denial != null) { LogBlockedOperation(denial); return false; } CommitOperation(state.Apply(DoorCommand.Toggle)); return true; } private void LogBlockedOperation(string reason) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!(Time.unscaledTime < nextBlockedLog)) { nextBlockedLog = Time.unscaledTime + 5f; SecretPlugin.Warn($"Panel operation blocked: {reason}; door={view.GetZDO().m_uid}; " + $"owner={view.GetZDO().GetOwner()}; state={state.Value}; progress={progress:0.000}; " + $"rig={rig != null}; failed={failed}; cooldown={Mathf.Max(0f, nextOperation - Time.unscaledTime):0.000}"); } } private void CommitOperation(DoorState next) { view.GetZDO().Set("com.tomtom.secret.state.v1", next.Value); state = next; automaticClose.Cancel(); nextOperation = Time.unscaledTime + 0.75f + 0.15f; PublishNativeState(); } private bool PathClear(bool open) { if (rig == null) { return false; } try { for (int i = 1; i <= 12; i++) { rig.Apply(kind, state, Mathf.Lerp(progress, open ? 1f : 0f, (float)i / 12f)); Physics.SyncTransforms(); if (rig.ContainsCharacter()) { return false; } } return true; } finally { rig.Apply(kind, state, progress); Physics.SyncTransforms(); } } private void Reply(long sender, string message) { view.InvokeRPC(sender, "Secret_Reply", new object[1] { message }); } private void ReceiveReply(long sender, string message) { if (view.IsValid() && sender == view.GetZDO().GetOwner()) { SecretPlugin.Tell(message); } } public bool Interact(Humanoid user, bool hold, bool alt) { if (!Object.op_Implicit((Object)(object)nativeDoor)) { return InteractPanel(user, hold, alt); } return ((Door)nativeDoor).Interact(user, hold, alt); } internal bool InteractPanel(Humanoid user, bool hold, bool alt) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_011b: 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) if (switchInteraction) { switchPipelineReached = true; if (hold || !initialized || !Object.op_Implicit((Object)(object)view) || !view.IsValid()) { return RejectSwitch("The Stoneveil panel is not initialized for interaction", interactionSwitch, "client"); } Player val = (Player)(object)((user is Player) ? user : null); if (val == null) { return RejectSwitch("The switch user is not a player", interactionSwitch, "client"); } ZDOMan instance = ZDOMan.instance; ZDO val2 = ((instance != null) ? instance.GetZDO(interactionSwitch) : null); string interactionDenialReason = LinkedSwitchAccess.GetInteractionDenialReason(val, val2, view.GetZDO(), switchOpen); if (interactionDenialReason != null) { return RejectSwitch(interactionDenialReason, interactionSwitch, "client"); } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return RejectSwitch("Door access denied by the local ward check", interactionSwitch, "client"); } if (!PrivateArea.CheckAccess(val2.GetPosition(), 0f, true, false)) { return RejectSwitch("Switch access denied by the local ward check", interactionSwitch, "client"); } ZPackage val3 = new ZPackage(); val3.Write(interactionSwitch); val3.Write(switchOpen); view.InvokeRPC("Stoneveil_LinkedSwitch", new object[1] { val3 }); return true; } if (!hold && initialized && view.IsValid() && new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)).Enabled) { Player val4 = (Player)(object)((user is Player) ? user : null); if (val4 != null) { Request(val4, DoorCommand.Toggle); return true; } } return false; } private bool RejectSwitch(string reason, ZDOID sourceId, string stage) { //IL_0045: 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) LastSwitchFailure = reason; ZDO val = ((Object.op_Implicit((Object)(object)view) && view.IsValid()) ? view.GetZDO() : null); SecretPlugin.Warn($"Linked switch denied ({stage}): {reason}; switch={sourceId}; door={val?.m_uid}; " + $"prefab={((val != null) ? new int?(val.GetPrefab()) : ((int?)null))}; owner={((val != null) ? new long?(val.GetOwner()) : ((long?)null))}"); return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverName() { if (!Object.op_Implicit((Object)(object)piece)) { return ""; } return piece.m_name; } public float GetHoverOffset() { return 0f; } public string GetHoverText() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!initialized || !view.IsValid()) { return ""; } DoorState doorState = new DoorState(view.GetZDO().GetInt("com.tomtom.secret.state.v1", 0)); if (!doorState.Enabled || doorState.Concealed) { return ""; } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize("$piece_noaccess"); } return Localization.instance.Localize(piece.m_name + "\n[<color=yellow><b>$KEY_Use</b></color>] " + (doorState.Open ? "$piece_door_close" : "$piece_door_open")); } internal void StructuralPose(bool closed) { rig?.Apply(kind, state, closed ? 0f : progress); } private void OnDestroy() { automaticClose.Cancel(); if (Object.op_Implicit((Object)(object)nativeDoor)) { ((MonoBehaviour)nativeDoor).CancelInvoke(); if (Object.op_Implicit((Object)(object)view)) { view.Unregister("UseDoor"); } Object.Destroy((Object)(object)nativeDoor); } MovingPanels.Remove(this); rig?.Dispose(); if (initialized && Object.op_Implicit((Object)(object)view)) { view.Unregister("Secret_Command"); view.Unregister("Secret_Reply"); view.Unregister("Stoneveil_LinkedSwitch"); } } } [BepInPlugin("com.tomtom.secret", "Stoneveil", "0.4.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class SecretPlugin : BaseUnityPlugin { public const string Guid = "com.tomtom.secret"; public const string Version = "0.4.4"; internal const float Duration = 0.75f; internal static readonly Dictionary<int, PanelKind> Supported = new Dictionary<int, PanelKind>(); internal static SecretPlugin Instance; private Harmony harmony; private ConfigEntry<KeyboardShortcut> convert; private ConfigEntry<KeyboardShortcut> remove; private ConfigEntry<KeyboardShortcut> motion; private ConfigEntry<KeyboardShortcut> reverse; private ConfigEntry<KeyboardShortcut> conceal; private void Awake() { //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown Instance = this; LinkedSwitchRpc.Initialize(); string[] array = new string[5] { "wood_wall_quarter", "wood_wall_half", "woodwall", "stone_wall_2x1", "stone_wall_1x1" }; foreach (string text in array) { Supported[StringExtensionMethods.GetStableHashCode(text)] = PanelKind.Wall; } array = new string[5] { "wood_floor", "wood_floor_1x1", "stone_floor_2x2", "wood_roof", "wood_roof_45" }; foreach (string text2 in array) { Supported[StringExtensionMethods.GetStableHashCode(text2)] = PanelKind.Hatch; } convert = Bind("Convert", (KeyCode)104, (KeyCode)308); remove = Bind("Remove hinge", (KeyCode)104, (KeyCode)306, (KeyCode)308); motion = Bind("Cycle motion", (KeyCode)106, (KeyCode)308); reverse = Bind("Reverse swing", (KeyCode)106, (KeyCode)306, (KeyCode)308); conceal = Bind("Conceal prompt", (KeyCode)107, (KeyCode)308); harmony = new Harmony("com.tomtom.secret"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Stoneveil 0.4.4 loaded. Hammer + Alt+H converts a supported piece."); } private ConfigEntry<KeyboardShortcut> Bind(string name, KeyCode key, params KeyCode[] modifiers) { //IL_000c: 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 ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hammer controls", name, new KeyboardShortcut(key, modifiers), "Used while holding the vanilla hammer and aiming at a supported piece."); } private void Update() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) LinkedSwitchRpc.Update(); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !HasHammer(localPlayer) || !GameAccess.TakeInput(localPlayer) || Hud.IsPieceSelectionVisible()) { return; } DoorCommand? doorCommand = null; KeyboardShortcut value = remove.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { doorCommand = DoorCommand.Remove; } else { value = reverse.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { doorCommand = DoorCommand.Reverse; } else { value = convert.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { doorCommand = DoorCommand.Convert; } else { value = motion.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { doorCommand = DoorCommand.CycleMotion; } else { value = conceal.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { doorCommand = DoorCommand.ToggleConcealment; } } } } } if (doorCommand.HasValue) { Piece hoveringPiece = localPlayer.GetHoveringPiece(); SecretDoor secretDoor = (Object.op_Implicit((Object)(object)hoveringPiece) ? ((Component)hoveringPiece).GetComponent<SecretDoor>() : null); if (!Object.op_Implicit((Object)(object)secretDoor)) { Tell("Aim at a supported wall, floor, or roof piece."); } else { secretDoor.Request(localPlayer, doorCommand.Value); } } } internal static bool HasHammer(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid()) { return component.GetZDO().GetInt(ZDOVars.s_rightItem, 0) == StringExtensionMethods.GetStableHashCode("Hammer"); } return false; } internal static void Tell(string message) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } } internal static void Warn(string message) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)message); } private void OnDestroy() { SecretDoor[] array = Object.FindObjectsByType<SecretDoor>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } Instance = null; } } [HarmonyPatch(typeof(ZNetView), "Awake")] internal static class AttachDoorPatch { private static void Postfix(ZNetView __instance) { if (__instance.IsValid() && SecretPlugin.Supported.ContainsKey(__instance.GetZDO().GetPrefab()) && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<Piece>()) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<SecretDoor>())) { ((Component)__instance).gameObject.AddComponent<SecretDoor>(); } } } internal sealed class StoneStack : IDisposable { private readonly List<(GameObject source, GameObject copy)> objects = new List<(GameObject, GameObject)>(); private readonly Dictionary<Renderer, Renderer> renderers = new Dictionary<Renderer, Renderer>(); private readonly List<(Collider source, Collider copy)> colliders = new List<(Collider, Collider)>(); private readonly List<(LODGroup source, LODGroup copy)> lodGroups = new List<(LODGroup, LODGroup)>(); private readonly List<GameObject> snapPoints = new List<GameObject>(); private readonly MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); internal Transform Upper { get; } internal StoneStack(Transform root, IEnumerable<Transform> lowerParts) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) Upper = new GameObject("Secret_UpperStone").transform; Upper.SetParent(root, false); Vector3 upperOffset = StoneStackLayout.UpperOffset; Upper.localPosition = new Vector3(upperOffset.X, upperOffset.Y, upperOffset.Z); try { foreach (Transform lowerPart in lowerParts) { CopyTree(lowerPart, Upper); } LODGroup component = ((Component)root).GetComponent<LODGroup>(); if (Object.op_Implicit((Object)(object)component)) { lodGroups.Add((component, ((Component)Upper).gameObject.AddComponent<LODGroup>())); } foreach (var lodGroup in lodGroups) { LOD[] lODs = lodGroup.source.GetLODs(); for (int i = 0; i < lODs.Length; i++) { List<Renderer> list = new List<Renderer>(); Renderer[] array = lODs[i].renderers; foreach (Renderer val in array) { if (Object.op_Implicit((Object)(object)val) && renderers.TryGetValue(val, out var value)) { list.Add(value); } } lODs[i].renderers = list.ToArray(); } lodGroup.copy.SetLODs(lODs); lodGroup.copy.localReferencePoint = lodGroup.source.localReferencePoint; lodGroup.copy.size = lodGroup.source.size; lodGroup.copy.fadeMode = lodGroup.source.fadeMode; lodGroup.copy.animateCrossFading = lodGroup.source.animateCrossFading; lodGroup.copy.enabled = lodGroup.source.enabled; } AddSnapPoints(root); SyncVisuals(); } catch { Dispose(); throw; } } private void CopyTree(Transform source, Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown GameObject val = new GameObject(((Object)source).name); val.layer = ((Component)source).gameObject.layer; val.transform.SetParent(parent, false); val.transform.localPosition = source.localPosition; val.transform.localRotation = source.localRotation; val.transform.localScale = source.localScale; objects.Add((((Component)source).gameObject, val)); MeshFilter component = ((Component)source).GetComponent<MeshFilter>(); if (Object.op_Implicit((Object)(object)component)) { val.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; } Renderer[] components = ((Component)source).GetComponents<Renderer>(); foreach (Renderer val2 in components) { if (!(val2 is MeshRenderer)) { throw new InvalidOperationException("This stone wall uses unsupported animated or particle geometry."); } MeshRenderer val3 = val.AddComponent<MeshRenderer>(); ((Renderer)val3).sharedMaterials = val2.sharedMaterials; ((Renderer)val3).shadowCastingMode = val2.shadowCastingMode; ((Renderer)val3).receiveShadows = val2.receiveShadows; ((Renderer)val3).lightProbeUsage = val2.lightProbeUsage; ((Renderer)val3).reflectionProbeUsage = val2.reflectionProbeUsage; ((Renderer)val3).probeAnchor = val2.probeAnchor; renderers.Add(val2, (Renderer)(object)val3); } Collider[] components2 = ((Component)source).GetComponents<Collider>(); foreach (Collider val4 in components2) { if (val4.isTrigger) { continue; } BoxCollider val5 = (BoxCollider)(object)((val4 is BoxCollider) ? val4 : null); Collider val6; if (val5 != null) { BoxCollider obj = val.AddComponent<BoxCollider>(); obj.center = val5.center; obj.size = val5.size; val6 = (Collider)(object)obj; } else { MeshCollider val7 = (MeshCollider)(object)((val4 is MeshCollider) ? val4 : null); if (val7 == null) { throw new InvalidOperationException("This stone wall uses an unsupported collider."); } MeshCollider obj2 = val.AddComponent<MeshCollider>(); obj2.sharedMesh = val7.sharedMesh; obj2.convex = val7.convex; val6 = (Collider)(object)obj2; } val6.sharedMaterial = val4.sharedMaterial; val6.contactOffset = val4.contactOffset; val6.enabled = val4.enabled; colliders.Add((val4, val6)); } LODGroup component2 = ((Component)source).GetComponent<LODGroup>(); if (Object.op_Implicit((Object)(object)component2)) { lodGroups.Add((component2, val.AddComponent<LODGroup>())); } foreach (Transform item in source) { Transform source2 = item; CopyTree(source2, val.transform); } } private void AddSnapPoints(Transform root) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); List<Transform> list2 = new List<Transform>(); foreach (Transform item in root) { Transform val = item; if (((Component)val).CompareTag("snappoint")) { list2.Add(val); list.Add(val.localPosition); } } foreach (Transform item2 in list2) { Vector3 vector = StoneStackLayout.UpperPoint(PanelRig.ToNumerics(item2.localPosition)); Vector3 position = new Vector3(vector.X, vector.Y, vector.Z); if (!list.Exists(delegate(Vector3 other) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references) Vector3 val3 = other - position; return ((Vector3)(ref val3)).sqrMagnitude < 0.0001f; })) { GameObject val2 = new GameObject("Secret_UpperSnap"); val2.transform.SetParent(root, false); val2.transform.localPosition = position; val2.transform.localRotation = item2.localRotation; val2.tag = "snappoint"; snapPoints.Add(val2); list.Add(position); } } } internal void SyncVisuals() { foreach (var @object in objects) { if (Object.op_Implicit((Object)(object)@object.source) && Object.op_Implicit((Object)(object)@object.copy) && @object.copy.activeSelf != @object.source.activeSelf) { @object.copy.SetActive(@object.source.activeSelf); } } foreach (KeyValuePair<Renderer, Renderer> renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer.Key) && Object.op_Implicit((Object)(object)renderer.Value)) { renderer.Value.enabled = renderer.Key.enabled; renderer.Value.sharedMaterials = renderer.Key.sharedMaterials; renderer.Key.GetPropertyBlock(propertyBlock); renderer.Value.SetPropertyBlock(propertyBlock); } } foreach (var collider in colliders) { if (Object.op_Implicit((Object)(object)collider.source) && Object.op_Implicit((Object)(object)collider.copy)) { collider.copy.enabled = collider.source.enabled; } } } internal static void RemoveTemporary(GameObject target) { if (Object.op_Implicit((Object)(object)target)) { target.SetActive(false); target.transform.SetParent((Transform)null, false); Object.Destroy((Object)(object)target); } } public void Dispose() { foreach (GameObject snapPoint in snapPoints) { RemoveTemporary(snapPoint); } snapPoints.Clear(); if (Object.op_Implicit((Object)(object)Upper)) { RemoveTemporary(((Component)Upper).gameObject); } } } internal static class StoneStackLayout { internal const string PrefabName = "stone_wall_2x1"; internal static Vector3 UpperOffset => Vector3.UnitY; internal static Vector3 UpperPoint(Vector3 lowerPoint) { return lowerPoint + UpperOffset; } } [HarmonyPatch(typeof(WearNTear), "UpdateSupport")] internal static class SupportPatch { private static void Prefix(out bool __state) { __state = SecretDoor.MovingPanels.Count != 0; if (!__state) { return; } foreach (SecretDoor movingPanel in SecretDoor.MovingPanels) { movingPanel.StructuralPose(closed: true); } Physics.SyncTransforms(); } private static void Finalizer(bool __state) { if (!__state) { return; } foreach (SecretDoor movingPanel in SecretDoor.MovingPanels) { movingPanel.StructuralPose(closed: false); } Physics.SyncTransforms(); } } }