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 TownPortal v1.0.40
plugins/TownPortal.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using TownPortal.Runic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("TownPortal")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Open a blue wood portal back to your bed.")] [assembly: AssemblyFileVersion("1.0.40.0")] [assembly: AssemblyInformationalVersion("1.0.40")] [assembly: AssemblyProduct("TownPortal")] [assembly: AssemblyTitle("TownPortal")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = "")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.40.0")] [module: UnverifiableCode] [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 TownPortal { public class ArrivalGuard : MonoBehaviour { private Vector3 _pos; private Quaternion _rot; private float _correctAfter; private float _until; private string _totemKey; private bool _snapped; private float _totemSeen; private float _resnapUntil; private int _resnaps; public void Arm(Vector3 pos, float yaw) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Arm(pos, yaw, null); } public void Arm(Vector3 pos, float yaw, string totemKey) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) _pos = pos; _rot = Quaternion.Euler(0f, yaw, 0f); _correctAfter = Time.time + 2.2f; _until = Time.time + 12f; _totemKey = (string.IsNullOrEmpty(totemKey) ? null : totemKey); _snapped = false; _totemSeen = -1f; _resnaps = 0; if (_totemKey != null) { _until = Time.time + 30f; } } private void TotemStep() { //IL_00d6: 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_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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0148: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { Object.Destroy((Object)(object)this); } else { if (((Character)localPlayer).IsTeleporting()) { return; } if (!RunicApi.TryGetLoadedTotem(_totemKey, out var totem, out var attached)) { _totemSeen = -1f; return; } if (_totemSeen < 0f) { _totemSeen = Time.time; } float num = Time.time - _totemSeen; if (!_snapped) { if (!(num < (attached ? 0.5f : 1.5f))) { if (RunicApi.TryGetDeckPoint(_totemKey, out var point)) { Place(localPlayer, point); } _snapped = true; _resnapUntil = Time.time + 6f; } } else if (Time.time > _resnapUntil || _resnaps >= 3) { Object.Destroy((Object)(object)this); } else { Vector3 position = ((Component)localPlayer).transform.position; Vector3 position2 = totem.position; Vector2 val = new Vector2(position.x - position2.x, position.z - position2.z); if (((Vector2)(ref val)).sqrMagnitude < 400f && (((Character)localPlayer).InWater() || position.y < position2.y - 1.5f) && RunicApi.TryGetDeckPoint(_totemKey, out var point2)) { Place(localPlayer, point2); _resnaps++; } } } } private static void Place(Player player, Vector3 point) { //IL_0006: 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_002c: Unknown result type (might be due to invalid IL or missing references) ((Component)player).transform.position = point; if ((Object)(object)((Character)player).m_body != (Object)null) { ((Character)player).m_body.position = point; ((Character)player).m_body.linearVelocity = Vector3.zero; } } private void LateUpdate() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) if (Time.time > _until) { Object.Destroy((Object)(object)this); } else if (_totemKey != null) { TotemStep(); } else { if (Time.time < _correctAfter) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Vector3 position = ((Component)localPlayer).transform.position; bool num = position.y > 3000f && _pos.y < 3000f; bool flag = _pos.y < 3000f && position.y > _pos.y + 8f; if (num || flag) { ((Component)localPlayer).transform.position = _pos; ((Component)localPlayer).transform.rotation = _rot; if ((Object)(object)((Character)localPlayer).m_body != (Object)null) { ((Character)localPlayer).m_body.linearVelocity = Vector3.zero; } } } } } internal static class BookArt { private sealed class Maps { public Texture2D Albedo; public Texture2D Normal; public Texture2D Metal; public Texture2D Emission; } private static Mesh _mesh; private static Material _blueMat; private static Material _greyMat; private static Sprite _blueIcon; private static Sprite _greyIcon; private static Maps _tomeMaps; private static Maps _mysteriousMaps; public static Sprite Icon(bool restored) { if (restored) { if ((Object)(object)_blueIcon == (Object)null) { _blueIcon = MakeIcon(restored: true); } return _blueIcon; } if ((Object)(object)_greyIcon == (Object)null) { _greyIcon = MakeIcon(restored: false); } return _greyIcon; } public static bool Attach(GameObject prefab, bool restored) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0099: 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_00b5: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return false; } Mesh val = BookMesh(); Material val2 = BookMaterial(restored); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } Transform val3 = prefab.transform.Find("attach"); if ((Object)(object)val3 == (Object)null) { GameObject val4 = new GameObject("attach"); val4.transform.SetParent(prefab.transform, false); val3 = val4.transform; } Transform val5 = val3.Find("attachobj"); GameObject val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).gameObject : ((Component)val3).gameObject); val3.localPosition = Vector3.zero; val3.localRotation = Quaternion.identity; val3.localScale = Vector3.one; val6.transform.localPosition = Vector3.zero; val6.transform.localRotation = Quaternion.identity; val6.transform.localScale = Vector3.one; val6.layer = prefab.layer; MeshFilter val7 = val6.GetComponent<MeshFilter>(); if ((Object)(object)val7 == (Object)null) { val7 = val6.AddComponent<MeshFilter>(); } val7.sharedMesh = val; MeshRenderer val8 = val6.GetComponent<MeshRenderer>(); if ((Object)(object)val8 == (Object)null) { val8 = val6.AddComponent<MeshRenderer>(); } ((Renderer)val8).sharedMaterial = val2; ((Renderer)val8).enabled = true; ((Renderer)val8).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val8).receiveShadows = true; Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val9 in componentsInChildren) { if (!((Object)(object)val9 == (Object)(object)val8)) { val9.enabled = false; } } BoxCollider component = prefab.GetComponent<BoxCollider>(); if ((Object)(object)component != (Object)null) { component.center = new Vector3(0f, 0.034f, 0f); component.size = new Vector3(0.185f, 0.068f, 0.252f); } return true; } private static Mesh BookMesh() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_mesh != (Object)null) { return _mesh; } byte[] array = Resource("TownPortal.BookArt.mesh.bin"); if (array == null || array.Length < 12 || array[0] != 84 || array[1] != 77 || array[2] != 66 || array[3] != 49) { Plugin.Log.LogError((object)"The leather tome mesh is missing from the plugin."); return null; } int num = BitConverter.ToInt32(array, 4); int num2 = BitConverter.ToInt32(array, 8); int offset = 12; int num3 = offset + num * 32 + num2 * 2; if (num <= 0 || num2 <= 0 || array.Length < num3) { Plugin.Log.LogError((object)"The leather tome mesh is incomplete."); return null; } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector3[] array3 = (Vector3[])(object)new Vector3[num]; Vector2[] array4 = (Vector2[])(object)new Vector2[num]; for (int i = 0; i < num; i++) { array2[i] = new Vector3(ReadFloat(array, ref offset), ReadFloat(array, ref offset), ReadFloat(array, ref offset)); } for (int j = 0; j < num; j++) { array3[j] = new Vector3(ReadFloat(array, ref offset), ReadFloat(array, ref offset), ReadFloat(array, ref offset)); } for (int k = 0; k < num; k++) { array4[k] = new Vector2(ReadFloat(array, ref offset), ReadFloat(array, ref offset)); } int[] array5 = new int[num2]; for (int l = 0; l < num2; l++) { array5[l] = BitConverter.ToUInt16(array, offset); offset += 2; } _mesh = new Mesh { name = "TownPortal_Tome" }; _mesh.vertices = MirrorX(array2); _mesh.normals = MirrorX(array3); _mesh.uv = array4; _mesh.triangles = array5; _mesh.RecalculateTangents(); Color32[] array6 = (Color32[])(object)new Color32[num]; for (int m = 0; m < num; m++) { array6[m] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); } _mesh.colors32 = array6; return _mesh; } private static Material BookMaterial(bool restored) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) if (restored && (Object)(object)_blueMat != (Object)null) { return _blueMat; } if (!restored && (Object)(object)_greyMat != (Object)null) { return _greyMat; } Shader val = Shader.Find("Custom/Creature"); if ((Object)(object)val == (Object)null) { val = Cache.GetPrefab<Shader>("Custom/Creature"); } if ((Object)(object)val == (Object)null || ((Object)val).name.Contains("Error")) { Plugin.Log.LogError((object)"Custom/Creature was not available. The tome keeps the amber model."); return null; } if (!EnsureTextures(restored)) { return null; } Maps maps = (restored ? _tomeMaps : _mysteriousMaps); Material val2 = new Material(val); ((Object)val2).name = (restored ? "TownPortal_Tome_Mat" : "TownPortal_MysteriousTome_Mat"); val2.shader = val; StripTint(val2); SetFloat(val2, "_Metallic", 0f); SetFloat(val2, "_MetalGloss", 0f); SetFloat(val2, "_Glossiness", 0.15f); SetFloat(val2, "_UseGlossmap", 1f); SetFloat(val2, "_BumpScale", 0.6f); SetFloat(val2, "_Cull", 0f); SetFloat(val2, "_TwoSidedNormals", 1f); if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.white); } val2.SetTexture("_MainTex", (Texture)(object)maps.Albedo); val2.SetTexture("_BumpMap", (Texture)(object)maps.Normal); val2.EnableKeyword("_NORMALMAP"); val2.EnableKeyword("_TWOSIDEDNORMALS_ON"); val2.SetTexture("_MetallicGlossMap", (Texture)(object)maps.Metal); val2.EnableKeyword("_METALLICGLOSSMAP"); val2.EnableKeyword("_USEGLOSSMAP_ON"); val2.SetTexture("_EmissionMap", (Texture)(object)maps.Emission); if (restored) { if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", new Color(0.7f, 1.7f, 2f)); } val2.EnableKeyword("_EMISSION"); } else { if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", Color.black); } val2.DisableKeyword("_EMISSION"); } Texture texture = val2.GetTexture("_MainTex"); Plugin.Log.LogInfo((object)(((Object)val2).name + " shader=" + ((Object)val2.shader).name + " main=" + (((Object)(object)texture != (Object)null) ? ((Object)texture).name : "null") + " metallic=" + (val2.HasProperty("_Metallic") ? val2.GetFloat("_Metallic").ToString("0.00") : "?"))); if (restored) { _blueMat = val2; } else { _greyMat = val2; } return val2; } private static void StripTint(Material mat) { Shader shader = mat.shader; int propertyCount = shader.GetPropertyCount(); for (int i = 0; i < propertyCount; i++) { string propertyName = shader.GetPropertyName(i); switch (propertyName) { case "_Hue": case "_Saturation": case "_Value": case "_UseStyles": case "_Style": case "_NoiseGlowEnabled": mat.SetFloat(propertyName, 0f); break; } } mat.DisableKeyword("_USESTYLES_ON"); mat.DisableKeyword("NOISEGLOW"); } private static Sprite MakeIcon(bool restored) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture(restored ? "TownPortal.BookArt.tome_icon.png" : "TownPortal.BookArt.mysterious_icon.png", mipmap: false); if ((Object)(object)val == (Object)null) { return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).name = (restored ? "TownPortal_Tome_icon" : "TownPortal_MysteriousTome_icon"); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).width); } private static bool EnsureTextures(bool restored) { if (restored && _tomeMaps != null) { return true; } if (!restored && _mysteriousMaps != null) { return true; } string text = (restored ? "tome" : "mysterious"); Texture2D val = LoadTexture("TownPortal.BookArt." + text + "_albedo.png", mipmap: true); Texture2D val2 = LoadTexture("TownPortal.BookArt." + text + "_normal.png", mipmap: true, linear: true); Texture2D val3 = LoadTexture("TownPortal.BookArt." + text + "_metal.png", mipmap: true, linear: true); Texture2D val4 = LoadTexture("TownPortal.BookArt." + text + "_emission.png", mipmap: true); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { Plugin.Log.LogError((object)("The " + text + " tome textures are missing from the plugin.")); return false; } PackNormal(val2); Crisp((Texture)(object)val); Crisp((Texture)(object)val2); Crisp((Texture)(object)val3); Crisp((Texture)(object)val4); ((Object)val).name = (restored ? "TownPortal_Tome_Albedo" : "TownPortal_MysteriousTome_Albedo"); ((Object)val2).name = (restored ? "TownPortal_Tome_Normal" : "TownPortal_MysteriousTome_Normal"); ((Object)val3).name = (restored ? "TownPortal_Tome_MetallicSmoothness" : "TownPortal_MysteriousTome_MetallicSmoothness"); ((Object)val4).name = (restored ? "TownPortal_Tome_Emission" : "TownPortal_MysteriousTome_Emission"); Maps maps = new Maps { Albedo = val, Normal = val2, Metal = val3, Emission = val4 }; if (restored) { _tomeMaps = maps; } else { _mysteriousMaps = maps; } return true; } private static void SetFloat(Material mat, string name, float value) { if (mat.HasProperty(name)) { mat.SetFloat(name, value); } } private static void PackNormal(Texture2D tex) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) Color32[] pixels = tex.GetPixels32(); for (int i = 0; i < pixels.Length; i++) { Color32 val = pixels[i]; byte r = val.r; byte g = val.g; val.r = byte.MaxValue; val.g = g; val.b = byte.MaxValue; val.a = r; pixels[i] = val; } tex.SetPixels32(pixels); tex.Apply(true, false); } private static Texture2D LoadTexture(string resource, bool mipmap, bool linear = false) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown byte[] array = Resource(resource); if (array == null) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, mipmap, linear); if (!LoadPng(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Object)val).name = resource; return val; } private static bool LoadPng(Texture2D tex, byte[] bytes) { try { return ImageConversion.LoadImage(tex, bytes); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not decode the leather tome art. " + ex.Message)); return false; } } private static float ReadFloat(byte[] bytes, ref int offset) { float result = BitConverter.ToSingle(bytes, offset); offset += 4; return result; } private static void Crisp(Texture tex) { if (!((Object)(object)tex == (Object)null)) { tex.filterMode = (FilterMode)0; tex.wrapMode = (TextureWrapMode)1; tex.anisoLevel = 0; } } private static Vector3[] MirrorX(Vector3[] values) { for (int i = 0; i < values.Length; i++) { values[i].x = 0f - values[i].x; } return values; } private static byte[] Resource(string name) { Stream manifestResourceStream = typeof(BookArt).Assembly.GetManifestResourceStream(name); if (manifestResourceStream == null) { return null; } using (manifestResourceStream) { byte[] array = new byte[manifestResourceStream.Length]; int i; int num; for (i = 0; i < array.Length; i += num) { num = manifestResourceStream.Read(array, i, array.Length - i); if (num <= 0) { break; } } return (i == array.Length) ? array : null; } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class ClearCommand { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Postfix>b__0_0(ConsoleEventArgs args) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { args.Context.AddString("Not in a world."); } else if (ZNet.instance.IsServer()) { int num = PortalService.ClearWorld(); args.Context.AddString("Cleared " + num + " town portal objects and the old map markers. Save the world once so they stay gone."); } else if (!Net.EnsureReady()) { args.Context.AddString("Not connected."); } else { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "TownPortal_Clear", new object[1] { (object)new ZPackage() }); args.Context.AddString("Asked the server to clear town portals and the old map markers. Save once after it finishes."); } } } private static void Postfix() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { args.Context.AddString("Not in a world."); } else if (ZNet.instance.IsServer()) { int num = PortalService.ClearWorld(); args.Context.AddString("Cleared " + num + " town portal objects and the old map markers. Save the world once so they stay gone."); } else if (!Net.EnsureReady()) { args.Context.AddString("Not connected."); } else { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "TownPortal_Clear", new object[1] { (object)new ZPackage() }); args.Context.AddString("Asked the server to clear town portals and the old map markers. Save once after it finishes."); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("townportal_clear", "Destroy every town portal and clear the tome cooldown.", (ConsoleEvent)obj, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } internal static class Content { public const string MysteriousName = "TownPortal_MysteriousTome"; public const string TomeName = "TownPortal_Tome"; public const string DoorName = "TownPortal_Door"; public const string GateName = "TownPortal_ReturnGate"; public const string SeHome = "SE_NowhereLikeHome"; public const string SeRest = "SE_TomeRests"; private static bool _built; private static SharedData _tomeShared; private static StatusEffect _seHome; private static StatusEffect _seRest; private static readonly Dictionary<string, bool> ChestLog = new Dictionary<string, bool>(); public static void Build() { //IL_003f: 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_006d: 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) //IL_00b8: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_0125: 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_0135: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown if (!_built) { _built = true; PrefabManager.OnVanillaPrefabsAvailable -= Build; Sprite val = Icons.Book(new Color(0.45f, 0.28f, 0.16f), new Color(0.75f, 0.62f, 0.42f)); Sprite val2 = Icons.Book(new Color(0.1f, 0.18f, 0.38f), new Color(0.45f, 0.75f, 1f)); Sprite val3 = BookArt.Icon(restored: true); Sprite val4 = BookArt.Icon(restored: false); Sprite val5 = (((Object)(object)val3 != (Object)null) ? val3 : val2); Sprite val6 = (((Object)(object)val4 != (Object)null) ? val4 : val); ItemConfig val7 = new ItemConfig { Name = "Mysterious Tome", Description = "A ruined book. The way home is still written in it, for someone willing to make it whole.", Enabled = false }; CustomItem val8 = new CustomItem("TownPortal_MysteriousTome", "Amber", val7); ItemManager.Instance.AddItem(val8); Tune(val8, 1, (ItemType)1, val6); if (!BookArt.Attach(val8.ItemPrefab, restored: false)) { Plugin.Log.LogWarning((object)"The mysterious tome is still the amber stand-in."); } ItemConfig val9 = new ItemConfig { Name = "Tome of Town Portal", Description = TomeDescription(), CraftingStation = CraftingStations.Workbench, MinStationLevel = 1 }; val9.AddRequirement("TownPortal_MysteriousTome", 1, 0); val9.AddRequirement("SurtlingCore", 10, 0); val9.AddRequirement("GreydwarfEye", 25, 0); val9.AddRequirement("LeatherScraps", 15, 0); val9.AddRequirement("DeerHide", 5, 0); CustomItem val10 = new CustomItem("TownPortal_Tome", "Amber", val9); ItemManager.Instance.AddItem(val10); Tune(val10, 1, (ItemType)16, val5); _tomeShared = val10.ItemDrop.m_itemData.m_shared; if (!BookArt.Attach(val10.ItemPrefab, restored: true)) { Plugin.Log.LogWarning((object)"The tome of town portal is still the amber stand-in."); } BuildEffects(val6, val5); BuildDoor(); BuildGate(); } } public static bool FirstChestLog(string prefab, bool accepted) { if (ChestLog.ContainsKey(prefab)) { return false; } ChestLog[prefab] = accepted; return true; } private static void Tune(CustomItem item, int stack, ItemType type, Sprite icon) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Invalid comparison between Unknown and I4 SharedData shared = item.ItemDrop.m_itemData.m_shared; shared.m_maxStackSize = stack; shared.m_weight = 1f; shared.m_maxQuality = 1; shared.m_itemType = type; shared.m_teleportable = true; shared.m_icons = (Sprite[])(object)new Sprite[1] { icon }; item.ItemDrop.m_itemData.m_dropPrefab = item.ItemPrefab; if (item.ItemDrop.m_itemData.m_customData == null) { item.ItemDrop.m_itemData.m_customData = new Dictionary<string, string>(); } item.ItemDrop.m_itemData.m_customData["TownPortal"] = (((int)type == 16) ? "tome" : "ruined"); } private static void BuildEffects(Sprite ruined, Sprite restored) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown StatusEffect val = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)val).name = "SE_NowhereLikeHome"; val.m_name = "Nowhere Like Home"; val.m_tooltip = "The way back is still open."; val.m_ttl = Mathf.Max(1f, Plugin.DurationSeconds.Value); val.m_icon = restored; val.m_flashIcon = false; val.m_cooldownIcon = false; val.m_startMessage = ""; val.m_stopMessage = ""; ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(val, false)); _seHome = val; StatusEffect val2 = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)val2).name = "SE_TomeRests"; val2.m_name = "The Tome Rests"; val2.m_tooltip = "The tome cannot open another door yet."; val2.m_ttl = Mathf.Max(1f, Plugin.CooldownSeconds.Value); val2.m_icon = ruined; val2.m_flashIcon = false; val2.m_cooldownIcon = false; val2.m_startMessage = ""; val2.m_stopMessage = ""; ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(val2, false)); _seRest = val2; } public static void ApplyTimers() { if ((Object)(object)_seHome != (Object)null) { _seHome.m_ttl = Mathf.Max(1f, Plugin.DurationSeconds.Value); } if ((Object)(object)_seRest != (Object)null) { _seRest.m_ttl = Mathf.Max(1f, Plugin.CooldownSeconds.Value); } if ((Object)(object)ObjectDB.instance != (Object)null) { StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_NowhereLikeHome")); if ((Object)(object)statusEffect != (Object)null) { statusEffect.m_ttl = Mathf.Max(1f, Plugin.DurationSeconds.Value); } StatusEffect statusEffect2 = ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode("SE_TomeRests")); if ((Object)(object)statusEffect2 != (Object)null) { statusEffect2.m_ttl = Mathf.Max(1f, Plugin.CooldownSeconds.Value); } } } public static string TomeDescription() { //IL_0013: 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) string text = KeyText((Plugin.OpenKey != null) ? Plugin.OpenKey.Value : KeyboardShortcut.Empty); string text2 = ((text != null) ? (text + " or L2 + right stick") : "L2 + right stick"); return "Restored to its former glory. While it is in your inventory, " + text2 + " opens a door home to your Runic Spawn Point, or to the bed you have claimed."; } public static void ApplyTomeText() { string description = TomeDescription(); if (_tomeShared != null) { _tomeShared.m_description = description; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("TownPortal_Tome") : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null && val2.m_itemData != null && val2.m_itemData.m_shared != null) { val2.m_itemData.m_shared.m_description = description; } } public static string KeyText(KeyboardShortcut key) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_004a: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref key)).MainKey == 0) { return null; } List<string> list = new List<string>(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers) { list.Add(KeyName(modifier)); } list.Add(KeyName(((KeyboardShortcut)(ref key)).MainKey)); return string.Join(" + ", list.ToArray()); } private unsafe static string KeyName(KeyCode code) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected I4, but got Unknown //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if ((int)code <= 27) { if ((int)code == 13) { return "Enter"; } if ((int)code == 27) { return "Esc"; } } else { if ((int)code == 96) { return "`"; } switch (code - 303) { case 5: return "Left Alt"; case 4: return "Right Alt"; case 1: return "Left Shift"; case 0: return "Right Shift"; case 3: return "Left Ctrl"; case 2: return "Right Ctrl"; case 7: return "Left Cmd"; case 6: return "Right Cmd"; } } string text = ((object)(*(KeyCode*)(&code))/*cast due to .constrained prefix*/).ToString(); if (text.Length == 6 && text.StartsWith("Alpha", StringComparison.Ordinal)) { return text.Substring(5); } if (text.StartsWith("Keypad", StringComparison.Ordinal)) { return "Numpad " + text.Substring(6); } if (text.StartsWith("Mouse", StringComparison.Ordinal)) { return "Mouse " + text.Substring(5); } return text; } private static void BuildDoor() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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) GameObject val = PrefabManager.Instance.CreateClonedPrefab("TownPortal_Door", "portal_wood"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"portal_wood was not found. The town portal door was not registered."); return; } StripPortalLogic(val); RecolorBlue(val); ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { component.m_persistent = true; } val.AddComponent<TownDoor>(); GameObject val2 = new GameObject("TownPortalTrigger"); val2.transform.SetParent(val.transform, false); int num = LayerMask.NameToLayer("character_trigger"); val2.layer = ((num >= 0) ? num : 0); BoxCollider obj = val2.AddComponent<BoxCollider>(); ((Collider)obj).isTrigger = true; obj.size = new Vector3(1.4f, 2.4f, 1.2f); obj.center = new Vector3(0f, 1.3f, 0f); val2.AddComponent<DoorTrigger>(); Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true); foreach (Collider val3 in componentsInChildren) { if (!val3.isTrigger && !((Object)(object)((Component)val3).GetComponent<DoorLabel>() != (Object)null)) { ((Component)val3).gameObject.AddComponent<DoorLabel>(); } } PrefabManager.Instance.AddPrefab(val); } private static void StripPortalLogic(GameObject door) { TeleportWorld[] componentsInChildren = door.GetComponentsInChildren<TeleportWorld>(true); foreach (TeleportWorld val in componentsInChildren) { PortalLook portalLook = door.GetComponent<PortalLook>(); if ((Object)(object)portalLook == (Object)null) { portalLook = door.AddComponent<PortalLook>(); } portalLook.Capture(val); Object.DestroyImmediate((Object)(object)val); } Piece[] componentsInChildren2 = door.GetComponentsInChildren<Piece>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[j]); } WearNTear[] componentsInChildren3 = door.GetComponentsInChildren<WearNTear>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[k]); } HoverText[] componentsInChildren4 = door.GetComponentsInChildren<HoverText>(true); for (int l = 0; l < componentsInChildren4.Length; l++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[l]); } } private static void RecolorBlue(GameObject door) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(0.3f, 0.62f, 1f); Color val2 = new Color(0.55f, 0.82f, 1f) * 1.8f; Light[] componentsInChildren = door.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].color = val; } ParticleSystem[] componentsInChildren2 = door.GetComponentsInChildren<ParticleSystem>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { MainModule main = componentsInChildren2[j].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(val); } Renderer[] componentsInChildren3 = door.GetComponentsInChildren<Renderer>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Material[] materials = componentsInChildren3[k].materials; foreach (Material val3 in materials) { if ((Object)(object)val3 == (Object)null) { continue; } string text = ((Object)val3).name.ToLowerInvariant(); if (text.Contains("glow") || text.Contains("portal") || text.Contains("flare") || text.Contains("swirl") || text.Contains("light") || text.Contains("particle") || val3.IsKeywordEnabled("_EMISSION")) { if (val3.HasProperty("_EmissionColor")) { val3.EnableKeyword("_EMISSION"); val3.SetColor("_EmissionColor", val2); } if (val3.HasProperty("_EmissiveColor")) { val3.SetColor("_EmissiveColor", val2); } if (val3.HasProperty("_Color")) { val3.color = val; } } } } } private static void BuildGate() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabManager.Instance.CreateEmptyPrefab("TownPortal_ReturnGate", true); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Could not create the return gate prefab."); return; } ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null) { component.m_persistent = true; } MeshFilter component2 = val.GetComponent<MeshFilter>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } MeshRenderer component3 = val.GetComponent<MeshRenderer>(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3); } BoxCollider component4 = val.GetComponent<BoxCollider>(); if ((Object)(object)component4 != (Object)null) { Object.DestroyImmediate((Object)(object)component4); } GameObject val2 = new GameObject("Field"); val2.transform.SetParent(val.transform, false); val2.AddComponent<MeshFilter>().sharedMesh = OpenCylinder(0.55f, 1.55f, 24); MeshRenderer obj = val2.AddComponent<MeshRenderer>(); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; GameObject val3 = new GameObject("Use"); val3.transform.SetParent(val.transform, false); int num = LayerMask.NameToLayer("piece_nonsolid"); val3.layer = ((num >= 0) ? num : 0); CapsuleCollider obj2 = val3.AddComponent<CapsuleCollider>(); obj2.height = 1.55f; obj2.radius = 0.55f; obj2.center = new Vector3(0f, 0.775f, 0f); ((Collider)obj2).isTrigger = false; val3.AddComponent<GateInteract>(); val.AddComponent<GateBody>(); PrefabManager.Instance.AddPrefab(val); } private static Mesh OpenCylinder(float radius, float height, int segments) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) Mesh val = new Mesh { name = "TownPortalField" }; Vector3[] array = (Vector3[])(object)new Vector3[segments * 2]; Vector3[] array2 = (Vector3[])(object)new Vector3[array.Length]; Vector2[] array3 = (Vector2[])(object)new Vector2[array.Length]; Color[] array4 = (Color[])(object)new Color[array.Length]; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.2f, 0.45f, 1f, 1f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.45f, 0.72f, 1f, 0.85f); for (int i = 0; i < segments; i++) { float num = (float)i / (float)segments * (float)Math.PI * 2f; float num2 = Mathf.Cos(num) * radius; float num3 = Mathf.Sin(num) * radius; array[i] = new Vector3(num2, 0f, num3); array[i + segments] = new Vector3(num2, height, num3); int num4 = i + segments; int num5 = i; Vector3 val4 = new Vector3(num2, 0f, num3); val4 = (array2[num4] = (array2[num5] = ((Vector3)(ref val4)).normalized)); float num6 = (float)i / (float)segments; array3[i] = new Vector2(num6, 0f); array3[i + segments] = new Vector2(num6, 1f); array4[i] = val2; array4[i + segments] = val3; } int[] array5 = new int[segments * 12]; int num7 = 0; for (int j = 0; j < segments; j++) { int num8 = (j + 1) % segments; int num9 = j; int num10 = num8; int num11 = j + segments; int num12 = num8 + segments; array5[num7++] = num9; array5[num7++] = num11; array5[num7++] = num10; array5[num7++] = num10; array5[num7++] = num11; array5[num7++] = num12; array5[num7++] = num9; array5[num7++] = num10; array5[num7++] = num11; array5[num7++] = num10; array5[num7++] = num12; array5[num7++] = num11; } val.vertices = array; val.normals = array2; val.uv = array3; val.colors = array4; val.triangles = array5; return val; } } public class DoorLabel : MonoBehaviour, Hoverable { private TownDoor _door; private void Awake() { _door = ((Component)this).GetComponentInParent<TownDoor>(); } public string GetHoverName() { if (!((Object)(object)_door != (Object)null)) { return "Town Portal"; } return _door.HoverName(); } public string GetHoverText() { if (!((Object)(object)_door != (Object)null)) { return "Town Portal"; } return _door.HoverText(); } public float GetHoverOffset() { return 0f; } } public class DoorTrigger : MonoBehaviour { private TownDoor _door; private void Awake() { _door = ((Component)this).GetComponentInParent<TownDoor>(); } private void OnTriggerEnter(Collider other) { if (!((Object)(object)_door == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { Player val = ((Component)other).GetComponent<Player>(); if ((Object)(object)val == (Object)null) { val = ((Component)other).GetComponentInParent<Player>(); } if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { Net.RequestTraverse(((Component)_door).GetComponent<ZNetView>()); } } } } internal static class Feedback { public static void ShowLocal(string message, bool denied) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !string.IsNullOrEmpty(message)) { ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } } public static void ToPeer(long peer, string message, bool denied) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (!string.IsNullOrEmpty(message)) { if (peer == 0L || ZRoutedRpc.instance == null) { Plugin.Log.LogInfo((object)("Town portal: no one to tell: " + message)); return; } if (peer == ZDOMan.GetSessionID()) { ShowLocal(message, denied); return; } ZPackage val = new ZPackage(); val.Write(denied); val.Write(message); ZRoutedRpc.instance.InvokeRoutedRPC(peer, "TownPortal_Deny", new object[1] { val }); } } public static void ToPlayer(long playerId, string message, bool denied) { long num = Net.PeerOfPlayer(playerId); if (num != 0L) { ToPeer(num, message, denied); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartNet { private static void Postfix() { Net.Ensure(); } } public class GateBody : MonoBehaviour { private ZNetView _net; private Material _material; private Color _color; private string _totemKey; private float _nextKeyCheck; private Transform _totem; private Vector3 _offset; private bool _offsetFinal; private int _offsetTries; private float _nextOffsetTry; private float _totemSeen; private float _nextSync; private static readonly Vector3[] Spots = (Vector3[])(object)new Vector3[6] { new Vector3(1.4f, 0f, 0f), new Vector3(-1.4f, 0f, 0f), new Vector3(0f, 0f, 1.4f), new Vector3(1.4f, 0f, -1.7f), new Vector3(-1.4f, 0f, -1.7f), new Vector3(0f, 0f, 2.6f) }; private void Awake() { _net = ((Component)this).GetComponent<ZNetView>(); } private void Start() { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_net != (Object)null && _net.IsValid()) { PortalService.Watch(_net); if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && PortalService.Expired(_net.GetZDO())) { ZNetScene.instance.Destroy(((Component)this).gameObject); return; } } MeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<MeshRenderer>(); if (!((Object)(object)componentInChildren == (Object)null)) { _material = BlueMaterial(); if (!((Object)(object)_material == (Object)null)) { _color = new Color(0.25f, 0.55f, 1f, 0.45f); ApplyColor(_color); ((Renderer)componentInChildren).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)componentInChildren).receiveShadows = false; ((Renderer)componentInChildren).material = _material; } } GateNameLabel.Attach(((Component)this).gameObject); } private static Material BlueMaterial() { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) Material val = null; GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("portal_wood") : null); if ((Object)(object)val2 != (Object)null) { ParticleSystemRenderer[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystemRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material sharedMaterial = ((Renderer)componentsInChildren[i]).sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null) && !((Object)(object)sharedMaterial.shader == (Object)null) && !((Object)sharedMaterial.shader).name.Contains("Error")) { val = sharedMaterial; break; } } } Shader val3 = (((Object)(object)val != (Object)null) ? val.shader : null); if ((Object)(object)val3 == (Object)null) { string[] array = new string[3] { "Custom/Particle", "Custom/AlphaParticle", "Unlit/Color" }; for (int j = 0; j < array.Length; j++) { Shader val4 = Shader.Find(array[j]); if ((Object)(object)val4 != (Object)null && !((Object)val4).name.Contains("Error")) { val3 = val4; break; } } } if ((Object)(object)val3 == (Object)null) { return null; } Material val5 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(val3)); if (val5.HasProperty("_MainTex") && (Object)(object)val5.GetTexture("_MainTex") == (Object)null) { Texture2D val6 = new Texture2D(1, 1, (TextureFormat)4, false); val6.SetPixel(0, 0, Color.white); val6.Apply(); val5.SetTexture("_MainTex", (Texture)(object)val6); } val5.renderQueue = 3000; return val5; } private void ApplyColor(Color color) { //IL_002b: 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_004e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_material == (Object)null)) { if (_material.HasProperty("_Color")) { _material.SetColor("_Color", color); } if (_material.HasProperty("_TintColor")) { _material.SetColor("_TintColor", color); } _material.color = color; } } private void Update() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_material != (Object)null) { float a = 0.38f + Mathf.Sin(Time.time * 1.6f) * 0.06f; Color color = _color; color.a = a; ApplyColor(color); } } private void LateUpdate() { //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_01ff: 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_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_net == (Object)null || !_net.IsValid()) { return; } ZDO zDO = _net.GetZDO(); if (Time.time >= _nextKeyCheck) { _nextKeyCheck = Time.time + 1f; string text = zDO.GetString("totem_key", ""); text = (string.IsNullOrEmpty(text) ? null : text); if (text != _totemKey) { _totemKey = text; _totem = null; } } if (_totemKey == null) { return; } Vector3 val; if ((Object)(object)_totem == (Object)null) { if (!RunicApi.TryGetLoadedTotem(_totemKey, out var totem, out var _)) { Vector3 position = zDO.GetPosition(); val = ((Component)this).transform.position - position; if (((Vector3)(ref val)).sqrMagnitude > 0.25f) { ((Component)this).transform.position = position; } return; } _totem = totem; _offsetFinal = false; _offsetTries = 0; _nextOffsetTry = 0f; _totemSeen = Time.time; _offset = FallbackOffset(); } if (!_offsetFinal && Time.time >= _nextOffsetTry) { _nextOffsetTry = Time.time + 0.5f; RunicApi.TryGetLoadedTotem(_totemKey, out var _, out var attached2); if (attached2 || Time.time - _totemSeen > 1.5f) { _offsetTries++; if (TryPickOffset(out var offset)) { _offset = offset; _offsetFinal = true; } else if (_offsetTries >= 10) { _offsetFinal = true; } } } ((Component)this).transform.position = _totem.TransformPoint(_offset); ((Component)this).transform.rotation = _totem.rotation; if (_net.IsOwner() && Time.time >= _nextSync) { _nextSync = Time.time + 0.5f; val = zDO.GetPosition() - ((Component)this).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 1f) { zDO.SetPosition(((Component)this).transform.position); } } } private Vector3 FallbackOffset() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0.05f, 0.85f); if (RunicApi.TryGetDeckPoint(_totemKey, out var point)) { val = _totem.InverseTransformPoint(point); } return val + Spots[0]; } private bool TryPickOffset(out Vector3 offset) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) offset = Vector3.zero; if (!RunicApi.TryGetDeckPoint(_totemKey, out var point)) { return false; } Vector3 val = _totem.InverseTransformPoint(point); int mask = LayerMask.GetMask(new string[5] { "terrain", "Default", "piece", "static_solid", "vehicle" }); int mask2 = LayerMask.GetMask(new string[4] { "Default", "piece", "static_solid", "vehicle" }); RaycastHit val2 = default(RaycastHit); for (int i = 0; i < Spots.Length; i++) { if (Physics.Raycast(_totem.TransformPoint(val + Spots[i]) + Vector3.up * 1.8f, Vector3.down, ref val2, 4f, mask, (QueryTriggerInteraction)1) && !(((RaycastHit)(ref val2)).normal.y < 0.6f) && !((Component)((RaycastHit)(ref val2)).collider).transform.IsChildOf(_totem) && (!((Object)(object)ZoneSystem.instance != (Object)null) || !(((RaycastHit)(ref val2)).point.y < ZoneSystem.instance.m_waterLevel - 0.1f)) && !Physics.CheckCapsule(((RaycastHit)(ref val2)).point + Vector3.up * 0.4f, ((RaycastHit)(ref val2)).point + Vector3.up * 1.7f, 0.35f, mask2, (QueryTriggerInteraction)1)) { offset = _totem.InverseTransformPoint(((RaycastHit)(ref val2)).point + Vector3.up * 0.02f); return true; } } return false; } private void OnDestroy() { PortalService.Forget(_net); if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } } public string HoverText() { string text = "Return"; long num = (((Object)(object)_net != (Object)null && _net.IsValid()) ? _net.GetZDO().GetLong("owner", 0L) : 0); if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerID() == num) { text = "Return and close"; } string text2 = HoverName() + "\n" + PortalService.Countdown(_net) + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text; if (Localization.instance == null) { return text2; } return Localization.instance.Localize(text2); } public string HoverName() { return (((Object)(object)_net != (Object)null && _net.IsValid()) ? GateNames.ReturnGate(_net.GetZDO()) : null) ?? "Return gate"; } public void RequestReturn() { if (!((Object)(object)_net == (Object)null) && _net.IsValid()) { Net.RequestReturn(_net); } } } public class GateInteract : MonoBehaviour, Hoverable, Interactable { private GateBody _body; private GateBody Body { get { if ((Object)(object)_body == (Object)null) { _body = ((Component)this).GetComponentInParent<GateBody>(); } return _body; } } public string GetHoverName() { GateBody body = Body; if (!((Object)(object)body != (Object)null)) { return "Return gate"; } return body.HoverName(); } public string GetHoverText() { GateBody body = Body; if (!((Object)(object)body != (Object)null)) { return "Return gate"; } return body.HoverText(); } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { if (hold || alt) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return false; } GateBody body = Body; if ((Object)(object)body == (Object)null) { return false; } body.RequestReturn(); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } } public class GateNameLabel : MonoBehaviour { private const float FadeFrom = 11f; private const float HideFrom = 15f; private const float MaxAlpha = 0.9f; private static TMP_FontAsset _font; private static bool _fontSearched; private ZNetView _net; private TextMeshPro _text; private MeshRenderer _renderer; private string _shown; private float _nextRead; private float _alpha = -1f; public static void Attach(GameObject gate) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)gate == (Object)null) && !((Object)(object)gate.GetComponentInChildren<GateNameLabel>(true) != (Object)null) && (int)SystemInfo.graphicsDeviceType != 4 && (!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated())) { GameObject val = new GameObject("OwnerName"); val.transform.SetParent(gate.transform, false); val.transform.localPosition = new Vector3(0f, 2.05f, 0f); val.AddComponent<GateNameLabel>(); } } private void Awake() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) _net = ((Component)this).GetComponentInParent<ZNetView>(); _text = ((Component)this).gameObject.AddComponent<TextMeshPro>(); TMP_FontAsset val = GameFont(); if ((Object)(object)val != (Object)null) { ((TMP_Text)_text).font = val; } ((TMP_Text)_text).fontSize = 2.2f; ((TMP_Text)_text).alignment = (TextAlignmentOptions)514; ((TMP_Text)_text).richText = false; ((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)_text).overflowMode = (TextOverflowModes)0; ((TMP_Text)_text).rectTransform.sizeDelta = new Vector2(6f, 0.6f); ((Graphic)_text).color = new Color(1f, 0.93f, 0.78f, 0f); ((TMP_Text)_text).text = ""; _renderer = ((Component)this).GetComponent<MeshRenderer>(); if ((Object)(object)_renderer != (Object)null) { ((Renderer)_renderer).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)_renderer).receiveShadows = false; ((Renderer)_renderer).enabled = false; } } private static TMP_FontAsset GameFont() { if ((Object)(object)_font != (Object)null || _fontSearched) { return _font; } _fontSearched = true; GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("sign") : null); if ((Object)(object)val != (Object)null) { Sign componentInChildren = val.GetComponentInChildren<Sign>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_textWidget != (Object)null) { _font = ((TMP_Text)componentInChildren.m_textWidget).font; } if ((Object)(object)_font == (Object)null) { TextMeshProUGUI componentInChildren2 = val.GetComponentInChildren<TextMeshProUGUI>(true); if ((Object)(object)componentInChildren2 != (Object)null) { _font = ((TMP_Text)componentInChildren2).font; } } } return _font; } private void LateUpdate() { //IL_00d0: 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) if ((Object)(object)_text == (Object)null || (Object)(object)_renderer == (Object)null) { return; } if (Time.time >= _nextRead) { _nextRead = Time.time + 1f; string text = (((Object)(object)_net != (Object)null && _net.IsValid()) ? GateNames.ReturnGate(_net.GetZDO()) : null); if (text != _shown) { _shown = text; ((TMP_Text)_text).text = text ?? ""; } } Camera mainCamera = Utils.GetMainCamera(); bool num = _shown != null && (Object)(object)mainCamera != (Object)null && (Plugin.ShowGateNames == null || Plugin.ShowGateNames.Value); float num2 = 0f; if (num) { float num3 = Vector3.Distance(((Component)mainCamera).transform.position, ((Component)this).transform.position); num2 = 0.9f * Mathf.Clamp01((15f - num3) / 4f); } if (num2 <= 0.01f) { if (((Renderer)_renderer).enabled) { ((Renderer)_renderer).enabled = false; } _alpha = 0f; return; } Face(mainCamera); if (Mathf.Abs(num2 - _alpha) > 0.02f) { _alpha = num2; ((TMP_Text)_text).alpha = num2; } if (!((Renderer)_renderer).enabled) { ((Renderer)_renderer).enabled = true; } } private void OnWillRenderObject() { Face(Utils.GetMainCamera()); } private void Face(Camera cam) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cam != (Object)null) { ((Component)this).transform.rotation = ((Component)cam).transform.rotation; } } } internal static class GateNames { public const string Key = "owner_name"; private const string PinSuffix = "'s town portal"; public static string Owner(ZDO zdo) { string text = ((zdo != null) ? zdo.GetString("owner_name", "") : null); if (string.IsNullOrEmpty(text)) { return null; } return text; } public static string FromDoor(ZDO door) { string text = Owner(door); if (text != null) { return text; } string text2 = ((door != null) ? door.GetString("pinName", "") : null); if (!string.IsNullOrEmpty(text2) && text2.Length > "'s town portal".Length && text2.EndsWith("'s town portal", StringComparison.Ordinal)) { return text2.Substring(0, text2.Length - "'s town portal".Length); } return null; } public static string ReturnGate(ZDO gate) { string text = Owner(gate); if (text == null) { return null; } return text + "'s return gate"; } public static string TownPortal(ZDO door) { string text = ((door != null) ? door.GetString("pinName", "") : null); if (!string.IsNullOrEmpty(text)) { return text; } string text2 = Owner(door); if (text2 == null) { return null; } return text2 + "'s town portal"; } } internal static class Hotkey { public static void Poll() { if (!Pressed() || (Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).IsDead() || BlockedByUi()) { return; } if (((Character)Player.m_localPlayer).InPlaceMode()) { Net.Refuse("Put away your build tool first."); return; } PortalService.RepairTomes(Player.m_localPlayer); if (!PortalService.HasTome(Player.m_localPlayer)) { if (PortalService.HasMysteriousTome(Player.m_localPlayer)) { Net.Refuse("That is the ruined tome. Craft it into the Tome of Town Portal first."); } else { Net.Refuse("The Tome of Town Portal has to be in your inventory."); } } else if (((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_TomeRests"))) { Net.Refuse("The tome is not ready."); } else { Net.RequestOpen(); } } private static bool Pressed() { //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) if (Plugin.OpenKey != null) { KeyboardShortcut value = Plugin.OpenKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return true; } } if (ZInput.instance != null && ZInput.GetButton("JoyLTrigger")) { return ZInput.GetButtonDown("JoyRStick"); } return false; } private static bool BlockedByUi() { if (Console.IsVisible() || TextInput.IsVisible()) { return true; } if (InventoryGui.IsVisible() || Menu.IsVisible() || StoreGui.IsVisible()) { return true; } if (Minimap.IsOpen()) { return true; } if (ChatFocused()) { return true; } if (((Character)Player.m_localPlayer).InCutscene()) { return true; } return false; } private static bool ChatFocused() { if ((Object)(object)Chat.instance == (Object)null) { return false; } return Chat.instance.HasFocus(); } } internal static class Icons { public static Sprite Book(Color cover, Color page) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0041: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)0; Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); Color[] array = (Color[])(object)new Color[4096]; for (int i = 0; i < array.Length; i++) { array[i] = val2; } FillRect(array, 64, 14, 10, 50, 54, cover); FillRect(array, 64, 18, 14, 46, 50, page); Color color = default(Color); ((Color)(ref color))..ctor(page.r * 0.45f + 0.2f, page.g * 0.7f + 0.15f, 1f, 1f); FillRect(array, 64, 28, 22, 38, 44, color); FillRect(array, 64, 10, 12, 16, 52, cover * 0.7f); val.SetPixels(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); } private static void FillRect(Color[] pixels, int size, int x0, int y0, int x1, int y1, Color color) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) for (int i = y0; i <= y1; i++) { for (int j = x0; j <= x1; j++) { pixels[i * size + j] = color; } } } } internal static class Loot { private static readonly HashSet<string> Logged = new HashSet<string>(); public static bool TryRoll(Container container) { if (WorldGenerator.instance == null) { return false; } ZDO zDO = container.m_nview.GetZDO(); if (zDO.GetBool("TownPortal_TomeRolled", false)) { return true; } string prefabName = Utils.GetPrefabName(((Component)container).gameObject); if (!IsTomeChest(container, prefabName, out var reason)) { if (reason == "no world") { return false; } Note(prefabName, accepted: false, reason); return true; } zDO.Set("TownPortal_TomeRolled", true); Note(prefabName, accepted: true, "rolled"); float num = Mathf.Clamp01(Plugin.DropChance.Value); if (Random.value > num) { return true; } Inventory inventory = container.GetInventory(); if (inventory == null) { return true; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("TownPortal_MysteriousTome") : null); if ((Object)(object)val == (Object)null || !inventory.AddItem(val, 1)) { return true; } container.Save(); return true; } private unsafe static bool IsTomeChest(Container container, string prefab, out string reason) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Invalid comparison between Unknown and I4 reason = null; if (string.IsNullOrEmpty(prefab)) { reason = "no name"; return false; } string text = prefab.ToLowerInvariant(); if (text.Contains("barrel")) { reason = "barrel"; return false; } if (!text.Contains("chest")) { reason = "not a chest"; return false; } if (container.m_defaultItems == null || container.m_defaultItems.m_drops == null || container.m_defaultItems.m_drops.Count == 0) { reason = "no default loot"; return false; } if (container.m_nview.GetZDO().GetLong("creator", 0L) != 0L) { reason = "player placed"; return false; } if (WorldGenerator.instance == null) { reason = "no world"; return false; } Biome biome = WorldGenerator.instance.GetBiome(((Component)container).transform.position); if ((int)biome != 1 && (int)biome != 8) { reason = ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString(); return false; } return true; } private static void Note(string prefab, bool accepted, string reason) { if (Plugin.LogChests != null && Plugin.LogChests.Value && Logged.Add(prefab + ":" + accepted)) { Plugin.Log.LogInfo((object)("Tome chest " + prefab + " -> " + (accepted ? "eligible" : ("skip (" + reason + ")")))); } } } [HarmonyPatch(typeof(Container), "Awake")] internal static class LootPatch { private static void Postfix(Container __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<TomeRoller>() != (Object)null)) { ((Component)__instance).gameObject.AddComponent<TomeRoller>(); } } } internal static class MapPin { private static readonly Dictionary<string, PinData> Pins = new Dictionary<string, PinData>(); private static Sprite _icon; private static bool _synced; private static float _refresh; private static string _signature = ""; public static void Tick() { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) { if (Net.EnsureReady()) { _refresh += Time.unscaledDeltaTime; if (!(_refresh < 2f)) { _refresh = 0f; Refresh(); } } } else if ((Object)(object)Player.m_localPlayer == (Object)null) { if (_synced || Pins.Count > 0) { Reset(); } } else { if ((Object)(object)Minimap.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || !Net.EnsureReady()) { return; } if (!_synced) { RemoveSavedTownPins(); _synced = true; if (ZNet.instance.IsServer()) { Refresh(); } else { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.instance.GetServerPeerID(), "TownPortal_PinSync", new object[1] { (object)new ZPackage() }); } } if (ZNet.instance.IsServer()) { _refresh += Time.unscaledDeltaTime; if (!(_refresh < 2f)) { _refresh = 0f; Refresh(); } } } } public static void Show(long user, uint id, Vector3 pos, string label) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Minimap.instance == (Object)null)) { string key = Key(user, id); Hide(user, id); PinData val = Minimap.instance.AddPin(pos, (PinType)0, label ?? "Town portal", false, false, 0L, default(PlatformUserID)); val.m_icon = Icon(); Pins[key] = val; } } public static void Hide(long user, uint id) { string key = Key(user, id); if (Pins.TryGetValue(key, out var value)) { Pins.Remove(key); if (value != null && (Object)(object)Minimap.instance != (Object)null) { Minimap.instance.RemovePin(value); } } } public static void HideAll() { RemoveSavedTownPins(); CommitMap(); } public static int RemoveSavedTownPins() { Pins.Clear(); if ((Object)(object)Minimap.instance == (Object)null) { return 0; } List<PinData> pins = Minimap.instance.m_pins; int num = 0; bool flag = false; for (int num2 = pins.Count - 1; num2 >= 0; num2--) { PinData val = pins[num2]; if (IsTownPin(val)) { if (val.m_save) { flag = true; } Minimap.instance.RemovePin(val); num++; } } if (flag) { CommitMap(); } return num; } private static void CommitMap() { if (!((Object)(object)Minimap.instance == (Object)null) && !((Object)(object)Game.instance == (Object)null) && !((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.GetWorldUID() != 0L) { Minimap.instance.SaveMapData(); } } public static void Reset() { HideAll(); _synced = false; _refresh = 0f; _signature = ""; } public static void Refresh() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = Doors(); string text = Signature(list); if (text == _signature) { return; } _signature = text; RemoveSavedTownPins(); for (int i = 0; i < list.Count; i++) { ZDO val = list[i]; string text2 = val.GetString("pinName", ""); if (string.IsNullOrEmpty(text2)) { text2 = "Town portal"; } Show(((ZDOID)(ref val.m_uid)).UserID, ((ZDOID)(ref val.m_uid)).ID, val.GetPosition(), text2); } Fanout("TownPortal_PinList", PackAll().GetArray()); } public static void BroadcastShow(ZDOID id, Vector3 pos, string label) { //IL_000e: 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) Show(((ZDOID)(ref id)).UserID, ((ZDOID)(ref id)).ID, pos, label); Fanout("TownPortal_Pin", PackOne(((ZDOID)(ref id)).UserID, ((ZDOID)(ref id)).ID, pos, label)); } public static void BroadcastHide(ZDOID id) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown Hide(((ZDOID)(ref id)).UserID, ((ZDOID)(ref id)).ID); ZPackage val = new ZPackage(); val.Write(((ZDOID)(ref id)).UserID); val.Write((long)((ZDOID)(ref id)).ID); Fanout("TownPortal_Unpin", val.GetArray()); } public static void BroadcastClear() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) HideAll(); Fanout("TownPortal_PinClear", new ZPackage().GetArray()); } public static void ShowAllFromWorld() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) foreach (ZDO item in Doors()) { string text = item.GetString("pinName", ""); if (string.IsNullOrEmpty(text)) { text = "Town portal"; } Show(((ZDOID)(ref item.m_uid)).UserID, ((ZDOID)(ref item.m_uid)).ID, item.GetPosition(), text); } } public static ZPackage PackAll() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = Doors(); ZPackage val = new ZPackage(); val.Write(list.Count); for (int i = 0; i < list.Count; i++) { ZDO val2 = list[i]; string text = val2.GetString("pinName", ""); if (string.IsNullOrEmpty(text)) { text = "Town portal"; } val.Write(((ZDOID)(ref val2.m_uid)).UserID); val.Write((long)((ZDOID)(ref val2.m_uid)).ID); val.Write(val2.GetPosition()); val.Write(text); } return val; } public static void ApplyList(ZPackage pkg) { //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_002f: Unknown result type (might be due to invalid IL or missing references) RemoveSavedTownPins(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { long user = pkg.ReadLong(); uint id = (uint)pkg.ReadLong(); Vector3 pos = pkg.ReadVector3(); string label = pkg.ReadString(); Show(user, id, pos, label); } } private static List<ZDO> Doors() { return PortalService.LiveDoors(); } private static byte[] PackOne(long user, uint id, Vector3 pos, string label) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(user); val.Write((long)id); val.Write(pos); val.Write(label ?? "Town portal"); return val.GetArray(); } private static void Fanout(string method, byte[] data) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown if (data == null || (Object)(object)ZNet.instance == (Object)null || ZRoutedRpc.instance == null) { return; } List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers(); if (connectedPeers == null) { return; } for (int i = 0; i < connectedPeers.Count; i++) { ZNetPeer val = connectedPeers[i]; if (val != null) { ZRoutedRpc.instance.InvokeRoutedRPC(val.m_uid, method, new object[1] { (object)new ZPackage(data) }); } } } private static string Signature(List<ZDO> doors) { //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) if (doors.Count == 0) { return ""; } string[] array = new string[doors.Count]; for (int i = 0; i < doors.Count; i++) { ZDOID uid = doors[i].m_uid; array[i] = ((ZDOID)(ref uid)).UserID + ":" + ((ZDOID)(ref uid)).ID; } Array.Sort(array, (IComparer<string>?)StringComparer.Ordinal); return string.Join("|", array); } private static bool IsTownPin(PinData pin) { if (pin == null) { return false; } if ((Object)(object)_icon != (Object)null && (Object)(object)pin.m_icon == (Object)(object)_icon) { return true; } string name = pin.m_name; if (!string.IsNullOrEmpty(name)) { return name.IndexOf("town portal", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static string Key(long user, uint id) { return user + ":" + id; } private static Sprite Icon() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_icon != (Object)null) { return _icon; } Texture2D val = new Texture2D(48, 48, (TextureFormat)4, false); ((Texture)val).filterMode = (FilterMode)1; Color[] array = (Color[])(object)new Color[2304]; float num = 23.5f; float num2 = 20.16f; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.22f, 0.48f, 1f, 0.95f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.78f, 0.9f, 1f, 1f); for (int i = 0; i < 48; i++) { for (int j = 0; j < 48; j++) { float num3 = (float)j - num; float num4 = (float)i - num; float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4); if (!(num5 > num2)) { float num6 = num5 / num2; array[i * 48 + j] = ((num5 > num2 - 2.2f) ? val3 : Color.Lerp(val2, val3, num6 * num6)); } } } val.SetPixels(array); val.Apply(); _icon = Sprite.Create(val, new Rect(0f, 0f, 48f, 48f), new Vector2(0.5f, 0.5f), 48f); return _icon; } } internal static class Net { private static ZRoutedRpc _hooked; private const int TotemTag = 1; private const float AnswerTimeout = 12f; private static bool _totemPending; private static float _totemPendingSince; private static int _openPending; private static float _openPendingSince; private static int _openSerial; private static float _travelPendingUntil; public static void Ensure() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && _hooked != instance) { _hooked = instance; _totemPending = false; _openPending = 0; _travelPendingUntil = 0f; instance.Register<ZPackage>("TownPortal_Request", (Action<long, ZPackage>)OnRequest); instance.Register<ZPackage>("TownPortal_Opened", (Action<long, ZPackage>)OnOpened); instance.Register<ZPackage>("TownPortal_Traverse", (Action<long, ZPackage>)OnTraverse); instance.Register<ZPackage>("TownPortal_Return", (Action<long, ZPackage>)OnReturn); instance.Register<ZPackage>("TownPortal_Closed", (Action<long, ZPackage>)OnClosed); instance.Register<ZPackage>("TownPortal_Reset", (Action<long, ZPackage>)OnReset); instance.Register<ZPackage>("TownPortal_Deny", (Action<long, ZPackage>)OnDeny); instance.Register<ZPackage>("TownPortal_Go", (Action<long, ZPackage>)OnGo); instance.Register<ZPackage>("TownPortal_Clear", (Action<long, ZPackage>)OnClear); instance.Register<ZPackage>("TownPortal_Pin", (Action<long, ZPackage>)OnPin); instance.Register<ZPackage>("TownPortal_Unpin", (Action<long, ZPackage>)OnUnpin); instance.Register<ZPackage>("TownPortal_PinClear", (Action<long, ZPackage>)OnPinClear); instance.Register<ZPackage>("TownPortal_PinSync", (Action<long, ZPackage>)OnPinSync); instance.Register<ZPackage>("TownPortal_PinList", (Action<long, ZPackage>)OnPinList); SpawnPointCommand.Register(instance); } } internal static bool EnsureReady() { Ensure(); return ZRoutedRpc.instance != null; } private static long ServerPeer() { return ZRoutedRpc.instance.GetServerPeerID(); } public static void RequestOpen() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!EnsureReady()) { Refuse("You are not connected to a world."); return; } if (_openPending != 0 && Time.time - _openPendingSince < 12f) { Feedback.ShowLocal("The door is already opening...", denied: false); Plugin.Log.LogInfo((object)"Town portal: open ignored, the server has not answered the last request yet."); return; } if (_totemPending && Time.time - _totemPendingSince < 75f) { Feedback.ShowLocal("Still looking for your Runic Spawn Point...", denied: false); Plugin.Log.LogInfo((object)"Town portal: open ignored, still waiting for the Runic Spawn Point lookup."); return; } _totemPending = false; _openPending = 0; if (RunicApi.HasSpawnPoint) { _totemPending = true; _totemPendingSince = Time.time; Plugin.Log.LogInfo((object)"Town portal: open requested, asking the server where the Runic Spawn Point is."); RunicApi.RequestSpawnPointInfo(delegate(bool found, Vector3 pos, string key, ZDOID id, bool onVehicle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) OnTotemAnswer(found, pos, key, id); }); } else { SendOpen(Player.m_localPlayer, null, ZDOID.None, Vector3.zero); } } private static void OnTotemAnswer(bool found, Vector3 pos, string key, ZDOID id) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) if (_totemPending) { _totemPending = false; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { Plugin.Log.LogInfo((object)"Town portal: open dropped, the player died or left while the spawn point was looked up."); } else if (!EnsureReady()) { Refuse("You are not connected to a world."); } else if (!PortalService.HasTome(localPlayer)) { Refuse("The Tome of Town Portal has to be in your inventory."); } else if (!found || string.IsNullOrEmpty(key)) { Rules.Destination(localPlayer, out var worldStart); ((Character)localPlayer).Message((MessageType)1, worldStart ? "Couldn't find your Runic Spawn Point. The door opens toward the starting stones." : "Couldn't find your Runic Spawn Point. The door opens to your bed instead.", 0, (Sprite)null, false); SendOpen(localPlayer, null, ZDOID.None, Vector3.zero); } else { SendOpen(localPlayer, key, id, pos); } } } private static void SendOpen(Player player, string totemKey, ZDOID totemId, Vector3 totemPos) { //IL_00b1: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_0138: 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_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || ((Character)player).IsDead()) { Plugin.Log.LogInfo((object)"Town portal: open dropped, no living local player."); return; } if (((Character)player).InPlaceMode()) { Refuse("Put away your build tool first."); return; } if (((Character)player).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_TomeRests"))) { Refuse("The tome is not ready."); return; } if (!Rules.PortalsAllowed(out var deny)) { Refuse(deny); return; } float yawOffset = ((Plugin.PortalYawOffset != null) ? Plugin.PortalYawOffset.Value : 0f); float radius = ((Plugin.SearchRadius != null) ? Plugin.SearchRadius.Value : 6f); if (!Placement.TryFind(player, radius, yawOffset, out var pos, out var rot)) { Refuse("The door has nowhere to open."); return; } Vector3 val = pos + rot * Vector3.forward * 1.8f; val.y = Rules.FloorNear(val, pos.y); bool worldStart; Vector3 val2 = Rules.Destination(player, out worldStart); bool flag = !string.IsNullOrEmpty(totemKey); ZPackage val3 = new ZPackage(); val3.Write(++_openSerial); val3.Write(player.GetPlayerID()); val3.Write(player.GetPlayerName() ?? ""); val3.Write(pos); val3.Write(rot); val3.Write(val); val3.Write(((Quaternion)(ref rot)).eulerAngles.y + 180f); val3.Write(val2); val3.Write(worldStart); val3.Write(flag ? 1 : 0); if (flag) { val3.Write(totemKey); val3.Write(totemId); val3.Write(totemPos); } _openPending = _openSerial; _openPendingSince = Time.time; Plugin.Log.LogInfo((object)("Town portal: open request sent to the server. Door at " + Fmt(pos) + ", leads to " + (flag ? "the Runic Spawn Point" : (worldStart ? "the starting stones" : "the bed")) + ".")); ZRoutedRpc.instance.InvokeRoutedRPC(ServerPeer(), "TownPortal_Request", new object[1] { val3 }); if (_openPending == _openSerial && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(OpenTimeout(_openSerial)); } } private static IEnumerator OpenTimeout(int serial) { yield return (object)new WaitForSecondsRealtime(12f); if (_openPending == serial) { _openPending = 0; Refuse("The server did not answer. Try again in a moment."); } } internal static void Refuse(string message) { Feedback.ShowLocal(message, denied: true); Plugin.Log.LogInfo((object)("Town portal: open refused: " +