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 ForsakenPowerHotbar v1.0.1
BepInEx/plugins/ForsakenPowerHotbar/ForsakenPowerHotbar.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ForsakenPowerHotbar")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Modal Forsaken power selector with immediate passive power switching.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+4f2b89a3e9825574aabed9fa776dae94754a680a")] [assembly: AssemblyProduct("ForsakenPowerHotbar")] [assembly: AssemblyTitle("ForsakenPowerHotbar")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Naurium.ForsakenPowerHotbar { public static class ModalInput { private static readonly string[] AttackButtons = new string[6] { "Attack", "SecondaryAttack", "Block", "JoyAttack", "JoySecondaryAttack", "JoyBlock" }; private static readonly FieldInfo CurrentAttack = RequiredField(typeof(Humanoid), "m_currentAttack"); private static readonly FieldInfo PreviousAttack = RequiredField(typeof(Humanoid), "m_previousAttack"); private static readonly FieldInfo DrawTime = RequiredField(typeof(Humanoid), "m_attackDrawTime"); private static readonly FieldInfo PrimaryQueue = RequiredField(typeof(Player), "m_queuedAttackTimer"); private static readonly FieldInfo SecondaryQueue = RequiredField(typeof(Player), "m_queuedSecondAttackTimer"); private static readonly FieldInfo AutoRun = RequiredField(typeof(Player), "m_autoRun"); private static bool _waitForRelease; private static int _closedFrame = -10; private static CursorLockMode _savedLock; private static bool _savedVisible; private static bool _savedRequested; public static bool BlockGameplay { get { if (!SelectorWindow.IsOpen) { return Time.frameCount <= _closedFrame + 1; } return true; } } public static bool BlocksAttacks { get { if (!BlockGameplay) { return _waitForRelease; } return true; } } private static FieldInfo RequiredField(Type type, string name) { return AccessTools.Field(type, name) ?? throw new MissingFieldException(type.FullName, name); } public static void Validate() { _ = CurrentAttack; } public static void Open() { //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) _savedLock = ZCursor.LockState; _savedVisible = Cursor.visible; _savedRequested = ZCursor.IsRequested; _waitForRelease = true; CancelAttack(Player.m_localPlayer); ShowCursor(); } public static void Close() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) _closedFrame = Time.frameCount; _waitForRelease = true; CancelAttack(Player.m_localPlayer); ZCursor.LockState = _savedLock; if (_savedRequested) { ZCursor.Show(); } else { ZCursor.Hide(); } Cursor.visible = _savedVisible; } public static void ShowCursor() { ZCursor.LockState = (CursorLockMode)0; ZCursor.Show(); } public static void Update() { if (SelectorWindow.IsOpen) { ShowCursor(); } else { if (!_waitForRelease || Time.frameCount <= _closedFrame + 1) { return; } string[] attackButtons = AttackButtons; for (int i = 0; i < attackButtons.Length; i++) { if (ZInput.GetButton(attackButtons[i])) { return; } } _waitForRelease = false; } } public static void Reset() { _waitForRelease = false; _closedFrame = -10; } public static void CancelAttack(Player player) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { Attack val = (Attack)CurrentAttack.GetValue(player); if (val != null) { val.Abort(); val.Stop(); ((Component)player).GetComponent<ZSyncAnimation>().SetTrigger("attack_abort"); } CurrentAttack.SetValue(player, null); PreviousAttack.SetValue(player, null); PrimaryQueue.SetValue(player, 0f); SecondaryQueue.SetValue(player, 0f); DrawTime.SetValue(player, -1f); ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon != null && !string.IsNullOrEmpty(currentWeapon.m_shared.m_attack.m_drawAnimationState)) { ((Component)player).GetComponent<ZSyncAnimation>().SetBool(currentWeapon.m_shared.m_attack.m_drawAnimationState, false); } AutoRun.SetValue(player, false); player.SetControls(Vector3.zero, false, false, false, false, false, false, false, false, false, false, false); player.SetMouseLook(Vector2.zero); } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class ControllerInputPatch { private static void Postfix(PlayerController __instance, ref bool __result) { if (ModalInput.BlockGameplay && (Object)(object)((Component)__instance).GetComponent<Player>() == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class PlayerInputPatch { private static void Postfix(Player __instance, ref bool __result) { if (ModalInput.BlockGameplay && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { __result = false; } } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class PlayerControlsPatch { 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_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) if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { if (ModalInput.BlocksAttacks) { attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = false))))); } if (ModalInput.BlockGameplay) { movedir = Vector3.zero; jump = (crouch = (run = (autoRun = (dodge = false)))); } } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal static class StartAttackPatch { private static bool Prefix(Humanoid __instance, ref bool __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !ModalInput.BlocksAttacks) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ZInput), "IsMouseActive")] internal static class MouseActivePatch { private static void Postfix(ref bool __result) { if (SelectorWindow.IsOpen) { __result = true; } } } [HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")] internal static class CameraMouseCapturePatch { private static bool Prefix() { if (!SelectorWindow.IsOpen) { return true; } ModalInput.ShowCursor(); return false; } } [HarmonyPatch(typeof(Menu), "Update")] internal static class MenuInputPatch { private static bool Prefix() { return !ModalInput.BlockGameplay; } } public enum PowerMode { One, All, Vanilla } public sealed class ModSettings { public ConfigEntry<bool> Enabled { get; } public ConfigEntry<PowerMode> Mode { get; } public ConfigEntry<KeyboardShortcut> ToggleKey { get; } public ModSettings(ConfigFile config) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) Enabled = config.Bind<bool>("General", "ModEnabled", true, "Enable the selector and power mode."); Mode = config.Bind<PowerMode>("General", "PowerAmount", PowerMode.One, "One: selected power is passive. All: unlocked powers are passive. Vanilla: normal power activation."); ToggleKey = config.Bind<KeyboardShortcut>("Selector", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Open the modal power selector. Use Close or X to dismiss it."); } } public static class PassivePowerService { private sealed class OwnedEffect { public StatusEffect Instance { get; } public float OriginalTtl { get; } public OwnedEffect(StatusEffect instance, float originalTtl) { Instance = instance; OriginalTtl = originalTtl; } } private static readonly ConditionalWeakTable<Player, Dictionary<int, OwnedEffect>> OwnedEffects = new ConditionalWeakTable<Player, Dictionary<int, OwnedEffect>>(); public static bool IsUnlocked(Player player, PowerDefinition power) { return VanillaPowerAvailability.IsAvailable(player, power); } public static bool Select(Player player, string powerId) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || Plugin.Settings == null || !Plugin.Settings.Enabled.Value) { return false; } PowerDefinition powerDefinition = PowerCatalog.Find(powerId); if (powerDefinition == null) { Plugin.Log.LogWarning((object)("Rejected unknown guardian power selection: " + (powerId ?? "<null>"))); return false; } if (!IsUnlocked(player, powerDefinition)) { Plugin.Log.LogWarning((object)("Rejected locked guardian power selection: " + powerDefinition.Id)); return false; } RequireTemplate(powerDefinition); float guardianPowerCooldown = player.m_guardianPowerCooldown; try { player.SetGuardianPower(powerDefinition.Id); } finally { player.m_guardianPowerCooldown = guardianPowerCooldown; } return true; } public static void Reconcile(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || Plugin.Settings == null) { return; } if (!Plugin.Settings.Enabled.Value || Plugin.Settings.Mode.Value == PowerMode.Vanilla) { Restore(player); return; } List<PowerDefinition> desiredPowers = GetDesiredPowers(player, Plugin.Settings.Mode.Value); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (PowerDefinition item in desiredPowers) { hashSet.Add(item.Id); } SEMan sEMan = ((Character)player).GetSEMan(); Dictionary<int, OwnedEffect> ownedEffects = GetOwnedEffects(player); StatusEffect[] array = sEMan.GetStatusEffects().ToArray(); foreach (StatusEffect val in array) { if (IsCatalogPower(val)) { int num = val.NameHash(); OwnedEffect value; if (!hashSet.Contains(((Object)val).name)) { sEMan.RemoveStatusEffect(num, true); ownedEffects.Remove(num); } else if (ownedEffects.TryGetValue(num, out value) && value.Instance == val) { val.m_ttl = 0f; } else { sEMan.RemoveStatusEffect(num, true); ownedEffects.Remove(num); } } } foreach (PowerDefinition item2 in desiredPowers) { StatusEffect val2 = RequireTemplate(item2); int num2 = val2.NameHash(); StatusEffect statusEffect = sEMan.GetStatusEffect(num2); OwnedEffect value2; if ((Object)(object)statusEffect == (Object)null) { sEMan.AddStatusEffect(val2, false, 0, 0f, (short)(-1)); statusEffect = sEMan.GetStatusEffect(num2); if ((Object)(object)statusEffect == (Object)null) { throw new InvalidOperationException("Valheim rejected guardian power status effect '" + item2.Id + "'."); } ownedEffects[num2] = new OwnedEffect(statusEffect, statusEffect.m_ttl); } else if (!ownedEffects.TryGetValue(num2, out value2) || value2.Instance != statusEffect) { throw new InvalidOperationException("Guardian power status effect '" + item2.Id + "' was not created by this plugin."); } statusEffect.m_ttl = 0f; } } public static void Restore(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !OwnedEffects.TryGetValue(player, out var value)) { return; } SEMan sEMan = ((Character)player).GetSEMan(); foreach (KeyValuePair<int, OwnedEffect> item in value) { StatusEffect statusEffect = sEMan.GetStatusEffect(item.Key); if (statusEffect == item.Value.Instance) { statusEffect.m_ttl = item.Value.OriginalTtl; sEMan.RemoveStatusEffect(statusEffect, true); } } value.Clear(); OwnedEffects.Remove(player); } public static float GetCooldown(Player player) { if (!((Object)(object)player == (Object)null)) { return player.m_guardianPowerCooldown; } return 0f; } private static List<PowerDefinition> GetDesiredPowers(Player player, PowerMode mode) { List<PowerDefinition> list = new List<PowerDefinition>(); switch (mode) { case PowerMode.One: { PowerDefinition powerDefinition = PowerCatalog.Find(player.GetGuardianPowerName()); if (powerDefinition != null && IsUnlocked(player, powerDefinition)) { list.Add(powerDefinition); } break; } case PowerMode.All: foreach (PowerDefinition item in PowerCatalog.All) { if (IsUnlocked(player, item)) { list.Add(item); } } break; default: throw new ArgumentOutOfRangeException("mode", mode, "Unknown power mode."); case PowerMode.Vanilla: break; } return list; } private static Dictionary<int, OwnedEffect> GetOwnedEffects(Player player) { if (OwnedEffects.TryGetValue(player, out var value)) { return value; } value = new Dictionary<int, OwnedEffect>(); OwnedEffects.Add(player, value); return value; } private static StatusEffect RequireTemplate(PowerDefinition power) { if ((Object)(object)ObjectDB.instance == (Object)null) { throw new InvalidOperationException("ObjectDB is unavailable while reconciling guardian powers."); } foreach (StatusEffect statusEffect in ObjectDB.instance.m_StatusEffects) { if ((Object)(object)statusEffect != (Object)null && string.Equals(((Object)statusEffect).name, power.Id, StringComparison.Ordinal)) { return statusEffect; } } throw new InvalidOperationException("Valheim status effect '" + power.Id + "' is missing from ObjectDB."); } private static bool IsCatalogPower(StatusEffect effect) { if ((Object)(object)effect != (Object)null) { return PowerCatalog.Find(((Object)effect).name) != null; } return false; } } [BepInPlugin("naurium.forsakenpowerhotbar", "Forsaken Power Hotbar", "1.0.1")] [BepInIncompatibility("com.custom.valheim.forsakenpowerselector")] [BepInIncompatibility("digitalroot.mods.passiveforsakenpowers.jvl")] [BepInIncompatibility("radthordax.valheim.PassiveForsakenPowers")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "naurium.forsakenpowerhotbar"; public const string Version = "1.0.1"; private Harmony _harmony; private float _nextReconcile; private bool _reconcileFailed; public static Plugin Instance { get; private set; } public static ModSettings Settings { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Settings = new ModSettings(((BaseUnityPlugin)this).Config); ModalInput.Validate(); _harmony = new Harmony("naurium.forsakenpowerhotbar"); _harmony.PatchAll(typeof(Plugin).Assembly); Settings.Enabled.SettingChanged += SettingsChanged; Settings.Mode.SettingChanged += SettingsChanged; Log.LogInfo((object)"Forsaken Power Hotbar 1.0.1 loaded. F8 opens the modal selector."); } private void Update() { //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) ModalInput.Update(); Player localPlayer = Player.m_localPlayer; if (!Settings.Enabled.Value || (Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { SelectorWindow.Close(); return; } KeyboardShortcut value = Settings.ToggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && !SelectorWindow.IsOpen && CanOpen()) { SelectorWindow.Open(); } if (Time.unscaledTime < _nextReconcile || (Object)(object)ObjectDB.instance == (Object)null) { return; } _nextReconcile = Time.unscaledTime + 0.5f; try { PassivePowerService.Reconcile(localPlayer); _reconcileFailed = false; } catch (Exception ex) { if (!_reconcileFailed) { Log.LogError((object)("Passive reconciliation failed: " + ex)); } _reconcileFailed = true; } } private static bool CanOpen() { if (!Menu.IsVisible() && !Console.IsVisible() && !InventoryGui.IsVisible() && !StoreGui.IsVisible() && !TextInput.IsVisible() && !Minimap.IsOpen()) { if (!((Object)(object)Chat.instance == (Object)null)) { return !Chat.instance.HasFocus(); } return true; } return false; } private void LateUpdate() { if (SelectorWindow.IsOpen) { ModalInput.ShowCursor(); } } private void OnGUI() { SelectorWindow.Draw(); } private void SettingsChanged(object sender, EventArgs args) { SelectorWindow.Close(); if (!((Object)(object)Player.m_localPlayer == (Object)null)) { if (Settings.Enabled.Value) { PassivePowerService.Reconcile(Player.m_localPlayer); } else { PassivePowerService.Restore(Player.m_localPlayer); } } } private void OnDestroy() { SelectorWindow.Close(); ModalInput.Reset(); if ((Object)(object)Player.m_localPlayer != (Object)null) { PassivePowerService.Restore(Player.m_localPlayer); } if (Settings != null) { Settings.Enabled.SettingChanged -= SettingsChanged; Settings.Mode.SettingChanged -= SettingsChanged; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } Instance = null; } } public sealed class PowerDefinition { public string Id { get; } public string Name { get; } public string ShortDescription { get; } public string Description => PowerText.Description(PowerText.Template(Id)); public string DefeatedKey { get; } public string Trophy { get; } public PowerDefinition(string id, string name, string shortDescription, string defeatedKey, string trophy) { Id = id; Name = name; ShortDescription = shortDescription; DefeatedKey = defeatedKey; Trophy = trophy; } } public static class PowerCatalog { private static readonly IReadOnlyList<PowerDefinition> Powers = Array.AsReadOnly(new PowerDefinition[7] { new PowerDefinition("GP_Eikthyr", "Eikthyr", "Less run, jump and swim stamina.", "defeated_eikthyr", "TrophyEikthyr"), new PowerDefinition("GP_TheElder", "The Elder", "Faster chopping, mining and health regen.", "defeated_gdking", "TrophyTheElder"), new PowerDefinition("GP_Bonemass", "Bonemass", "Physical resistance and improved blocking.", "defeated_bonemass", "TrophyBonemass"), new PowerDefinition("GP_Moder", "Moder", "Tailwind, carry, speed and frost resistance.", "defeated_dragon", "TrophyDragonQueen"), new PowerDefinition("GP_Yagluth", "Yagluth", "Lightning resistance, farming and damage.", "defeated_goblinking", "TrophyGoblinKing"), new PowerDefinition("GP_Queen", "The Queen", "Eitr regen, free sneaking and poison resistance.", "defeated_queen", "TrophySeekerQueen"), new PowerDefinition("GP_Fader", "Fader", "Adrenaline gain, stagger and fire resistance.", "defeated_fader", "TrophyFader") }); public static IReadOnlyList<PowerDefinition> All => Powers; internal static PowerDefinition Find(string id) { if (string.IsNullOrEmpty(id)) { return null; } for (int i = 0; i < Powers.Count; i++) { if (string.Equals(Powers[i].Id, id, StringComparison.Ordinal)) { return Powers[i]; } } return null; } } [HarmonyPatch(typeof(Player), "SetGuardianPower")] internal static class SetGuardianPowerPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { PassivePowerService.Reconcile(__instance); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] internal static class PlayerSpawnedPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { PassivePowerService.Reconcile(__instance); } } } [HarmonyPatch(typeof(Player), "StartGuardianPower")] internal static class StartGuardianPowerPatch { [HarmonyPrefix] private static bool Prefix(Player __instance, ref bool __result) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (ModalInput.BlockGameplay) { __result = false; return false; } ModSettings settings = Plugin.Settings; if (settings == null || !settings.Enabled.Value || settings.Mode.Value == PowerMode.Vanilla) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Player), "GetGuardianPowerHUD")] internal static class GuardianPowerHudPatch { [HarmonyPrefix] private static bool Prefix(Player __instance, ref StatusEffect se, ref float cooldown) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } ModSettings settings = Plugin.Settings; if (settings == null || !settings.Enabled.Value || settings.Mode.Value == PowerMode.Vanilla) { return true; } se = null; cooldown = 0f; return false; } } internal static class PowerText { private static readonly Regex RichText = new Regex("<[^>]+>", RegexOptions.Compiled); private static readonly HashSet<string> MissingTemplates = new HashSet<string>(StringComparer.Ordinal); internal static StatusEffect Template(string id) { StatusEffect obj = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(id))); if ((Object)(object)obj == (Object)null && MissingTemplates.Add(id)) { Plugin.Log.LogError((object)("Cannot display missing guardian power effect '" + id + "'.")); } return obj; } internal static string Description(StatusEffect effect) { if ((Object)(object)effect == (Object)null) { return "Effect details unavailable."; } List<string> list = new List<string>(); string[] array = effect.GetTooltipString().Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && !text.StartsWith("$se_ttl:", StringComparison.Ordinal)) { list.Add(RichText.Replace(Localization.instance.Localize(text), string.Empty)); } } return string.Join(" · ", list); } internal static string SelectedDetails(Player player) { PowerDefinition powerDefinition = (((Object)(object)player == (Object)null) ? null : PowerCatalog.Find(player.GetGuardianPowerName())); if (powerDefinition == null) { return "Select a power to see its full effects."; } StatusEffect statusEffect = ((Character)player).GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode(powerDefinition.Id)); return Description(((Object)(object)statusEffect == (Object)null) ? Template(powerDefinition.Id) : statusEffect); } } internal sealed class SelectorStyles { public readonly GUIStyle Window; public readonly GUIStyle Title; public readonly GUIStyle Label; public readonly GUIStyle Small; public readonly GUIStyle Detail; public readonly GUIStyle Name; public readonly GUIStyle Button; public readonly GUIStyle Row; public readonly GUIStyle Badge; public SelectorStyles() { //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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_002a: Expected O, but got Unknown //IL_0049: 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 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0176: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021e: 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_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Expected O, but got Unknown //IL_025e: 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) Window = new GUIStyle(GUI.skin.window) { padding = new RectOffset(0, 0, 0, 0) }; Window.normal.background = Texture(new Color(0.075f, 0.086f, 0.1f, 1f)); Window.onNormal.background = Window.normal.background; Window.border = new RectOffset(0, 0, 0, 0); Title = Text(22, new Color(0.96f, 0.88f, 0.66f), (FontStyle)1); Label = Text(15, Color.white, (FontStyle)0); Small = Text(12, new Color(0.67f, 0.72f, 0.76f), (FontStyle)0); Detail = new GUIStyle(Small) { wordWrap = true, alignment = (TextAnchor)0 }; Name = Text(16, Color.white, (FontStyle)1); Badge = Text(11, new Color(0.9f, 0.76f, 0.43f), (FontStyle)1); Badge.alignment = (TextAnchor)5; Button = new GUIStyle(GUI.skin.button) { fontSize = 14, alignment = (TextAnchor)4, border = new RectOffset(0, 0, 0, 0) }; Button.normal.background = Texture(new Color(0.2f, 0.23f, 0.27f)); Button.hover.background = Texture(new Color(0.29f, 0.33f, 0.37f)); Button.active.background = Texture(new Color(0.34f, 0.29f, 0.18f)); Button.normal.textColor = (Button.hover.textColor = (Button.active.textColor = Color.white)); Row = new GUIStyle(Button) { alignment = (TextAnchor)3 }; Row.normal.background = Texture(new Color(0.115f, 0.13f, 0.15f)); Row.hover.background = Texture(new Color(0.19f, 0.21f, 0.24f)); } private static GUIStyle Text(int size, Color color, FontStyle weight = (FontStyle)0) { //IL_000a: 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_0016: 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_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = size, fontStyle = weight, alignment = (TextAnchor)3, padding = new RectOffset(0, 0, 0, 0), wordWrap = false }; val.normal.textColor = color; return val; } private static Texture2D Texture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1) { hideFlags = (HideFlags)61 }; val.SetPixel(0, 0, color); val.Apply(); return val; } } public static class SelectorWindow { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawContent; } private const int WindowId = 17493423; private static Rect _window; private static Vector2 _scroll; private static Vector2 _activeScroll; private static SelectorStyles _styles; private static bool _placed; private static string _error; public static bool IsOpen { get; private set; } public static void Open() { //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) if (!IsOpen && Plugin.Settings != null && Plugin.Settings.Enabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Character)Player.m_localPlayer).IsDead()) { VanillaPowerAvailability.Refresh(force: true); IsOpen = true; _error = null; _activeScroll = Vector2.zero; ModalInput.Open(); } } public static void Close() { if (IsOpen) { IsOpen = false; ModalInput.Close(); } } public static void Draw() { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0177: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Invalid comparison between Unknown and I4 //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Invalid comparison between Unknown and I4 if (!IsOpen || (Object)(object)Player.m_localPlayer == (Object)null) { return; } if (_styles == null) { _styles = new SelectorStyles(); } Matrix4x4 matrix = GUI.matrix; Color color = GUI.color; int depth = GUI.depth; float num = Mathf.Clamp(Mathf.Min((float)Screen.width / 960f, (float)Screen.height / 720f), 0.65f, 1.35f); float num2 = (float)Screen.width / num; float num3 = (float)Screen.height / num; GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f)); GUI.depth = -1000; Fill(new Rect(0f, 0f, num2, num3), new Color(0f, 0f, 0f, 0.55f)); if (!_placed) { _window = new Rect((num2 - 460f) / 2f, (num3 - 660f) / 2f, 460f, 660f); _placed = true; } ((Rect)(ref _window)).width = Mathf.Min(460f, num2 - 24f); ((Rect)(ref _window)).height = Mathf.Min(660f, num3 - 24f); ClampWindow(num2, num3); try { Rect window = _window; object obj = <>O.<0>__DrawContent; if (obj == null) { WindowFunction val = DrawContent; <>O.<0>__DrawContent = val; obj = (object)val; } _window = GUI.Window(17493423, window, (WindowFunction)obj, GUIContent.none, _styles.Window); Event current = Event.current; if ((int)current.type == 0 || (int)current.type == 1 || (int)current.type == 6) { current.Use(); } } finally { GUI.matrix = matrix; GUI.color = color; GUI.depth = depth; GUI.enabled = true; } } private static void ClampWindow(float width, float height) { ((Rect)(ref _window)).x = Mathf.Clamp(((Rect)(ref _window)).x, 12f, Mathf.Max(12f, width - ((Rect)(ref _window)).width - 12f)); ((Rect)(ref _window)).y = Mathf.Clamp(((Rect)(ref _window)).y, 12f, Mathf.Max(12f, height - ((Rect)(ref _window)).height - 12f)); } private static void DrawContent(int id) { //IL_002a: 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_005e: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) float num = ((Rect)(ref _window)).width - 40f; Fill(new Rect(0f, 0f, ((Rect)(ref _window)).width, 3f), new Color(0.75f, 0.59f, 0.27f)); GUI.Label(new Rect(20f, 17f, num - 34f, 30f), "FORSAKEN POWERS", _styles.Title); if (GUI.Button(new Rect(((Rect)(ref _window)).width - 50f, 17f, 30f, 28f), "X", _styles.Button)) { Close(); } GUI.Label(new Rect(20f, 51f, num, 22f), ModeText(), _styles.Small); string guardianPowerName = Player.m_localPlayer.GetGuardianPowerName(); PowerDefinition powerDefinition = PowerCatalog.Find(guardianPowerName); bool flag = powerDefinition != null && !PassivePowerService.IsUnlocked(Player.m_localPlayer, powerDefinition); string text = "Selected: " + PowerName(guardianPowerName) + (flag ? " (locked)" : ""); GUI.Label(new Rect(20f, 85f, num, 24f), text, _styles.Label); float num2 = DrawSelectionDetails(num) + 14f; Fill(new Rect(20f, num2 - 8f, num, 1f), new Color(0.25f, 0.28f, 0.31f)); float num3 = ((Rect)(ref _window)).height - num2 - 69f; _scroll = GUI.BeginScrollView(new Rect(20f, num2, num, num3), _scroll, new Rect(0f, 0f, num - 18f, (float)PowerCatalog.All.Count * 61f)); for (int i = 0; i < PowerCatalog.All.Count; i++) { DrawPower(PowerCatalog.All[i], new Rect(0f, (float)i * 61f, num - 18f, 56f), guardianPowerName); } GUI.EndScrollView(); float num4 = ((Rect)(ref _window)).height - 58f; if (!string.IsNullOrEmpty(_error)) { GUI.Label(new Rect(20f, num4, num - 112f, 20f), _error, _styles.Small); } if (GUI.Button(new Rect(((Rect)(ref _window)).width - 120f, num4 - 3f, 100f, 32f), "Close", _styles.Button)) { Close(); } GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _window)).width - 55f, 74f)); } private static float DrawSelectionDetails(float inner) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) string text = PowerText.SelectedDetails(Player.m_localPlayer); float num = _styles.Detail.CalcHeight(new GUIContent(text), inner - 18f); float num2 = Mathf.Min(112f, num); _activeScroll = GUI.BeginScrollView(new Rect(20f, 113f, inner, num2), _activeScroll, new Rect(0f, 0f, inner - 18f, num)); GUI.Label(new Rect(0f, 0f, inner - 18f, num), text, _styles.Detail); GUI.EndScrollView(); return 113f + num2; } private static void DrawPower(PowerDefinition power, Rect rect, string selected) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) bool num = PassivePowerService.IsUnlocked(Player.m_localPlayer, power); bool flag = num && selected == power.Id; GUI.enabled = num && !flag; bool flag2 = GUI.Button(rect, GUIContent.none, _styles.Row); GUI.enabled = true; if (flag) { Fill(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, 3f, ((Rect)(ref rect)).height), new Color(0.88f, 0.71f, 0.36f)); } Color color = GUI.color; if (!num) { GUI.color = new Color(0.52f, 0.56f, 0.59f); } DrawIcon(power.Id, new Rect(((Rect)(ref rect)).x + 9f, ((Rect)(ref rect)).y + 9f, 36f, 36f)); GUI.Label(new Rect(((Rect)(ref rect)).x + 57f, ((Rect)(ref rect)).y + 7f, ((Rect)(ref rect)).width - 150f, 23f), power.Name, _styles.Name); string text = ((!num) ? "LOCKED" : (flag ? "SELECTED" : "SELECT")); GUI.Label(new Rect(((Rect)(ref rect)).xMax - 100f, ((Rect)(ref rect)).y + 8f, 88f, 20f), text, _styles.Badge); string text2 = (num ? power.ShortDescription : VanillaPowerAvailability.LockedReason(power)); GUI.Label(new Rect(((Rect)(ref rect)).x + 57f, ((Rect)(ref rect)).y + 31f, ((Rect)(ref rect)).width - 65f, 18f), text2, _styles.Small); GUI.color = color; if (!flag2) { return; } try { if (!PassivePowerService.Select(Player.m_localPlayer, power.Id)) { _error = "Power could not be selected. See the mod log."; return; } _activeScroll = Vector2.zero; _error = null; } catch (Exception ex) { Plugin.Log.LogError((object)("Power selection failed: " + ex)); _error = "Selection failed. See the mod log."; } } private static string PowerName(string id) { foreach (PowerDefinition item in PowerCatalog.All) { if (item.Id == id) { return item.Name; } } if (!string.IsNullOrEmpty(id)) { return id; } return "None"; } private static string ModeText() { PowerDefinition powerDefinition = PowerCatalog.Find(Player.m_localPlayer.GetGuardianPowerName()); if (Plugin.Settings.Mode.Value == PowerMode.One && (powerDefinition == null || !PassivePowerService.IsUnlocked(Player.m_localPlayer, powerDefinition))) { return "PASSIVE / Defeat a boss and mount its trophy"; } return Plugin.Settings.Mode.Value switch { PowerMode.One => "PASSIVE / Your selected power stays active", PowerMode.All => "PASSIVE / All unlocked powers stay active", _ => "VANILLA / Activate your selected power normally", }; } private static void DrawIcon(string id, Rect rect) { //IL_003f: 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_0045: 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) if (!((Object)(object)ObjectDB.instance == (Object)null)) { StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(id)); if (!((Object)(object)statusEffect == (Object)null) && !((Object)(object)statusEffect.m_icon == (Object)null)) { Sprite icon = statusEffect.m_icon; Rect textureRect = icon.textureRect; GUI.DrawTextureWithTexCoords(rect, (Texture)(object)icon.texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)icon.texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)icon.texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)icon.texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)icon.texture).height)); } } } private static void Fill(Rect rect, Color color) { //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_000b: Unknown result type (might be due to invalid IL or missing references) Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; } } public static class VanillaPowerAvailability { private sealed class StonePrefab { public int SectorIndex; public bool Scanning = true; public float RescanAt; public string Name { get; } public int PrefabHash { get; } public HashSet<string> PowerIds { get; } = new HashSet<string>(StringComparer.Ordinal); public HashSet<ZDOID> KnownZdos { get; } = new HashSet<ZDOID>(); public StonePrefab(string name) { Name = name; PrefabHash = StringExtensionMethods.GetStableHashCode(name); } } private const float RefreshInterval = 0.35f; private const float FullRescanInterval = 30f; private const float RemoteRequestInterval = 10f; private const float ForcedRequestInterval = 1f; private static readonly List<StonePrefab> StonePrefabs = new List<StonePrefab>(); private static readonly Dictionary<int, StonePrefab> StonePrefabsByHash = new Dictionary<int, StonePrefab>(); private static readonly HashSet<string> AvailablePowerIds = new HashSet<string>(StringComparer.Ordinal); private static readonly List<ZDO> ScanResults = new List<ZDO>(); private static readonly List<ZDOID> StaleIds = new List<ZDOID>(); private static ZDOMan _zdoMan; private static ZNetScene _znetScene; private static ZoneSystem _zoneSystem; private static ZNet _znet; private static long _sessionId; private static float _nextRefreshAt; private static float _nextRemoteRequestAt; private static float _nextForcedRequestAt; private static int _scanCursor; private static bool _initialized; public static bool IsAvailable(Player player, PowerDefinition power) { if ((Object)(object)player == (Object)null || power == null || string.IsNullOrEmpty(power.Id)) { return false; } Refresh(); if (HasDefeatedBoss(power)) { return AvailablePowerIds.Contains(power.Id); } return false; } public static void Refresh(bool force = false) { float unscaledTime = Time.unscaledTime; if (EnsureWorldState() && (force || !(unscaledTime < _nextRefreshAt))) { _nextRefreshAt = unscaledTime + 0.35f; AvailablePowerIds.Clear(); ValidateKnownZdos(); DiscoverLoadedStones(); AdvancePrefabScan(unscaledTime); RequestKnownStones(unscaledTime, force); } } public static string LockedReason(PowerDefinition power) { if (power == null) { return "Power availability is unknown."; } if ((Object)(object)ZoneSystem.instance == (Object)null) { return "Enter a world before checking this power."; } if (!HasDefeatedBoss(power)) { return "Defeat " + power.Name + " to unlock this power."; } if (IsAvailable(Player.m_localPlayer, power)) { return string.Empty; } return "Visit spawn to check its mounted trophy."; } private static bool EnsureWorldState() { ZDOMan instance = ZDOMan.instance; ZNetScene instance2 = ZNetScene.instance; ZoneSystem instance3 = ZoneSystem.instance; ZNet instance4 = ZNet.instance; if (instance == null || (Object)(object)instance2 == (Object)null || (Object)(object)instance3 == (Object)null) { ResetState(); return false; } long sessionID = ZDOMan.GetSessionID(); if (_initialized && _zdoMan == instance && _znetScene == instance2 && _zoneSystem == instance3 && _znet == instance4 && _sessionId == sessionID) { return true; } ResetState(); _zdoMan = instance; _znetScene = instance2; _zoneSystem = instance3; _znet = instance4; _sessionId = sessionID; _initialized = true; DiscoverSacrificialPrefabs(instance2); return true; } private static void DiscoverSacrificialPrefabs(ZNetScene scene) { foreach (GameObject prefab in scene.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } ItemStand[] componentsInChildren = prefab.GetComponentsInChildren<ItemStand>(true); foreach (ItemStand val in componentsInChildren) { if ((Object)(object)val == (Object)null || val.m_canBeRemoved || (Object)(object)val.m_guardianPower == (Object)null) { continue; } PowerDefinition powerDefinition = PowerCatalog.Find(((Object)val.m_guardianPower).name); if (powerDefinition != null) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); if (!StonePrefabsByHash.TryGetValue(stableHashCode, out var value)) { value = new StonePrefab(((Object)prefab).name); StonePrefabsByHash.Add(stableHashCode, value); StonePrefabs.Add(value); } value.PowerIds.Add(powerDefinition.Id); } } } } private static void ValidateKnownZdos() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_005d: 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_00ae: Unknown result type (might be due to invalid IL or missing references) foreach (StonePrefab stonePrefab in StonePrefabs) { StaleIds.Clear(); foreach (ZDOID knownZdo in stonePrefab.KnownZdos) { ZDO zDO = _zdoMan.GetZDO(knownZdo); if (zDO == null || zDO.GetPrefab() != stonePrefab.PrefabHash) { StaleIds.Add(knownZdo); } else { AddAvailablePowers(stonePrefab, zDO.GetInt(ZDOVars.s_item, 0)); } } foreach (ZDOID staleId in StaleIds) { stonePrefab.KnownZdos.Remove(staleId); } } } private static void AddAvailablePowers(StonePrefab stone, int mountedItemHash) { foreach (string powerId in stone.PowerIds) { PowerDefinition powerDefinition = PowerCatalog.Find(powerId); if (powerDefinition != null && mountedItemHash == StringExtensionMethods.GetStableHashCode(powerDefinition.Trophy)) { AvailablePowerIds.Add(powerDefinition.Id); } } } private static void DiscoverLoadedStones() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) ItemStand[] array = Object.FindObjectsByType<ItemStand>((FindObjectsSortMode)0); foreach (ItemStand val in array) { if ((Object)(object)val == (Object)null || val.m_canBeRemoved || (Object)(object)val.m_guardianPower == (Object)null) { continue; } PowerDefinition powerDefinition = PowerCatalog.Find(((Object)val.m_guardianPower).name); if (powerDefinition == null) { continue; } ZNetView netView = GetNetView(val); ZDO val2 = (((Object)(object)netView == (Object)null) ? null : netView.GetZDO()); if (val2 == null) { continue; } int prefab = val2.GetPrefab(); if (StonePrefabsByHash.TryGetValue(prefab, out var value) && value.PowerIds.Contains(powerDefinition.Id)) { value.KnownZdos.Add(val2.m_uid); if (val.HaveAttachment() && val.GetAttachedItem() == StringExtensionMethods.GetStableHashCode(powerDefinition.Trophy)) { AvailablePowerIds.Add(powerDefinition.Id); } } } } private static ZNetView GetNetView(ItemStand stand) { ZNetView netViewOverride = stand.m_netViewOverride; if (!((Object)(object)netViewOverride != (Object)null)) { return ((Component)stand).GetComponent<ZNetView>(); } return netViewOverride; } private static void AdvancePrefabScan(float now) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (StonePrefabs.Count == 0) { return; } int num = 0; while (num < StonePrefabs.Count) { StonePrefab stonePrefab = StonePrefabs[_scanCursor]; _scanCursor = (_scanCursor + 1) % StonePrefabs.Count; if (!stonePrefab.Scanning) { if (now < stonePrefab.RescanAt) { num++; continue; } stonePrefab.Scanning = true; stonePrefab.SectorIndex = 0; } ScanResults.Clear(); bool allZDOsWithPrefabIterative = _zdoMan.GetAllZDOsWithPrefabIterative(stonePrefab.Name, ScanResults, ref stonePrefab.SectorIndex); foreach (ZDO scanResult in ScanResults) { if (scanResult != null && scanResult.GetPrefab() == stonePrefab.PrefabHash) { stonePrefab.KnownZdos.Add(scanResult.m_uid); AddAvailablePowers(stonePrefab, scanResult.GetInt(ZDOVars.s_item, 0)); } } if (allZDOsWithPrefabIterative) { stonePrefab.Scanning = false; stonePrefab.RescanAt = now + 30f; } break; } } private static void RequestKnownStones(float now, bool force) { //IL_005b: 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_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_znet == (Object)null || _znet.IsServer()) { return; } bool flag = force && now >= _nextForcedRequestAt; if (!flag && now < _nextRemoteRequestAt) { return; } foreach (StonePrefab stonePrefab in StonePrefabs) { foreach (ZDOID knownZdo in stonePrefab.KnownZdos) { _zdoMan.RequestZDO(knownZdo); } } _nextRemoteRequestAt = now + 10f; if (flag) { _nextForcedRequestAt = now + 1f; } } private static bool HasDefeatedBoss(PowerDefinition power) { if (power != null && !string.IsNullOrEmpty(power.DefeatedKey) && (Object)(object)ZoneSystem.instance != (Object)null) { return ZoneSystem.instance.GetGlobalKey(power.DefeatedKey); } return false; } private static void ResetState() { StonePrefabs.Clear(); StonePrefabsByHash.Clear(); AvailablePowerIds.Clear(); ScanResults.Clear(); StaleIds.Clear(); _zdoMan = null; _znetScene = null; _zoneSystem = null; _znet = null; _sessionId = 0L; _nextRefreshAt = 0f; _nextRemoteRequestAt = 0f; _nextForcedRequestAt = 0f; _scanCursor = 0; _initialized = false; } } }