using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ConditionalConfigSync; using HarmonyLib; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; using Waystones; using YamlDotNet.Serialization; [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.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } public class WaystoneSmall : MonoBehaviour, TextReceiver, Hoverable, Interactable { private class SacrificeHoverItem { public string itemName; public int amount; public int value; public int inventoryCount; public int totalCount; } [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] public static class TextsDialog_UpdateTextsList_WaystoneSacrificeItems { private static void Postfix(TextsDialog __instance) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown string text = BuildConfiguredSacrificeItemsText(); if (text.Length != 0) { string waystoneTopic = Localization.instance.Localize("$ws_tutorial_waystone_label"); int num = __instance.m_texts.FindIndex((TextInfo info) => info != null && (info.m_topic == "$ws_tutorial_waystone_label" || info.m_topic == waystoneTopic || Localization.instance.Localize(info.m_topic) == waystoneTopic)); if (num >= 0) { __instance.m_texts.Insert(num + 1, new TextInfo("$ws_compendium_sacrifice_items_topic", text)); } } } } [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) { ((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; private const float sacrificeHoverItemsUpdateInterval = 1f; private static float nextSacrificeHoverItemsUpdate; private static readonly List sacrificeHoverItems = new List(); public void Awake() { if (!initial) { m_activeObject = ((Component)((Component)this).transform.Find("WayEffect")).gameObject; m_activeObject.SetActive(false); m_nview = ((Component)this).GetComponent(); if ((Object)(object)m_nview != (Object)null && m_nview.IsValid()) { ((MonoBehaviour)this).InvokeRepeating("UpdateStatus", 0f, 1f); m_nview.Register("RPC_SetTag", (Action)RPC_SetTag); m_nview.Register("ToggleActivated", (Action)RPC_ToggleActivated); m_nview.Register("RPC_AddCharge", (Action)RPC_AddCharge); } } } 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> activatedPlayers = GetActivatedPlayers(); if (activatedPlayers.RemoveAll((KeyValuePair 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> activatedPlayers = GetActivatedPlayers(); foreach (KeyValuePair item in activatedPlayers) { if (item.Key == playerID) { return; } } activatedPlayers.Add(new KeyValuePair(playerID, playerName)); SetActivatedPlayers(activatedPlayers); m_activateEffect.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, -1); } public void SetActivatedPlayers(List> users) { m_nview.GetZDO().Set(ZDOVars.s_permitted, users.Count, false); for (int i = 0; i < users.Count; i++) { KeyValuePair keyValuePair = users[i]; m_nview.GetZDO().Set("pu_id" + i, keyValuePair.Key); m_nview.GetZDO().Set("pu_name" + i, keyValuePair.Value); } } public List> 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[$KEY_Use] $ws_tooltip_start_search $ws_piece_waystone_settag"); string text2 = ((!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) ? "$KEY_AltPlace" : "$KEY_JoyAltKeys"); sb.Append("\n[" + text2 + " + $KEY_Use] " + (IsActive() ? "$ws_piece_waystone_deactivate" : "$ws_piece_waystone_activate")); if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown) { if (WorldData.IsOnCooldown()) { sb.Append("\n$hud_powernotready: " + WorldData.GetCooldownString() + ""); } } else if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) { if (WaystoneList.IsPlayerChargeStorage()) { sb.Append($"\n$ws_tooltip_player_charge {WorldData.GetPlayerCharge()}"); } else { sb.Append($"\n$ws_tooltip_waystone_charge {WaystoneList.GetWaystoneCharge(m_nview.GetZDO())}"); } } AppendSacrificeItemsHoverText(Player.m_localPlayer); 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 + 1f; 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)(() => ZInput.GetButton("Use") || ZInput.GetButton("JoyUse"))); if (!TextInput.IsVisible() && IsSearchAllowed(player, validateCharge: false) && global::Waystones.Waystones.CanCast()) { ((Character)player).Message((MessageType)2, "$ws_piece_waystone_activation", 0, (Sprite)null); WaystoneList.EnterSearchMode(m_nview.GetZDO()); } } public bool UseItem(Humanoid user, ItemData item) { if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && global::Waystones.Waystones.itemSacrifitionReduceCooldown.Value) { int cooldown = 0; if (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; } } if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) { int charge = 0; if (TryChargeWaystoneOnItemSacrifice(user, item, item.m_shared.m_name, ref charge)) { ((Character)user).Message((MessageType)2, Localization.instance.Localize("$ws_piece_waystone_charge_added", new string[1] { charge.ToString() }), 0, (Sprite)null); return true; } } return false; } private bool TryReduceCooldownOnItemSacrifice(Humanoid user, ItemData item, string itemName, ref int cooldown) { if (itemName == null) { return false; } itemName = itemName.GetItemName(); 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 bool TryChargeWaystoneOnItemSacrifice(Humanoid user, ItemData item, string itemName, ref int charge) { if (itemName == null || !m_nview.IsValid()) { return false; } itemName = itemName.GetItemName(); if (global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(itemName, out var value) && value > 0) { return TryConsumeChargeItem(user, item, itemName, value, 1, ref charge); } string text = global::Waystones.Waystones.itemsToReduceCooldown.Value.Keys.FirstOrDefault((string key) => key == itemName || key.StartsWith(itemName + ":")); if (text != null && global::Waystones.Waystones.itemsToReduceCooldown.Value.TryGetValue(text, out var value2) && value2 > 0) { string[] array = text.Split(':'); if (array.Length > 1 && array[0] == itemName && int.TryParse(array[1], out var result)) { return TryConsumeChargeItem(user, item, itemName, value2, result, ref charge); } } return false; } private bool TryConsumeChargeItem(Humanoid user, ItemData item, string itemName, int addCharge, int amount, ref int charge) { if (amount <= 0 || CountItems(user.GetInventory(), itemName) < amount) { return false; } charge = WaystoneList.GetPotentialChargeAdded(m_nview.GetZDO(), addCharge); if (charge <= 0) { return false; } if (!((amount == 1) ? user.GetInventory().RemoveOneItem(item) : user.GetInventory().RemoveItem(item, amount))) { return false; } AddCharge(addCharge); return true; } private void AddCharge(int amount) { if (m_nview.IsValid() && amount > 0) { if (WaystoneList.IsPlayerChargeStorage()) { WaystoneList.AddCharge(m_nview.GetZDO(), amount); return; } if (m_nview.IsOwner()) { WaystoneList.AddWaystoneCharge(m_nview.GetZDO(), amount); return; } m_nview.InvokeRPC("RPC_AddCharge", new object[1] { amount }); } } public void RPC_AddCharge(long sender, int amount) { if (m_nview.IsValid() && m_nview.IsOwner()) { WaystoneList.AddWaystoneCharge(m_nview.GetZDO(), amount); } } private int CountItems(Inventory inventory, string itemName) { return CountOwnInventoryItems(inventory, itemName); } private static int CountOwnInventoryItems(Inventory inventory, string itemName) { if (inventory == null) { return 0; } int num = 0; foreach (ItemData item in inventory.m_inventory) { if (item.m_shared.m_name.GetItemName() == itemName && item.m_worldLevel >= Game.m_worldLevel) { num += item.m_stack; } } return num; } private static int CountAvailableItems(Inventory inventory, string itemName) { if (inventory == null) { return 0; } return inventory.CountItems(itemName, -1, true); } private static void AppendSacrificeItemsHoverText(Player player) { if (!global::Waystones.Waystones.showSacrificeItemsInHover.Value || !ShouldShowSacrificeItems()) { return; } RefreshSacrificeHoverItems(player); if (sacrificeHoverItems.Count == 0) { return; } sb.Append("\n\n"); sb.Append((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_sacrifice_add_charge" : "$ws_tooltip_sacrifice_reduce_cooldown"); string text = ((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_charges" : "$ws_tooltip_seconds"); foreach (SacrificeHoverItem sacrificeHoverItem in sacrificeHoverItems) { sb.Append("\n - "); sb.Append("" + sacrificeHoverItem.itemName + ""); if (sacrificeHoverItem.amount > 1) { sb.Append($" x{sacrificeHoverItem.amount}"); } sb.Append(string.Format(" - {0}: {1}{2}. $settings_inventory: {3}", text, (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "+" : "-", sacrificeHoverItem.value, sacrificeHoverItem.inventoryCount)); if (sacrificeHoverItem.totalCount != sacrificeHoverItem.inventoryCount) { sb.Append($", $item_total: {sacrificeHoverItem.totalCount}"); } } } private static bool ShouldShowSacrificeItems() { return global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge || (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && global::Waystones.Waystones.itemSacrifitionReduceCooldown.Value); } private static void RefreshSacrificeHoverItems(Player player) { if (Time.time < nextSacrificeHoverItemsUpdate) { return; } nextSacrificeHoverItemsUpdate = Time.time + 1f; sacrificeHoverItems.Clear(); if ((Object)(object)player == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } foreach (KeyValuePair item in global::Waystones.Waystones.itemsToReduceCooldown.Value) { if (item.Value > 0 && TryParseSacrificeEntry(item.Key, out var itemName, out var amount)) { int num = CountOwnInventoryItems(inventory, itemName); int num2 = CountAvailableItems(inventory, itemName); if (num > 0 || num2 > 0) { sacrificeHoverItems.Add(new SacrificeHoverItem { itemName = itemName, amount = amount, value = item.Value, inventoryCount = num, totalCount = num2 }); } } } } private static bool TryParseSacrificeEntry(string key, out string itemName, out int amount) { itemName = key; amount = 1; if (string.IsNullOrWhiteSpace(key)) { return false; } string[] array = key.Split(':'); if (array.Length == 1) { return true; } if (array.Length != 2 || string.IsNullOrWhiteSpace(array[0]) || !int.TryParse(array[1], out amount) || amount <= 0) { return false; } itemName = array[0]; return true; } private static string BuildConfiguredSacrificeItemsText() { if (!ShouldShowSacrificeItems()) { return ""; } if (global::Waystones.Waystones.itemsToReduceCooldown.Value.Count == 0) { return ""; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_sacrifice_add_charge" : "$ws_tooltip_sacrifice_reduce_cooldown"); string arg = ((global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "$ws_tooltip_charges" : "$ws_tooltip_seconds"); foreach (KeyValuePair item in global::Waystones.Waystones.itemsToReduceCooldown.Value) { if (item.Value > 0 && TryParseSacrificeEntry(item.Key, out var itemName, out var amount)) { stringBuilder.Append("\n - "); stringBuilder.Append(itemName); if (amount > 1) { stringBuilder.Append($" x{amount}"); } stringBuilder.Append(string.Format(" - {0}: {1}{2}", arg, (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge) ? "+" : "-", item.Value)); } } return stringBuilder.ToString(); } public bool IsActive() { return m_activeObject.activeSelf; } public string GetText() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = m_nview.GetZDO(); if (zDO == null) { return ""; } string text = zDO.GetString(ZDOVars.s_tagauthor, ""); PlatformUserID val = (PlatformUserID)(string.IsNullOrEmpty(text) ? PlatformUserID.None : new PlatformUserID(text)); return CensorShittyWords.FilterUGC(zDO.GetString(ZDOVars.s_tag, ""), (UGCType)4, val, 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) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (m_nview.IsValid()) { m_nview.InvokeRPC("RPC_SetTag", new object[2] { text, ((object)((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID/*cast due to .constrained prefix*/).ToString() }); } } 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> GetWaystoneActivatedPlayers(ZDO zdo) { List> list = new List>(); int num = zdo.GetInt(ZDOVars.s_permitted, 0); for (int i = 0; i < num; i++) { long num2 = zdo.GetLong("pu_id" + i, 0L); string value = zdo.GetString("pu_name" + i, ""); if (num2 != 0) { list.Add(new KeyValuePair(num2, value)); } } return list; } public static bool IsWaystoneActivated(ZDO zdo, long playerID) { if (zdo == null) { return false; } foreach (KeyValuePair waystoneActivatedPlayer in GetWaystoneActivatedPlayers(zdo)) { if (global::Waystones.Waystones.allowForEveryone.Value || waystoneActivatedPlayer.Key == playerID) { return true; } } return false; } internal static bool IsSearchAllowed(Player player, bool validateCharge = true) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return false; } if ((Object)(object)player != (Object)(object)Player.m_localPlayer) { return false; } if (global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Cooldown && WorldData.IsOnCooldown()) { ((Character)player).Message((MessageType)2, "$hud_powernotready: " + WorldData.GetCooldownString(), 0, (Sprite)null); return false; } if (validateCharge && global::Waystones.Waystones.waystoneMode.Value == global::Waystones.Waystones.WaystoneMode.Charge && !WaystoneList.CanStartSearchWithCharge(WaystoneList.GetCurrentTravelCharge(player.GetPlayerID(), ((Component)player).transform.position))) { ((Character)player).Message((MessageType)2, "$ws_message_not_enough_charge", 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(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 const string defaultLanguage = "English"; private static readonly Dictionary>> PlaceholderProcessors; private static readonly Dictionary> loadedTexts; private static readonly ConditionalWeakTable localizationLanguage; private static readonly List> localizationObjects; private static BaseUnityPlugin? _plugin; private static readonly List 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 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> value2)) { text = value2.Aggregate(text, (string current, KeyValuePair> kv) => current.Replace("{" + kv.Key + "}", kv.Value())); } localization.AddWord(key, text); } public static void AddPlaceholder(string key, string placeholder, ConfigEntry config, Func? convertConfigValue = null) where T : notnull { if (convertConfigValue == null) { convertConfigValue = (T val) => val.ToString(); } if (!PlaceholderProcessors.ContainsKey(key)) { PlaceholderProcessors[key] = new Dictionary>(); } config.SettingChanged += delegate { UpdatePlaceholder(); }; if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage())) { UpdatePlaceholder(); } void UpdatePlaceholder() { PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value); UpdatePlaceholderText(Localization.instance, key); } } public static void AddText(string key, string text) { List> list = new List>(); foreach (WeakReference localizationObject in localizationObjects) { if (localizationObject.TryGetTarget(out var target)) { Dictionary dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)]; if (!target.m_translations.ContainsKey(key)) { dictionary[key] = text; target.AddWord(key, text); } } else { list.Add(localizationObject); } } foreach (WeakReference item in list) { localizationObjects.Remove(item); } } public static IEnumerator Load() { yield return (object)new WaitUntil((Func)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized)); if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", ""))) { PlatformPrefs.SetString("language", "English"); } LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage()); } private static void LoadLocalization(Localization __instance, string language) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown if (!localizationLanguage.Remove(__instance)) { localizationObjects.Add(new WeakReference(__instance)); } localizationLanguage.Add(__instance, language); Dictionary localizationFiles = new Dictionary(); string[] prefixes = new string[2] { Plugin.Info.Metadata.Name + ".", Plugin.Info.Metadata.Name.Replace(" ", "") + "." }; Scan(Paths.ConfigPath, warn: true); Scan(Paths.PluginPath, warn: false); 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 dictionary = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(Encoding.UTF8.GetString(array)); if (dictionary == null) { throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty."); } string text = null; if (language != "English") { if (localizationFiles.ContainsKey(language)) { text = File.ReadAllText(localizationFiles[language]); } else { byte[] array2 = LoadTranslationFromAssembly(language); if (array2 != null) { text = Encoding.UTF8.GetString(array2); } } } if (text == null && localizationFiles.ContainsKey("English")) { text = File.ReadAllText(localizationFiles["English"]); } if (text != null) { Dictionary dictionary2; try { dictionary2 = ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text) ?? new Dictionary(); } catch (Exception arg) { global::Waystones.Waystones.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}"); dictionary2 = new Dictionary(); } foreach (KeyValuePair item in dictionary2) { dictionary[item.Key] = item.Value; } } loadedTexts[language] = dictionary; foreach (KeyValuePair item2 in dictionary) { UpdatePlaceholderText(__instance, item2.Key); } void Scan(string root, bool warn) { foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories) where fileExtensions.Contains(Path.GetExtension(f)) select f) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3); string[] array3 = prefixes; foreach (string text2 in array3) { if (fileNameWithoutExtension.StartsWith(text2)) { string text3 = fileNameWithoutExtension.Substring(text2.Length); if (!string.IsNullOrWhiteSpace(text3)) { if (localizationFiles.ContainsKey(text3)) { if (warn) { global::Waystones.Waystones.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3); } } else { localizationFiles[text3] = item3; } } break; } } } } } 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>>(); loadedTexts = new Dictionary>(); localizationLanguage = new ConditionalWeakTable(); localizationObjects = new List>(); fileExtensions = new List { ".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) { using MemoryStream memoryStream = new MemoryStream(); if ((object)containingAssembly == null) { containingAssembly = Assembly.GetCallingAssembly(); } string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal)); if (text != null) { containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream); } return (memoryStream.Length == 0L) ? null : memoryStream.ToArray(); } } } namespace Waystones { public static class DirectionSearch { internal enum DirectionIconType { None, Waystone, Location, Death, Bed, Point } public class Direction { public string name; public Vector3 position; public Quaternion rotation; public double cooldown; public int travelCost; public int arrivalCharge; private const int NoArrivalCharge = int.MinValue; private readonly WaystoneList.WaystoneData waystone; private readonly DirectionIconType iconType; private readonly string locationIconName; public static readonly StringBuilder _sb = new StringBuilder(5); internal bool IsWaystone => waystone != null; internal Sprite Icon => GetDirectionIcon(iconType, locationIconName); internal Vector2 IconOffset { get { //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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) DirectionIconType directionIconType = iconType; if (1 == 0) { } Vector2 result = (Vector2)(directionIconType switch { DirectionIconType.Death => new Vector2(0.3f, -0.5f), DirectionIconType.Bed => new Vector2(0.5f, -5f / 6f), DirectionIconType.Point => new Vector2(0.05f, -0.1f), _ => Vector2.zero, }); if (1 == 0) { } return result; } } public Direction(string name, Vector3 position) : this(name, position, Quaternion.identity, null, DirectionIconType.None, null) { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) public Direction(string name, Vector3 position, Quaternion rotation) : this(name, position, rotation, null, DirectionIconType.None, null) { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) internal Direction(string name, Vector3 position, DirectionIconType iconType) : this(name, position, Quaternion.identity, null, iconType, null) { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) internal Direction(string name, Vector3 position, string locationIconName) : this(name, position, Quaternion.identity, null, DirectionIconType.Location, locationIconName) { }//IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) internal Direction(string name, WaystoneList.WaystoneData waystone) : this(name, waystone.searchPosition, waystone.searchRotation, waystone, DirectionIconType.Waystone, null) { }//IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) private Direction(string name, Vector3 position, Quaternion rotation, WaystoneList.WaystoneData waystone, DirectionIconType iconType, string locationIconName) { //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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0066: Unknown result type (might be due to invalid IL or missing references) this.name = name; this.position = position; this.rotation = rotation; this.waystone = waystone; this.iconType = iconType; this.locationIconName = locationIconName; cooldown = WorldData.GetCooldownTimeToTarget(position); travelCost = WorldData.GetTravelChargeCost(Object.op_Implicit((Object)(object)Player.m_localPlayer) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero, position); arrivalCharge = waystone?.charge ?? int.MinValue; } public string GetHoverText() { //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) _sb.Clear(); _sb.Append(name); if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Cooldown) { _sb.Append("\n[$KEY_Use] $ws_tooltip_moving_to"); _sb.Append("\n\n$ws_tooltip_cooldown_after " + WorldData.TimerString(cooldown) + ""); } else if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge) { _sb.Append("\n[$KEY_Use] $ws_tooltip_moving_to"); _sb.Append($"\n\n$ws_tooltip_travel_cost {travelCost}"); if (WaystoneList.IsPlayerChargeStorage()) { int playerCharge = WorldData.GetPlayerCharge(); _sb.Append($"\n$ws_tooltip_player_charge {playerCharge}"); _sb.Append($"\n$ws_tooltip_player_charge_after {playerCharge - travelCost}"); } else if (arrivalCharge != int.MinValue) { _sb.Append($"\n$ws_tooltip_arrival_charge {arrivalCharge}"); bool flag = WaystoneList.HasEnoughWaystoneCharge(arrivalCharge, travelCost, Waystones.allowWaystoneChargeOverdraft.Value); _sb.Append("\n$ws_tooltip_return_check " + (flag ? "$menu_yes" : "$menu_no") + ""); } } else { float value = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, position); string text = FormatUnits(value, (Waystones.orientationDistanceUnit.Value == Waystones.DistanceUnit.Yards) ? " yd" : "m"); _sb.Append("\n$ws_tooltip_distance " + text + ""); } return Localization.instance.Localize(_sb.ToString()); } private static string FormatUnits(float value, string unit) { if (value < 1000f) { return $"{Mathf.RoundToInt(value)}{unit}"; } float num = value / 1000f; return (num >= 10f) ? $"{num:0}k{unit}" : $"{num:0.#}k{unit}"; } } private readonly struct DirectionIconTarget { public readonly Sprite sprite; public readonly Vector2 screenPosition; public readonly Vector2 iconOffset; public readonly float alpha; public readonly float angle; public DirectionIconTarget(Sprite sprite, Vector2 screenPosition, Vector2 iconOffset, float alpha, float angle) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //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) this.sprite = sprite; this.screenPosition = screenPosition; this.iconOffset = iconOffset; this.alpha = alpha; this.angle = angle; } } [StructLayout(LayoutKind.Explicit)] private struct FloatIntUnion { [FieldOffset(0)] public float floatValue; [FieldOffset(0)] public int intValue; } [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) { //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Expected O, but got Unknown //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(((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(((Component)prefab.transform.Find("WayEffect/sfx")).gameObject, val.transform); ((Object)val2).name = "sfx"; val2.AddComponent(); val2.SetActive(true); screenBlackenerSfx = val2.GetComponent(); } screenBlackener = val.GetComponent(); ((Component)screenBlackener).gameObject.SetActive(false); directionIcons.Clear(); visibleDirectionIcons.Clear(); GameObject val3 = new GameObject("Waystones_DirectionSearchIcons", new Type[2] { typeof(RectTransform), typeof(CanvasGroup) }); val3.transform.SetParent(val.transform.parent, false); val3.transform.SetSiblingIndex(val.transform.GetSiblingIndex() + 1); directionIconLayer = val3.GetComponent(); directionIconLayer.anchorMin = Vector2.zero; directionIconLayer.anchorMax = Vector2.one; directionIconLayer.offsetMin = Vector2.zero; directionIconLayer.offsetMax = Vector2.zero; directionIconLayer.pivot = new Vector2(0.5f, 0.5f); CanvasGroup component = val3.GetComponent(); component.interactable = false; component.blocksRaycasts = false; directionIconCanvas = val3.GetComponentInParent(); val3.SetActive(false); } } [HarmonyPatch(typeof(Minimap), "OnDestroy")] public static class Minimap_OnDestroy_ClearDirectionIcons { private static void Postfix() { ClearDirectionIcons(); } } [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 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 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 directions = new List(); private static Direction current; private static bool activated; private static readonly Direction placeOfMystery = new Direction("$ws_location_random_point", Vector3.zero); private static float currentAngle; private static WaystoneList.WaystoneData sourceWaystone; private static float defaultFoV; private static float targetFoV; private static RectTransform directionIconLayer; private static Canvas directionIconCanvas; private static readonly List directionIcons = new List(); private static readonly List visibleDirectionIcons = new List(); private static readonly Dictionary locationDirectionIcons = new Dictionary(StringComparer.Ordinal); private static Sprite waystoneDirectionIcon; private static Sprite deathDirectionIcon; private static Sprite bedDirectionIcon; private static Sprite pointDirectionIcon; private const int FastInverseSquareRootMagic = 1597463007; private const float DirectionIconAlphaScale = 0.3f; private const float DirectionIconAlphaOffset = -0.1f; 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, validateCharge: false)) { WaystoneList.EnterSearchMode(); } } internal static void Enter() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Waystones.CanCast() || !WaystoneSmall.IsSearchAllowed(localPlayer, validateCharge: false)) { return; } sourceWaystone = WaystoneList.GetSearchSourceWaystone() ?? WaystoneList.GetClosestActivatedWaystoneData(((Component)localPlayer).transform.position); if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge && !WaystoneList.HasEnoughTravelCharge(sourceWaystone, WorldData.MinWaystoneChargeCost, Waystones.allowWaystoneChargeOverdraft.Value)) { sourceWaystone = null; ((Character)localPlayer).Message((MessageType)2, "$ws_message_not_enough_charge", 0, (Sprite)null); return; } if (!activated) { Game.FadeTimeScale(Waystones.slowFactorTime.Value, 4f); targetFoV = defaultFoV; Waystones.LogInfo($"Search mode activated at {((Component)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 (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Cooldown && !WorldData.IsOnCooldown()) { WorldData.SetCooldown(Waystones.cooldownSearchMode.Value); } Waystones.LogInfo("Search mode ended"); } activated = false; current = null; currentAngle = 0f; sourceWaystone = null; SetDirectionIconLayerActive(active: false); WaystoneList.UpdatePins(); } internal static void FillDirections() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0192: 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(), DirectionIconType.Bed)); } ZoneSystem.instance.tempIconList.Clear(); ZoneSystem.instance.GetLocationIcons(ZoneSystem.instance.tempIconList); foreach (KeyValuePair tempIcon in ZoneSystem.instance.tempIconList) { if (tempIcon.Value == "StartTemple" && Waystones.locationShowStartTemple.Value) { directions.Add(new Direction("$ws_location_start_temple", tempIcon.Key, tempIcon.Value)); } else if (tempIcon.Value == "Vendor_BlackForest" && Waystones.locationShowHaldor.Value) { directions.Add(new Direction("$npc_haldor", tempIcon.Key, tempIcon.Value)); } else if (tempIcon.Value == "Hildir_camp" && Waystones.locationShowHildir.Value) { directions.Add(new Direction("$npc_hildir", tempIcon.Key, tempIcon.Value)); } else if (tempIcon.Value == "BogWitch_Camp" && Waystones.locationShowBogWitch.Value) { directions.Add(new Direction("$npc_bogwitch", tempIcon.Key, tempIcon.Value)); } } PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile.HaveDeathPoint() && Waystones.locationShowLastTombstone.Value) { directions.Add(new Direction("$ws_location_last_tombstone", playerProfile.GetDeathPoint(), DirectionIconType.Death)); } directions.AddRange(WorldData.GetSavedDirections()); CollectionExtensions.Do((IEnumerable)directions, (Action)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); if (Waystones.waystoneMode.Value != Waystones.WaystoneMode.Orientation) { return; } float maxDistance = Waystones.orientationWaystoneVisibilityDistance.Value; directions.RemoveAll(delegate(Direction d) { //IL_000b: 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) float num = Utils.DistanceXZ(((Component)Player.m_localPlayer).transform.position, d.position); if (num <= maxDistance) { return false; } string name = d.name; if (1 == 0) { } bool result = name switch { "$ws_location_spawn_point" => !Waystones.orientationShowDistantCurrentSpawn.Value, "$ws_location_last_tombstone" => !Waystones.orientationShowDistantLastTombstone.Value, "$ws_location_last_ship" => !Waystones.orientationShowDistantLastShip.Value, "$ws_location_last_location" => !Waystones.orientationShowDistantLastPoint.Value, "$ws_location_start_temple" => !Waystones.orientationShowDistantStartTemple.Value, "$npc_haldor" => !Waystones.orientationShowDistantHaldor.Value, "$npc_hildir" => !Waystones.orientationShowDistantHildir.Value, "$npc_bogwitch" => !Waystones.orientationShowDistantBogWitch.Value, _ => d.IsWaystone && !Waystones.orientationShowDistantWaystones.Value, }; if (1 == 0) { } return result; }); } 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: 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_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: 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()) { Direction direction = ((current == placeOfMystery) ? new Direction("$ws_location_random_point", GetRandomPoint()) : current); if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Orientation) { Exit(); return; } if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge && !WaystoneList.HasEnoughTravelCharge(sourceWaystone, direction.travelCost, Waystones.allowWaystoneChargeOverdraft.Value)) { MessageHud.instance.ShowMessage((MessageType)2, "$ws_message_not_enough_charge", 0, (Sprite)null, false); return; } Waystones.TeleportAttempt(direction.position, direction.rotation, direction.cooldown, direction.name, sourceWaystone, direction.travelCost); 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(); Vector3 pos = ((Character)Player.m_localPlayer).GetEyePoint(); UpdateDirectionIcons(look, pos); currentAngle = Vector3.Angle(look, Vector3.down); if (currentAngle < GetCurrentSensivity() && Waystones.locationShowRandomPoint.Value) { current = placeOfMystery; } else if (directions.Count != 0) { 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 float GetCurrentIconSensivityThreshold() { return Waystones.iconSensitivityThreshold.Value * targetFoV / defaultFoV; } internal static void InitializeDirectionIcons(Minimap minimap) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) locationDirectionIcons.Clear(); waystoneDirectionIcon = WaystoneList.iconWaystone; deathDirectionIcon = GetMapIcon(minimap, (PinType)4); bedDirectionIcon = GetMapIcon(minimap, (PinType)5); pointDirectionIcon = null; foreach (SpriteData icon in minimap.m_icons) { if (Object.op_Implicit((Object)(object)icon.m_icon) && ((Object)icon.m_icon).name == "mapicon_pin") { pointDirectionIcon = icon.m_icon; } } pointDirectionIcon = (Object.op_Implicit((Object)(object)pointDirectionIcon) ? pointDirectionIcon : GetMapIcon(minimap, (PinType)6)); foreach (LocationSpriteData locationIcon in minimap.m_locationIcons) { if (!string.IsNullOrEmpty(locationIcon.m_name) && Object.op_Implicit((Object)(object)locationIcon.m_icon)) { locationDirectionIcons[locationIcon.m_name] = locationIcon.m_icon; } } } internal static void ClearDirectionIcons() { locationDirectionIcons.Clear(); waystoneDirectionIcon = null; deathDirectionIcon = null; bedDirectionIcon = null; pointDirectionIcon = null; } private static Sprite GetMapIcon(Minimap minimap, PinType pinType) { //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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) foreach (SpriteData icon in minimap.m_icons) { if (icon.m_name == pinType) { return icon.m_icon; } } return null; } private static Sprite GetDirectionIcon(DirectionIconType iconType, string locationIconName) { if (1 == 0) { } Sprite value; Sprite result = (Sprite)(iconType switch { DirectionIconType.Waystone => waystoneDirectionIcon, DirectionIconType.Location => (!string.IsNullOrEmpty(locationIconName) && locationDirectionIcons.TryGetValue(locationIconName, out value)) ? value : null, DirectionIconType.Death => deathDirectionIcon, DirectionIconType.Bed => bedDirectionIcon, DirectionIconType.Point => pointDirectionIcon, _ => null, }); if (1 == 0) { } return result; } private static void UpdateDirectionIcons(Vector3 lookDirection, Vector3 eyePosition) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) bool flag = activated && Waystones.showDirectionIcons.Value && Object.op_Implicit((Object)(object)directionIconLayer); visibleDirectionIcons.Clear(); SetDirectionIconLayerActive(flag); if (!flag) { return; } Camera val = (Object.op_Implicit((Object)(object)GameCamera.instance) ? GameCamera.instance.m_camera : null); if (!Object.op_Implicit((Object)(object)val)) { HideUnusedDirectionIcons(0); return; } float currentIconSensivityThreshold = GetCurrentIconSensivityThreshold(); foreach (Direction direction in directions) { Sprite icon = direction.Icon; if (!Object.op_Implicit((Object)(object)icon)) { continue; } Vector3 val2 = direction.position - eyePosition; float num = Vector3.Angle(lookDirection, val2); if (!(num > currentIconSensivityThreshold)) { Vector3 val3 = val.WorldToScreenPoint(direction.position); if (!(val3.z <= 0f)) { float directionIconAlpha = GetDirectionIconAlpha(num, currentIconSensivityThreshold); visibleDirectionIcons.Add(new DirectionIconTarget(icon, Vector2.op_Implicit(val3), direction.IconOffset, directionIconAlpha, num)); } } } visibleDirectionIcons.Sort((DirectionIconTarget left, DirectionIconTarget right) => right.angle.CompareTo(left.angle)); Camera val4 = ((Object.op_Implicit((Object)(object)directionIconCanvas) && (int)directionIconCanvas.renderMode != 0) ? directionIconCanvas.worldCamera : null); int num2 = 0; Vector2 val5 = default(Vector2); foreach (DirectionIconTarget visibleDirectionIcon in visibleDirectionIcons) { if (RectTransformUtility.ScreenPointToLocalPointInRectangle(directionIconLayer, visibleDirectionIcon.screenPosition, val4, ref val5)) { Image directionIconImage = GetDirectionIconImage(num2); RectTransform rectTransform = ((Graphic)directionIconImage).rectTransform; float value = Waystones.directionIconSize.Value; directionIconImage.sprite = visibleDirectionIcon.sprite; rectTransform.anchoredPosition = val5 + visibleDirectionIcon.iconOffset * value; rectTransform.sizeDelta = new Vector2(value, value); ((Transform)rectTransform).SetSiblingIndex(num2); ((Graphic)directionIconImage).color = new Color(1f, 1f, 1f, visibleDirectionIcon.alpha); ((Component)directionIconImage).gameObject.SetActive(true); num2++; } } HideUnusedDirectionIcons(num2); } private static float GetDirectionIconAlpha(float angle, float visibilityThreshold) { if (visibilityThreshold <= 0f) { return 0f; } float num = Mathf.Clamp01(angle / visibilityThreshold); if (num < 0.08f) { return 1f; } float num2 = num * 2f; float num3 = 0.3f * FastInverseSquareRoot(num2 - 0.1f) - 0.2175f; return Mathf.Clamp01(num3); } private static float FastInverseSquareRoot(float value) { FloatIntUnion floatIntUnion = new FloatIntUnion { floatValue = value }; floatIntUnion.intValue = 1597463007 - (floatIntUnion.intValue >> 1); float floatValue = floatIntUnion.floatValue; return floatValue * (1.5f - 0.5f * value * floatValue * floatValue); } private static Image GetDirectionIconImage(int index) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) while (directionIcons.Count <= index) { GameObject val = new GameObject("DirectionIcon", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent((Transform)(object)directionIconLayer, false); Image component = val.GetComponent(); component.preserveAspect = true; ((Graphic)component).raycastTarget = false; RectTransform rectTransform = ((Graphic)component).rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0.5f); rectTransform.anchorMax = new Vector2(0.5f, 0.5f); rectTransform.pivot = new Vector2(0.5f, 0.5f); directionIcons.Add(component); } return directionIcons[index]; } private static void HideUnusedDirectionIcons(int firstUnusedIndex) { for (int i = firstUnusedIndex; i < directionIcons.Count; i++) { ((Component)directionIcons[i]).gameObject.SetActive(false); } } private static void SetDirectionIconLayerActive(bool active) { if (Object.op_Implicit((Object)(object)directionIconLayer) && ((Component)directionIconLayer).gameObject.activeSelf != active) { ((Component)directionIconLayer).gameObject.SetActive(active); } } 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); } } public static class ItemNameTokens { [HarmonyPatch(typeof(Player), "Load")] private static class Player_Load_UpdateRegisters { private static void Prefix() { UpdateRegisters(); } } public static readonly Dictionary itemNames = new Dictionary(StringComparer.OrdinalIgnoreCase); public static void UpdateRegisters() { if (!Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } itemNames.Clear(); foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); if (component != null) { SharedData val = component.m_itemData?.m_shared; if (val != null && !string.IsNullOrWhiteSpace(val.m_name) && val.m_name.StartsWith("$")) { itemNames[((Object)item).name] = val.m_name; itemNames[val.m_name] = val.m_name; } } } Waystones.ReadInitialConfigs(); } public static string GetItemName(this string input) { string value; return itemNames.TryGetValue((input ?? "").Trim(), out value) ? value : input; } } internal static class WaystoneList { public class WaystoneData { public string tag; public Vector3 searchPosition; public Quaternion searchRotation; public Vector3 worldPosition; public int charge; } [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 }); DirectionSearch.InitializeDirectionIcons(__instance); } } [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(); activatedWaystones.Clear(); searchSourceWaystone = null; } } [HarmonyPatch(typeof(ZDOMan), "Load")] public static class ZDOMan_Load_WaystoneListInit { private static void Postfix(ZDOMan __instance) { foreach (KeyValuePair 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 waystonePins = new List(); public static readonly List activatedWaystones = new List(); private static WaystoneData searchSourceWaystone; public static readonly HashSet waystoneObjects = new HashSet(); public const string customDataKey = "WaystoneList"; public const string chargeZdoKey = "WaystoneCharges"; private const float waystoneSearchPointOffset = 1f; private const float defaultWaystoneMatchDistance = 8f; private const string markedLocationRequestRpc = "MarkedLocationRequest"; private const string markedLocationResponseRpc = "MarkedLocationResponse"; private const string consumeWaystoneChargeRequestRpc = "ConsumeWaystoneChargeRequest"; public static void UpdatePins() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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 (WaystoneData activatedWaystone in activatedWaystones) { waystonePins.Add(Minimap.instance.AddPin(activatedWaystone.searchPosition, (PinType)WaystoneIconType.pinType, activatedWaystone.tag, false, false, Player.m_localPlayer.GetPlayerID(), default(PlatformUserID))); } } internal static void RegisterRPCs() { if (ZNet.instance.IsServer()) { ZRoutedRpc.instance.Register("MarkedLocationRequest", (Action)RPC_MarkedLocationRequest); ZRoutedRpc.instance.Register("ConsumeWaystoneChargeRequest", (Action)RPC_ConsumeWaystoneChargeRequest); } else { ZRoutedRpc.instance.Register("MarkedLocationResponse", (Action)RPC_MarkedLocationResponse); } } public static void EnterSearchMode(ZDO sourceZdo = null) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && !((Object)(object)ZNet.instance == (Object)null)) { if (!ZNet.instance.IsServer()) { MarkedLocationRequest(sourceZdo); return; } GetActivatedWaystones(localPlayer.GetPlayerID()); searchSourceWaystone = CreateSearchSourceWaystone(sourceZdo, ((Component)localPlayer).transform.position); DirectionSearch.Enter(); } } public static void MarkedLocationRequest(ZDO sourceZdo = null) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer)) { Waystones.LogInfo("Marked location request"); ZPackage val = new ZPackage(); val.Write(localPlayer.GetPlayerID()); val.Write(((Component)localPlayer).transform.position); bool flag = sourceZdo != null; val.Write(flag ? 1 : 0); if (flag) { val.Write(sourceZdo.GetPosition()); } ZRoutedRpc.instance.InvokeRoutedRPC("MarkedLocationRequest", new object[1] { val }); } } public static List GetActivatedWaystones(long playerID) { activatedWaystones.Clear(); waystoneObjects.RemoveWhere((ZDO zdo) => zdo == null); foreach (ZDO waystoneObject in waystoneObjects) { if (WaystoneSmall.IsWaystoneActivated(waystoneObject, playerID)) { string text = waystoneObject.GetString(ZDOVars.s_tag, ""); if (!string.IsNullOrWhiteSpace(text)) { activatedWaystones.Add(CreateWaystoneData(waystoneObject, text)); } } } return activatedWaystones; } private static WaystoneData CreateWaystoneData(ZDO zdo, string tag) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_001c: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (zdo == null) { return null; } Vector3 position = zdo.GetPosition(); Quaternion rotation = zdo.GetRotation(); Vector3 val = rotation * Vector3.forward; return new WaystoneData { tag = tag, worldPosition = position, searchPosition = position + val * 1f + Vector3.up, searchRotation = rotation * Quaternion.Euler(0f, 180f, 0f), charge = GetWaystoneCharge(zdo) }; } private static WaystoneData CreateSearchSourceWaystone(ZDO sourceZdo, Vector3 playerPosition) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (sourceZdo == null) { sourceZdo = GetClosestWaystone(playerPosition); } return CreateWaystoneData(sourceZdo, (sourceZdo == null) ? "" : sourceZdo.GetString(ZDOVars.s_tag, "")); } public static WaystoneData GetSearchSourceWaystone() { return searchSourceWaystone; } public static WaystoneData GetClosestActivatedWaystoneData(Vector3 point, float maxDistance = 8f) { //IL_001c: 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) WaystoneData result = null; float num = maxDistance; foreach (WaystoneData activatedWaystone in activatedWaystones) { float num2 = Utils.DistanceXZ(point, activatedWaystone.worldPosition); if (num2 <= num) { num = num2; result = activatedWaystone; } } return result; } public static int GetClosestActivatedWaystoneCharge(long playerID, Vector3 point, float maxDistance = 8f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) WaystoneData closestActivatedWaystoneData = GetClosestActivatedWaystoneData(point, maxDistance); if (closestActivatedWaystoneData != null) { return closestActivatedWaystoneData.charge; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ZDO closestWaystone = GetClosestWaystone(point, maxDistance); return (closestWaystone != null) ? GetWaystoneCharge(closestWaystone) : 0; } return 0; } public static bool IsPlayerChargeStorage() { return Waystones.waystoneChargeStorage.Value == Waystones.ChargeStorage.Player; } public static int GetDefaultWaystoneCharge() { return WorldData.GetDefaultCharge(); } public static int GetCurrentTravelCharge(long playerID, Vector3 point, float maxDistance = 8f) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) return IsPlayerChargeStorage() ? WorldData.GetPlayerCharge() : GetClosestActivatedWaystoneCharge(playerID, point, maxDistance); } public static int GetWaystoneCharge(ZDO zdo) { if (zdo == null) { return 0; } int num = zdo.GetInt("WaystoneCharges", GetDefaultWaystoneCharge()); return Waystones.allowWaystoneChargeOverflow.Value ? num : Mathf.Min(num, WorldData.MaxWaystoneCharge); } public static int GetPotentialChargeAdded(ZDO zdo, int amount) { return IsPlayerChargeStorage() ? WorldData.GetPotentialPlayerChargeAdded(amount) : GetPotentialWaystoneChargeAdded(zdo, amount); } public static int GetPotentialWaystoneChargeAdded(ZDO zdo, int amount) { if (zdo == null || amount <= 0) { return 0; } int waystoneCharge = GetWaystoneCharge(zdo); int maxWaystoneCharge = WorldData.MaxWaystoneCharge; if (Waystones.allowWaystoneChargeOverflow.Value) { return (waystoneCharge < maxWaystoneCharge) ? amount : 0; } int num = Mathf.Min(waystoneCharge + amount, maxWaystoneCharge); return Mathf.Max(0, num - waystoneCharge); } public static bool CanStartSearchWithCharge(int current) { return HasEnoughCharge(current, WorldData.MinWaystoneChargeCost, Waystones.allowWaystoneChargeOverdraft.Value); } public static bool HasEnoughTravelCharge(WaystoneData sourceWaystone, int amount, bool allowOverdraftWhenPositive) { int current = (IsPlayerChargeStorage() ? WorldData.GetPlayerCharge() : (sourceWaystone?.charge ?? 0)); return HasEnoughCharge(current, amount, allowOverdraftWhenPositive); } public static bool HasEnoughWaystoneCharge(WaystoneData waystone, int amount, bool allowOverdraftWhenPositive) { return waystone != null && HasEnoughCharge(waystone.charge, amount, allowOverdraftWhenPositive); } public static bool HasEnoughWaystoneCharge(int current, int amount, bool allowOverdraftWhenPositive) { return HasEnoughCharge(current, amount, allowOverdraftWhenPositive); } public static bool TryConsumeTravelCharge(WaystoneData sourceWaystone, long playerID, int amount, bool allowOverdraftWhenPositive = false) { return IsPlayerChargeStorage() ? WorldData.TryConsumePlayerCharge(amount, allowOverdraftWhenPositive) : TryConsumeWaystoneCharge(sourceWaystone, playerID, amount, allowOverdraftWhenPositive); } public static bool TryConsumeWaystoneCharge(WaystoneData waystone, long playerID, int amount, bool allowOverdraftWhenPositive = false) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (waystone == null || amount <= 0) { return false; } if (!HasEnoughCharge(waystone.charge, amount, allowOverdraftWhenPositive)) { return false; } if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer()) { ZDO closestWaystone = GetClosestWaystone(waystone.worldPosition, 2f); if (!TryConsumeWaystoneCharge(closestWaystone, amount, allowOverdraftWhenPositive)) { return false; } waystone.charge = GetWaystoneCharge(closestWaystone); return true; } waystone.charge -= amount; ConsumeWaystoneChargeRequest(playerID, waystone.worldPosition, amount, allowOverdraftWhenPositive); return true; } public static bool TryConsumeWaystoneCharge(ZDO zdo, int amount, bool allowOverdraftWhenPositive = false) { if (zdo == null || amount <= 0) { return false; } int waystoneCharge = GetWaystoneCharge(zdo); if (!HasEnoughCharge(waystoneCharge, amount, allowOverdraftWhenPositive)) { return false; } zdo.Set("WaystoneCharges", waystoneCharge - amount); return true; } private static bool HasEnoughCharge(int current, int amount, bool allowOverdraftWhenPositive) { return current >= amount || (allowOverdraftWhenPositive && current > 0); } public static int AddCharge(ZDO zdo, int amount) { return IsPlayerChargeStorage() ? WorldData.AddPlayerCharge(amount) : AddWaystoneCharge(zdo, amount); } public static int AddWaystoneCharge(ZDO zdo, int amount) { int potentialWaystoneChargeAdded = GetPotentialWaystoneChargeAdded(zdo, amount); if (potentialWaystoneChargeAdded <= 0) { return 0; } zdo.Set("WaystoneCharges", GetWaystoneCharge(zdo) + potentialWaystoneChargeAdded); return potentialWaystoneChargeAdded; } public static ZDO GetClosestActivatedWaystone(long playerID, Vector3 point, float maxDistance = 8f) { //IL_002e: 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) ZDO result = null; float num = maxDistance; foreach (ZDO waystoneObject in waystoneObjects) { if (WaystoneSmall.IsWaystoneActivated(waystoneObject, playerID)) { float num2 = Utils.DistanceXZ(point, waystoneObject.GetPosition()); if (num2 <= num) { num = num2; result = waystoneObject; } } } return result; } public static ZDO GetClosestWaystone(Vector3 point, float maxDistance = 8f) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) ZDO result = null; float num = maxDistance; waystoneObjects.RemoveWhere((ZDO zdo) => zdo == null); foreach (ZDO waystoneObject in waystoneObjects) { float num2 = Utils.DistanceXZ(point, waystoneObject.GetPosition()); if (num2 <= num) { num = num2; result = waystoneObject; } } return result; } private static void ConsumeWaystoneChargeRequest(long playerID, Vector3 worldPosition, int amount, bool allowOverdraftWhenPositive) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(playerID); val.Write(worldPosition); val.Write(amount); val.Write(allowOverdraftWhenPositive ? 1 : 0); ZRoutedRpc.instance.InvokeRoutedRPC("ConsumeWaystoneChargeRequest", new object[1] { val }); } public static void RPC_ConsumeWaystoneChargeRequest(long sender, ZPackage pkg) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) long num = pkg.ReadLong(); Vector3 val = pkg.ReadVector3(); int num2 = pkg.ReadInt(); pkg.ReadInt(); bool value = Waystones.allowWaystoneChargeOverdraft.Value; ZDO closestWaystone = GetClosestWaystone(val, 2f); if (!TryConsumeWaystoneCharge(closestWaystone, num2, value)) { Waystones.LogInfo($"Rejected waystone charge consume request from {sender}. Player: {num}, amount: {num2}, position: {val}"); } } public static void RPC_MarkedLocationRequest(long sender, ZPackage request) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) long playerID = request.ReadLong(); Vector3 playerPosition = request.ReadVector3(); ZDO sourceZdo = null; if (request.ReadInt() != 0) { sourceZdo = GetClosestWaystone(request.ReadVector3(), 2f); } GetActivatedWaystones(playerID); WaystoneData waystoneData = CreateSearchSourceWaystone(sourceZdo, playerPosition); ZPackage val = new ZPackage(); val.Write(activatedWaystones.Count); foreach (WaystoneData activatedWaystone in activatedWaystones) { WriteWaystoneData(val, activatedWaystone); } val.Write((waystoneData != null) ? 1 : 0); if (waystoneData != null) { WriteWaystoneData(val, waystoneData); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "MarkedLocationResponse", new object[1] { val }); } public static void RPC_MarkedLocationResponse(long sender, ZPackage pkg) { Waystones.LogInfo("Server responded with activated location list"); activatedWaystones.Clear(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { activatedWaystones.Add(ReadWaystoneData(pkg)); } searchSourceWaystone = ((pkg.ReadInt() != 0) ? ReadWaystoneData(pkg) : null); DirectionSearch.Enter(); } private static void WriteWaystoneData(ZPackage pkg, WaystoneData waystone) { //IL_0019: 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_0033: Unknown result type (might be due to invalid IL or missing references) pkg.Write(waystone.tag ?? ""); pkg.Write(waystone.searchPosition); pkg.Write(waystone.searchRotation); pkg.Write(waystone.worldPosition); pkg.Write(waystone.charge); } private static WaystoneData ReadWaystoneData(ZPackage pkg) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) return new WaystoneData { tag = pkg.ReadString(), searchPosition = pkg.ReadVector3(), searchRotation = pkg.ReadQuaternion(), worldPosition = pkg.ReadVector3(), charge = pkg.ReadInt() }; } } internal class PieceWaystone { [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_AddPiece { [HarmonyPriority(800)] 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_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Expected O, but got Unknown //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0470: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Expected O, but got Unknown //IL_051b: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)waystonePrefab)) { WayStone val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((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(); LOD[] lODs = component.GetLODs(); List 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()); 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().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().shape; ((ShapeModule)(ref shape)).radius = 0.005f; EmissionModule emission = ((Component)val2).GetComponent().emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(5f); Transform val3 = waystonePrefab.transform.Find("WayEffect/Particle System sparcs"); val3.localScale *= 0.4f; MainModule main2 = ((Component)val3).GetComponent().main; ((MainModule)(ref main2)).startSpeed = MinMaxCurve.op_Implicit(1f); ((MainModule)(ref main2)).maxParticles = 200; EmissionModule emission2 = ((Component)val3).GetComponent().emission; ((EmissionModule)(ref emission2)).rateOverTime = MinMaxCurve.op_Implicit(20f); ((Component)val3).gameObject.SetActive(!Waystones.disableWaystoneSparcs.Value); Light component2 = ((Component)waystonePrefab.transform.Find("WayEffect/Point light")).GetComponent(); component2.intensity = 1.1f; Light component3 = ((Component)waystonePrefab.transform.Find("Point light (1)")).GetComponent(); component3.intensity = 1.1f; ((Component)component3).gameObject.AddComponent().m_lightDistance = 50f; waystonePrefab.GetComponentInChildren().m_type = (Type)2; Component obj = CustomPrefabs.AddComponent(waystonePrefab, typeof(ZNetView)); ZNetView val4 = (ZNetView)(object)((obj is ZNetView) ? obj : null); val4.m_persistent = true; val4.m_distant = true; val4.m_type = (ObjectType)2; Component obj2 = CustomPrefabs.AddComponent(waystonePrefab, typeof(Piece)); Piece val5 = (Piece)(object)((obj2 is Piece) ? obj2 : null); val5.m_icon = itemWaystone; val5.m_name = "$ws_piece_waystone_name"; val5.m_description = "$ws_piece_waystone_description"; val5.m_clipGround = true; val5.m_clipEverything = true; val5.m_notOnTiltingSurface = true; val5.m_noClipping = false; ((StaticTarget)val5).m_randomTarget = false; Component obj3 = CustomPrefabs.AddComponent(waystonePrefab, typeof(WearNTear)); WearNTear val6 = (WearNTear)(object)((obj3 is WearNTear) ? obj3 : null); GameObject val7 = new GameObject("new"); val7.transform.SetParent(waystonePrefab.transform); val7.transform.SetSiblingIndex(0); waystonePrefab.transform.Find("model").SetParent(val7.transform); val6.m_new = val7; val6.m_worn = val7; val6.m_broken = val7; val6.m_noRoofWear = false; val6.m_noSupportWear = false; val6.m_burnable = false; val6.m_supports = false; val6.m_ashDamageResist = true; val6.m_staticPosition = true; val6.m_materialType = (MaterialType)1; val6.m_health = 1000f; val6.m_damages.m_pierce = (DamageModifier)1; val6.m_damages.m_chop = (DamageModifier)4; val6.m_damages.m_pickaxe = (DamageModifier)4; val6.m_damages.m_fire = (DamageModifier)1; val6.m_damages.m_frost = (DamageModifier)1; val6.m_damages.m_poison = (DamageModifier)3; val6.m_damages.m_spirit = (DamageModifier)3; WayStone component4 = waystonePrefab.GetComponent(); WaystoneSmall.initial = true; WaystoneSmall waystoneSmall = waystonePrefab.AddComponent(); WaystoneSmall.initial = false; Object.Destroy((Object)(object)component4); GameObject val8 = new GameObject("GuidePoint"); val8.transform.SetParent(waystonePrefab.transform); val8.transform.localPosition = new Vector3(-0.5f, 8.9f, -1.3f); Component obj4 = CustomPrefabs.AddComponent(val8, typeof(GuidePoint)); GuidePoint val9 = (GuidePoint)(object)((obj4 is GuidePoint) ? obj4 : null); val9.m_text.m_alwaysSpawn = false; val9.m_text.m_key = "ws_waystone"; val9.m_text.m_topic = "$ws_tutorial_waystone_topic"; val9.m_text.m_label = "$ws_tutorial_waystone_label"; val9.m_text.m_text = ((Waystones.waystoneMode.Value == Waystones.WaystoneMode.Orientation) ? "$ws_tutorial_waystone_text_orientation" : "$ws_tutorial_waystone_text"); Waystones.LogInfo("Waystone prefab added"); } if (!Object.op_Implicit((Object)(object)waystonePrefab)) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("stone_pile"); if ((Object)(object)prefab != (Object)null) { waystonePrefab.GetComponent().m_placeEffect.m_effectPrefabs = prefab.GetComponent().m_placeEffect.m_effectPrefabs.ToArray(); waystonePrefab.GetComponent().m_destroyedEffect.m_effectPrefabs = prefab.GetComponent().m_destroyedEffect.m_effectPrefabs.ToArray(); waystonePrefab.GetComponent().m_hitEffect.m_effectPrefabs = prefab.GetComponent().m_hitEffect.m_effectPrefabs.ToArray(); } WaystoneSmall component5 = waystonePrefab.GetComponent(); WayStone val10 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((WayStone val14) => ((Object)val14).name == "Waystone")); if ((Object)(object)val10 != (Object)null) { component5.m_activateEffect.m_effectPrefabs = val10.m_activeEffect.m_effectPrefabs.ToArray(); } GameObject prefab2 = ZNetScene.instance.GetPrefab("guard_stone"); PrivateArea val11 = ((prefab2 != null) ? prefab2.GetComponent() : null); if ((Object)(object)val11 != (Object)null) { component5.m_deactivateEffect.m_effectPrefabs = val11.m_removedPermittedEffect.m_effectPrefabs.ToArray(); } GameObject prefab3 = ZNetScene.instance.GetPrefab("piece_workbench"); GuidePoint val12 = ((prefab3 != null) ? prefab3.GetComponentInChildren() : null); if ((Object)(object)val12 != (Object)null) { waystonePrefab.GetComponentInChildren().m_ravenPrefab = val12.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(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Hammer"); PieceTable val13 = ((itemPrefab == null) ? null : itemPrefab.GetComponent()?.m_itemData.m_shared.m_buildPieces); if (val13 != null) { val13.m_pieces.RemoveAll((GameObject piece) => ((Object)piece).name == "Waystone_small"); val13.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(); List list = new List(); 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(), 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(); } } 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(); ((Behaviour)sfx).enabled = true; volume = sfx.volume; main = ((Component)((Component)this).transform.Find("Sparcs")).GetComponent().main; light = ((Component)((Component)this).transform.Find("Light")).GetComponent(); } 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() && 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 bool playerChargeInitialized; public int playerCharge; public const string customDataKey = "Waystones"; public static bool saveNextGroundPositionAsShipLocation; public static int MaxWaystoneCharge => Mathf.Clamp(Waystones.maxWaystoneCharge.Value, 1, 100000); public static int MinWaystoneChargeCost => Mathf.Clamp(Waystones.chargeCostMinimum.Value, 1, 100000); public static int MaxWaystoneChargeCost => Mathf.Max(MinWaystoneChargeCost, Mathf.Clamp(Waystones.chargeCostMaximum.Value, 1, 100000)); public static int MinWaystoneChargeDistance => Mathf.Clamp(Waystones.chargeDistanceMinimum.Value, 1, 100000); public static int MaxWaystoneChargeDistance => Mathf.Max(MinWaystoneChargeDistance, Mathf.Clamp(Waystones.chargeDistanceMaximum.Value, 1, 100000)); public static List GetSavedDirections() { //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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) List result = new List(); WorldData worldData = GetWorldData(GetState()); if (worldData != null) { if (worldData.lastShip != Vector3.zero && Waystones.locationShowLastShip.Value) { result.Add(new DirectionSearch.Direction("$ws_location_last_ship", worldData.lastShip, DirectionSearch.DirectionIconType.Point)); } if (worldData.lastPosition != Vector3.zero && Waystones.locationShowLastPoint.Value) { result.Add(new DirectionSearch.Direction("$ws_location_last_location", worldData.lastPosition, DirectionSearch.DirectionIconType.Point)); } } if (Waystones.locationShowWaystones.Value) { CollectionExtensions.Do((IEnumerable)WaystoneList.activatedWaystones, (Action)delegate(WaystoneList.WaystoneData waystone) { result.Add(new DirectionSearch.Direction("$ws_piece_waystone_name \"" + waystone.tag + "\"", waystone)); }); } return result; } public unsafe 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 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*)(&val))/*cast due to .constrained prefix*/).ToString()); } public unsafe 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 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*)(&val))/*cast due to .constrained prefix*/).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)); } public static int GetTravelChargeCost(Vector3 from, Vector3 target) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) int minWaystoneChargeCost = MinWaystoneChargeCost; int maxWaystoneChargeCost = MaxWaystoneChargeCost; if (target == Vector3.zero) { return minWaystoneChargeCost; } float num = Utils.DistanceXZ(from, target); int minWaystoneChargeDistance = MinWaystoneChargeDistance; int maxWaystoneChargeDistance = MaxWaystoneChargeDistance; if (num < (float)minWaystoneChargeDistance) { return minWaystoneChargeCost; } if (num > (float)maxWaystoneChargeDistance) { return maxWaystoneChargeCost; } if (maxWaystoneChargeDistance == minWaystoneChargeDistance) { return maxWaystoneChargeCost; } float num2 = (num - (float)minWaystoneChargeDistance) / (float)(maxWaystoneChargeDistance - minWaystoneChargeDistance); return Mathf.Clamp(Mathf.RoundToInt(Mathf.Lerp((float)minWaystoneChargeCost, (float)maxWaystoneChargeCost, num2)), minWaystoneChargeCost, maxWaystoneChargeCost); } public static int GetDefaultCharge() { return Waystones.defaultWaystoneChargeFull.Value ? MaxWaystoneCharge : 0; } private int GetStoredPlayerCharge() { return playerChargeInitialized ? playerCharge : GetDefaultCharge(); } private static int NormalizeStoredCharge(int charge) { return Waystones.allowWaystoneChargeOverflow.Value ? charge : Mathf.Min(charge, MaxWaystoneCharge); } public static int GetPlayerCharge() { if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance)) { return 0; } WorldData worldData = GetWorldData(GetState()); return (worldData == null) ? GetDefaultCharge() : NormalizeStoredCharge(worldData.GetStoredPlayerCharge()); } public static int GetPotentialPlayerChargeAdded(int amount) { if (amount <= 0) { return 0; } int num = GetPlayerCharge(); if (Waystones.allowWaystoneChargeOverflow.Value) { return amount; } int num2 = Mathf.Min(num + amount, MaxWaystoneCharge); return Mathf.Max(0, num2 - num); } public static int AddPlayerCharge(int amount) { int potentialPlayerChargeAdded = GetPotentialPlayerChargeAdded(amount); if (potentialPlayerChargeAdded <= 0 || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance)) { return 0; } List state = GetState(); WorldData worldData = GetWorldData(state, createIfEmpty: true); int num = NormalizeStoredCharge(worldData.GetStoredPlayerCharge()); worldData.playerChargeInitialized = true; worldData.playerCharge = num + potentialPlayerChargeAdded; Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Waystones.LogInfo($"Player waystone charge added: +{potentialPlayerChargeAdded}, current: {worldData.playerCharge}"); return potentialPlayerChargeAdded; } public static bool TryConsumePlayerCharge(int amount, bool allowOverdraftWhenPositive) { if (amount <= 0 || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance)) { return false; } List state = GetState(); WorldData worldData = GetWorldData(state, createIfEmpty: true); int num = NormalizeStoredCharge(worldData.GetStoredPlayerCharge()); if (num < amount && (!allowOverdraftWhenPositive || num <= 0)) { return false; } worldData.playerChargeInitialized = true; worldData.playerCharge = num - amount; Player.m_localPlayer.m_customData["Waystones"] = SaveWorldDataList(state); Waystones.LogInfo($"Player waystone charge consumed: -{amount}, current: {worldData.playerCharge}"); return true; } private static DateTime GetTime() { return DateTime.Now.ToUniversalTime(); } internal static WorldData GetWorldData(List 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 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 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 GetState() { string value; return Player.m_localPlayer.m_customData.TryGetValue("Waystones", out value) ? GetWorldDataList(value) : new List(); } private static List GetWorldDataList(string value) { List data = new List(); CollectionExtensions.Do(SplitToLines(value), (Action)delegate(string line) { data.Add(JsonUtility.FromJson(line)); }); return data; } private static string SaveWorldDataList(List list) { StringBuilder sb = new StringBuilder(); CollectionExtensions.Do((IEnumerable)list, (Action)delegate(WorldData data) { sb.AppendLine(JsonUtility.ToJson((object)data)); }); return sb.ToString(); } private static IEnumerable 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; } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("shudnal.Waystones", "Waystones", "1.2.0")] public class Waystones : BaseUnityPlugin { private sealed class SacrificeItemsComparer : IEqualityComparer> { public static readonly SacrificeItemsComparer Instance = new SacrificeItemsComparer(); public bool Equals(Dictionary first, Dictionary second) { if (first == second) { return true; } if (first == null || second == null || first.Count != second.Count) { return false; } foreach (KeyValuePair item in first) { if (!second.TryGetValue(item.Key, out var value) || value != item.Value) { return false; } } return true; } public int GetHashCode(Dictionary value) { if (value == null) { return 0; } int num = 0; foreach (KeyValuePair item in value) { num ^= ((item.Key?.GetHashCode() ?? 0) * 397) ^ item.Value; } return num; } } public enum CooldownTime { WorldTime, GlobalTime } public enum WaystoneMode { Cooldown, Charge, Orientation } public enum ChargeStorage { Waystone, Player } public enum DistanceUnit { Meters, Yards } [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 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__93_0; public static ConsoleEvent <>9__96_0; internal void b__93_0(object sender, EventArgs args) { PieceWaystone.SetPieceRequirements(); } internal void b__96_0(ConsoleEventArgs args) { WorldData.SetCooldown(args.TryParameterInt(1, 0)); } } public const string pluginID = "shudnal.Waystones"; public const string pluginName = "Waystones"; public const string pluginVersion = "1.2.0"; private readonly Harmony harmony = new Harmony("shudnal.Waystones"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.Waystones") { DisplayName = "Waystones", CurrentVersion = "1.2.0", MinimumRequiredVersion = "1.2.0", ModRequired = true }; internal static Waystones instance; internal static ConfigEntry configLocked; internal static ConfigEntry loggingEnabled; internal static ConfigEntry shortcut; internal static ConfigEntry pieceRecipe; internal static ConfigEntry itemSacrifitionReduceCooldown; internal static ConfigEntry showSacrificeItemsInHover; internal static ConfigEntry disableWaystoneSparcs; internal static ConfigEntry locationWaystonesShowOnMap; internal static ConfigEntry locationShowCurrentSpawn; internal static ConfigEntry locationShowLastPoint; internal static ConfigEntry locationShowLastShip; internal static ConfigEntry locationShowLastTombstone; internal static ConfigEntry locationShowStartTemple; internal static ConfigEntry locationShowHaldor; internal static ConfigEntry locationShowHildir; internal static ConfigEntry locationShowBogWitch; internal static ConfigEntry locationShowWaystones; internal static ConfigEntry locationShowRandomPoint; internal static ConfigEntry useShortcutToEnter; internal static ConfigEntry allowEncumbered; internal static ConfigEntry allowNonTeleportableItems; internal static ConfigEntry emitNoiseOnTeleportation; internal static ConfigEntry allowWet; internal static ConfigEntry allowSensed; internal static ConfigEntry allowNonSitting; internal static ConfigEntry tagCharactersLimit; internal static ConfigEntry allowForEveryone; internal static ConfigEntry directionSensitivity; internal static ConfigEntry directionSensitivityThreshold; internal static ConfigEntry showDirectionIcons; internal static ConfigEntry directionIconSize; internal static ConfigEntry iconSensitivityThreshold; internal static ConfigEntry fadeMax; internal static ConfigEntry fadeMin; internal static ConfigEntry slowFactorTime; internal static ConfigEntry slowFactorLookDeceleration; internal static ConfigEntry slowFactorLookMinimum; internal static ConfigEntry fovDelta; internal static ConfigEntry sfxSensitivityThreshold; internal static ConfigEntry sfxMax; internal static ConfigEntry sfxMin; internal static ConfigEntry sfxPitchMax; internal static ConfigEntry sfxPitchMin; internal static ConfigEntry cooldownTime; internal static ConfigEntry cooldownMaximum; internal static ConfigEntry cooldownMinimum; internal static ConfigEntry cooldownDistanceMaximum; internal static ConfigEntry cooldownDistanceMinimum; internal static ConfigEntry cooldownShort; internal static ConfigEntry cooldownSearchMode; internal static ConfigEntry waystoneMode; internal static ConfigEntry maxWaystoneCharge; internal static ConfigEntry allowWaystoneChargeOverdraft; internal static ConfigEntry defaultWaystoneChargeFull; internal static ConfigEntry allowWaystoneChargeOverflow; internal static ConfigEntry waystoneChargeStorage; internal static ConfigEntry chargeCostMaximum; internal static ConfigEntry chargeCostMinimum; internal static ConfigEntry chargeDistanceMaximum; internal static ConfigEntry chargeDistanceMinimum; internal static ConfigEntry orientationWaystoneVisibilityDistance; internal static ConfigEntry orientationDistanceUnit; internal static ConfigEntry orientationShowDistantCurrentSpawn; internal static ConfigEntry orientationShowDistantLastPoint; internal static ConfigEntry orientationShowDistantLastShip; internal static ConfigEntry orientationShowDistantLastTombstone; internal static ConfigEntry orientationShowDistantStartTemple; internal static ConfigEntry orientationShowDistantHaldor; internal static ConfigEntry orientationShowDistantHildir; internal static ConfigEntry orientationShowDistantBogWitch; internal static ConfigEntry orientationShowDistantWaystones; internal static ConfigEntry particlesCollision; internal static ConfigEntry particlesMaxAmount; internal static ConfigEntry particlesMinRateOverTime; internal static ConfigEntry particlesMaxRateOverTime; internal static ConfigEntry particlesMinForceOverTime; internal static ConfigEntry particlesMaxForceOverTime; public static readonly CustomSyncedValue> itemsToReduceCooldown = new CustomSyncedValue>((ConditionalConfigSync)(object)configSync, "Items to reduce cooldowns", new Dictionary(), 0, (IEqualityComparer>)SacrificeItemsComparer.Instance); public static string configDirectory; internal static FileSystemWatcher configWatcher; private const string itemsToReduceCooldownFilter = "shudnal.Waystones.reduce_cooldowns.*"; private void Awake() { harmony.PatchAll(); instance = this; ConfigInit(); ((ConditionalConfigSync)configSync).AddLockingConfigEntry(configLocked); Game.isModded = true; configDirectory = Path.Combine(Paths.ConfigPath, "shudnal.Waystones"); LoadIcons(); ((MonoBehaviour)this).StartCoroutine(Localizer.Load()); } public void ConfigInit() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_05c7: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Expected O, but got Unknown //IL_0727: Unknown result type (might be due to invalid IL or missing references) //IL_0731: Expected O, but got Unknown //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Expected O, but got Unknown configLocked = serverConfig("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.", synchronizedSetting: false); pieceRecipe = serverConfig("General", "Recipe", "SurtlingCore:1,GreydwarfEye:5,Stone:5", "Piece recipe"); disableWaystoneSparcs = config("General", "Disable waystone sparks", defaultValue: false, "Disable little sparks constantly emitting from waystone object. Restart required.", synchronizedSetting: false); waystoneMode = serverConfig("General", "Waystone mode", WaystoneMode.Cooldown, "Cooldown - You will only be able to teleport again after the specified time has passed\nCharge - requires waystone to be charged to start teleportation, charges consumption depends on distance, no cooldown on teleportation\nOrientation - Use waystones only for navigation, not teleportation"); maxWaystoneCharge = serverConfig("General", "Max waystone charge", 100, new ConfigDescription("Maximum waystone charge for Charge mode.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100000), Array.Empty())); allowWaystoneChargeOverdraft = serverConfig("Charge mode", "Allow charge overdraft", defaultValue: true, "If enabled, teleportation can consume more charge than the source waystone currently has as long as its charge is positive. This may leave negative charge."); defaultWaystoneChargeFull = serverConfig("Charge mode", "Default charge is full", defaultValue: false, "If enabled, waystones without stored charge data start with maximum charge. If disabled, they start empty."); allowWaystoneChargeOverflow = serverConfig("Charge mode", "Allow charge above maximum", defaultValue: true, "If enabled, item sacrifices can increase stored charge above Max waystone charge, but only once."); waystoneChargeStorage = serverConfig("Charge mode", "Charge storage", ChargeStorage.Waystone, "Where charge is stored and consumed.\nWaystone - item sacrifices charge the interacted waystone, and travel consumes the source waystone charge.\nPlayer - item sacrifices charge the player in current world data, and travel consumes player charge."); pieceRecipe.SettingChanged += delegate { PieceWaystone.SetPieceRequirements(); }; itemSacrifitionReduceCooldown = serverConfig("Item sacrifition", "Sacrifice item from list to reduce cooldown", defaultValue: true, "Enable sacrifition of item from list to reduce waystone cooldown"); showSacrificeItemsInHover = config("Item sacrifition", "Show available sacrifice items in hover text", defaultValue: true, "Show sacrifice items available to the player in waystone hover text.", synchronizedSetting: false); 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"); locationShowBogWitch = config("Locations", "Show Bog Witch", defaultValue: true, "Show Bog Witch 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("Restrictions", "Shortcut", new KeyboardShortcut((KeyCode)121, Array.Empty()), "Enter/Exit direction search mode", synchronizedSetting: false); tagCharactersLimit = serverConfig("Restrictions", "Tag characters limit", 15, "Max length of waystone tag. Values less than 10 will be ignored."); allowForEveryone = serverConfig("Restrictions", "Allow all players to use activated waystones", defaultValue: false, "If enabled, any player can use a waystone once it has been activated by someone."); directionSensitivity = config("Search mode", "Target sensitivity threshold", 1.5f, "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", 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", 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", 40f, "Mouse camera sensitivity acceleration factor.\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.", synchronizedSetting: false); fovDelta = config("Search mode", "FoV delta", 40f, "How much camera FoV can be changed both sides using zoom"); showDirectionIcons = config("Search mode - Icons", "Show direction icons", defaultValue: false, "Show precise screen-space icons for available locations and player-built waystones when looking near their direction."); directionIconSize = config("Search mode - Icons", "Direction icon size", 32f, new ConfigDescription("Screen-space direction icon size in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange(16f, 128f), Array.Empty())); iconSensitivityThreshold = config("Search mode - Icons", "Icon sensitivity threshold", 8f, "Angle between look direction and target direction for direction icons to be visible."); cooldownTime = serverConfig("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 = serverConfig("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 = serverConfig("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 = serverConfig("Travel cooldown", "Fast travelling cooldown maximum", 7200, "Maximal cooldown to be set after successfull fast travelling"); cooldownMinimum = serverConfig("Travel cooldown", "Fast travelling cooldown minimum", 600, "Minimal cooldown to be set after successfull fast travelling"); cooldownShort = serverConfig("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"); chargeDistanceMaximum = serverConfig("Travel charge", "Fast travelling distance maximum", 5000, "If fast travelling distance is larger than that, charge cost will be set to maximum. World radius is 10000."); chargeDistanceMinimum = serverConfig("Travel charge", "Fast travelling distance minimum", 500, "If fast travelling distance is smaller than that, charge cost will be set to minimum. World radius is 10000."); chargeCostMaximum = serverConfig("Travel charge", "Fast travelling charge maximum", 50, new ConfigDescription("Maximum charge cost after successful fast travelling.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100000), Array.Empty())); chargeCostMinimum = serverConfig("Travel charge", "Fast travelling charge minimum", 20, new ConfigDescription("Minimum charge cost after successful fast travelling.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 100000), Array.Empty())); orientationWaystoneVisibilityDistance = serverConfig("Orientation mode", "Waystone visibility distance", 1000, "Maximum distance to show other waystones in orientation mode."); orientationDistanceUnit = config("Orientation mode", "Distance unit", DistanceUnit.Meters, "Displayed units for orientation mode distance."); orientationShowDistantCurrentSpawn = config("Orientation mode", "Show distant current spawn", defaultValue: true, "Show current spawn marker even if farther than orientation distance."); orientationShowDistantLastPoint = config("Orientation mode", "Show distant last location", defaultValue: true, "Show last location marker even if farther than orientation distance."); orientationShowDistantLastShip = config("Orientation mode", "Show distant last ship", defaultValue: true, "Show last ship marker even if farther than orientation distance."); orientationShowDistantLastTombstone = config("Orientation mode", "Show distant last tombstone", defaultValue: true, "Show last tombstone marker even if farther than orientation distance."); orientationShowDistantStartTemple = config("Orientation mode", "Show distant sacrificial stones", defaultValue: true, "Show sacrificial stones marker even if farther than orientation distance."); orientationShowDistantHaldor = config("Orientation mode", "Show distant Haldor", defaultValue: true, "Show Haldor marker even if farther than orientation distance."); orientationShowDistantHildir = config("Orientation mode", "Show distant Hildir", defaultValue: true, "Show Hildir marker even if farther than orientation distance."); orientationShowDistantBogWitch = config("Orientation mode", "Show distant Bog Witch", defaultValue: true, "Show Bog Witch marker even if farther than orientation distance."); orientationShowDistantWaystones = config("Orientation mode", "Show distant waystones", defaultValue: false, "Show player-built waystone markers even if farther than orientation distance."); 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__96_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { WorldData.SetCooldown(args.TryParameterInt(1, 0)); }; <>c.<>9__96_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_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) TeleportAttempt(targetPoint, targetRotation, cooldown, location, null, 0); } internal static void TeleportAttempt(Vector3 targetPoint, Quaternion targetRotation, double cooldown, string location, WaystoneList.WaystoneData sourceWaystone, int travelCost) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) if (!CanCast()) { return; } if (!Utility.IsNullOrWhiteSpace(location)) { MessageHud.instance.ShowMessage((MessageType)1, "$ws_tooltip_moving_to " + location, 0, (Sprite)null, false); } SEMan sEMan = ((Character)Player.m_localPlayer).GetSEMan(); if (sEMan.HaveStatusEffect(SE_Waystone.statusEffectWaystonesHash)) { ((Character)Player.m_localPlayer).GetSEMan().RemoveStatusEffect(SE_Waystone.statusEffectWaystonesHash, false); return; } bool validateCharge = waystoneMode.Value != WaystoneMode.Charge || travelCost <= 0; if (!WaystoneSmall.IsSearchAllowed(Player.m_localPlayer, validateCharge)) { return; } SE_Waystone sE_Waystone = ((Character)Player.m_localPlayer).GetSEMan().AddStatusEffect(SE_Waystone.statusEffectWaystonesHash, false, 0, 0f) as SE_Waystone; if ((Object)(object)sE_Waystone != (Object)null) { sE_Waystone.targetPoint = targetPoint; sE_Waystone.targetCooldown = cooldown; sE_Waystone.targetRotation = targetRotation; sE_Waystone.sourceWaystone = sourceWaystone; sE_Waystone.travelCost = travelCost; if (emitNoiseOnTeleportation.Value) { ((Character)Player.m_localPlayer).AddNoise(50f); BaseAI.DoProjectileHitNoise(((Component)Player.m_localPlayer).transform.position, 50f, (Character)(object)Player.m_localPlayer); } if (!Utility.IsNullOrWhiteSpace(location)) { MessageHud.instance.ShowMessage((MessageType)2, "$ws_message_travelling_to " + location, 0, (Sprite)null, false); ((StatusEffect)sE_Waystone).m_name = location; LogInfo($"Teleport initiated to {location} pos {targetPoint} cooldown {WorldData.TimerString(cooldown)}"); } } } public static bool CanCast() { Player localPlayer = Player.m_localPlayer; return !((Object)(object)localPlayer == (Object)null) && !((Character)localPlayer).IsDead() && !((Character)localPlayer).InCutscene() && !((Character)localPlayer).IsTeleporting() && !((Character)localPlayer).InInterior() && ((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !TextInput.IsVisible() && !GameCamera.InFreeFly() && !StoreGui.IsVisible() && !InventoryGui.IsVisible(); } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } private ConfigEntry config(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { return ((ConditionalConfigSync)configSync).AddConfigEntry(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)1, synchronizedSetting).SourceConfig; } private ConfigEntry serverConfig(string group, string name, T defaultValue, ConfigDescription description) { return ((ConditionalConfigSync)configSync).AddConfigEntry(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)0, true).SourceConfig; } private ConfigEntry config(string group, string name, T defaultValue, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } private ConfigEntry serverConfig(string group, string name, T defaultValue, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return serverConfig(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty())); } private void LoadIcons() { LoadIcon("SE_Waystone.png", ref SE_Waystone.iconWaystones); LoadIcon("item_waystone.png", ref PieceWaystone.itemWaystone); LoadIcon("icon_waystone.png", ref WaystoneList.iconWaystone); } internal static void LoadIcon(string filename, ref Sprite icon) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Texture2D tex = new Texture2D(2, 2); if (LoadTexture(filename, ref tex)) { icon = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), Vector2.zero); } } internal static bool LoadTexture(string filename, ref Texture2D tex) { string text = Path.Combine(configDirectory, filename); if (File.Exists(text)) { LogInfo("Loaded image: " + text); return ImageConversion.LoadImage(tex, File.ReadAllBytes(text)); } Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); ((Object)tex).name = Path.GetFileNameWithoutExtension(filename); return ImageConversion.LoadImage(tex, array, true); } private static bool PreventPlayerInput() { return (Object)(object)Player.m_localPlayer != (Object)null && ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(SE_Waystone.statusEffectWaystonesHash); } public static void SetupConfigWatcher(bool enabled) { if (Directory.Exists(Paths.ConfigPath)) { if (enabled) { ReadInitialConfigs(); } if (configWatcher == null) { configWatcher = new FileSystemWatcher(Paths.ConfigPath, "shudnal.Waystones.reduce_cooldowns.*"); configWatcher.Changed += ReadConfigs; configWatcher.Created += ReadConfigs; configWatcher.Renamed += ReadConfigs; configWatcher.Deleted += ReadConfigs; configWatcher.IncludeSubdirectories = false; configWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; } configWatcher.EnableRaisingEvents = enabled; } } internal static void ReadInitialConfigs() { FileInfo[] files = new DirectoryInfo(Paths.ConfigPath).GetFiles("shudnal.Waystones.reduce_cooldowns.*", SearchOption.AllDirectories); foreach (FileInfo fileInfo in files) { ReadConfigFile(fileInfo.Name, fileInfo.FullName); } } private static void ReadConfigs(object sender, FileSystemEventArgs eargs) { if (eargs is RenamedEventArgs) { ReadInitialConfigs(); } else { ReadConfigFile(eargs.Name, eargs.FullPath); } } private static void ReadConfigFile(string filename, string fullname) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); try { string text = File.ReadAllText(fullname); if (text != null) { foreach (KeyValuePair item in ((BuilderSkeleton)new DeserializerBuilder()).IgnoreFields().Build().Deserialize>(text) ?? new Dictionary()) { if (item.Value > 0) { string text2 = NormalizeSacrificeItemKey(item.Key); if (!Utility.IsNullOrWhiteSpace(text2)) { dictionary[text2] = item.Value; } } } } } catch (Exception ex) { LogInfo("Error reading file (" + fullname + ")! Error: " + ex.Message); } itemsToReduceCooldown.AssignLocalValueIfChanged(dictionary); LogInfo($"Loaded {dictionary.Count} items from file {filename}"); } private static string NormalizeSacrificeItemKey(string key) { if (Utility.IsNullOrWhiteSpace(key)) { return ""; } key = key.Trim(); int num = key.LastIndexOf(':'); if (num < 0) { return key.GetItemName(); } string text = key.Substring(0, num).Trim(); string text2 = key.Substring(num + 1).Trim(); if (Utility.IsNullOrWhiteSpace(text)) { return ""; } if (Utility.IsNullOrWhiteSpace(text2)) { return text.GetItemName(); } return text.GetItemName() + ":" + text2; } } public class SE_Waystone : SE_Stats { [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_AddStatusEffects { public static void AddCustomStatusEffects(ObjectDB odb) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown RegisterEffects(); if (odb.m_StatusEffects.Count > 0 && !odb.m_StatusEffects.Any((StatusEffect se) => ((Object)se).name == "WaystoneFastTravel")) { SE_Waystone sE_Waystone = ScriptableObject.CreateInstance(); ((Object)sE_Waystone).name = "WaystoneFastTravel"; ((StatusEffect)sE_Waystone).m_nameHash = statusEffectWaystonesHash; ((StatusEffect)sE_Waystone).m_icon = iconWaystones; ((SE_Stats)sE_Waystone).m_noiseModifier = 1f; ((SE_Stats)sE_Waystone).m_stealthModifier = -1f; ((SE_Stats)sE_Waystone).m_staminaDrainPerSec = 10f; ((StatusEffect)sE_Waystone).m_name = "$se_waystone_name"; ((StatusEffect)sE_Waystone).m_tooltip = "$se_waystone_tooltip"; ((StatusEffect)sE_Waystone).m_startEffects.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { new EffectData { m_prefab = vfx_Waystones, m_enabled = true, m_inheritParentScale = true, m_attach = true } }; ((StatusEffect)sE_Waystone).m_ttl = 10f; odb.m_StatusEffects.Add((StatusEffect)(object)sE_Waystone); } } private static void Postfix(ObjectDB __instance) { AddCustomStatusEffects(__instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_AddStatusEffects { private static void Postfix(ObjectDB __instance) { ObjectDB_Awake_AddStatusEffects.AddCustomStatusEffects(__instance); } } [HarmonyPatch(typeof(Player), "ActivateGuardianPower")] public static class Player_ActivateGuardianPower_PreventGuardianPower { private static bool Prefix(Player __instance) { return !((Character)__instance).GetSEMan().HaveStatusEffect(statusEffectWaystonesHash) && !(blockGPTime > Time.time); } } public const string statusEffectWaystonesName = "WaystoneFastTravel"; public static readonly int statusEffectWaystonesHash = StringExtensionMethods.GetStableHashCode("WaystoneFastTravel"); public const string vfx_WaystonesName = "vfx_Waystones"; public static readonly int vfx_WaystonesHash = StringExtensionMethods.GetStableHashCode("vfx_Waystones"); public const string vfx_WaystonesParticles = "Sparcs"; public const string vfx_WaystonesSfx = "Sfx"; public const string vfx_WaystonesLight = "Light"; public const string statusEffectName = "$se_waystone_name"; public const string statusEffectTooltip = "$se_waystone_tooltip"; public static Sprite iconWaystones; public static GameObject vfx_Waystones; public static float blockGPTime; [NonSerialized] public Vector3 targetPoint = Vector3.zero; [NonSerialized] public Quaternion targetRotation = Quaternion.identity; [NonSerialized] public double targetCooldown = 0.0; [NonSerialized] internal WaystoneList.WaystoneData sourceWaystone; [NonSerialized] internal int travelCost; [NonSerialized] private bool lookDirTriggered; [NonSerialized] private bool teleportTriggered; [NonSerialized] private ZNetView effectNetView; public override void UpdateStatusEffect(float dt) { //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) ((SE_Stats)this).UpdateStatusEffect(dt); if (((StatusEffect)this).m_startEffectInstances == null) { return; } if ((Object)(object)effectNetView == (Object)null) { effectNetView = ((StatusEffect)this).m_startEffectInstances[0].GetComponent(); } WaystoneTravelEffect.SetProgress(effectNetView, ((StatusEffect)this).m_time / ((StatusEffect)this).m_ttl); if (ControlLocalPlayer()) { Player localPlayer = Player.m_localPlayer; if (!lookDirTriggered && targetPoint != Vector3.zero) { lookDirTriggered = true; ((Character)localPlayer).SetLookDir(targetPoint - ((Component)localPlayer).transform.position, 5f); blockGPTime = Time.time + ((StatusEffect)this).m_ttl + 1f; ((Character)localPlayer).GetZAnim().SetTrigger("gpower"); } if (((Character)localPlayer).m_lookTransitionTime > 0f) { ((Component)localPlayer).transform.rotation = ((Character)localPlayer).m_lookYaw; } localPlayer.SetMouseLookForward(false); localPlayer.m_lookPitch = Mathf.MoveTowards(localPlayer.m_lookPitch, 0f, dt * 10f); ((Character)localPlayer).GetZAnim().SetSpeed(0.125f); if (!teleportTriggered && ((StatusEffect)this).GetRemaningTime() < 0.75f && targetPoint != Vector3.zero) { ((Character)localPlayer).TeleportTo(targetPoint, (targetRotation == Quaternion.identity) ? ((Component)localPlayer).transform.rotation : targetRotation, true); WorldData.SaveLastPosition(((Component)localPlayer).transform.position); teleportTriggered = true; } } if (targetPoint != Vector3.zero) { Vector3 val = targetPoint - ((Component)((StatusEffect)this).m_character).transform.position; ((Vector3)(ref val)).Normalize(); ((StatusEffect)this).m_startEffectInstances[0].transform.rotation = Quaternion.LookRotation(val); ((StatusEffect)this).m_startEffectInstances[0].transform.localPosition = Vector3.MoveTowards(((StatusEffect)this).m_startEffectInstances[0].transform.localPosition, new Vector3(0f, 1.5f, -0.3f), dt / 10f); } } public override void Setup(Character character) { ((SE_Stats)this).Setup(character); character.StopEmote(); } public override void Stop() { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) ((StatusEffect)this).Stop(); if (!Object.op_Implicit((Object)(object)((StatusEffect)this).m_character)) { return; } ((StatusEffect)this).m_character.GetZAnim().SetSpeed(1f); ((StatusEffect)this).m_character.m_lookTransitionTime = 0f; if ((Object)(object)((StatusEffect)this).m_character == (Object)(object)Player.m_localPlayer) { if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Cooldown) { WorldData.SetCooldown(teleportTriggered ? targetCooldown : ((double)Waystones.cooldownShort.Value)); } else if (Waystones.waystoneMode.Value == Waystones.WaystoneMode.Charge && teleportTriggered && travelCost > 0 && !WaystoneList.TryConsumeTravelCharge(sourceWaystone, Player.m_localPlayer.GetPlayerID(), travelCost, Waystones.allowWaystoneChargeOverdraft.Value)) { Waystones.LogInfo($"Failed to consume travel charge after teleport. Cost: {travelCost}, storage: {Waystones.waystoneChargeStorage.Value}, source: {((sourceWaystone == null) ? Vector3.zero : sourceWaystone.worldPosition)}"); } } } public override void OnDamaged(HitData hit, Character attacker) { ((StatusEffect)this).OnDamaged(hit, attacker); if (!((Object)(object)attacker == (Object)null)) { ((StatusEffect)this).m_time = ((StatusEffect)this).m_time - 1f; blockGPTime += 1f; } } private bool ControlLocalPlayer() { return (Object)(object)((StatusEffect)this).m_character != (Object)null && (Object)(object)((StatusEffect)this).m_character == (Object)(object)Player.m_localPlayer; } public static void RegisterEffects() { //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return; } if (!Object.op_Implicit((Object)(object)vfx_Waystones)) { WayStone val = Resources.FindObjectsOfTypeAll().FirstOrDefault(); if ((Object)(object)val == (Object)null) { return; } vfx_Waystones = CustomPrefabs.InitPrefabClone(ObjectDB.instance.GetStatusEffect(SEMan.s_statusEffectCold).m_startEffects.m_effectPrefabs[0].m_prefab, "vfx_Waystones"); for (int num = vfx_Waystones.transform.childCount - 1; num >= 0; num--) { Transform child = vfx_Waystones.transform.GetChild(num); child.parent = null; Object.Destroy((Object)(object)((Component)child).gameObject); } WaystoneTravelEffect.initial = true; vfx_Waystones.AddComponent(); WaystoneTravelEffect.initial = false; ZSyncTransform component = vfx_Waystones.GetComponent(); component.m_syncRotation = true; component.m_useGravity = false; component.m_syncScale = false; ((Object)Object.Instantiate(((Component)val).transform.Find("WayEffect/sfx"), vfx_Waystones.transform)).name = "Sfx"; GameObject gameObject = ((Component)Object.Instantiate(((Component)val).transform.Find("WayEffect/Point light"), vfx_Waystones.transform)).gameObject; ((Object)gameObject).name = "Light"; gameObject.transform.localPosition = new Vector3(0f, 0f, -0.2f); Light component2 = gameObject.GetComponent(); component2.cullingMask = -1; component2.shadows = (LightShadows)0; component2.intensity = 0f; GameObject gameObject2 = ((Component)Object.Instantiate(((Component)val).transform.Find("WayEffect/Particle System sparcs"), vfx_Waystones.transform)).gameObject; ((Object)gameObject2).name = "Sparcs"; gameObject2.transform.localPosition = new Vector3(0f, 0f, -0.1f); ParticleSystem component3 = gameObject2.GetComponent(); MainModule main = component3.main; ((MainModule)(ref main)).maxParticles = Waystones.particlesMaxAmount.Value; ((MainModule)(ref main)).duration = 20f; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).simulationSpeed = 1f; ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(1f); ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1f); EmissionModule emission = component3.emission; MinMaxCurve rateOverTime = ((EmissionModule)(ref emission)).rateOverTime; ((MinMaxCurve)(ref rateOverTime)).mode = (ParticleSystemCurveMode)1; ((MinMaxCurve)(ref rateOverTime)).curve = AnimationCurve.Linear(0f, (float)Waystones.particlesMinRateOverTime.Value, 1f, (float)Waystones.particlesMaxRateOverTime.Value); ((EmissionModule)(ref emission)).rateOverTime = rateOverTime; if (Waystones.particlesCollision.Value) { CollisionModule collision = component3.collision; ((CollisionModule)(ref collision)).enabled = true; ((CollisionModule)(ref collision)).type = (ParticleSystemCollisionType)1; } ForceOverLifetimeModule forceOverLifetime = component3.forceOverLifetime; ((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = true; MinMaxCurve z = ((ForceOverLifetimeModule)(ref forceOverLifetime)).z; ((MinMaxCurve)(ref z)).mode = (ParticleSystemCurveMode)1; ((MinMaxCurve)(ref z)).curve = AnimationCurve.Linear(0f, (float)Waystones.particlesMinForceOverTime.Value, 1f, (float)Waystones.particlesMaxForceOverTime.Value); ((ForceOverLifetimeModule)(ref forceOverLifetime)).z = z; ((ForceOverLifetimeModule)(ref forceOverLifetime)).zMultiplier = 3f; } if (Object.op_Implicit((Object)(object)vfx_Waystones)) { if (ZNetScene.instance.m_namedPrefabs.ContainsKey(vfx_WaystonesHash)) { ZNetScene.instance.m_prefabs.Remove(ZNetScene.instance.m_namedPrefabs[vfx_WaystonesHash]); ZNetScene.instance.m_namedPrefabs.Remove(vfx_WaystonesHash); } ZNetScene.instance.m_prefabs.Add(vfx_Waystones); ZNetScene.instance.m_namedPrefabs.Add(vfx_WaystonesHash, vfx_Waystones); } } } }