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 ExploredMapTeleport v0.3.0
plugins/Valheim.MapTeleport.dll
Decompiled 3 days agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("KenJorissen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0")] [assembly: AssemblyProduct("Valheim.MapTeleport")] [assembly: AssemblyTitle("Valheim.MapTeleport")] [assembly: AssemblyVersion("0.3.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ValheimMapTeleport { internal static class DestinationPolicy { internal static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } internal static bool IsValidPoint(float x, float z, float radius) { if (IsFinite(x) && IsFinite(z) && IsFinite(radius) && radius > 0f) { return (double)x * (double)x + (double)z * (double)z < (double)radius * (double)radius; } return false; } internal static bool IsSafeTerrain(float height, float waterLevel, float normalY, float maxSlope, float maxWaterDepth = 0f) { if (IsFinite(height) && IsFinite(waterLevel) && IsFinite(normalY) && normalY >= -1f && normalY <= 1f && IsFinite(maxSlope) && maxSlope >= 0f && maxSlope < 90f && IsFinite(maxWaterDepth) && maxWaterDepth >= 0f && ((maxWaterDepth == 0f) ? (height > waterLevel + 0.3f) : (height >= waterLevel - maxWaterDepth))) { return normalY >= (float)Math.Cos((double)maxSlope * Math.PI / 180.0); } return false; } } [BepInPlugin("kenjorissen.mods.exploredmapteleport", "Explored Map Teleport", "0.3.0")] public sealed class MapTeleportPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Minimap), "Start")] private static class MapStartPatch { private static void Postfix(Minimap __instance) { Instance?.CreateToggle(__instance); } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] private static class MapClickPatch { private static bool Prefix(Minimap __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 MapTeleportPlugin instance = Instance; if ((Object)(object)instance == (Object)null || !instance.enabledSetting.Value || !instance.armed || (int)__instance.m_mode != 2) { return true; } instance.RequestTeleport(__instance); return false; } } [HarmonyPatch(typeof(Minimap), "OnMapDblClick")] private static class MapDoubleClickPatch { private static bool Prefix() { if (!((Object)(object)Instance == (Object)null)) { if (!Instance.armed) { return !Object.op_Implicit((Object)(object)Instance.activePlayer); } return false; } return true; } } [HarmonyPatch(typeof(Minimap), "SetMapMode")] private static class MapModePatch { private static void Postfix(Minimap __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.m_mode != 2) { Instance?.SetArmed(value: false); } } } [HarmonyPatch(typeof(Player), "UpdateTeleport")] private static class TeleportPatch { private static void Prefix(Player __instance) { MapTeleportPlugin instance = Instance; if ((Object)(object)instance == (Object)null) { return; } try { instance.ValidateBeforeArrival(__instance); if ((Object)(object)instance.activePlayer == (Object)(object)__instance && ((Character)__instance).IsTeleporting() && !instance.validated && !instance.returning) { TeleportTimer.Invoke(__instance) = Mathf.Min(TeleportTimer.Invoke(__instance), 4f); } } catch (Exception ex) { ((BaseUnityPlugin)instance).Logger.LogError((object)("Landing validation failed: " + ex)); if ((Object)(object)instance.activePlayer == (Object)(object)__instance && !instance.returning) { instance.ReturnToOrigin(__instance, "Could not verify a safe landing."); } } } private static void Postfix(Player __instance) { MapTeleportPlugin instance = Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.activePlayer != (Object)(object)__instance) && !((Character)__instance).IsTeleporting()) { Tell(__instance, instance.returning ? "Map teleport cancelled; returned to the starting point." : "Map teleport complete."); ((BaseUnityPlugin)instance).Logger.LogInfo((object)(instance.returning ? "Map teleport returned to origin." : "Map teleport complete.")); instance.activePlayer = null; instance.activeWorld = null; instance.activeMap = null; } } } public const string PluginGuid = "kenjorissen.mods.exploredmapteleport"; public const string PluginName = "Explored Map Teleport"; public const string PluginVersion = "0.3.0"; private static MapTeleportPlugin? Instance; private static readonly Func<Minimap, Vector3, Vector3> ScreenToWorld = AccessTools.MethodDelegate<Func<Minimap, Vector3, Vector3>>(AccessTools.Method(typeof(Minimap), "ScreenToWorldPoint", (Type[])null, (Type[])null), (object)null, true); private static readonly Func<Minimap, Vector3, bool> IsExplored = AccessTools.MethodDelegate<Func<Minimap, Vector3, bool>>(AccessTools.Method(typeof(Minimap), "IsExplored", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef<Player, Vector3> TargetPosition = AccessTools.FieldRefAccess<Player, Vector3>("m_teleportTargetPos"); private static readonly FieldRef<Player, Quaternion> TargetRotation = AccessTools.FieldRefAccess<Player, Quaternion>("m_teleportTargetRot"); private static readonly FieldRef<Player, float> TeleportTimer = AccessTools.FieldRefAccess<Player, float>("m_teleportTimer"); private ConfigEntry<bool> enabledSetting; private ConfigEntry<float> maxSlope; private ConfigEntry<float> maxRadius; private ConfigEntry<float> maxWaterDepth; private ConfigEntry<bool> searchNearby; private ConfigEntry<float> innerRadius; private ConfigEntry<float> outerRadius; private Harmony? harmony; private Toggle? mapToggle; private bool armed; private Player? activePlayer; private WorldGenerator? activeWorld; private Minimap? activeMap; private Vector3 origin; private Quaternion originRotation; private Vector3 requested; private float startedAt; private float nextLandingCheck; private bool validated; private bool returning; private int obstructionMask; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Expected O, but got Unknown Instance = this; enabledSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Show the map teleport toggle. The toggle itself always starts OFF."); maxSlope = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MaximumSlopeDegrees", 55f, new ConfigDescription("Maximum landing slope. Steeper ground may cause sliding; existing configured values are retained.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 70f), Array.Empty<object>())); maxRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MaximumWorldRadius", 10000f, new ConfigDescription("Reject destinations at/beyond this radius. Increase only for an expanded world.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 100000f), Array.Empty<object>())); maxWaterDepth = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "MaximumWaterDepthMetres", 1f, new ConfigDescription("Maximum water depth above the terrain, measured against the mean water level. Waves may be deeper. Zero restores the original dry-land margin.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); searchNearby = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "SearchNearby", true, "If the clicked point is unsafe, try eight directions on each of two nearby rings. Every centre must be explored and pass all safety checks."); innerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "InnerSearchRadiusMetres", 4f, new ConfigDescription("First search ring radius. The smaller configured radius is always tried first.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 16f), Array.Empty<object>())); outerRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Safety", "OuterSearchRadiusMetres", 8f, new ConfigDescription("Second search ring radius. Two distinct radii give at most 16 alternatives.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 16f), Array.Empty<object>())); obstructionMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "piece", "terrain", "vehicle", "character" }); harmony = new Harmony("kenjorissen.mods.exploredmapteleport"); harmony.PatchAll(typeof(MapTeleportPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Explored Map Teleport v0.3.0 loaded. Map toggle starts OFF; no XPortalNetworks dependency."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Landing settings: slope={maxSlope.Value:0.#} degrees, water depth={maxWaterDepth.Value:0.#}m, nearby={searchNearby.Value}, rings={innerRadius.Value:0.#}m/{outerRadius.Value:0.#}m."); } private void OnDestroy() { Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } if (Object.op_Implicit((Object)(object)mapToggle)) { Object.Destroy((Object)(object)((Component)mapToggle).gameObject); } Instance = null; } private void Update() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)mapToggle)) { ((Component)mapToggle).gameObject.SetActive(enabledSetting.Value); } if (!enabledSetting.Value || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)Minimap.instance) || (int)Minimap.instance.m_mode != 2) { SetArmed(value: false); } if (activePlayer != null && (!Object.op_Implicit((Object)(object)activePlayer) || (Object)(object)activePlayer != (Object)(object)Player.m_localPlayer || activeWorld != WorldGenerator.instance || activeMap != Minimap.instance)) { activePlayer = null; activeWorld = null; activeMap = null; } } private void CreateToggle(Minimap map) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00f8: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)mapToggle)) { Object.Destroy((Object)(object)((Component)mapToggle).gameObject); } if (!Object.op_Implicit((Object)(object)map.m_publicPosition)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Cannot add map toggle: vanilla public-position toggle is missing."); return; } mapToggle = Object.Instantiate<Toggle>(map.m_publicPosition, ((Component)map.m_publicPosition).transform.parent); ((Object)mapToggle).name = "ExploredMapTeleportToggle"; mapToggle.group = null; mapToggle.onValueChanged = new ToggleEvent(); Localize[] componentsInChildren = ((Component)mapToggle).GetComponentsInChildren<Localize>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } TMP_Text[] componentsInChildren2 = ((Component)mapToggle).GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].text = "Map teleport (explored)"; } RectTransform val = (RectTransform)((Component)mapToggle).transform; val.anchoredPosition += new Vector2(0f, 40f); mapToggle.SetIsOnWithoutNotify(false); ((UnityEvent<bool>)(object)mapToggle.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value) { armed = enabledSetting.Value && value; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Map teleport toggle " + (armed ? "ON" : "OFF"))); }); armed = false; ((Component)mapToggle).gameObject.SetActive(enabledSetting.Value); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Map teleport toggle added to standard map."); } private void SetArmed(bool value) { armed = value; if (Object.op_Implicit((Object)(object)mapToggle) && mapToggle.isOn != value) { mapToggle.SetIsOnWithoutNotify(value); } } private static void Tell(Player player, string message) { ((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false); } private void RequestTeleport(Minimap map) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } if (Object.op_Implicit((Object)(object)activePlayer) || ((Character)localPlayer).IsTeleporting()) { Tell(localPlayer, "A teleport is already in progress."); } else if (((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).InInterior() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).IsAttachedToShip() || localPlayer.GetDoodadController() != null) { Tell(localPlayer, "Map teleport is unavailable in your current state."); } else { if (WorldGenerator.instance == null || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } Vector3 val = ScreenToWorld(map, ZInput.pointerPosition); if (!DestinationPolicy.IsValidPoint(val.x, val.z, maxRadius.Value) || !IsExplored(map, val)) { Tell(localPlayer, "Choose an explored location inside the world boundary."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rejected map teleport: unexplored or out-of-bounds destination."); return; } if (!((Humanoid)localPlayer).IsTeleportable(false)) { Tell(localPlayer, "Your inventory contains items that cannot be teleported."); return; } if (!TryLoadingPosition(map, val, out var position)) { Tell(localPlayer, "No suitable ground or shallow water at that point or nearby."); return; } origin = ((Component)localPlayer).transform.position; originRotation = ((Component)localPlayer).transform.rotation; if (!((Character)localPlayer).TeleportTo(position, originRotation, true)) { Tell(localPlayer, "Teleport unavailable; wait a moment and try again."); return; } requested = val; activePlayer = localPlayer; activeWorld = WorldGenerator.instance; activeMap = map; startedAt = Time.realtimeSinceStartup; nextLandingCheck = startedAt; validated = false; returning = false; SetArmed(value: false); map.SetMapMode((MapMode)1); Tell(localPlayer, "Loading destination and checking the landing..."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Map teleport requested: ({val.x:0.0}, {val.z:0.0})."); } } private bool EligibleCentre(Minimap map, Vector3 point) { //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_0024: Unknown result type (might be due to invalid IL or missing references) if (DestinationPolicy.IsValidPoint(point.x, point.z, maxRadius.Value)) { return IsExplored(map, point); } return false; } private bool TryLoadingPosition(Minimap map, Vector3 centre, out Vector3 position) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //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: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Vector3 selected = Vector3.zero; LandingResult num = NearbyLandingSearch.Find(centre.x, centre.z, searchNearby.Value, innerRadius.Value, outerRadius.Value, delegate(float x, float z) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(x, 0f, z); if (!EligibleCentre(map, val)) { return LandingResult.Rejected; } float num2 = WorldGenerator.instance.GetHeight(x, z); float num3 = default(float); if (ZoneSystem.instance.GetGroundHeight(val, ref num3)) { num2 = num3; } if (!DestinationPolicy.IsSafeTerrain(num2, ZoneSystem.instance.m_waterLevel, 1f, maxSlope.Value, maxWaterDepth.Value) || ZoneSystem.IsLavaPreHeightmap(val, 0.6f)) { return LandingResult.Rejected; } selected = new Vector3(x, Mathf.Max(num2, ZoneSystem.instance.m_waterLevel) + 2f, z); return LandingResult.Found; }); position = selected; return num == LandingResult.Found; } private LandingResult CheckLanding(Player player, Vector3 candidate, out Vector3 landing) { //IL_0001: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) landing = candidate; if (!Object.op_Implicit((Object)(object)Minimap.instance) || !EligibleCentre(Minimap.instance, candidate)) { return LandingResult.Rejected; } if (!ZNetScene.instance.IsAreaReady(candidate) || !ZoneSystem.instance.IsZoneLoaded(candidate)) { return LandingResult.WaitingForLoad; } Vector3 val = default(Vector3); Biome val2 = default(Biome); BiomeArea val3 = default(BiomeArea); Heightmap val4 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref landing, ref val, ref val2, ref val3, ref val4); if (!Object.op_Implicit((Object)(object)val4) || !DestinationPolicy.IsSafeTerrain(landing.y, ZoneSystem.instance.m_waterLevel, val.y, maxSlope.Value, maxWaterDepth.Value) || ZoneSystem.instance.IsLava(landing, true)) { return LandingResult.Rejected; } landing.y += 0.3f; Collider[] array = Physics.OverlapCapsule(landing + Vector3.up * 0.5f, landing + Vector3.up * 1.6f, 0.35f, obstructionMask, (QueryTriggerInteraction)1); foreach (Collider val5 in array) { if (Object.op_Implicit((Object)(object)val5) && !((Component)val5).transform.IsChildOf(((Component)player).transform)) { return LandingResult.Rejected; } } return LandingResult.Found; } private void ValidateBeforeArrival(Player player) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)(object)activePlayer || !((Character)player).IsTeleporting() || validated || returning) { return; } if (activeWorld != WorldGenerator.instance || activeMap != Minimap.instance) { activePlayer = null; activeWorld = null; activeMap = null; return; } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - startedAt > 25f) { ReturnToOrigin(player, "Destination loading timed out."); } else { if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)ZoneSystem.instance) || realtimeSinceStartup < nextLandingCheck) { return; } nextLandingCheck = realtimeSinceStartup + 0.1f; Vector3 selected = Vector3.zero; switch (NearbyLandingSearch.Find(requested.x, requested.z, searchNearby.Value, innerRadius.Value, outerRadius.Value, delegate(float x, float z) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Vector3 landing; LandingResult num2 = CheckLanding(player, new Vector3(x, 0f, z), out landing); if (num2 == LandingResult.Found) { selected = landing; } return num2; })) { case LandingResult.WaitingForLoad: break; default: ReturnToOrigin(player, "No safe explored landing at that point or nearby."); break; case LandingResult.Found: { TargetPosition.Invoke(player) = selected; validated = true; float num = Vector2.Distance(new Vector2(requested.x, requested.z), new Vector2(selected.x, selected.z)); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Landing validated at ({selected.x:0.0}, {selected.y:0.0}, {selected.z:0.0}); nearby offset={num:0.0}m."); break; } } } } private void ReturnToOrigin(Player player, string reason) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) TargetPosition.Invoke(player) = origin; TargetRotation.Invoke(player) = originRotation; TeleportTimer.Invoke(player) = 0f; returning = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)(reason + " Returning to the starting point.")); Tell(player, reason + " Returning to your starting point."); } } internal enum LandingResult { Rejected, WaitingForLoad, Found } internal static class NearbyLandingSearch { private const float Diagonal = 0.70710677f; private static readonly float[] X = new float[8] { 1f, 0.70710677f, 0f, -0.70710677f, -1f, -0.70710677f, 0f, 0.70710677f }; private static readonly float[] Z = new float[8] { 0f, 0.70710677f, 1f, 0.70710677f, 0f, -0.70710677f, -1f, -0.70710677f }; internal static int CandidateCount(bool nearby, float radiusA, float radiusB) { if (!nearby || !DestinationPolicy.IsFinite(radiusA) || !DestinationPolicy.IsFinite(radiusB) || radiusA <= 0f || radiusB <= 0f) { return 1; } if (radiusA != radiusB) { return 17; } return 9; } internal static bool Offset(int index, bool nearby, float radiusA, float radiusB, out float x, out float z) { x = (z = 0f); int num = CandidateCount(nearby, radiusA, radiusB); if (index < 0 || index >= num) { return false; } if (index == 0) { return true; } float num2 = ((index <= 8) ? Math.Min(radiusA, radiusB) : Math.Max(radiusA, radiusB)); int num3 = (index - 1) % 8; x = X[num3] * num2; z = Z[num3] * num2; return true; } internal static LandingResult Find(float originX, float originZ, bool nearby, float radiusA, float radiusB, Func<float, float, LandingResult> check) { if (!DestinationPolicy.IsFinite(originX) || !DestinationPolicy.IsFinite(originZ)) { return LandingResult.Rejected; } bool flag = false; int num = CandidateCount(nearby, radiusA, radiusB); for (int i = 0; i < num; i++) { Offset(i, nearby, radiusA, radiusB, out var x, out var z); LandingResult landingResult = check(originX + x, originZ + z); switch (landingResult) { case LandingResult.Found: return landingResult; case LandingResult.WaitingForLoad: flag = true; break; } } if (!flag) { return LandingResult.Rejected; } return LandingResult.WaitingForLoad; } } }