Decompiled source of Waystones v1.0.5
Waystones.dll
Decompiled a month 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.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.UI; using Waystones; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Waystones")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Waystones")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1af3a9e7-99be-490a-a211-741aaff1aef2")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } public class WaystoneSmall : MonoBehaviour, TextReceiver, Hoverable, Interactable { [HarmonyPatch(typeof(TextInput), "Update")] public static class TextInput_Update_HoldUseButton { private static void Postfix(TextInput __instance) { ((TMP_InputField)__instance.m_inputField).readOnly = false; if ((__instance.m_queuedSign is WaystoneSmall && TextInput.IsVisible() && blockInputUntil > Time.time && ZInput.GetButton("Use")) || ZInput.GetButton("JoyUse")) { ((TMP_InputField)__instance.m_inputField).readOnly = true; } } } public GameObject m_activeObject; public EffectList m_activateEffect = new EffectList(); public EffectList m_deactivateEffect = new EffectList(); public static bool initial = false; public static StringBuilder sb = new StringBuilder(); public ZNetView m_nview; public static float blockInputUntil; public const float waystoneHoldSetTagDelay = 0.35f; public void Awake() { if (!initial) { m_activeObject = ((Component)((Component)this).transform.Find("WayEffect")).gameObject; m_activeObject.SetActive(false); m_nview = ((Component)this).GetComponent<ZNetView>(); if ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) { ((MonoBehaviour)this).InvokeRepeating("UpdateStatus", 0f, 1f); m_nview.Register<string, string>("RPC_SetTag", (Action<long, string, string>)RPC_SetTag); m_nview.Register<long, string>("ToggleActivated", (Action<long, long, string>)RPC_ToggleActivated); } } } public void RPC_ToggleActivated(long uid, long playerID, string name) { if (m_nview.IsOwner()) { if (IsActivated(playerID)) { RemoveActivated(playerID); } else { AddActivated(playerID, name); } UpdateStatus(); } } public void RemoveActivated(long playerID) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<long, string>> activatedPlayers = GetActivatedPlayers(); if (activatedPlayers.RemoveAll((KeyValuePair<long, string> x) => x.Key == playerID) > 0) { SetActivatedPlayers(activatedPlayers); m_deactivateEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } } public bool IsActivated(long playerID) { return IsWaystoneActivated(m_nview.GetZDO(), playerID); } public void AddActivated(long playerID, string playerName) { //IL_0069: 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) List<KeyValuePair<long, string>> activatedPlayers = GetActivatedPlayers(); foreach (KeyValuePair<long, string> item in activatedPlayers) { if (item.Key == playerID) { return; } } activatedPlayers.Add(new KeyValuePair<long, string>(playerID, playerName)); SetActivatedPlayers(activatedPlayers); m_activateEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } public void SetActivatedPlayers(List<KeyValuePair<long, string>> users) { m_nview.GetZDO().Set(ZDOVars.s_permitted, users.Count, false); for (int i = 0; i < users.Count; i++) { KeyValuePair<long, string> keyValuePair = users[i]; m_nview.GetZDO().Set("pu_id" + i, keyValuePair.Key); m_nview.GetZDO().Set("pu_name" + i, keyValuePair.Value); } } public List<KeyValuePair<long, string>> GetActivatedPlayers() { return GetWaystoneActivatedPlayers(m_nview.GetZDO()); } public bool IsEnabled() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return false; } return IsActivated(Player.m_localPlayer.GetPlayerID()); } public void UpdateStatus() { bool active = IsEnabled(); m_activeObject.SetActive(active); } public string GetHoverText() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!m_nview.IsValid()) { return ""; } if ((Object)(object)Player.m_localPlayer == (Object)null) { return ""; } if (((Character)Player.m_localPlayer).InInterior()) { return GetHoverName(); } if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false)) { return Localization.instance.Localize(GetHoverName() + "\n$piece_noaccess"); } sb.Clear(); sb.Append(GetHoverName()); string text = StringExtensionMethods.RemoveRichTextTags(GetText()); if (text.Length > 0) { sb.AppendFormat(" \"{0}\"", text); } sb.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $ws_tooltip_start_search $ws_piece_waystone_settag"); string text2 = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys"); sb.Append("\n[<color=yellow><b>" + text2 + " + $KEY_Use</b></color>] " + (IsActive() ? "$ws_piece_waystone_deactivate" : "$ws_piece_waystone_activate")); return Localization.instance.Localize(sb.ToString()); } public string GetHoverName() { return IsActive() ? "$ws_piece_waystone_activated" : "$ws_piece_waystone_name"; } public bool Interact(Humanoid human, bool hold, bool alt) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || ((Character)Player.m_localPlayer).InInterior() || !PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } if (hold) { if (ZInput.GetButtonPressedTimer("Use") + ZInput.GetButtonPressedTimer("JoyUse") > 0.35f && !TextInput.IsVisible()) { blockInputUntil = Time.time + 0.7f; ZInput.ResetButtonStatus("Use"); ZInput.ResetButtonStatus("JoyUse"); TextInput.instance.RequestText((TextReceiver)(object)this, "$ws_piece_waystone_tag", Math.Max(global::Waystones.Waystones.tagCharactersLimit.Value, 10)); } return false; } Player val = (Player)(object)((human is Player) ? human : null); if (alt) { m_nview.InvokeRPC("ToggleActivated", new object[2] { val.GetPlayerID(), val.GetPlayerName() }); return true; } ((MonoBehaviour)this).StartCoroutine(ActivationToggleRequested(val)); return true; } public IEnumerator ActivationToggleRequested(Player player) { yield return (object)new WaitWhile((Func<bool>)(() => ZInput.GetButton("Use") || ZInput.GetButton("JoyUse"))); if (!TextInput.IsVisible() && IsSearchAllowed(player) && global::Waystones.Waystones.CanCast()) { ((Character)player).Message((MessageType)2, "$ws_piece_waystone_activation", 0, (Sprite)null); WaystoneList.EnterSearchMode(); } } public bool UseItem(Humanoid user, ItemData item) { int cooldown = 0; if (global::Waystones.Waystones.itemSacrifitionReduceCooldown.Value) { GameObject dropPrefab = item.m_dropPrefab; if (TryReduceCooldownOnItemSacrifice(user, item, (dropPrefab != null) ? ((Object)dropPrefab).name : null, ref cooldown) || TryReduceCooldownOnItemSacrifice(user, item, item.m_shared.m_name, ref cooldown)) { ((Character)user).Message((MessageType)2, Localization.instance.Localize("$ws_piece_waystone_cooldown_reduced", new string[1] { cooldown.ToString() }), 0, (Sprite)null); if (WorldData.IsOnCooldown()) { ((Character)user).Message((MessageType)1, "$hud_powernotready: " + WorldData.GetCooldownString(), 0, (Sprite)null); } return true; } } return false; } private bool TryReduceCooldownOnItemSacrifice(Humanoid user, ItemData item, string itemName, ref int cooldown) { if (itemName == null) { return false; } if (global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(itemName, out var value) && (cooldown = value) > 0) { return user.GetInventory().RemoveOneItem(item) && WorldData.TryReduceCooldown(value); } string text = global::Waystones.Waystones.itemsToReduceCooldown.Value.Keys.FirstOrDefault((string key) => key.StartsWith(itemName)); if (text != null && global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(text, out var value2) && (cooldown = value2) > 0) { string[] array = text.Split(':'); int result; return array.Length > 1 && array[0] == itemName && int.TryParse(array[1], out result) && CountItems(user.GetInventory(), itemName) >= result && user.GetInventory().RemoveItem(item, result) && WorldData.TryReduceCooldown(value2); } return false; } private int CountItems(Inventory inventory, string itemName) { return inventory.m_inventory.Where(delegate(ItemData item) { int result; if (!(item.m_shared.m_name == itemName)) { GameObject dropPrefab = item.m_dropPrefab; result = ((((dropPrefab != null) ? ((Object)dropPrefab).name : null) == itemName) ? 1 : 0); } else { result = 1; } return (byte)result != 0; }).Sum((ItemData item) => item.m_stack); } public bool IsActive() { return m_activeObject.activeSelf; } public string GetText() { ZDO zDO = m_nview.GetZDO(); if (zDO == null) { return ""; } return CensorShittyWords.FilterUGC(zDO.GetString(ZDOVars.s_tag, ""), (UGCType)4, zDO.GetString(ZDOVars.s_tagauthor, ""), 0L); } public void GetTagSignature(out string tagRaw, out string authorId) { ZDO zDO = m_nview.GetZDO(); tagRaw = zDO.GetString(ZDOVars.s_tag, ""); authorId = zDO.GetString(ZDOVars.s_tagauthor, ""); } public void SetText(string text) { if (m_nview.IsValid()) { m_nview.InvokeRPC("RPC_SetTag", new object[2] { text, PrivilegeManager.GetNetworkUserId() }); } } public void RPC_SetTag(long sender, string tag, string authorId) { if (m_nview.IsValid() && m_nview.IsOwner()) { GetTagSignature(out var tagRaw, out var authorId2); if (!(tagRaw == tag) || !(authorId2 == authorId)) { ZDO zDO = m_nview.GetZDO(); zDO.Set(ZDOVars.s_tag, tag); zDO.Set(ZDOVars.s_tagauthor, authorId); } } } public static List<KeyValuePair<long, string>> GetWaystoneActivatedPlayers(ZDO zdo) { List<KeyValuePair<long, string>> list = new List<KeyValuePair<long, string>>(); int @int = zdo.GetInt(ZDOVars.s_permitted, 0); for (int i = 0; i < @int; i++) { long @long = zdo.GetLong("pu_id" + i, 0L); string @string = zdo.GetString("pu_name" + i, ""); if (@long != 0) { list.Add(new KeyValuePair<long, string>(@long, @string)); } } return list; } public static bool IsWaystoneActivated(ZDO zdo, long playerID) { if (zdo == null) { return false; } foreach (KeyValuePair<long, string> waystoneActivatedPlayer in GetWaystoneActivatedPlayers(zdo)) { if (waystoneActivatedPlayer.Key == playerID) { return true; } } return false; } internal static bool IsSearchAllowed(Player player) { if ((Object)(object)player == (Object)null) { return false; } if ((Object)(object)player != (Object)(object)Player.m_localPlayer) { return false; } if (WorldData.IsOnCooldown()) { ((Character)player).Message((MessageType)2, "$hud_powernotready: " + WorldData.GetCooldownString(), 0, (Sprite)null); return false; } if (IsNotInPosition(player)) { ((Character)player).Message((MessageType)2, "$msg_cart_incorrectposition", 0, (Sprite)null); return false; } if (!global::Waystones.Waystones.allowEncumbered.Value && ((Character)player).IsEncumbered()) { ((Character)player).Message((MessageType)2, "$se_encumbered_start", 0, (Sprite)null); return false; } if (!global::Waystones.Waystones.allowNonTeleportableItems.Value && !((Humanoid)player).IsTeleportable()) { ((Character)player).Message((MessageType)2, "$msg_noteleport", 0, (Sprite)null); return false; } if (!global::Waystones.Waystones.allowWet.Value && ((Character)player).GetSEMan().HaveStatusEffect(SEMan.s_statusEffectWet)) { ((Character)player).Message((MessageType)2, "$msg_bedwet", 0, (Sprite)null); return false; } if (!global::Waystones.Waystones.allowSensed.Value && player.IsSensed()) { ((Character)player).Message((MessageType)2, "$msg_bedenemiesnearby", 0, (Sprite)null); return false; } if (!global::Waystones.Waystones.allowNonSitting.Value && !((Character)player).IsSitting()) { ((Character)player).Message((MessageType)2, "$ws_piece_waystone_sit", 0, (Sprite)null); return false; } return true; } internal static bool IsNotInPosition(Player player) { return ((Character)player).IsAttachedToShip() || ((Character)player).IsAttached() || ((Character)player).IsDead() || ((Character)player).IsRiding() || player.IsSleeping() || ((Character)player).IsTeleporting() || ((Character)player).InPlaceMode() || ((Character)player).InBed() || ((Character)player).InCutscene() || ((Character)player).InInterior(); } } internal class CustomPrefabs { [HarmonyPatch(typeof(ZNetView), "Awake")] public static class ZNetView_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "Awake")] public static class ZSyncTransform_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ZSyncTransform), "OnEnable")] public static class ZSyncTransform_OnEnable_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Awake")] public static class ItemDrop_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(Piece), "Awake")] public static class Piece_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(WearNTear), "Awake")] public static class WearNTear_Awake_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(WearNTear), "Start")] public static class WearNTear_Start_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } [HarmonyPatch(typeof(GuidePoint), "Start")] public static class GuidePoint_Start_AddPrefab { [HarmonyPriority(800)] private static bool Prefix() { return !prefabInit; } } private const string c_rootObjectName = "_shudnalRoot"; private const string c_rootPrefabsName = "Prefabs"; private static GameObject rootObject; private static GameObject rootPrefabs; public static bool prefabInit; private static void InitRootObject() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown if ((Object)(object)rootObject == (Object)null) { rootObject = (GameObject)(((object)GameObject.Find("_shudnalRoot")) ?? ((object)new GameObject("_shudnalRoot"))); } Object.DontDestroyOnLoad((Object)(object)rootObject); if ((Object)(object)rootPrefabs == (Object)null) { Transform obj = rootObject.transform.Find("Prefabs"); rootPrefabs = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)rootPrefabs == (Object)null) { rootPrefabs = new GameObject("Prefabs"); rootPrefabs.transform.SetParent(rootObject.transform, false); rootPrefabs.SetActive(false); } } } internal static GameObject InitPrefabClone(GameObject prefabToClone, string prefabName) { InitRootObject(); if ((Object)(object)rootPrefabs.transform.Find(prefabName) != (Object)null) { return ((Component)rootPrefabs.transform.Find(prefabName)).gameObject; } prefabInit = true; GameObject val = Object.Instantiate<GameObject>(prefabToClone, rootPrefabs.transform, false); prefabInit = false; ((Object)val).name = prefabName; return val; } internal static Component AddComponent(GameObject gameObject, Type type) { prefabInit = true; Component result = gameObject.AddComponent(type); prefabInit = false; return result; } } namespace LocalizationManager { [PublicAPI] public class Localizer { private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors; private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts; private static readonly ConditionalWeakTable<Localization, string> localizationLanguage; private static readonly List<WeakReference<Localization>> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List<string> fileExtensions; private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } private static void UpdatePlaceholderText(Localization localization, string key) { localizationLanguage.TryGetValue(localization, out string value); string text = loadedTexts[value][key]; if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull { string key2 = key; string placeholder2 = placeholder; Func<T, string> convertConfigValue2 = convertConfigValue; ConfigEntry<T> config2 = config; if (convertConfigValue2 == null) { convertConfigValue2 = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key2)) { PlaceholderProcessors[key2] = new Dictionary<string, Func<string>>(); } config2.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value); UpdatePlaceholderText(Localization.instance, key2); } } public static void AddText(string key, string text) { List<WeakReference<Localization>> list = new List<WeakReference<Localization>>(); foreach (WeakReference<Localization> localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference<Localization> item in list) { localizationObjects.Remove(item); } } public static void Load() { LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference<Localization>(__instance)); } localizationLanguage.Add(__instance, language); Dictionary<string, string> dictionary = new Dictionary<string, string>(); foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories) where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0 select f) { string text = Path.GetFileNameWithoutExtension(item).Split('.')[1]; if (dictionary.ContainsKey(text)) { Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped.")); } else { dictionary[text] = item; } } byte[] array = LoadTranslationFromAssembly("English"); if (array == null) { throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml."); } Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array)); if (dictionary2 == null) { throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text2 = null; if (language != "English") { if (dictionary.ContainsKey(language)) { text2 = File.ReadAllText(dictionary[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text2 = Encoding.UTF8.GetString(array2); } } } if (text2 == null && dictionary.ContainsKey("English")) { text2 = File.ReadAllText(dictionary["English"]); } if (text2 != null) { foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>()) { dictionary2[item2.Key] = item2.Value; } } loadedTexts[language] = dictionary2; foreach (KeyValuePair<string, string> item3 in dictionary2) { UpdatePlaceholderText(__instance, item3.Key); } } static Localizer() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>(); loadedTexts = new Dictionary<string, Dictionary<string, string>>(); localizationLanguage = new ConditionalWeakTable<Localization, string>(); localizationObjects = new List<WeakReference<Localization>>(); fileExtensions = new List<string> { ".json", ".yml" }; Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static byte[]? LoadTranslationFromAssembly(string language) { foreach (string fileExtension in fileExtensions) { byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension); if (array != null) { return array; } } return null; } public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null) { string resourceFileName2 = resourceFileName; using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Waystones { internal static class CustomSyncedValuesSynchronizer { private static readonly Queue<IEnumerator> coroutines = new Queue<IEnumerator>(); private static readonly WaitWhile waitForServerUpdate = new WaitWhile((Func<bool>)(() => ConfigSync.ProcessingServerUpdate)); public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, T value) { AddToQueue(AssignAfterServerUpdate(syncedValue, value, assignIfChanged: false)); } public static void AssignValueSafe<T>(this CustomSyncedValue<T> syncedValue, Func<T> function) { AddToQueue(AssignAfterServerUpdate(syncedValue, function, assignIfChanged: false)); } public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, T value) { AddToQueue(AssignAfterServerUpdate(syncedValue, value, assignIfChanged: true)); } public static void AssignValueIfChanged<T>(this CustomSyncedValue<T> syncedValue, Func<T> function) { AddToQueue(AssignAfterServerUpdate(syncedValue, function, assignIfChanged: true)); } private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, Func<T> function, bool assignIfChanged) { yield return AssignAfterServerUpdate(syncedValue, function(), assignIfChanged); } private static IEnumerator AssignAfterServerUpdate<T>(CustomSyncedValue<T> syncedValue, T value, bool assignIfChanged) { if (!assignIfChanged || !syncedValue.Value.Equals(value)) { yield return waitForServerUpdate; syncedValue.AssignLocalValue(value); } } private static void AddToQueue(IEnumerator coroutine) { coroutines.Enqueue(coroutine); if (coroutines.Count == 1) { ((MonoBehaviour)Waystones.instance).StartCoroutine(CoroutineCoordinator()); } } private static IEnumerator CoroutineCoordinator() { while (true) { if (coroutines.Count > 0) { yield return ((MonoBehaviour)Waystones.instance).StartCoroutine(coroutines.Peek()); coroutines.Dequeue(); } else if (coroutines.Count == 0) { break; } } } } public static class DirectionSearch { public class Direction { public string name; public Vector3 position; public Quaternion rotation; public double cooldown; public static readonly StringBuilder _sb = new StringBuilder(3); public Direction(string name, Vector3 position) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) this.name = name; this.position = position; rotation = Quaternion.identity; cooldown = WorldData.GetCooldownTimeToTarget(position); } public Direction(string name, Vector3 position, Quaternion rotation) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) this.name = name; this.position = position; this.rotation = rotation; cooldown = WorldData.GetCooldownTimeToTarget(position); } public string GetHoverText() { _sb.Clear(); _sb.Append(name); _sb.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $ws_tooltip_moving_to"); _sb.Append("\n\n$ws_tooltip_cooldown_after <color=#add8e6>" + WorldData.TimerString(cooldown) + "</color>"); return Localization.instance.Localize(_sb.ToString()); } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] public static class Hud_UpdateCrosshair_HoverTextDirectionMode { private static void Postfix(Hud __instance) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (activated && current != null) { ((TMP_Text)__instance.m_hoverName).SetText(current.GetHoverText()); ((Graphic)__instance.m_crosshair).color = (Color)((((TMP_Text)__instance.m_hoverName).text.Length > 0) ? Color.yellow : new Color(1f, 1f, 1f, 0.5f)); } } } [HarmonyPatch(typeof(Hud), "Awake")] public static class Hud_Awake_BlackPanelInit { private static void Postfix(Hud __instance) { GameObject val = Object.Instantiate<GameObject>(((Component)__instance.m_loadingScreen).gameObject, ((Component)__instance.m_loadingScreen).transform.parent); ((Object)val).name = "Waystones_DirectionSearchBlack"; val.transform.SetSiblingIndex(0); val.transform.Find("Loading/TopFade").SetParent(val.transform); val.transform.Find("Loading/BottomFade").SetParent(val.transform); for (int num = val.transform.childCount - 1; num >= 0; num--) { Transform child = val.transform.GetChild(num); switch (((Object)child).name) { case "Loading": case "Sleeping": case "Teleporting": case "Image": case "Tip": case "panel_separator": Object.Destroy((Object)(object)((Component)child).gameObject); break; } } GameObject prefab = ZNetScene.instance.GetPrefab("guard_stone"); if ((Object)(object)prefab != (Object)null) { GameObject val2 = Object.Instantiate<GameObject>(((Component)prefab.transform.Find("WayEffect/sfx")).gameObject, val.transform); ((Object)val2).name = "sfx"; val2.AddComponent<FollowPlayer>(); val2.SetActive(true); screenBlackenerSfx = val2.GetComponent<AudioSource>(); } screenBlackener = val.GetComponent<CanvasGroup>(); ((Component)screenBlackener).gameObject.SetActive(false); Waystones.LogInfo("Blackener panel initialized"); } } [HarmonyPatch(typeof(Hud), "UpdateBlackScreen")] public static class Hud_UpdateBlackScreen_DirectionModeScreenEffect { private static void Postfix(float dt) { if (activated) { ((Component)screenBlackener).gameObject.SetActive(true); screenBlackener.alpha = Mathf.MoveTowards(screenBlackener.alpha, Mathf.Lerp(Waystones.fadeMin.Value, Waystones.fadeMax.Value, currentAngle / Mathf.Max(GetCurrentScreenSensivityThreshold(), GetCurrentSensivity())), dt); screenBlackenerSfx.volume = Mathf.MoveTowards(screenBlackenerSfx.volume, Mathf.Lerp(Waystones.sfxMax.Value, Waystones.sfxMin.Value, currentAngle / Mathf.Max(GetCurrentSfxSensivityThreshold(), GetCurrentSensivity())), dt * 3f); screenBlackenerSfx.pitch = Mathf.MoveTowards(screenBlackenerSfx.pitch, Mathf.Lerp(Waystones.sfxPitchMax.Value, Waystones.sfxPitchMin.Value, currentAngle / Mathf.Max(GetCurrentSfxSensivityThreshold(), GetCurrentSensivity())), dt); return; } screenBlackener.alpha = Mathf.MoveTowards(screenBlackener.alpha, 0f, dt / 2f); screenBlackenerSfx.volume = Mathf.MoveTowards(screenBlackenerSfx.volume, 0f, dt); screenBlackenerSfx.pitch = Mathf.MoveTowards(screenBlackenerSfx.pitch, 1f, dt); if (screenBlackener.alpha <= 0f) { ((Component)screenBlackener).gameObject.SetActive(false); } } } [HarmonyPatch] public static class JoyRightStick_SlowFactor { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ZInput), "GetJoyRightStickX", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZInput), "GetJoyRightStickY", (Type[])null, (Type[])null); } private static void Postfix(ref float __result) { if (activated) { if (!Game.CanPause()) { __result /= 2f; } else if (Game.m_timeScale != 0f) { __result *= Mathf.Clamp(1f / Game.m_timeScale, 1f, 2f); } } } } [HarmonyPatch(typeof(ZInput), "GetMouseDelta")] public static class ZInput_GetMouseDelta_SlowFactor { private static void Postfix(ref Vector2 __result) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (activated) { __result *= Mathf.Clamp(((Vector2)(ref __result)).magnitude / Waystones.slowFactorLookDeceleration.Value, Waystones.slowFactorLookMinimum.Value, 1f); } } } [HarmonyPatch] public static class StopDirectionMode_Postfix { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(Menu), "Show", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Menu), "Hide", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Game), "Unpause", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Game), "Pause", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZoneSystem), "OnDestroy", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(FejdStartup), "Start", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(FejdStartup), "OnDestroy", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Player), "SetSleeping", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Player), "UseHotbarItem", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Player), "StartGuardianPower", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null); } private static void Postfix() { Exit(force: true); } } [HarmonyPatch(typeof(GameCamera), "Awake")] public static class GameCamera_Awake_SetDefaultPov { private static void Postfix(GameCamera __instance) { defaultFoV = ((__instance.m_fov == 0f) ? 65f : __instance.m_fov); } } [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] public static class GameCamera_UpdateCamera_BlockCameraDistance { private static void Prefix(GameCamera __instance, ref float __state) { if (activated) { __state = __instance.m_zoomSens; __instance.m_zoomSens = 0f; } } private static void Postfix(GameCamera __instance, float __state) { if (activated) { __instance.m_zoomSens = __state; } } } [HarmonyPatch(typeof(Player), "SetControls")] public static class Player_SetControls_SearchModeExit { private static void Postfix(Player __instance, Vector3 movedir, bool attack, bool secondaryAttack, bool block, bool jump, bool crouch, bool run, bool autoRun, bool dodge) { if (activated && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (((Vector3)(ref movedir)).magnitude > 0.05f || attack || secondaryAttack || block || jump || crouch || run || autoRun || dodge)) { Exit(force: true); } } } [HarmonyPatch(typeof(Player), "FindHoverObject")] public static class Player_FindHoverObject_SearchMode { private static bool Prefix(Player __instance, out GameObject hover, out Character hoverCreature) { hover = null; hoverCreature = null; if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!activated) { return true; } return false; } } [HarmonyPatch(typeof(Player), "GetHoverObject")] public static class Player_GetHoverObject_SearchMode { private static bool Prefix(Player __instance, ref GameObject __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (!activated) { return true; } __result = null; return false; } } [HarmonyPatch(typeof(Minimap), "OnMapLeftDown")] public static class Minimap_ShowPinNameInput_BlockPinDialogInSearchMode { private static bool Prefix(Minimap __instance) { if (!IsActivated) { return true; } __instance.m_leftClickTime = Time.time; __instance.m_leftDownTime = Time.time; return false; } } private static List<Direction> directions = new List<Direction>(); private static Direction current; private static bool activated; private static readonly Direction placeOfMystery = new Direction("$ws_location_random_point", Vector2.op_Implicit(Vector2.zero)); private static float currentAngle; private static float defaultFoV; private static float targetFoV; public static CanvasGroup screenBlackener; public static AudioSource screenBlackenerSfx; public static bool IsActivated => activated; internal static void Toggle() { if (activated) { Exit(); } else if (Waystones.useShortcutToEnter.Value && Waystones.CanCast() && WaystoneSmall.IsSearchAllowed(Player.m_localPlayer)) { WaystoneList.EnterSearchMode(); } } internal static void Enter() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (Waystones.CanCast()) { if (!activated) { Game.FadeTimeScale(Waystones.slowFactorTime.Value, 4f); targetFoV = defaultFoV; Waystones.LogInfo($"Search mode activated at {((Component)Player.m_localPlayer).transform.position}"); } FillDirections(); activated = true; WaystoneList.UpdatePins(); } } internal static void Exit(bool force = false) { if (!Waystones.CanCast() && !force) { return; } if (activated) { GameCamera.instance.m_fov = defaultFoV; if (Game.m_timeScale >= Waystones.slowFactorTime.Value) { Game.FadeTimeScale(1f, 1f); } if (!WorldData.IsOnCooldown()) { WorldData.SetCooldown(Waystones.cooldownSearchMode.Value); } Waystones.LogInfo("Search mode ended"); } activated = false; current = null; currentAngle = 0f; WaystoneList.UpdatePins(); } internal static void FillDirections() { //IL_0024: 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_0190: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) directions.Clear(); if (Waystones.locationShowCurrentSpawn.Value) { directions.Add(new Direction("$ws_location_spawn_point", GetSpawnPoint())); } ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); foreach (KeyValuePair<Vector3, string> tempIcon in ZoneSystem.instance.tempIconList) { if (tempIcon.Value == "StartTemple" && Waystones.locationShowStartTemple.Value) { directions.Add(new Direction("$ws_location_start_temple", tempIcon.Key)); } else if (tempIcon.Value == "Vendor_BlackForest" && Waystones.locationShowHaldor.Value) { directions.Add(new Direction("$npc_haldor", tempIcon.Key)); } else if ((tempIcon.Value == "Hildir_camp") & Waystones.locationShowHildir.Value) { directions.Add(new Direction("$npc_hildir", tempIcon.Key)); } } PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile.HaveDeathPoint() && Waystones.locationShowLastTombstone.Value) { directions.Add(new Direction("$ws_location_last_tombstone", playerProfile.GetDeathPoint())); } directions.AddRange(WorldData.GetSavedDirections()); CollectionExtensions.Do<Direction>((IEnumerable<Direction>)directions, (Action<Direction>)delegate(Direction d) { //IL_0021: 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_004c: Unknown result type (might be due to invalid IL or missing references) Waystones.LogInfo(string.Format("{0} {1} {2} {3}", Localization.instance.Localize(d.name), d.position, WorldData.TimerString(d.cooldown), (Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position) < 10f) ? "(filtered, too close)" : "")); }); directions.RemoveAll((Direction d) => Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position) < 10f); } internal static Vector3 GetSpawnPoint() { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile.HaveCustomSpawnPoint()) { return playerProfile.GetCustomSpawnPoint(); } return playerProfile.GetHomePoint(); } internal static void Update() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Waystones.shortcut.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Toggle(); } else if (activated && (ZInput.GetButtonDown("Block") || ZInput.GetButtonDown("JoyButtonB"))) { Exit(); } if (current != null && (ZInput.GetButton("Use") || ZInput.GetButton("JoyUse")) && Waystones.CanCast()) { if (current == placeOfMystery) { current.position = GetRandomPoint(); } Waystones.TeleportAttempt(current.position, current.rotation, current.cooldown, current.name); Exit(); } if (activated && !Waystones.CanCast()) { Exit(force: true); } if (!activated) { return; } current = null; targetFoV -= Mathf.Clamp(ZInput.GetMouseScrollWheel(), -1f, 1f); if (ZInput.GetButton("JoyAltKeys") && !Hud.InRadial()) { if (ZInput.GetButton("JoyCamZoomIn")) { targetFoV -= 1f; } else if (ZInput.GetButton("JoyCamZoomOut")) { targetFoV += 1f; } } targetFoV = Mathf.Clamp(targetFoV, defaultFoV - Waystones.fovDelta.Value, defaultFoV + Waystones.fovDelta.Value); GameCamera.instance.m_fov = Mathf.MoveTowards(GameCamera.instance.m_fov, targetFoV, Waystones.fovDelta.Value); Vector3 look = ((Character)Player.m_localPlayer).GetLookDir(); currentAngle = Vector3.Angle(look, Vector3.down); if (currentAngle < GetCurrentSensivity() && Waystones.locationShowRandomPoint.Value) { current = placeOfMystery; } else if (directions.Count != 0) { Vector3 pos = ((Character)Player.m_localPlayer).GetEyePoint(); directions = directions.OrderBy((Direction dir) => Vector3.Angle(look, dir.position - pos)).ToList(); currentAngle = Vector3.Angle(look, directions[0].position - pos); if (currentAngle < GetCurrentSensivity()) { current = directions[0]; } } } private static float GetCurrentSensivity() { return Waystones.directionSensitivity.Value * targetFoV / defaultFoV; } private static float GetCurrentScreenSensivityThreshold() { return Waystones.directionSensitivityThreshold.Value * targetFoV / defaultFoV; } private static float GetCurrentSfxSensivityThreshold() { return Waystones.sfxSensitivityThreshold.Value * targetFoV / defaultFoV; } private static Vector3 GetRandomPoint() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 zero = Vector3.zero; do { zero = GetRandomPointInRadius(Vector3.zero, 10000f); } while (!IsValidRandomPointForTeleport(ref zero)); return zero; } private static bool IsValidRandomPointForTeleport(ref Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0018: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Biome biome = WorldGenerator.instance.GetBiome(pos); if ((int)biome == 256 || (int)biome == 0 || !Player.m_localPlayer.m_knownBiome.Contains(biome)) { return false; } pos = new Vector3(pos.x, 31f, pos.z); return true; } public static Vector3 GetRandomPointInRadius(Vector3 center, float radius) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) float num = Random.value * (float)Math.PI * 2f; float num2 = Random.Range(0f, radius); return center + new Vector3(Mathf.Sin(num) * num2, 0f, Mathf.Cos(num) * num2); } } internal static class WaystoneList { [HarmonyPatch(typeof(Minimap), "Start")] public static class WaystoneIconType { public static int pinType; private static void Postfix(Minimap __instance) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) pinType = __instance.m_visibleIconTypes.Length; bool[] array = new bool[pinType + 1]; Array.Copy(__instance.m_visibleIconTypes, array, pinType); __instance.m_visibleIconTypes = array; __instance.m_icons.Add(new SpriteData { m_name = (PinType)pinType, m_icon = iconWaystone }); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_WaystoneList { private static void Postfix() { RegisterRPCs(); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] public static class ZoneSystem_OnDestroy_WaystoneList { private static void Postfix() { waystoneObjects.Clear(); } } [HarmonyPatch(typeof(ZDOMan), "Load")] public static class ZDOMan_Load_WaystoneListInit { private static void Postfix(ZDOMan __instance) { foreach (KeyValuePair<ZDOID, ZDO> item in __instance.m_objectsByID) { if (item.Value.GetPrefab() == PieceWaystone.waystoneHash) { waystoneObjects.Add(item.Value); } } } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(ZDOID), typeof(Vector3), typeof(int) })] public static class ZDOMan_CreateNewZDO_WaystoneListAddNew { private static void Postfix(int prefabHashIn, ZDO __result) { if (((prefabHashIn != 0) ? prefabHashIn : __result.GetPrefab()) == PieceWaystone.waystoneHash) { waystoneObjects.Add(__result); } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] public static class ZDOMan_HandleDestroyedZDO_WaystoneListRemove { private static void Prefix(ZDOMan __instance, ZDOID uid) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = __instance.GetZDO(uid); if (zDO != null && zDO.GetPrefab() == PieceWaystone.waystoneHash) { waystoneObjects.Remove(zDO); } } } [HarmonyPatch(typeof(ZDO), "Deserialize")] public static class ZDO_Deserialize_WaystoneListAdd { private static void Postfix(ZDO __instance) { if (__instance.GetPrefab() == PieceWaystone.waystoneHash) { waystoneObjects.Add(__instance); } } } public static Sprite iconWaystone; public static readonly List<PinData> waystonePins = new List<PinData>(); public static readonly List<Tuple<string, Vector3, Quaternion>> activatedWaystones = new List<Tuple<string, Vector3, Quaternion>>(); public static readonly HashSet<ZDO> waystoneObjects = new HashSet<ZDO>(); public const string customDataKey = "WaystoneList"; public static void UpdatePins() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) foreach (PinData waystonePin in waystonePins) { Minimap.instance.RemovePin(waystonePin); } waystonePins.Clear(); if (!Waystones.locationWaystonesShowOnMap.Value || !DirectionSearch.IsActivated) { return; } foreach (Tuple<string, Vector3, Quaternion> activatedWaystone in activatedWaystones) { waystonePins.Add(Minimap.instance.AddPin(activatedWaystone.Item2, (PinType)WaystoneIconType.pinType, activatedWaystone.Item1, false, false, Player.m_localPlayer.GetPlayerID(), "")); } } internal static void RegisterRPCs() { if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register<long>("MarkedLocationRequest", (Action<long, long>)RPC_MarkedLocationRequest); } else { ZRoutedRpc.instance.Register<ZPackage>("MarkedLocationResponse", (Action<long, ZPackage>)RPC_MarkedLocationResponse); } } public static void EnterSearchMode() { if (!ZNet.instance.IsServer()) { MarkedLocationRequest(); } else if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { GetActivatedWaystones(Player.m_localPlayer.GetPlayerID()); DirectionSearch.Enter(); } } public static void MarkedLocationRequest() { Waystones.LogInfo("Marked location request"); ZRoutedRpc.instance.InvokeRoutedRPC("MarkedLocationRequest", new object[1] { Player.m_localPlayer.GetPlayerID() }); } public static List<Tuple<string, Vector3, Quaternion>> GetActivatedWaystones(long playerID) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_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) activatedWaystones.Clear(); foreach (ZDO waystoneObject in waystoneObjects) { if (WaystoneSmall.IsWaystoneActivated(waystoneObject, playerID)) { string @string = waystoneObject.GetString(ZDOVars.s_tag, ""); if (!string.IsNullOrWhiteSpace(@string)) { Vector3 position = waystoneObject.GetPosition(); Quaternion rotation = waystoneObject.GetRotation(); Vector3 val = rotation * Vector3.forward; Vector3 item = position + val * 1f + Vector3.up; activatedWaystones.Add(Tuple.Create<string, Vector3, Quaternion>(@string, item, rotation * Quaternion.Euler(0f, 180f, 0f))); } } } return activatedWaystones; } public static void RPC_MarkedLocationRequest(long sender, long playerID) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) GetActivatedWaystones(playerID); ZPackage val = new ZPackage(); val.Write(activatedWaystones.Count); foreach (Tuple<string, Vector3, Quaternion> activatedWaystone in activatedWaystones) { val.Write(activatedWaystone.Item1); val.Write(activatedWaystone.Item2); val.Write(activatedWaystone.Item3); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "MarkedLocationResponse", new object[1] { val }); } public static void RPC_MarkedLocationResponse(long sender, ZPackage pkg) { //IL_002e: 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) Waystones.LogInfo("Server responded with activated location list"); activatedWaystones.Clear(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { activatedWaystones.Add(Tuple.Create<string, Vector3, Quaternion>(pkg.ReadString(), pkg.ReadVector3(), pkg.ReadQuaternion())); } DirectionSearch.Enter(); } } internal class PieceWaystone { [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_AddPiece { private static void Postfix() { RegisterPiece(); } } public static Sprite itemWaystone; internal static GameObject waystonePrefab; internal const string waystoneName = "Waystone_small"; public static int waystoneHash = StringExtensionMethods.GetStableHashCode("Waystone_small"); public const string waystonePieceName = "$ws_piece_waystone_name"; public const string waystonePieceDescription = "$ws_piece_waystone_description"; public static void RegisterPiece() { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01df: 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_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Expected O, but got Unknown //IL_03d7: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0424: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Expected O, but got Unknown //IL_04a8: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)waystonePrefab)) { WayStone val = ((IEnumerable<WayStone>)Resources.FindObjectsOfTypeAll<WayStone>()).FirstOrDefault((Func<WayStone, bool>)((WayStone ws) => ((Object)ws).name == "Waystone")); if ((Object)(object)val == (Object)null) { return; } waystonePrefab = CustomPrefabs.InitPrefabClone(((Component)val).gameObject, "Waystone_small"); Transform transform = waystonePrefab.transform; transform.localScale *= 0.15f; LODGroup component = waystonePrefab.GetComponent<LODGroup>(); LOD[] lODs = component.GetLODs(); List<Renderer> list = lODs[0].renderers.Where((Renderer r) => ((Object)r).name == "model").ToList(); list.Add((Renderer)(object)((Component)waystonePrefab.transform.Find("WayEffect/Particle System sparcs")).GetComponent<ParticleSystemRenderer>()); lODs[0].renderers = list.ToArray(); component.SetLODs(lODs); Object.Destroy((Object)(object)((Component)waystonePrefab.transform.Find("WayEffect/Particle System")).gameObject); Object.Destroy((Object)(object)((Component)waystonePrefab.transform.Find("WayEffect/sfx")).gameObject); Transform val2 = waystonePrefab.transform.Find("WayEffect/Particle System (1)"); val2.localScale *= 0.75f; MainModule main = ((Component)val2).GetComponent<ParticleSystem>().main; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.75f); ((MainModule)(ref main)).startSpeedMultiplier = 0.1f; ((MainModule)(ref main)).maxParticles = 75; ShapeModule shape = ((Component)val2).GetComponent<ParticleSystem>().shape; ((ShapeModule)(ref shape)).radius = 0.005f; EmissionModule emission = ((Component)val2).GetComponent<ParticleSystem>().emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(5f); Transform obj2 = waystonePrefab.transform.Find("WayEffect/Particle System sparcs"); obj2.localScale *= 0.4f; Light component2 = ((Component)waystonePrefab.transform.Find("WayEffect/Point light")).GetComponent<Light>(); component2.intensity = 1.1f; Light component3 = ((Component)waystonePrefab.transform.Find("Point light (1)")).GetComponent<Light>(); component3.intensity = 1.1f; ((Component)component3).gameObject.AddComponent<LightLod>().m_lightDistance = 50f; waystonePrefab.GetComponentInChildren<EffectArea>().m_type = (Type)2; Component obj3 = CustomPrefabs.AddComponent(waystonePrefab, typeof(ZNetView)); ZNetView val3 = (ZNetView)(object)((obj3 is ZNetView) ? obj3 : null); val3.m_persistent = true; val3.m_distant = true; val3.m_type = (ObjectType)2; Component obj4 = CustomPrefabs.AddComponent(waystonePrefab, typeof(Piece)); Piece val4 = (Piece)(object)((obj4 is Piece) ? obj4 : null); val4.m_icon = itemWaystone; val4.m_name = "$ws_piece_waystone_name"; val4.m_description = "$ws_piece_waystone_description"; val4.m_clipGround = true; val4.m_clipEverything = true; val4.m_notOnTiltingSurface = true; val4.m_noClipping = false; ((StaticTarget)val4).m_randomTarget = false; Component obj5 = CustomPrefabs.AddComponent(waystonePrefab, typeof(WearNTear)); WearNTear val5 = (WearNTear)(object)((obj5 is WearNTear) ? obj5 : null); GameObject val6 = new GameObject("new"); val6.transform.SetParent(waystonePrefab.transform); val6.transform.SetSiblingIndex(0); waystonePrefab.transform.Find("model").SetParent(val6.transform); val5.m_new = val6; val5.m_worn = val6; val5.m_broken = val6; val5.m_noRoofWear = false; val5.m_noSupportWear = true; val5.m_burnable = false; val5.m_supports = false; val5.m_ashDamageResist = true; val5.m_materialType = (MaterialType)1; val5.m_health = 1000f; val5.m_damages.m_pierce = (DamageModifier)1; val5.m_damages.m_chop = (DamageModifier)4; val5.m_damages.m_pickaxe = (DamageModifier)4; val5.m_damages.m_fire = (DamageModifier)1; val5.m_damages.m_frost = (DamageModifier)1; val5.m_damages.m_poison = (DamageModifier)3; val5.m_damages.m_spirit = (DamageModifier)3; WayStone component4 = waystonePrefab.GetComponent<WayStone>(); WaystoneSmall.initial = true; WaystoneSmall waystoneSmall = waystonePrefab.AddComponent<WaystoneSmall>(); WaystoneSmall.initial = false; Object.Destroy((Object)(object)component4); GameObject val7 = new GameObject("GuidePoint"); val7.transform.SetParent(waystonePrefab.transform); val7.transform.localPosition = new Vector3(-0.5f, 8.9f, -1.3f); Component obj6 = CustomPrefabs.AddComponent(val7, typeof(GuidePoint)); GuidePoint val8 = (GuidePoint)(object)((obj6 is GuidePoint) ? obj6 : null); val8.m_text.m_alwaysSpawn = false; val8.m_text.m_key = "ws_waystone"; val8.m_text.m_topic = "$ws_tutorial_waystone_topic"; val8.m_text.m_label = "$ws_tutorial_waystone_label"; val8.m_text.m_text = "$ws_tutorial_waystone_text"; Waystones.LogInfo("Waystone prefab added"); } if (Object.op_Implicit((Object)(object)waystonePrefab)) { GameObject prefab = ZNetScene.instance.GetPrefab("stone_pile"); if ((Object)(object)prefab != (Object)null) { waystonePrefab.GetComponent<Piece>().m_placeEffect.m_effectPrefabs = prefab.GetComponent<Piece>().m_placeEffect.m_effectPrefabs.ToArray(); waystonePrefab.GetComponent<WearNTear>().m_destroyedEffect.m_effectPrefabs = prefab.GetComponent<WearNTear>().m_destroyedEffect.m_effectPrefabs.ToArray(); waystonePrefab.GetComponent<WearNTear>().m_hitEffect.m_effectPrefabs = prefab.GetComponent<WearNTear>().m_hitEffect.m_effectPrefabs.ToArray(); } WaystoneSmall component5 = waystonePrefab.GetComponent<WaystoneSmall>(); WayStone val9 = ((IEnumerable<WayStone>)Resources.FindObjectsOfTypeAll<WayStone>()).FirstOrDefault((Func<WayStone, bool>)((WayStone obj) => ((Object)obj).name == "Waystone")); if ((Object)(object)val9 != (Object)null) { component5.m_activateEffect.m_effectPrefabs = val9.m_activeEffect.m_effectPrefabs.ToArray(); } GameObject prefab2 = ZNetScene.instance.GetPrefab("guard_stone"); PrivateArea val10 = ((prefab2 != null) ? prefab2.GetComponent<PrivateArea>() : null); if ((Object)(object)val10 != (Object)null) { component5.m_deactivateEffect.m_effectPrefabs = val10.m_removedPermittedEffect.m_effectPrefabs.ToArray(); } GameObject prefab3 = ZNetScene.instance.GetPrefab("piece_workbench"); GuidePoint val11 = ((prefab3 != null) ? prefab3.GetComponentInChildren<GuidePoint>() : null); if ((Object)(object)val11 != (Object)null) { waystonePrefab.GetComponentInChildren<GuidePoint>().m_ravenPrefab = val11.m_ravenPrefab; } if (ZNetScene.instance.m_namedPrefabs.ContainsKey(waystoneHash)) { ZNetScene.instance.m_prefabs.Remove(ZNetScene.instance.m_namedPrefabs[waystoneHash]); ZNetScene.instance.m_namedPrefabs.Remove(waystoneHash); } ZNetScene.instance.m_prefabs.Add(waystonePrefab); ZNetScene.instance.m_namedPrefabs.Add(waystoneHash, waystonePrefab); SetPieceRequirements(); PieceTable val12 = ((IEnumerable<PieceTable>)Resources.FindObjectsOfTypeAll<PieceTable>()).FirstOrDefault((Func<PieceTable, bool>)((PieceTable ws) => ((Object)ws).name == "_HammerPieceTable")); if ((Object)(object)val12 != (Object)null && !val12.m_pieces.Contains(waystonePrefab)) { val12.m_pieces.Add(waystonePrefab); } } } public static void SetPieceRequirements() { //IL_00ba: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown if ((Object)(object)waystonePrefab == (Object)null) { return; } Piece component = waystonePrefab.GetComponent<Piece>(); List<Requirement> list = new List<Requirement>(); string[] array = Waystones.pieceRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length != 2) { continue; } int num = int.Parse(array2[1]); if (num > 0) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim()); if (!((Object)(object)itemPrefab == (Object)null)) { list.Add(new Requirement { m_amount = num, m_resItem = itemPrefab.GetComponent<ItemDrop>(), m_recover = true }); } } } component.m_resources = list.ToArray(); } } internal class WaystoneTravelEffect : MonoBehaviour { private ZNetView m_nview; private float volume; private AudioSource sfx; private MainModule main; private Light light; public static readonly int progressHash = StringExtensionMethods.GetStableHashCode("TravelProgress"); public static bool initial = false; private void Awake() { if (!initial) { m_nview = ((Component)this).GetComponent<ZNetView>(); } } private void Start() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) sfx = ((Component)((Component)this).transform.Find("Sfx")).GetComponent<AudioSource>(); ((Behaviour)sfx).enabled = true; volume = sfx.volume; main = ((Component)((Component)this).transform.Find("Sparcs")).GetComponent<ParticleSystem>().main; light = ((Component)((Component)this).transform.Find("Light")).GetComponent<Light>(); } private void Update() { //IL_0020: 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) float progress = GetProgress(m_nview); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.5f + 5.5f * progress); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(4f - 3.5f * progress); ((MainModule)(ref main)).simulationSpeed = 1f + progress; light.intensity = 1f + 2f * progress; light.range = 5f + 15f * progress; sfx.volume = volume * progress; } internal static void SetProgress(ZNetView netView, float progress) { if (!((Object)(object)netView == (Object)null) && netView.IsValid()) { netView.GetZDO().Set(progressHash, progress); } } internal static float GetProgress(ZNetView netView) { if ((Object)(object)netView == (Object)null || !netView.IsValid()) { return 0f; } return netView.GetZDO().GetFloat(progressHash, 0f); } } [Serializable] public class WorldData { [HarmonyPatch(typeof(Ship), "OnTriggerExit")] public static class Ship_OnTriggerExit_LastShipPosition { private static void Prefix(Ship __instance, Collider collider) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && (Object)(object)Player.m_localPlayer == (Object)(object)((Component)collider).GetComponent<Player>() && Ship.s_currentShips.Contains(__instance)) { saveNextGroundPositionAsShipLocation = true; } } } [HarmonyPatch(typeof(Player), "FixedUpdate")] public static class Player_FixedUpdate_SaveLastShipPosition { private static void Postfix(Player __instance) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && saveNextGroundPositionAsShipLocation && ((Character)__instance).IsOnGround() && !((Character)__instance).InWater() && (Object)(object)((Character)__instance).GetStandingOnShip() == (Object)null) { saveNextGroundPositionAsShipLocation = false; SaveLastShip(((Component)Player.m_localPlayer).transform.position); } } } public long worldUID; public string globalTime; public double worldTime; public Vector3 lastShip = Vector3.zero; public Vector3 lastPosition = Vector3.zero; public const string customDataKey = "Waystones"; public static bool saveNextGroundPositionAsShipLocation; public static List<DirectionSearch.Direction> GetSavedDirections() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_00b2: Unknown result type (might be due to invalid IL or missing references) List<DirectionSearch.Direction> result = new List<DirectionSearch.Direction>(); WorldData worldData = GetWorldData(GetState()); if (worldData == null) { return result; } _ = worldData.lastShip; if (worldData.lastShip != Vector3.zero && Waystones.locationShowLastShip.Value) { result.Add(new DirectionSearch.Direction("$ws_location_last_ship", worldData.lastShip)); } _ = worldData.lastPosition; if (worldData.lastPosition != Vector3.zero && Waystones.locationShowLastPoint.Value) { result.Add(new DirectionSearch.Direction("$ws_location_last_location", worldData.lastPosition)); } if (Waystones.locationShowWaystones.Value) { CollectionExtensions.Do<Tuple<string, Vector3, Quaternion>>((IEnumerable<Tuple<string, Vector3, Quaternion>>)WaystoneList.activatedWaystones, (Action<Tuple<string, Vector3, Quaternion>>)delegate(Tuple<string, Vector3, Quaternion> waystone) { //IL_001c: 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) result.Add(new DirectionSearch.Direction("$ws_piece_waystone_name \"" + waystone.Item1 + "\"", waystone.Item2, waystone.Item3)); }); } return result; } public static void SaveLastPosition(Vector3 position) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0035: Unknown result type (might be due to invalid IL or missing references) List<WorldData> state = GetState(); GetWorldData(state, createIfEmpty: true).lastPosition = position; Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Vector3 val = position; Waystones.LogInfo("Last teleport location saved: " + ((object)(Vector3)(ref val)).ToString()); } public static void SaveLastShip(Vector3 position) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_0035: Unknown result type (might be due to invalid IL or missing references) List<WorldData> state = GetState(); GetWorldData(state, createIfEmpty: true).lastShip = position; Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Vector3 val = position; Waystones.LogInfo("Last ship location saved: " + ((object)(Vector3)(ref val)).ToString()); } private double GetCooldownTime() { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return 0.0; } if (Waystones.cooldownTime.Value == Waystones.CooldownTime.WorldTime) { return (worldTime == 0.0) ? 0.0 : Math.Max(worldTime - ZNet.instance.GetTimeSeconds(), 0.0); } if (DateTime.TryParse(globalTime, CultureInfo.InvariantCulture, DateTimeStyles.None, out var result)) { return Math.Max((result - GetTime()).TotalSeconds, 0.0); } return 0.0; } private void SetCooldownTime(double cooldown) { if (Waystones.cooldownTime.Value == Waystones.CooldownTime.GlobalTime) { globalTime = GetTime().AddSeconds(cooldown).ToString(CultureInfo.InvariantCulture); } else { worldTime = ZNet.instance.GetTimeSeconds() + cooldown; } } public static double GetCooldownTimeToTarget(Vector3 target) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (target == Vector3.zero) { return Waystones.cooldownMinimum.Value; } float num = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, target); if (num < (float)Waystones.cooldownDistanceMinimum.Value) { return Waystones.cooldownMinimum.Value; } if (num > (float)Waystones.cooldownDistanceMaximum.Value) { return Waystones.cooldownMaximum.Value; } return Mathf.Lerp((float)Waystones.cooldownMinimum.Value, (float)Waystones.cooldownMaximum.Value, (num - (float)Waystones.cooldownDistanceMinimum.Value) / (float)(Waystones.cooldownDistanceMaximum.Value - Waystones.cooldownDistanceMinimum.Value)); } private static DateTime GetTime() { return DateTime.Now.ToUniversalTime(); } internal static WorldData GetWorldData(List<WorldData> state, bool createIfEmpty = false) { long uid = ZNet.instance.GetWorldUID(); WorldData worldData = state.Find((WorldData d) => d.worldUID == uid); if (createIfEmpty && worldData == null) { worldData = new WorldData { worldUID = uid }; state.Add(worldData); } return worldData; } public static void SetCooldown(double cooldown) { if (Object.op_Implicit((Object)(object)ZNet.instance)) { List<WorldData> state = GetState(); GetWorldData(state, createIfEmpty: true).SetCooldownTime(cooldown); Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Waystones.LogInfo("Cooldown set " + TimerString(cooldown)); } } public static bool TryReduceCooldown(int seconds) { if (!Object.op_Implicit((Object)(object)ZNet.instance)) { return false; } List<WorldData> state = GetState(); WorldData worldData = GetWorldData(state); if (worldData == null) { return false; } worldData.SetCooldownTime(Math.Max(worldData.GetCooldownTime() - (double)seconds, 0.0)); Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Waystones.LogInfo("Cooldown set " + TimerString(worldData.GetCooldownTime())); return true; } internal static bool IsOnCooldown() { WorldData worldData = GetWorldData(GetState()); return worldData != null && worldData.GetCooldownTime() > 0.0; } internal static string GetCooldownString() { WorldData worldData = GetWorldData(GetState()); return (worldData == null) ? "" : TimerString(worldData.GetCooldownTime()); } public static string TimerString(double seconds) { if (seconds < 60.0) { return DateTime.FromBinary(599266080000000000L).AddSeconds(seconds).ToString("ss\\s"); } TimeSpan timeSpan = TimeSpan.FromSeconds(seconds); if (timeSpan.Hours > 0) { return string.Format("{0}{1}", (int)timeSpan.TotalHours, new DateTime(timeSpan.Ticks).ToString("\\h mm\\m")); } if (timeSpan.Seconds == 0) { return new DateTime(timeSpan.Ticks).ToString("mm\\m"); } return new DateTime(timeSpan.Ticks).ToString("mm\\m ss\\s"); } private static List<WorldData> GetState() { string value; return Player.m_localPlayer.m_customData.TryGetValue("Waystones", out value) ? GetWorldDataList(value) : new List<WorldData>(); } private static List<WorldData> GetWorldDataList(string value) { List<WorldData> data = new List<WorldData>(); CollectionExtensions.Do<string>(SplitToLines(value), (Action<string>)delegate(string line) { data.Add(JsonUtility.FromJson<WorldData>(line)); }); return data; } private static string SaveWorldDataList(List<WorldData> list) { StringBuilder sb = new StringBuilder(); CollectionExtensions.Do<WorldData>((IEnumerable<WorldData>)list, (Action<WorldData>)delegate(WorldData data) { sb.AppendLine(JsonUtility.ToJson((object)data)); }); return sb.ToString(); } private static IEnumerable<string> SplitToLines(string input) { if (input == null) { yield break; } using StringReader reader = new StringReader(input); while (true) { string text; string line = (text = reader.ReadLine()); if (text == null) { break; } yield return line; } } } [BepInPlugin("shudnal.Waystones", "Waystones", "1.0.5")] public class Waystones : BaseUnityPlugin { public enum CooldownTime { WorldTime, GlobalTime } [HarmonyPatch(typeof(ZInput), "GetMouseDelta")] public static class ZInput_GetMouseDelta_PreventMouseInput { [HarmonyPriority(0)] public static void Postfix(ref Vector2 __result) { //IL_000b: 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) if (PreventPlayerInput()) { __result = Vector2.zero; } } } [HarmonyPatch] public static class JoyRightStick_SlowFactor { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ZInput), "GetJoyRightStickX", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZInput), "GetJoyRightStickY", (Type[])null, (Type[])null); } private static void Postfix(ref float __result) { if (PreventPlayerInput()) { __result = 0f; } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] public static class PlayerController_TakeInput_PreventPlayerMovements { [HarmonyPriority(800)] public static bool Prefix() { return !PreventPlayerInput(); } } [HarmonyPatch(typeof(Player), "SetMouseLook")] public static class Player_SetMouseLook_PreventPlayerMovements { [HarmonyPriority(800)] public static void Prefix(Player __instance, ref Vector2 mouseLook) { //IL_0016: 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) if (((Character)__instance).GetSEMan().HaveStatusEffect(SE_Waystone.statusEffectWaystonesHash)) { mouseLook = Vector2.zero; } } } [HarmonyPatch(typeof(Player), "ActivateGuardianPower")] public static class Player_ActivateGuardianPower_PreventGPowerUseWhenTeleporting { private static bool Prefix(Player __instance) { return !((Character)__instance).GetSEMan().HaveStatusEffect(SE_Waystone.statusEffectWaystonesHash); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public static class ZoneSystem_Start_InitSeasonStateAndConfigWatcher { private static void Postfix() { SetupConfigWatcher(enabled: true); } } [HarmonyPatch(typeof(ZoneSystem), "OnDestroy")] public static class ZoneSystem_OnDestroy_DisableConfigWatcher { private static void Postfix() { SetupConfigWatcher(enabled: false); } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__61_0; public static ConsoleEvent <>9__64_0; internal void <ConfigInit>b__61_0(object sender, EventArgs args) { PieceWaystone.SetPieceRequirements(); } internal void <InitCommands>b__64_0(ConsoleEventArgs args) { WorldData.SetCooldown(args.TryParameterInt(1, 0)); } } private const string pluginID = "shudnal.Waystones"; private const string pluginName = "Waystones"; private const string pluginVersion = "1.0.5"; private readonly Harmony harmony = new Harmony("shudnal.Waystones"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.Waystones") { DisplayName = "Waystones", CurrentVersion = "1.0.5", MinimumRequiredVersion = "1.0.5" }; internal static Waystones instance; internal static ConfigEntry<bool> configLocked; internal static ConfigEntry<bool> loggingEnabled; internal static ConfigEntry<KeyboardShortcut> shortcut; internal static ConfigEntry<string> pieceRecipe; internal static ConfigEntry<bool> itemSacrifitionReduceCooldown; internal static ConfigEntry<bool> locationWaystonesShowOnMap; internal static ConfigEntry<bool> locationShowCurrentSpawn; internal static ConfigEntry<bool> locationShowLastPoint; internal static ConfigEntry<bool> locationShowLastShip; internal static ConfigEntry<bool> locationShowLastTombstone; internal static ConfigEntry<bool> locationShowStartTemple; internal static ConfigEntry<bool> locationShowHaldor; internal static ConfigEntry<bool> locationShowHildir; internal static ConfigEntry<bool> locationShowWaystones; internal static ConfigEntry<bool> locationShowRandomPoint; internal static ConfigEntry<bool> useShortcutToEnter; internal static ConfigEntry<bool> allowEncumbered; internal static ConfigEntry<bool> allowNonTeleportableItems; internal static ConfigEntry<bool> emitNoiseOnTeleportation; internal static ConfigEntry<bool> allowWet; internal static ConfigEntry<bool> allowSensed; internal static ConfigEntry<bool> allowNonSitting; internal static ConfigEntry<int> tagCharactersLimit; internal static ConfigEntry<float> directionSensitivity; internal static ConfigEntry<float> directionSensitivityThreshold; internal static ConfigEntry<float> fadeMax; internal static ConfigEntry<float> fadeMin; internal static ConfigEntry<float> slowFactorTime; internal static ConfigEntry<float> slowFactorLookDeceleration; internal static ConfigEntry<float> slowFactorLookMinimum; internal static ConfigEntry<float> fovDelta; internal static ConfigEntry<float> sfxSensitivityThreshold; internal static ConfigEntry<float> sfxMax; internal static ConfigEntry<float> sfxMin; internal static ConfigEntry<float> sfxPitchMax; internal static ConfigEntry<float> sfxPitchMin; internal static ConfigEntry<CooldownTime> cooldownTime; internal static ConfigEntry<int> cooldownMaximum; internal static ConfigEntry<int> cooldownMinimum; internal static ConfigEntry<int> cooldownDistanceMaximum; internal static ConfigEntry<int> cooldownDistanceMinimum; internal static ConfigEntry<int> cooldownShort; internal static ConfigEntry<int> cooldownSearchMode; internal static ConfigEntry<bool> particlesCollision; internal static ConfigEntry<int> particlesMaxAmount; internal static ConfigEntry<int> particlesMinRateOverTime; internal static ConfigEntry<int> particlesMaxRateOverTime; internal static ConfigEntry<int> particlesMinForceOverTime; internal static ConfigEntry<int> particlesMaxForceOverTime; public static readonly CustomSyncedValue<Dictionary<string, int>> itemsToReduceCooldown = new CustomSyncedValue<Dictionary<string, int>>(configSync, "Items to reduce cooldowns", new Dictionary<string, int>()); public static string configDirectory; internal static FileSystemWatcher configWatcher; private const string itemsToReduceCooldownFilter = "shudnal.Waystones.reduce_cooldowns.*"; private void Awake() { harmony.PatchAll(); instance = this; ConfigInit(); configSync.AddLockingConfigEntry<bool>(configLocked); Game.isModded = true; configDirectory = Path.Combine(Paths.ConfigPath, "shudnal.Waystones"); LoadIcons(); Localizer.Load(); } public void ConfigInit() { //IL_02a9: Unknown result type (might be due to invalid IL or missing references) config("General", "NexusID", 2832, "Nexus mod ID for updates", synchronizedSetting: false); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false); pieceRecipe = config("General", "Recipe", "SurtlingCore:1,GreydwarfEye:5,Stone:5", "Piece recipe"); itemSacrifitionReduceCooldown = config("Item sacrifition", "Sacrifice item from list to reduce cooldown", defaultValue: true, "Enable sacrifition of item from list to reduce waystone cooldown"); pieceRecipe.SettingChanged += delegate { PieceWaystone.SetPieceRequirements(); }; locationWaystonesShowOnMap = config("Locations", "Show waystones on map", defaultValue: true, "Show waystone map pins"); locationShowCurrentSpawn = config("Locations", "Show current spawn", defaultValue: true, "Show current spawn point in search mode"); locationShowLastPoint = config("Locations", "Show last location", defaultValue: true, "Show last location from where you used fast travel last time in search mode"); locationShowLastShip = config("Locations", "Show last ship", defaultValue: true, "Show last ship position in search mode"); locationShowLastTombstone = config("Locations", "Show last tombstone", defaultValue: true, "Show last death position in search mode"); locationShowStartTemple = config("Locations", "Show sacrificial stones", defaultValue: true, "Show sacrificial stones positioin in search mode"); locationShowHaldor = config("Locations", "Show Haldor", defaultValue: true, "Show Haldor location in search mode"); locationShowHildir = config("Locations", "Show Hildir", defaultValue: true, "Show Hildir location in search mode"); locationShowWaystones = config("Locations", "Show waystones", defaultValue: true, "Show waystones network in search mode"); locationShowRandomPoint = config("Locations", "Show random point", defaultValue: true, "Show random point position in search mode"); emitNoiseOnTeleportation = config("Restrictions", "Emit noise on fast travelling", defaultValue: true, "If enabled then you will attract attention of nearby enemies on fast travelling start."); allowEncumbered = config("Restrictions", "Ignore encumbered to start search", defaultValue: false, "If enabled then encumbrance check before search start will be omitted."); allowNonTeleportableItems = config("Restrictions", "Ignore nonteleportable items to start search", defaultValue: false, "If enabled then inventory check before search start will be omitted."); allowWet = config("Restrictions", "Ignore wet status to start search", defaultValue: false, "If enabled then Wet status check before search start will be omitted."); allowSensed = config("Restrictions", "Ignore nearby enemies to start search", defaultValue: false, "If enabled then Sensed by nearby enemies check before search start will be omitted."); allowNonSitting = config("Restrictions", "Ignore sitting to start search", defaultValue: false, "If enabled then sitting position check before search start will be omitted."); useShortcutToEnter = config("Restrictions", "Use shortcut to toggle search mode", defaultValue: false, "If set you can enter direction search mode by pressing shortcut. If not set - you have to sit in front of the waystone to start search mode."); shortcut = config<KeyboardShortcut>("Restrictions", "Shortcut", new KeyboardShortcut((KeyCode)121, Array.Empty<KeyCode>()), "Enter/Exit direction search mode [Not Synced with Server]", synchronizedSetting: false); tagCharactersLimit = config("Restrictions", "Tag characters limit", 15, "Max length of waystone tag. Values less than 10 will be ignored."); directionSensitivity = config("Search mode", "Target sensitivity threshold", 2f, "Angle between look direction and target direction for location to appear in search mode"); directionSensitivityThreshold = config("Search mode", "Screen sensitivity threshold", 6f, "Angle between look direction and target direction for location to start appearing in search mode"); fadeMax = config("Search mode", "Screen fade max", 0.98f, "Screen darkness when sensitivity threshold is not met."); fadeMin = config("Search mode", "Screen fade min", 0.88f, "Screen darkness when looking at target"); sfxSensitivityThreshold = config("Search mode", "Sound effect sensitivity threshold", 20f, "Angle between look direction and target direction for sound to start appearing in direction search mode"); sfxMax = config("Search mode", "Sound effect max volume", 1.1f, "Volume of sound effect played in direction mode when looking at a target [Not Synced with Server]", synchronizedSetting: false); sfxMin = config("Search mode", "Sound effect min volume", 0.4f, "Volume of sound effect played in direction mode when sensitivity threshold is not met [Not Synced with Server]", synchronizedSetting: false); sfxPitchMax = config("Search mode", "Sound effect max pitch", 1f, "Pitch of sound effect played in direction mode when looking at a target"); sfxPitchMin = config("Search mode", "Sound effect min pitch", 0.8f, "Pitch of sound effect played in direction mode when sensitivity threshold is not met."); slowFactorTime = config("Search mode", "Slow factor time", 0.25f, "Multiplier of speed \u200b\u200bof time (singleplayer)"); slowFactorLookDeceleration = config("Search mode", "Slow factor mouse deceleration", 60f, "Mouse camera sensitivity acceleration factor. [Not Synced with Server]\nIncrease to make mouse acceleration proportionally lower, decrease to make mouse movement faster ", synchronizedSetting: false); slowFactorLookMinimum = config("Search mode", "Slow factor mouse minimum", 0.08f, "Minimum mouse camera sensitivity factor in search mode. [Not Synced with Server]", synchronizedSetting: false); fovDelta = config("Search mode", "FoV delta", 40f, "How much camera FoV can be changed both sides using zoom"); cooldownTime = config("Travel cooldown", "Time", CooldownTime.WorldTime, "Time type to calculate cooldown.\nWorld time - calculate from time passed in game world\nGlobal time - calculate from real world time"); cooldownDistanceMaximum = config("Travel cooldown", "Fast travelling distance maximum", 5000, "If fast travelling distance is larger then that cooldown will be set to maximum. World radius is 10000."); cooldownDistanceMinimum = config("Travel cooldown", "Fast travelling distance minimum", 500, "If fast travelling distance is smaller then that cooldown will be set to minimum. World radius is 10000."); cooldownMaximum = config("Travel cooldown", "Fast travelling cooldown maximum", 7200, "Maximal cooldown to be set after successfull fast travelling"); cooldownMinimum = config("Travel cooldown", "Fast travelling cooldown minimum", 600, "Minimal cooldown to be set after successfull fast travelling"); cooldownShort = config("Travel cooldown", "Fast travelling interrupted cooldown", 60, "Cooldown to be set if fast travelling was interrupted"); cooldownSearchMode = config("Travel cooldown", "Search mode cooldown", 30, "Cooldown to be set on search mode exit"); particlesCollision = config("Travelling effect", "Particles physics collision", defaultValue: false, "Make particles emitted while fast travelling collide with objects. Restart required."); particlesMaxAmount = config("Travelling effect", "Particles amount maximum", 8000, "Maximum amount of particles emitted. Restart required."); particlesMaxRateOverTime = config("Travelling effect", "Particles rate over time maximum", 4000, "Maximum amount of particles emitted per second at the curve end. Restart required."); particlesMinRateOverTime = config("Travelling effect", "Particles rate over time minimum", 50, "Minimum amount of particles emitted per second at the curve start. Restart required."); particlesMaxForceOverTime = config("Travelling effect", "Particles force over time maximum", 10, "Maximum emission force of particles emitted at the curve end. Restart required."); particlesMinForceOverTime = config("Travelling effect", "Particles force over time minimum", 5, "Minimum emission force of particles emitted at the curve start. Restart required."); InitCommands(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public void LateUpdate() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)SystemInfo.graphicsDeviceType != 4 && !((Object)(object)Player.m_localPlayer == (Object)null)) { if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible() && Object.op_Implicit((Object)(object)TextViewer.instance) && !TextViewer.instance.IsVisible() && !((Character)Player.m_localPlayer).InCutscene() && ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(SE_Waystone.statusEffectWaystonesHash) && (ZInput.GetButtonDown("Block") || ZInput.GetButtonDown("JoyButtonB"))) { ZInput.ResetButtonStatus("Block"); ZInput.ResetButtonStatus("JoyButtonB"); ((Character)Player.m_localPlayer).GetSEMan().RemoveStatusEffect(SE_Waystone.statusEffectWaystonesHash, false); } DirectionSearch.Update(); } } public static void InitCommands() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown object obj = <>c.<>9__64_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { WorldData.SetCooldown(args.TryParameterInt(1, 0)); }; <>c.<>9__64_0 = val; obj = (object)val; } new ConsoleCommand("setwaystonecooldown", "seconds", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } public static void TeleportAttempt(Vector3 targetPoint, Quaternion targetRotation, double cooldown, string location) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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) if (!CanCas