Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ReturnStone v1.0.10
ReturnStone.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ReturnStone")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.10.0")] [assembly: AssemblyInformationalVersion("1.0.10")] [assembly: AssemblyProduct("ReturnStone")] [assembly: AssemblyTitle("ReturnStone")] [assembly: AssemblyVersion("1.0.10.0")] namespace DragonMotion.ReturnStone; internal static class LocalizationWords { private static readonly MethodInfo AddWordMethod = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); private static readonly Dictionary<string, string> English = new Dictionary<string, string> { ["returnstone_name"] = "Return Stone", ["returnstone_description"] = "Raise the glowing rune through two green vortex pulses to return to your claimed bed. If no bed is claimed, it returns you to the world's starting altar.", ["returnstone_channeling"] = "The return rune awakens...", ["returnstone_cannot_start"] = "You must stand on solid ground to invoke the return rune.", ["returnstone_interrupted"] = "The return was interrupted.", ["returnstone_no_target"] = "No valid return point could be found.", ["returnstone_teleport_failed"] = "The return magic could not take hold." }; private static readonly Dictionary<string, string> Russian = new Dictionary<string, string> { ["returnstone_name"] = "Камень возврата", ["returnstone_description"] = "Поднимите светящуюся руну и выдержите два зелёных вихревых импульса, чтобы вернуться к своей кровати. Если кровать не назначена, камень вернёт вас к стартовому алтарю мира.", ["returnstone_channeling"] = "Руна возврата пробуждается...", ["returnstone_cannot_start"] = "Для призыва руны возврата нужно стоять на твёрдой земле.", ["returnstone_interrupted"] = "Возвращение прервано.", ["returnstone_no_target"] = "Не удалось найти точку возврата.", ["returnstone_teleport_failed"] = "Магия возврата не смогла сработать." }; internal static void ApplyCurrent() { try { Localization instance = Localization.instance; Apply(instance, instance.GetSelectedLanguage()); } catch (Exception ex) { Plugin.LogWarning("Could not apply Return Stone localization immediately: " + ex.Message); } } internal static void Apply(Localization localization, string language) { if (localization == null || AddWordMethod == null) { return; } foreach (KeyValuePair<string, string> item in string.Equals(language, "Russian", StringComparison.OrdinalIgnoreCase) ? Russian : English) { AddWordMethod.Invoke(localization, new object[2] { item.Key, item.Value }); } } } [BepInPlugin("dragonmotion.returnstone", "Return Stone", "1.0.10")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "dragonmotion.returnstone"; public const string PluginName = "Return Stone"; public const string PluginVersion = "1.0.10"; private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static void LogInfo(string message) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } internal static void LogWarning(string message) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)message); } } internal static void LogError(string message) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)message); } } private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown Instance = this; if (!ReturnStoneAssets.Load()) { ((BaseUnityPlugin)this).Logger.LogError((object)"Return Stone is disabled because the Unity asset bundle could not be loaded."); ((Behaviour)this).enabled = false; return; } _harmony = new Harmony("dragonmotion.returnstone"); _harmony.PatchAll(); LocalizationWords.ApplyCurrent(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Return Stone 1.0.10 loaded. Equip the stone and use the primary attack to return."); } private void OnDestroy() { ReturnStoneChannel.CancelActive(showMessage: false); ReturnStoneAssets.Unload(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; } } internal static class ReturnStoneAssets { private const string BundleFileName = "returnstone"; private static AssetBundle _bundle; internal static GameObject ModelPrefab { get; private set; } internal static Sprite Icon { get; private set; } internal static AudioClip CycleClip { get; private set; } internal static bool Load() { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty, "returnstone"); _bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)_bundle == (Object)null) { Plugin.LogError("Could not load Unity asset bundle: " + text); return false; } ModelPrefab = LoadRequired<GameObject>("Assets/Prefabs/ReturnStone_Model.prefab"); Icon = LoadRequired<Sprite>("Assets/Textures/returnstone_icon_v3.png"); CycleClip = LoadRequired<AudioClip>("Assets/Audio/return_channel_user.wav"); int num; if ((Object)(object)ModelPrefab != (Object)null && (Object)(object)Icon != (Object)null) { num = (((Object)(object)CycleClip != (Object)null) ? 1 : 0); if (num != 0) { goto IL_00af; } } else { num = 0; } Plugin.LogError("The Return Stone asset bundle is missing one or more required assets."); goto IL_00af; IL_00af: return (byte)num != 0; } internal static void Unload() { if ((Object)(object)_bundle != (Object)null) { _bundle.Unload(false); } _bundle = null; } private static T LoadRequired<T>(string path) where T : Object { T val = _bundle.LoadAsset<T>(path); if ((Object)(object)val == (Object)null) { Plugin.LogError("Missing bundle asset: " + path); } return val; } } internal static class ReturnStoneAudio { internal static AudioSource AttachCycleSource(GameObject target) { //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_0034: 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) if ((Object)(object)target == (Object)null || (Object)(object)ReturnStoneAssets.CycleClip == (Object)null) { return null; } GameObject val = new GameObject("ReturnStone_CycleAudio"); val.transform.SetParent(target.transform, false); val.transform.localPosition = Vector3.zero; AudioSource obj = val.AddComponent<AudioSource>(); Configure(obj, 32f); obj.clip = ReturnStoneAssets.CycleClip; obj.loop = false; obj.volume = 0.82f; return obj; } internal static void PlayCycle(AudioSource source) { if (!((Object)(object)source == (Object)null)) { source.Stop(); source.time = 0f; source.Play(); } } internal static void DestroyCycleSource(AudioSource source) { if (!((Object)(object)source == (Object)null)) { source.Stop(); Object.Destroy((Object)(object)((Component)source).gameObject); } } private static void Configure(AudioSource source, float maxDistance, float minDistance = 3.5f) { source.playOnAwake = false; source.spatialBlend = 0.72f; source.rolloffMode = (AudioRolloffMode)0; source.minDistance = minDistance; source.maxDistance = maxDistance; source.dopplerLevel = 0f; source.priority = 90; } } internal static class ReturnStoneChannel { internal const int CycleCount = 2; internal const float CycleDuration = 3.5f; internal const float Duration = 7f; private static ReturnStoneChannelController _active; internal static bool IsActive => (Object)(object)_active != (Object)null; internal static bool IsChanneling(Player player) { if ((Object)(object)_active != (Object)null) { return (Object)(object)_active.Owner == (Object)(object)player; } return false; } internal static bool TryStart(Player player) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_active != (Object)null || (Object)(object)player == (Object)null || !ReturnStoneRegistry.IsStoneEquipped(player)) { return false; } if (!CanStart(player)) { ((Character)player).Message((MessageType)2, "$returnstone_cannot_start", 0, (Sprite)null); return false; } ItemData rightItem = ((Humanoid)player).RightItem; if (!((Humanoid)player).GetInventory().ContainsItem(rightItem) || rightItem.m_stack < 1) { return false; } _active = new GameObject("ReturnStone_Channel").AddComponent<ReturnStoneChannelController>(); _active.Initialize(player, rightItem, OnFinished); return true; } internal static void CancelActive(bool showMessage) { if ((Object)(object)_active != (Object)null) { _active.Cancel(showMessage); } } private static void OnFinished(ReturnStoneChannelController controller) { if ((Object)(object)_active == (Object)(object)controller) { _active = null; } } private static bool CanStart(Player player) { if (!((Character)player).IsDead() && !((Character)player).InCutscene() && !((Character)player).IsTeleporting() && !((Character)player).InAttack() && !((Character)player).InDodge() && !((Character)player).IsStaggering() && !((Character)player).IsKnockedBack() && !((Character)player).IsAttached() && !((Character)player).IsSwimming() && ((Character)player).IsOnGround() && !Console.IsVisible() && !TextInput.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible() && ((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus())) { if (!((Object)(object)Hud.instance == (Object)null)) { return !Hud.InRadial(); } return true; } return false; } } internal sealed class ReturnStoneChannelController : MonoBehaviour { private Player _owner; private ItemData _item; private Action<ReturnStoneChannelController> _finished; private float _startedAt; private bool _ended; internal Player Owner => _owner; internal void Initialize(Player owner, ItemData item, Action<ReturnStoneChannelController> finished) { _owner = owner; _item = item; _finished = finished; _startedAt = Time.time; ReturnStoneNetwork.SendStart(owner); ((Character)owner).Message((MessageType)2, "$returnstone_channeling", 0, (Sprite)null); } private void Update() { if (_ended) { return; } if (!IsStillValid()) { string text = $"Return Stone channel became invalid: owner={(Object)(object)_owner != (Object)null}, "; Player owner = _owner; object arg = ((owner != null) ? new bool?(((Character)owner).IsDead()) : ((bool?)null)); Player owner2 = _owner; object arg2 = ((owner2 != null) ? new bool?(((Character)owner2).InCutscene()) : ((bool?)null)); Player owner3 = _owner; string text2 = $"dead={arg}, cutscene={arg2}, teleporting={((owner3 != null) ? new bool?(((Character)owner3).IsTeleporting()) : ((bool?)null))}, "; string text3 = $"equipped={ReturnStoneRegistry.IsStoneEquipped(_owner)}, "; Player owner4 = _owner; bool? obj; if (owner4 == null) { obj = null; } else { Inventory inventory = ((Humanoid)owner4).GetInventory(); obj = ((inventory != null) ? new bool?(inventory.ContainsItem(_item)) : ((bool?)null)); } Plugin.LogWarning(text + text2 + text3 + $"inventory={obj}, stack={_item?.m_stack ?? (-1)}."); Cancel(showMessage: true); } else if (Time.time - _startedAt >= 7f) { Complete(); } } internal void Cancel(bool showMessage) { if (_ended) { return; } _ended = true; if ((Object)(object)_owner != (Object)null) { ReturnStoneNetwork.SendCancel(_owner); if (showMessage) { ((Character)_owner).Message((MessageType)2, "$returnstone_interrupted", 0, (Sprite)null); } } FinishController(); } private bool IsStillValid() { if ((Object)(object)_owner != (Object)null && !((Character)_owner).IsDead() && !((Character)_owner).InCutscene() && !((Character)_owner).IsTeleporting() && ReturnStoneRegistry.IsStoneEquipped(_owner) && ((Humanoid)_owner).GetInventory().ContainsItem(_item)) { return _item.m_stack > 0; } return false; } private void Complete() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (_ended) { return; } if (!TryResolveTarget(out var target)) { ((Character)_owner).Message((MessageType)2, "$returnstone_no_target", 0, (Sprite)null); Cancel(showMessage: false); return; } Vector3 val = Vector3.ProjectOnPlane(((Character)_owner).GetLookDir(), Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.ProjectOnPlane(((Component)_owner).transform.forward, Vector3.up); } Quaternion val2 = ((((Vector3)(ref val)).sqrMagnitude < 0.001f) ? ((Component)_owner).transform.rotation : Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up)); if (!((Character)_owner).TeleportTo(target, val2, true)) { ((Character)_owner).Message((MessageType)2, "$returnstone_teleport_failed", 0, (Sprite)null); Cancel(showMessage: false); return; } _ended = true; ConsumeOneStone(); ReturnStoneNetwork.SendComplete(_owner); FinishController(); } private bool TryResolveTarget(out Vector3 target) { //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_0071: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0051: Unknown result type (might be due to invalid IL or missing references) target = Vector3.zero; if ((Object)(object)Game.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null) { return false; } PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); if (playerProfile != null && playerProfile.HaveCustomSpawnPoint()) { target = playerProfile.GetCustomSpawnPoint(); return true; } Vector3 val = default(Vector3); if (ZoneSystem.instance.GetLocationIcon(Game.instance.m_StartLocation, ref val)) { target = val + Vector3.up * 2f; return true; } return false; } private void ConsumeOneStone() { Inventory inventory = ((Humanoid)_owner).GetInventory(); if (inventory.ContainsItem(_item)) { if (_item.m_stack <= 1) { ((Humanoid)_owner).UnequipItem(_item, false); } inventory.RemoveOneItem(_item); } } private void FinishController() { _finished?.Invoke(this); _finished = null; Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static class ReturnStoneNetwork { private const string StartRpc = "dragonmotion.returnstone.start"; private const string CancelRpc = "dragonmotion.returnstone.cancel"; private const string CompleteRpc = "dragonmotion.returnstone.complete"; internal static void Register(Player player) { Player obj = player; ZNetView val = ((obj != null) ? ((Component)obj).GetComponent<ZNetView>() : null); if (!((Object)(object)val == (Object)null)) { val.Register<long>("dragonmotion.returnstone.start", (Action<long, long>)delegate(long _, long startMilliseconds) { ReturnStoneVisualController.Begin(player, startMilliseconds); }); val.Register("dragonmotion.returnstone.cancel", (Action<long>)delegate { ReturnStoneVisualController.Cancel(player); }); val.Register("dragonmotion.returnstone.complete", (Action<long>)delegate { ReturnStoneVisualController.Complete(player); }); } } internal static void SendStart(Player player) { ZNetView val = ((player != null) ? ((Component)player).GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { ReturnStoneVisualController.Begin(player, WorldMilliseconds()); return; } val.InvokeRPC(ZNetView.Everybody, "dragonmotion.returnstone.start", new object[1] { WorldMilliseconds() }); } internal static void SendCancel(Player player) { ZNetView val = ((player != null) ? ((Component)player).GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { ReturnStoneVisualController.Cancel(player); } else { val.InvokeRPC(ZNetView.Everybody, "dragonmotion.returnstone.cancel", Array.Empty<object>()); } } internal static void SendComplete(Player player) { ZNetView val = ((player != null) ? ((Component)player).GetComponent<ZNetView>() : null); if ((Object)(object)val == (Object)null || !val.IsValid()) { ReturnStoneVisualController.Complete(player); } else { val.InvokeRPC(ZNetView.Everybody, "dragonmotion.returnstone.complete", Array.Empty<object>()); } } internal static long WorldMilliseconds() { if (!((Object)(object)ZNet.instance != (Object)null)) { return (long)(Time.time * 1000f); } return (long)(ZNet.instance.GetTimeSeconds() * 1000.0); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] internal static class ReturnStoneZNetScenePatch { [HarmonyPriority(700)] private static void Prefix(ZNetScene __instance) { ReturnStoneRegistry.PrepareForScene(__instance); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] internal static class ReturnStoneObjectDbAwakePatch { [HarmonyPriority(600)] private static void Prefix(ObjectDB __instance) { ReturnStoneRegistry.RegisterInObjectDb(__instance, rebuildRegisters: false); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] internal static class ReturnStoneObjectDbCopyPatch { [HarmonyPriority(200)] private static void Postfix(ObjectDB __instance) { ReturnStoneRegistry.RegisterInObjectDb(__instance, rebuildRegisters: true); } } [HarmonyPatch(typeof(Player), "Awake")] internal static class ReturnStonePlayerAwakePatch { private static void Postfix(Player __instance) { ReturnStoneNetwork.Register(__instance); } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal static class ReturnStoneSuppressAttackPatch { private static bool Prefix(Humanoid __instance, ref bool __result) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ReturnStoneRegistry.IsStoneEquipped(Player.m_localPlayer)) { __result = ReturnStoneChannel.TryStart(Player.m_localPlayer); return false; } return true; } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class ReturnStoneControlPatch { private static void Prefix(Player __instance, ref Vector3 movedir, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool jump, ref bool crouch, ref bool run, ref bool autoRun, ref bool dodge) { //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) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && ReturnStoneChannel.IsChanneling(__instance)) { movedir = Vector3.zero; attack = false; attackHold = false; secondaryAttack = false; secondaryAttackHold = false; block = false; blockHold = false; jump = false; crouch = false; run = false; autoRun = false; dodge = false; } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] internal static class ReturnStoneEquipReferencePatch { private static void Prefix(ItemData item) { ReturnStoneRegistry.RepairItemReference(item); } } [HarmonyPatch(typeof(Humanoid), "DropItem")] internal static class ReturnStoneDropReferencePatch { private static void Prefix(ItemData item) { ReturnStoneRegistry.RepairItemReference(item); } } [HarmonyPatch(typeof(Inventory), "Load")] internal static class ReturnStoneInventoryLoadPatch { private static void Postfix(Inventory __instance) { ReturnStoneRegistry.RepairInventory(__instance); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] internal static class ReturnStoneInventoryAddPatch { [HarmonyPriority(800)] [HarmonyBefore(new string[] { "sighsorry.InventorySlots" })] private static void Prefix(ItemData item) { ReturnStoneRegistry.RepairItemReference(item); } } [HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[] { typeof(ItemData), typeof(int) })] internal static class ReturnStoneInventoryCanAddPatch { [HarmonyPriority(800)] [HarmonyBefore(new string[] { "sighsorry.InventorySlots" })] private static void Prefix(ItemData item) { ReturnStoneRegistry.RepairItemReference(item); } } [HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })] internal static class ReturnStoneLegacyPlayerLoadPatch { [HarmonyPostfix] [HarmonyPriority(800)] [HarmonyBefore(new string[] { "org.bepinex.helpers.ItemDataManager", "sighsorry.InventorySlots", "dragonmotion.InventorySlotsVisualToggle", "warpalicious.More_World_Locations_AIO", "obelisk.ru.localization.known-text-migration" })] private static void Postfix(Player __instance) { ReturnStoneRegistry.MigrateLegacyDummy(__instance); } } [HarmonyPatch(typeof(Localization), "SetupLanguage")] internal static class ReturnStoneLocalizationPatch { private static void Postfix(Localization __instance, string language) { LocalizationWords.Apply(__instance, language); } } internal static class ReturnStoneRegistry { internal const string PrefabName = "ReturnStone"; internal const string IdentityKey = "dragonmotion.returnstone.identity"; private const string RecipeName = "Recipe_ReturnStone"; private const string LegacyDummyPrefabName = "EL_DummyPrefab"; private static readonly FieldInfo NamedPrefabsField = AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs"); private static readonly MethodInfo UpdateRegistersMethod = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); private static readonly MethodInfo InventoryChangedMethod = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null); private static readonly FieldInfo KnownRecipesField = AccessTools.Field(typeof(Player), "m_knownRecipes"); private static readonly FieldInfo KnownMaterialField = AccessTools.Field(typeof(Player), "m_knownMaterial"); private static CraftingStation _sceneWorkbench; private static bool _recipeRegisteredLogWritten; private static GameObject _prefabContainer; internal static GameObject ItemPrefab { get; private set; } internal static Recipe Recipe { get; private set; } internal static bool IsStoneEquipped(Player player) { ItemData val = ((player != null) ? ((Humanoid)player).RightItem : null); if (IsStone(val)) { return val.m_equipped; } return false; } internal static bool IsStone(ItemData item) { if (item == null) { return false; } GameObject dropPrefab = item.m_dropPrefab; int num; if (!string.Equals((dropPrefab != null) ? ((Object)dropPrefab).name : null, "ReturnStone", StringComparison.Ordinal) && !string.Equals(item.m_shared?.m_name, "$returnstone_name", StringComparison.Ordinal)) { num = (HasIdentity(item) ? 1 : 0); if (num == 0) { goto IL_0055; } } else { num = 1; } RepairItemReference(item); goto IL_0055; IL_0055: return (byte)num != 0; } internal static void RepairItemReference(ItemData item) { if (item == null) { return; } GameObject dropPrefab = item.m_dropPrefab; if (string.Equals((dropPrefab != null) ? ((Object)dropPrefab).name : null, "ReturnStone", StringComparison.Ordinal) || string.Equals(item.m_shared?.m_name, "$returnstone_name", StringComparison.Ordinal) || HasIdentity(item)) { ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab("ReturnStone") : null); if ((Object)(object)val == (Object)null) { val = ItemPrefab; } ItemDrop val2 = ((val != null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null) && val2?.m_itemData?.m_shared != null) { item.m_dropPrefab = val; item.m_shared = val2.m_itemData.m_shared; item.m_variant = 0; item.m_stack = Mathf.Clamp(item.m_stack, 1, item.m_shared.m_maxStackSize); RemoveIdentity(item); } } } internal static void RepairInventory(Inventory inventory) { if (inventory == null) { return; } foreach (ItemData item in inventory.GetAllItems().ToList()) { RepairItemReference(item); } ConsolidatePlainStoneStacks(inventory); } internal static void MigrateLegacyDummy(Player player) { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null); if (val == null || (Object)(object)ItemPrefab == (Object)null) { return; } List<ItemData> list = val.GetAllItems().Where(IsLegacyDummy).ToList(); if (list.Count == 0) { return; } ItemData val2 = ((IEnumerable<ItemData>)list).FirstOrDefault((Func<ItemData, bool>)HasIdentity); HashSet<string> obj = KnownRecipesField?.GetValue(player) as HashSet<string>; HashSet<string> hashSet = KnownMaterialField?.GetValue(player) as HashSet<string>; bool flag = (obj != null && obj.Contains("$returnstone_name")) || (hashSet?.Contains("$returnstone_name") ?? false); if (val2 == null && flag) { List<ItemData> list2 = list.Where((ItemData item) => item.m_equipped && item.m_gridPos.y == 0).ToList(); if (list2.Count == 1) { val2 = list2[0]; } else if (list.Count == 1) { val2 = list[0]; } } if (val2 == null) { Plugin.LogWarning($"Found {list.Count} Epic Loot dummy item(s), but none could be identified " + "unambiguously as a legacy Return Stone. No inventory data was changed."); return; } Vector2i gridPos = val2.m_gridPos; int stack = val2.m_stack; bool equipped = val2.m_equipped; if (equipped) { val2.m_equipped = false; } RepairLegacyDummy(val2); bool flag2 = !equipped || ((Humanoid)player).EquipItem(val2, false); if (!flag2) { Plugin.LogWarning($"Recovered the legacy Return Stone at inventory {gridPos.x},{gridPos.y}, " + "but Valheim did not accept its saved equipped state. The item remains in its hotbar slot."); } Plugin.LogWarning("Recovered a legacy Return Stone from Epic Loot's EL_DummyPrefab at " + $"inventory {gridPos.x},{gridPos.y} (stack={stack}, equipped={equipped}, reequipped={flag2})."); } internal static void PrepareForScene(ZNetScene scene) { if (!((Object)(object)scene == (Object)null)) { CraftingStation val = FindWorkbenchInScene(scene); if ((Object)(object)val != (Object)null) { _sceneWorkbench = val; } EnsurePrefab(FindByName(scene.m_prefabs, "Club"), FindByName(scene.m_prefabs, "Stone"), FindByName(scene.m_prefabs, "SurtlingCore")); if ((Object)(object)ItemPrefab != (Object)null && !scene.m_prefabs.Any((GameObject prefab) => (Object)(object)prefab != (Object)null && ((Object)prefab).name == "ReturnStone")) { scene.m_prefabs.Add(ItemPrefab); } } } internal static void RegisterInObjectDb(ObjectDB objectDb, bool rebuildRegisters) { if ((Object)(object)objectDb == (Object)null) { return; } EnsurePrefab(FindByName(objectDb.m_items, "Club"), FindByName(objectDb.m_items, "Stone"), FindByName(objectDb.m_items, "SurtlingCore")); if (!((Object)(object)ItemPrefab == (Object)null)) { EnsureRuntimeSceneRegistration(); if (!objectDb.m_items.Any((GameObject prefab) => (Object)(object)prefab != (Object)null && ((Object)prefab).name == "ReturnStone")) { objectDb.m_items.Add(ItemPrefab); } EnsureRecipe(objectDb); if ((Object)(object)Recipe != (Object)null && !objectDb.m_recipes.Any((Recipe recipe) => (Object)(object)recipe != (Object)null && ((Object)recipe).name == "Recipe_ReturnStone")) { objectDb.m_recipes.Add(Recipe); } if (rebuildRegisters) { UpdateRegistersMethod?.Invoke(objectDb, null); } } } private static void EnsurePrefab(GameObject source, GameObject stoneSource, GameObject coreSource) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ItemPrefab != (Object)null) && !((Object)(object)source == (Object)null)) { EnsurePrefabContainer(); GameObject val = Object.Instantiate<GameObject>(source, _prefabContainer.transform, false); ((Object)val).name = "ReturnStone"; val.SetActive(true); ConfigureItemData(val); Transform obj = val.transform.Find("attach") ?? CreateAttachment(val.transform, "attach"); ClearAttachment(obj); ((Component)obj).gameObject.SetActive(true); obj.localPosition = Vector3.zero; obj.localRotation = Quaternion.identity; obj.localScale = Vector3.one; ReturnStoneRuntimeMaterials.Initialize(stoneSource, coreSource); InstallVisual(obj, "ReturnStone_Model", new Vector3(0.018f, -0.008f, 0.07f), Quaternion.Euler(8f, 15f, 92f), Vector3.one * 0.76f); BoxCollider val2 = val.GetComponent<BoxCollider>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<BoxCollider>(); } ((Component)val2).gameObject.SetActive(true); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; val2.center = new Vector3(0.018f, -0.008f, 0.07f); val2.size = new Vector3(0.25f, 0.33f, 0.16f); ItemPrefab = val; ValidatePrefabStructure(val); Plugin.LogInfo("Created active-self Return Stone prefab under an inactive container, with one vanilla-style attach visual."); } } private static void ConfigureItemData(GameObject prefab) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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_017b: Expected O, but got Unknown ItemDrop component = prefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("The vanilla Club prefab has no ItemDrop component."); } ItemData itemData = component.m_itemData; SharedData shared = itemData.m_shared; itemData.m_dropPrefab = prefab; itemData.m_stack = 1; itemData.m_quality = 1; itemData.m_variant = 0; itemData.m_durability = 100f; RemoveIdentity(itemData); shared.m_name = "$returnstone_name"; shared.m_description = "$returnstone_description"; shared.m_itemType = (ItemType)3; shared.m_attachOverride = (ItemType)3; shared.m_animationState = (AnimationState)1; shared.m_icons = (Sprite[])(object)new Sprite[1] { ReturnStoneAssets.Icon }; shared.m_maxStackSize = 50; shared.m_autoStack = true; shared.m_maxQuality = 1; shared.m_weight = 0.5f; shared.m_scaleWeightByQuality = 0f; shared.m_value = 0; shared.m_teleportable = true; shared.m_questItem = false; shared.m_equipDuration = 0.35f; shared.m_variants = 1; shared.m_centerCamera = false; shared.m_useDurability = false; shared.m_destroyBroken = false; shared.m_canBeReparied = false; shared.m_damages = default(DamageTypes); shared.m_damagesPerLevel = default(DamageTypes); shared.m_attackForce = 0f; shared.m_backstabBonus = 1f; shared.m_blockPower = 0f; shared.m_blockPowerPerLevel = 0f; shared.m_deflectionForce = 0f; shared.m_deflectionForcePerLevel = 0f; shared.m_timedBlockBonus = 1f; shared.m_ammoType = string.Empty; shared.m_secondaryAttack = new Attack(); if (shared.m_attack == null || string.IsNullOrEmpty(shared.m_attack.m_attackAnimation)) { throw new InvalidOperationException("The cloned vanilla Club has no usable primary attack definition."); } } private static void InstallVisual(Transform parent, string name, Vector3 position, Quaternion rotation, Vector3 scale) { //IL_0024: 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_003c: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(ReturnStoneAssets.ModelPrefab); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.transform.localPosition = position; obj.transform.localRotation = rotation; obj.transform.localScale = scale; obj.SetActive(true); ReturnStoneRuntimeMaterials.ApplyModel(obj); } private static Transform CreateAttachment(Transform parent, string name) { //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_0013: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.SetActive(true); return val.transform; } private static void ClearAttachment(Transform attach) { for (int num = attach.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)attach.GetChild(num)).gameObject); } } private static void EnsurePrefabContainer() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (!((Object)(object)_prefabContainer != (Object)null)) { _prefabContainer = new GameObject("ReturnStone_RuntimePrefabs"); Object.DontDestroyOnLoad((Object)(object)_prefabContainer); _prefabContainer.SetActive(false); } } private static void ValidatePrefabStructure(GameObject prefab) { ItemDrop component = prefab.GetComponent<ItemDrop>(); Rigidbody component2 = prefab.GetComponent<Rigidbody>(); Transform val = prefab.transform.Find("attach"); Renderer[] array = ((val != null) ? ((Component)val).GetComponentsInChildren<Renderer>(true) : null); BoxCollider componentInChildren = prefab.GetComponentInChildren<BoxCollider>(true); if (!prefab.activeSelf || (Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)val == (Object)null || !((Component)val).gameObject.activeSelf || array == null || array.Length == 0 || (Object)(object)componentInChildren == (Object)null) { throw new InvalidOperationException("Return Stone prefab failed vanilla item structure validation " + $"(activeSelf={prefab.activeSelf}, ItemDrop={(Object)(object)component != (Object)null}, Rigidbody={(Object)(object)component2 != (Object)null}, " + $"attach={(Object)(object)val != (Object)null}, renderers={((array != null) ? array.Length : 0)}, collider={(Object)(object)componentInChildren != (Object)null})."); } } private static void EnsureRecipe(ObjectDB objectDb) { ItemDrop component = ItemPrefab.GetComponent<ItemDrop>(); ItemDrop val = FindItem(objectDb, "Stone"); ItemDrop val2 = FindItem(objectDb, "Ruby"); ItemDrop val3 = FindItem(objectDb, "SurtlingCore"); ItemDrop val4 = FindItem(objectDb, "GreydwarfEye"); CraftingStation val5 = FindWorkbenchInRecipes(objectDb); if ((Object)(object)val5 == (Object)null) { val5 = _sceneWorkbench; } if ((Object)(object)val5 == (Object)null) { val5 = FindWorkbenchInScene(ZNetScene.instance); } if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null) { List<string> list = new List<string>(); if ((Object)(object)val == (Object)null) { list.Add("Stone"); } if ((Object)(object)val2 == (Object)null) { list.Add("Ruby"); } if ((Object)(object)val3 == (Object)null) { list.Add("SurtlingCore"); } if ((Object)(object)val4 == (Object)null) { list.Add("GreydwarfEye"); } if ((Object)(object)val5 == (Object)null) { list.Add("piece_workbench"); } Plugin.LogError("Return Stone recipe registration failed. Missing: " + string.Join(", ", list) + ". " + $"ObjectDB items={objectDb.m_items?.Count ?? 0}, recipes={objectDb.m_recipes?.Count ?? 0}, " + "ZNetScene=" + (((Object)(object)ZNetScene.instance != (Object)null) ? "ready" : "not ready") + "."); } else { if ((Object)(object)Recipe == (Object)null) { Recipe = ScriptableObject.CreateInstance<Recipe>(); ((Object)Recipe).name = "Recipe_ReturnStone"; Object.DontDestroyOnLoad((Object)(object)Recipe); } Recipe.m_item = component; Recipe.m_amount = 1; Recipe.m_enabled = true; Recipe.m_listSortWeight = 65; Recipe.m_craftingStation = val5; Recipe.m_repairStation = null; Recipe.m_minStationLevel = 1; Recipe.m_requireOnlyOneIngredient = false; Recipe.m_resources = (Requirement[])(object)new Requirement[4] { Requirement(val, 5), Requirement(val2, 1), Requirement(val3, 1), Requirement(val4, 1) }; if (!_recipeRegisteredLogWritten) { _recipeRegisteredLogWritten = true; Plugin.LogInfo("Registered Recipe_ReturnStone at " + ((Object)((Component)val5).gameObject).name + " from ObjectDB " + $"with {objectDb.m_items.Count} items and {objectDb.m_recipes.Count} recipes."); } } } private static CraftingStation FindWorkbenchInRecipes(ObjectDB objectDb) { if (objectDb?.m_recipes == null) { return null; } foreach (Recipe recipe in objectDb.m_recipes) { CraftingStation val = recipe?.m_craftingStation; if (IsWorkbench(val)) { return val; } } return null; } private static CraftingStation FindWorkbenchInScene(ZNetScene scene) { if ((Object)(object)scene == (Object)null) { return null; } GameObject obj = FindByName(scene.m_prefabs, "piece_workbench") ?? FindByName(scene.m_nonNetViewPrefabs, "piece_workbench") ?? scene.GetPrefab("piece_workbench"); CraftingStation val = ((obj != null) ? obj.GetComponent<CraftingStation>() : null); if (!IsWorkbench(val)) { return null; } return val; } private static bool IsWorkbench(CraftingStation station) { if ((Object)(object)station != (Object)null) { if (!string.Equals(((Object)((Component)station).gameObject).name, "piece_workbench", StringComparison.Ordinal)) { return string.Equals(station.m_name, "$piece_workbench", StringComparison.Ordinal); } return true; } return false; } private static Requirement Requirement(ItemDrop item, int amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new Requirement { m_resItem = item, m_amount = amount, m_amountPerLevel = 0, m_recover = false }; } private static ItemDrop FindItem(ObjectDB objectDb, string name) { GameObject obj = FindByName(objectDb.m_items, name); if (obj == null) { return null; } return obj.GetComponent<ItemDrop>(); } private static GameObject FindByName(IEnumerable<GameObject> prefabs, string name) { return prefabs?.FirstOrDefault((Func<GameObject, bool>)((GameObject prefab) => (Object)(object)prefab != (Object)null && ((Object)prefab).name == name)); } private static bool IsLegacyDummy(ItemData item) { if (item != null) { GameObject dropPrefab = item.m_dropPrefab; if (string.Equals((dropPrefab != null) ? ((Object)dropPrefab).name : null, "EL_DummyPrefab", StringComparison.Ordinal) && string.IsNullOrEmpty(item.m_shared?.m_name)) { if (item.m_shared?.m_icons != null) { return item.m_shared.m_icons.Length == 0; } return true; } } return false; } private static void RepairLegacyDummy(ItemData item) { ItemDrop component = ItemPrefab.GetComponent<ItemDrop>(); item.m_dropPrefab = ItemPrefab; item.m_shared = component.m_itemData.m_shared; item.m_variant = 0; item.m_quality = 1; item.m_stack = Mathf.Clamp(item.m_stack, 1, item.m_shared.m_maxStackSize); item.m_durability = item.GetMaxDurability(); RemoveIdentity(item); } private static bool HasIdentity(ItemData item) { if (item?.m_customData != null && item.m_customData.TryGetValue("dragonmotion.returnstone.identity", out var value)) { return string.Equals(value, "1", StringComparison.Ordinal); } return false; } private static void RemoveIdentity(ItemData item) { item?.m_customData?.Remove("dragonmotion.returnstone.identity"); } private static void ConsolidatePlainStoneStacks(Inventory inventory) { List<ItemData> list = (from item in inventory.GetAllItems().Where(IsPlainStackableStone) orderby item.m_equipped descending, item.m_gridPos.y, item.m_gridPos.x select item).ToList(); bool flag = false; for (int num = 0; num < list.Count; num++) { ItemData val = list[num]; if (val.m_stack <= 0 || val.m_stack >= val.m_shared.m_maxStackSize) { continue; } for (int num2 = num + 1; num2 < list.Count; num2++) { ItemData val2 = list[num2]; if (val2.m_stack <= 0 || val2.m_equipped || !CanShareStoneStack(val, val2)) { continue; } int num3 = Mathf.Min(val.m_shared.m_maxStackSize - val.m_stack, val2.m_stack); if (num3 > 0) { val.m_stack += num3; val2.m_stack -= num3; flag = true; if (val2.m_stack == 0) { inventory.GetAllItems().Remove(val2); } if (val.m_stack >= val.m_shared.m_maxStackSize) { break; } } } } if (flag) { InventoryChangedMethod?.Invoke(inventory, null); } } private static bool IsPlainStackableStone(ItemData item) { if (item?.m_shared != null) { GameObject dropPrefab = item.m_dropPrefab; if ((string.Equals((dropPrefab != null) ? ((Object)dropPrefab).name : null, "ReturnStone", StringComparison.Ordinal) || string.Equals(item.m_shared.m_name, "$returnstone_name", StringComparison.Ordinal)) && item.m_shared.m_maxStackSize > 1) { if (item.m_customData != null) { return item.m_customData.Count == 0; } return true; } } return false; } private static bool CanShareStoneStack(ItemData target, ItemData source) { if (IsPlainStackableStone(target) && IsPlainStackableStone(source) && target.m_shared.m_name == source.m_shared.m_name && target.m_quality == source.m_quality) { return target.m_worldLevel == source.m_worldLevel; } return false; } private static void EnsureRuntimeSceneRegistration() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || (Object)(object)ItemPrefab == (Object)null || NamedPrefabsField == null) { return; } int stableHashCode = StringExtensionMethods.GetStableHashCode("ReturnStone"); if (NamedPrefabsField.GetValue(instance) is Dictionary<int, GameObject> dictionary && !dictionary.ContainsKey(stableHashCode)) { if (!instance.m_prefabs.Contains(ItemPrefab)) { instance.m_prefabs.Add(ItemPrefab); } dictionary.Add(stableHashCode, ItemPrefab); } } } internal static class ReturnStoneRuntimeMaterials { private static Material _rock; private static Material _groove; private static Material _rune; internal static void Initialize(GameObject stoneSource, GameObject coreSource) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_rock != (Object)null)) { Material val = FirstMeshMaterial(stoneSource); Material val2 = FirstMeshMaterial(coreSource); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { throw new InvalidOperationException($"Vanilla material lookup failed (Stone={(Object)(object)val != (Object)null}, SurtlingCore={(Object)(object)val2 != (Object)null})."); } _rock = Clone(val, "ReturnStone_Rock_VanillaShader"); SetColor(_rock, new Color(0.23f, 0.28f, 0.2f, 1f)); ForceOpaque(_rock); _groove = Clone(val, "ReturnStone_Groove_VanillaShader"); SetColor(_groove, new Color(0.025f, 0.035f, 0.02f, 1f)); ForceOpaque(_groove); _rune = Clone(val2, "ReturnStone_Rune_VanillaShader"); ConfigureGlow(_rune, new Color(0.22f, 1f, 0.035f, 1f), 4.2f); ForceOpaque(_rune); ApplyModel(ReturnStoneAssets.ModelPrefab); string[] obj = new string[5] { "Rebound Return Stone model renderers to loaded vanilla shaders: rock=", null, null, null, null }; Shader shader = val.shader; obj[1] = ((shader != null) ? ((Object)shader).name : null); obj[2] = ", rune="; Shader shader2 = val2.shader; obj[3] = ((shader2 != null) ? ((Object)shader2).name : null); obj[4] = "."; Plugin.LogInfo(string.Concat(obj)); } } internal static void ApplyModel(GameObject model) { if ((Object)(object)model == (Object)null || (Object)(object)_rock == (Object)null) { return; } MeshRenderer[] componentsInChildren = model.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val in componentsInChildren) { string name = ((Object)((Component)val).gameObject).name; if (name.IndexOf("Rock", StringComparison.OrdinalIgnoreCase) >= 0) { ((Renderer)val).sharedMaterial = _rock; } else if (name.IndexOf("Groove", StringComparison.OrdinalIgnoreCase) >= 0) { ((Renderer)val).sharedMaterial = _groove; } else { ((Renderer)val).sharedMaterial = _rune; } } } private static Material FirstMeshMaterial(GameObject source) { if (source == null) { return null; } return source.GetComponentsInChildren<MeshRenderer>(true).SelectMany((MeshRenderer renderer) => ((Renderer)renderer).sharedMaterials).FirstOrDefault((Func<Material, bool>)((Material material) => (Object)(object)material != (Object)null)); } private static Material Clone(Material source, string name) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0014: Expected O, but got Unknown Material val = new Material(source) { name = name }; Object.DontDestroyOnLoad((Object)val); return val; } private static void ConfigureGlow(Material material, Color color, float emission) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_MainTex")) { material.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture); } if (material.HasProperty("_BaseMap")) { material.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture); } if (material.HasProperty("_EmissionMap")) { material.SetTexture("_EmissionMap", (Texture)(object)Texture2D.whiteTexture); } if (material.HasProperty("_BumpMap")) { material.SetTexture("_BumpMap", (Texture)null); } SetColor(material, color); Color val = default(Color); ((Color)(ref val))..ctor(color.r * emission, color.g * emission, color.b * emission, color.a); if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", val); } if (material.HasProperty("_EmissionStrength")) { material.SetFloat("_EmissionStrength", emission); } if (material.HasProperty("_Intensity")) { material.SetFloat("_Intensity", emission); } material.EnableKeyword("_EMISSION"); } } private static void SetColor(Material material, Color color) { //IL_0013: 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_0045: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty("_Color")) { material.SetColor("_Color", color); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", color); } if (material.HasProperty("_TintColor")) { material.SetColor("_TintColor", color); } } private static void ForceOpaque(Material material) { if (!((Object)(object)material == (Object)null)) { material.SetOverrideTag("RenderType", "Opaque"); if (material.HasProperty("_Mode")) { material.SetFloat("_Mode", 0f); } if (material.HasProperty("_Surface")) { material.SetFloat("_Surface", 0f); } if (material.HasProperty("_AlphaClip")) { material.SetFloat("_AlphaClip", 0f); } if (material.HasProperty("_ZWrite")) { material.SetFloat("_ZWrite", 1f); } if (material.HasProperty("_SrcBlend")) { material.SetFloat("_SrcBlend", 1f); } if (material.HasProperty("_DstBlend")) { material.SetFloat("_DstBlend", 0f); } material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; } } } internal static class ReturnStoneVanillaEffect { internal const string PrefabName = "vfx_Potion_health_medium"; internal const string TrailsName = "trails"; internal const string FlakesName = "flakes"; internal const string FlareName = "flare"; internal const string CloudName = "soft cloud"; internal const string LightName = "Point light"; internal const float CharacterHeight = 0.45f; internal const float StonePulseSize = 0.7f; internal const float StoneLightRange = 0.65f; internal const float StoneLightIntensity = 2.4f; internal const float StonePulseEmission = 2f; private static readonly FieldInfo LightFlickerBaseIntensityField = AccessTools.Field(typeof(LightFlicker), "m_baseIntensity"); private static readonly string[] ExpectedChildren = new string[5] { "trails", "flakes", "flare", "soft cloud", "Point light" }; private static bool _missingPrefabLogged; private static bool _missingChildLogged; internal static void PlayCycle(Transform characterAnchor, Transform stoneAnchor, int cycleIndex) { ZNetScene instance = ZNetScene.instance; GameObject val = ((instance != null) ? instance.GetPrefab("vfx_Potion_health_medium") : null); if ((Object)(object)val == (Object)null) { if (!_missingPrefabLogged) { _missingPrefabLogged = true; Plugin.LogError("Vanilla ritual effect prefab is missing: vfx_Potion_health_medium."); } return; } CreateCharacterVortex(val, characterAnchor, cycleIndex, preserveVanillaRed: false); if (cycleIndex == 1) { CreateCharacterVortex(val, characterAnchor, cycleIndex, preserveVanillaRed: true); } CreateStonePulse(val, stoneAnchor, cycleIndex); } private static void CreateCharacterVortex(GameObject prefab, Transform characterAnchor, int cycleIndex, bool preserveVanillaRed) { //IL_0011: 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_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_0009: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) Vector3 position = (((Object)(object)characterAnchor != (Object)null) ? (characterAnchor.position + Vector3.up * 0.45f) : Vector3.zero); string arg = (preserveVanillaRed ? "Red" : string.Empty); GameObject val = InstantiateEffect(prefab, position, characterAnchor, string.Format("ReturnStone_{0}_CharacterVortex{1}Cycle{2}", "vfx_Potion_health_medium", arg, cycleIndex + 1)); SetChildActive(val, "trails", active: true); SetChildActive(val, "flakes", active: true); SetChildActive(val, "flare", active: false); SetChildActive(val, "soft cloud", active: false); SetChildActive(val, "Point light", active: false); if (!preserveVanillaRed) { RecolorActive(val, new Color(0.14f, 1f, 0.025f, 1f), 3.2f); } StartActiveParticles(val); Object.Destroy((Object)(object)val, 3.5f); } private static void CreateStonePulse(GameObject prefab, Transform stoneAnchor, int cycleIndex) { //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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) Vector3 position = FindStoneCenter(stoneAnchor); GameObject obj = InstantiateEffect(prefab, position, stoneAnchor, string.Format("ReturnStone_{0}_StonePulseCycle{1}", "vfx_Potion_health_medium", cycleIndex + 1)); SetChildActive(obj, "trails", active: false); SetChildActive(obj, "flakes", active: false); SetChildActive(obj, "soft cloud", active: false); SetChildActive(obj, "flare", active: true); SetChildActive(obj, "Point light", active: true); Transform obj2 = obj.transform.Find("flare"); ParticleSystem val = ((obj2 != null) ? ((Component)obj2).GetComponent<ParticleSystem>() : null); if ((Object)(object)val != (Object)null) { MainModule main = val.main; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.7f); } Transform val2 = obj.transform.Find("Point light"); Light val3 = ((val2 != null) ? ((Component)val2).GetComponent<Light>() : null); if ((Object)(object)val3 != (Object)null) { val3.range = 0.65f; val3.intensity = 2.4f; LightFlicker component = ((Component)val2).GetComponent<LightFlicker>(); if ((Object)(object)component != (Object)null) { if (LightFlickerBaseIntensityField != null) { LightFlickerBaseIntensityField.SetValue(component, 2.4f); } else { ((Behaviour)component).enabled = false; } } } RecolorActive(obj, new Color(0.1f, 0.96f, 0.025f, 0.65f), 2f); StartActiveParticles(obj); Object.Destroy((Object)(object)obj, 3.5f); } private static GameObject InstantiateEffect(GameObject prefab, Vector3 position, Transform parent, string name) { //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) bool forceDisableInit = ZNetView.m_forceDisableInit; ZNetView.m_forceDisableInit = true; GameObject val; try { val = Object.Instantiate<GameObject>(prefab, position, Quaternion.identity); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } ((Object)val).name = name; if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, true); } val.SetActive(true); DisableInheritedAudio(val); ValidateExpectedChildren(val); return val; } private static void SetChildActive(GameObject effect, string childName, bool active) { Transform val = effect.transform.Find(childName); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(active); } } private static void ValidateExpectedChildren(GameObject effect) { if (!_missingChildLogged) { string[] array = ExpectedChildren.Where((string name) => (Object)(object)effect.transform.Find(name) == (Object)null).ToArray(); if (array.Length != 0) { _missingChildLogged = true; Plugin.LogWarning("vfx_Potion_health_medium is missing expected child objects: " + string.Join(", ", array) + "."); } } } private static Vector3 FindStoneCenter(Transform stoneAnchor) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)stoneAnchor == (Object)null) { return Vector3.zero; } Renderer[] array = (from renderer in ((Component)stoneAnchor).GetComponentsInChildren<Renderer>(true) where ((Object)((Component)renderer).gameObject).name.IndexOf("Rock", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)((Component)renderer).gameObject).name.IndexOf("Rune", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)((Component)renderer).gameObject).name.IndexOf("Groove", StringComparison.OrdinalIgnoreCase) >= 0 select renderer).ToArray(); if (array.Length == 0) { return stoneAnchor.position; } Bounds bounds = array[0].bounds; for (int num = 1; num < array.Length; num++) { ((Bounds)(ref bounds)).Encapsulate(array[num].bounds); } return ((Bounds)(ref bounds)).center; } private static void DisableInheritedAudio(GameObject effect) { AudioSource[] componentsInChildren = effect.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource obj in componentsInChildren) { obj.Stop(); ((Behaviour)obj).enabled = false; } } private static void StartActiveParticles(GameObject effect) { ParticleSystem[] componentsInChildren = effect.GetComponentsInChildren<ParticleSystem>(false); foreach (ParticleSystem obj in componentsInChildren) { obj.Clear(true); obj.Play(true); } } private static void RecolorActive(GameObject effect, Color green, float emissionStrength) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) Gradient val = new Gradient(); val.SetKeys((GradientColorKey[])(object)new GradientColorKey[3] { new GradientColorKey(green, 0f), new GradientColorKey(new Color(0.42f, 1f, 0.08f), 0.45f), new GradientColorKey(new Color(0.05f, 0.48f, 0.01f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(Mathf.Clamp01(green.a), 0.18f), new GradientAlphaKey(0f, 1f) }); ParticleSystem[] componentsInChildren = effect.GetComponentsInChildren<ParticleSystem>(false); foreach (ParticleSystem obj in componentsInChildren) { MainModule main = obj.main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(green); ColorOverLifetimeModule colorOverLifetime = obj.colorOverLifetime; if (((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled) { ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val); } } ReturnStoneEffectCleanup returnStoneEffectCleanup = effect.AddComponent<ReturnStoneEffectCleanup>(); Renderer[] componentsInChildren2 = effect.GetComponentsInChildren<Renderer>(false); foreach (Renderer val2 in componentsInChildren2) { Material[] sharedMaterials = val2.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { Material val3 = sharedMaterials[j]; if (!((Object)(object)val3 == (Object)null)) { Material val4 = new Material(val3) { name = "ReturnStone_Green_" + ((Object)val3).name }; SetGreen(val4, green, emissionStrength); sharedMaterials[j] = val4; returnStoneEffectCleanup.Track(val4); } } val2.sharedMaterials = sharedMaterials; } Light[] componentsInChildren3 = effect.GetComponentsInChildren<Light>(false); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].color = new Color(0.14f, 1f, 0.025f, 1f); } } private static void SetGreen(Material material, Color green, float emissionStrength) { //IL_0013: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (material.HasProperty("_Color")) { material.SetColor("_Color", green); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", green); } if (material.HasProperty("_TintColor")) { material.SetColor("_TintColor", green); } if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", new Color(0.14f * emissionStrength, 1f * emissionStrength, 0.025f * emissionStrength, green.a)); } material.EnableKeyword("_EMISSION"); } } internal sealed class ReturnStoneEffectCleanup : MonoBehaviour { private readonly HashSet<Material> _materials = new HashSet<Material>(); internal void Track(Material material) { if ((Object)(object)material != (Object)null) { _materials.Add(material); } } private void OnDestroy() { foreach (Material material in _materials) { if ((Object)(object)material != (Object)null) { Object.Destroy((Object)(object)material); } } _materials.Clear(); } } internal sealed class ReturnStoneVisualController : MonoBehaviour { internal const float CheerReleaseLeadTime = 0.5f; private const float CheerRaisedPoseTime = 0.5f; private const float CheerRaisedMinimumHeight = 1.3f; private static readonly int EmoteTag = Animator.StringToHash("emote"); private static readonly MethodInfo StopEmoteMethod = AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null); private Player _owner; private long _startMilliseconds; private Animator _animator; private Transform _rightHandBone; private float _animatorSpeed; private AnimatorCullingMode _animatorCullingMode; private Transform _characterAnchor; private Transform _stoneAnchor; private AudioSource _cycleAudio; private int _cyclesPlayed; private int _cheerLayer = -1; private int _cheerStateHash; private float _cheerHoldNormalizedTime; private float _cheerFreezeDisplacement; private bool _cheerHeld; private bool _cheerReleased; private bool _stopped; private float _elapsed; internal int CyclesPlayed => _cyclesPlayed; internal bool CheerHeld => _cheerHeld; internal bool CheerReleased => _cheerReleased; internal float CheerHoldNormalizedTime => _cheerHoldNormalizedTime; internal static void Begin(Player player, long startMilliseconds) { if (!((Object)(object)player == (Object)null)) { ReturnStoneVisualController returnStoneVisualController = ((Component)player).GetComponent<ReturnStoneVisualController>(); if ((Object)(object)returnStoneVisualController == (Object)null) { returnStoneVisualController = ((Component)player).gameObject.AddComponent<ReturnStoneVisualController>(); } returnStoneVisualController.StartVisual(player, startMilliseconds); } } internal static void Cancel(Player player) { if (player != null) { ((Component)player).GetComponent<ReturnStoneVisualController>()?.StopVisual(); } } internal static void Complete(Player player) { if (player != null) { ((Component)player).GetComponent<ReturnStoneVisualController>()?.StopVisual(); } } private void StartVisual(Player player, long startMilliseconds) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner != (Object)null) { StopVisual(destroyComponent: false); } _owner = player; _startMilliseconds = startMilliseconds; _cyclesPlayed = 0; _cheerLayer = -1; _cheerStateHash = 0; _cheerHoldNormalizedTime = 0f; _cheerFreezeDisplacement = 0f; _cheerHeld = false; _cheerReleased = false; _stopped = false; _elapsed = 0f; Transform val = ((Component)player).transform.Find("Visual"); _animator = (((Object)(object)val != (Object)null) ? (((Component)val).GetComponent<Animator>() ?? ((Component)val).GetComponentInChildren<Animator>(true)) : null); if ((Object)(object)_animator != (Object)null) { _animatorSpeed = _animator.speed; _animatorCullingMode = _animator.cullingMode; _animator.cullingMode = (AnimatorCullingMode)0; if (_animator.isHuman) { _rightHandBone = _animator.GetBoneTransform((HumanBodyBones)18); } } VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); _characterAnchor = ((Component)player).transform; _stoneAnchor = (((Object)(object)component != (Object)null && (Object)(object)component.m_rightHand != (Object)null) ? component.m_rightHand : ((Component)player).transform); _cycleAudio = ReturnStoneAudio.AttachCycleSource(((Component)_stoneAnchor).gameObject); ZNetView component2 = ((Component)player).GetComponent<ZNetView>(); if (((Object)(object)player == (Object)(object)Player.m_localPlayer || (Object)(object)component2 == (Object)null || !component2.IsValid() || component2.IsOwner()) && !player.StartEmote("cheer", true)) { Plugin.LogWarning("Valheim refused to start the cheer emote for Return Stone."); } } private void Update() { if ((Object)(object)_owner == (Object)null || _stopped) { return; } _elapsed = Mathf.Max(0f, (float)(ReturnStoneNetwork.WorldMilliseconds() - _startMilliseconds) / 1000f); if (_elapsed > 9f) { Plugin.LogWarning($"Stopping stale Return Stone presentation: elapsed={_elapsed:F3}, " + $"start={_startMilliseconds}, now={ReturnStoneNetwork.WorldMilliseconds()}."); StopVisual(); return; } HoldCheerAtRaisedPose(); if (!_cheerReleased && _elapsed >= 6.5f) { ReleaseCheerForTeleport(); } while (_cyclesPlayed < 2 && _elapsed >= (float)_cyclesPlayed * 3.5f) { PlayCycle(_cyclesPlayed); _cyclesPlayed++; } } private void LateUpdate() { //IL_0044: 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) if (_cheerHeld && !_cheerReleased && !((Object)(object)_animator == (Object)null) && _cheerLayer >= 0) { _animator.speed = 0f; AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(_cheerLayer); float num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime - Mathf.Floor(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime); if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash != _cheerStateHash || !(Mathf.Abs(num - _cheerHoldNormalizedTime) <= 0.004f)) { _animator.Play(_cheerStateHash, _cheerLayer, _cheerHoldNormalizedTime); _animator.Update(0f); _animator.speed = 0f; } } } private void HoldCheerAtRaisedPose() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_animator == (Object)null || _cheerHeld || _cheerReleased) { return; } for (int i = 0; i < _animator.layerCount; i++) { AnimatorStateInfo currentAnimatorStateInfo = _animator.GetCurrentAnimatorStateInfo(i); if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).tagHash != EmoteTag) { continue; } float num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime - Mathf.Floor(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime); if (!(num < 0.5f)) { Transform val = (((Object)(object)_rightHandBone != (Object)null) ? _rightHandBone : _stoneAnchor); if (!((Object)(object)val == (Object)null) && !(((Component)_owner).transform.InverseTransformPoint(val.position).y < 1.3f)) { _cheerLayer = i; _cheerStateHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash; FreezeCheerAtCurrentPose(num, val); } } break; } } private void FreezeCheerAtCurrentPose(float normalizedTime, Transform trackedHand) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_animator == (Object)null) && _cheerLayer >= 0 && _cheerStateHash != 0) { Vector3 val = (((Object)(object)trackedHand != (Object)null) ? trackedHand.position : Vector3.zero); _cheerHoldNormalizedTime = Mathf.Clamp(normalizedTime, 0.05f, 0.9f); _animator.speed = 0f; _cheerFreezeDisplacement = (((Object)(object)trackedHand != (Object)null) ? Vector3.Distance(val, trackedHand.position) : 0f); _cheerHeld = true; } } private void ReleaseCheerForTeleport() { _cheerReleased = true; if (!((Object)(object)_animator == (Object)null)) { if (_cheerHeld && _cheerLayer >= 0 && _cheerStateHash != 0) { _animator.Play(_cheerStateHash, _cheerLayer, _cheerHoldNormalizedTime); _animator.Update(0f); } _animator.speed = _animatorSpeed; _cheerHeld = false; } } private void PlayCycle(int cycleIndex) { ReturnStoneAudio.PlayCycle(_cycleAudio); ReturnStoneVanillaEffect.PlayCycle(_characterAnchor, _stoneAnchor, cycleIndex); } private void StopVisual(bool destroyComponent = true) { if (!((Object)(object)_owner == (Object)null)) { _stopped = true; RestoreCheer(); ReturnStoneAudio.DestroyCycleSource(_cycleAudio); _cycleAudio = null; _characterAnchor = null; _stoneAnchor = null; _owner = null; if (destroyComponent) { Object.Destroy((Object)(object)this); } } } private void RestoreCheer() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_animator != (Object)null) { _animator.speed = _animatorSpeed; _animator.cullingMode = _animatorCullingMode; } if ((Object)(object)_owner != (Object)null) { ZNetView component = ((Component)_owner).GetComponent<ZNetView>(); if ((Object)(object)_owner == (Object)(object)Player.m_localPlayer || (Object)(object)component == (Object)null || !component.IsValid() || component.IsOwner()) { StopEmoteMethod?.Invoke(_owner, null); } } _animator = null; _rightHandBone = null; _cheerHeld = false; _cheerReleased = false; } private void OnDestroy() { if (!((Object)(object)_owner == (Object)null)) { StopVisual(destroyComponent: false); } } }