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 HearthSort v0.1.9
BepInEx/plugins/HearthSort/HearthSort.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using HearthSort.Core; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HearthSort")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.9.0")] [assembly: AssemblyInformationalVersion("0.1.9")] [assembly: AssemblyProduct("HearthSort")] [assembly: AssemblyTitle("HearthSort")] [assembly: AssemblyVersion("0.1.9.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 HearthSort { internal sealed class BirdEnergy { private const string SaveKey = "HearthSort.flightEnergy"; private readonly Dictionary<long, FlightEnergy> characters = new Dictionary<long, FlightEnergy>(); private FlightEnergy current; private long currentId; private Hud hud; private RectTransform root; private RectTransform fill; private Image fillImage; private TextMeshProUGUI label; private int displayedEnergy = -1; internal bool CanFly { get { Bind(Player.m_localPlayer); if (current != null) { return current.Value > 0.0; } return false; } } private void Bind(Player player) { if (!Object.op_Implicit((Object)(object)player)) { return; } long playerID = player.GetPlayerID(); if (playerID == 0L) { current = null; currentId = 0L; } else if (current == null || currentId != playerID) { if (!characters.TryGetValue(playerID, out current)) { player.m_customData.TryGetValue("HearthSort.flightEnergy", out var value); characters[playerID] = (current = new FlightEnergy(value)); } currentId = playerID; } } internal void Save(Player player) { if (!((Object)(object)player != (Object)(object)Player.m_localPlayer)) { Bind(player); if (current != null) { player.m_customData["HearthSort.flightEnergy"] = current.Save(); } } } internal void Tick(Player player, float dt) { Bind(player); if (current != null && !((Character)player).IsDead() && !((Character)player).InIntro() && !((Character)player).InCutscene() && !((Character)player).IsTeleporting()) { BirdForm component = ((Component)player).GetComponent<BirdForm>(); bool flag = BirdForm.IsActive((Character)(object)player) && Object.op_Implicit((Object)(object)component) && component.InFlight; current.Step(dt, flag, flag && component.IsSprinting); if (flag && current.Value == 0.0) { Plugin.Instance.Birds.StopLocal(); component.End(effect: true); Plugin.Instance.Message("Flight energy depleted."); } } } private static RectTransform Rect(string name, Transform parent, Vector2 position, Vector2 size) { //IL_0014: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); component.anchorMax = val; component.anchorMin = val; component.anchoredPosition = position; component.sizeDelta = size; return component; } private static Image Panel(RectTransform rect, Color color, Sprite sprite = null) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) Image val = ((Component)rect).gameObject.AddComponent<Image>(); ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; if (Object.op_Implicit((Object)(object)sprite)) { val.sprite = sprite; val.type = (Type)1; } return val; } internal void UpdateHud() { //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0343: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: 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_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0409: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Bind(localPlayer); if ((Object)(object)hud != (Object)(object)Hud.instance || (Object.op_Implicit((Object)(object)root) && (!Object.op_Implicit((Object)(object)hud) || !Object.op_Implicit((Object)(object)hud.m_staminaBar2Root) || (Object)(object)((Transform)root).parent != (Object)(object)((Transform)hud.m_staminaBar2Root).parent))) { DestroyHud(); } if (!Object.op_Implicit((Object)(object)localPlayer) || current == null || !Object.op_Implicit((Object)(object)Hud.instance) || !Object.op_Implicit((Object)(object)Hud.instance.m_staminaBar2Root) || !Object.op_Implicit((Object)(object)Hud.instance.m_staminaText)) { if (Object.op_Implicit((Object)(object)root)) { ((Component)root).gameObject.SetActive(false); } return; } if (!Object.op_Implicit((Object)(object)root)) { hud = Hud.instance; RectTransform staminaBar2Root = hud.m_staminaBar2Root; root = Rect("HearthSort Flight Energy", ((Transform)staminaBar2Root).parent, Vector2.zero, new Vector2(208f, 24f)); root.anchorMin = staminaBar2Root.anchorMin; root.anchorMax = staminaBar2Root.anchorMax; root.pivot = staminaBar2Root.pivot; ((Transform)root).localScale = ((Transform)staminaBar2Root).localScale; Panel(root, new Color(0.05f, 0.07f, 0.09f, 0.9f)); RectTransform val = Rect("Track", (Transform)(object)root, Vector2.zero, new Vector2(200f, 16f)); Panel(val, new Color(0.13f, 0.2f, 0.24f, 0.95f)); fill = Rect("Energy", (Transform)(object)val, new Vector2(-100f, 0f), new Vector2(200f, 16f)); fill.pivot = new Vector2(0f, 0.5f); Image component = ((Component)hud.m_staminaBar2Fast.m_bar).GetComponent<Image>(); fillImage = Panel(fill, Color.cyan, Object.op_Implicit((Object)(object)component) ? component.sprite : null); label = ((Component)Rect("Label", (Transform)(object)root, Vector2.zero, new Vector2(204f, 24f))).gameObject.AddComponent<TextMeshProUGUI>(); ((TMP_Text)label).font = hud.m_staminaText.font; ((TMP_Text)label).fontSharedMaterial = hud.m_staminaText.fontSharedMaterial; ((TMP_Text)label).fontSize = 16f; ((TMP_Text)label).alignment = (TextAlignmentOptions)514; ((Graphic)label).raycastTarget = false; ((Graphic)label).color = Color.white; } root.anchoredPosition = hud.m_staminaBar2Root.anchoredPosition + new Vector2(0f, 38f); ((Transform)root).localScale = ((Transform)hud.m_staminaBar2Root).localScale; ((Component)root).gameObject.SetActive(BirdForm.IsActive((Character)(object)localPlayer) && current.Value < 100.0 && !((Character)localPlayer).IsDead() && !((Character)localPlayer).InIntro() && hud.IsVisible() && !Hud.IsUserHidden()); float num = (float)(current.Value / 100.0); fill.sizeDelta = new Vector2(200f * num, 16f); ((Graphic)fillImage).color = ((num <= 0.2f) ? new Color(0.94f, 0.48f, 0.22f) : new Color(0.35f, 0.8f, 0.88f)); int num2 = Mathf.FloorToInt((float)current.Value); if (num2 != displayedEnergy) { displayedEnergy = num2; ((TMP_Text)label).text = num2 + "%"; } } internal void DestroyHud() { if (Object.op_Implicit((Object)(object)root)) { Object.Destroy((Object)(object)((Component)root).gameObject); } root = (fill = null); label = null; fillImage = null; hud = null; displayedEnergy = -1; } } internal sealed class BirdForm : MonoBehaviour { private Player player; private Rigidbody body; private GameObject modelRoot; private GameObject flyingModel; private GameObject landedModel; private readonly Dictionary<Renderer, bool> renderers = new Dictionary<Renderer, bool>(); private readonly Dictionary<Light, bool> lights = new Dictionary<Light, bool>(); private bool active; private bool flying; private bool takeoff; private bool landing; private bool sprinting; private bool oldGravity; private CollisionDetectionMode oldCollision; private Vector3 oldEye; private float launchedAt; private float nextRenderScan; private float settlingUntil; private Vector3 direction; private float airspeed; private BirdSprint sprintInput; private PlayerController controller; private static readonly Func<PlayerController, bool, bool> TakeInput = AccessTools.MethodDelegate<Func<PlayerController, bool, bool>>(AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null), (object)null, true); private static readonly int LandedKey = StringExtensionMethods.GetStableHashCode("HearthSort.bird.landed"); private static readonly FieldRef<Character, float> GroundTouch = AccessTools.FieldRefAccess<Character, float>("m_lastGroundTouch"); private static readonly FieldRef<Character, float> JumpTimer = AccessTools.FieldRefAccess<Character, float>("m_jumpTimer"); private static readonly FieldRef<Character, float> FallTimer = AccessTools.FieldRefAccess<Character, float>("m_fallTimer"); private static readonly FieldRef<Character, float> AirAltitude = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude"); private static readonly FieldRef<Player, bool> Crouch = AccessTools.FieldRefAccess<Player, bool>("m_crouchToggled"); internal bool InFlight { get { if (active) { return flying; } return false; } } internal bool IsSprinting => sprinting; internal static bool IsActive(Character c) { Plugin instance = Plugin.Instance; if (instance == null) { return false; } return instance.Birds?.IsBird(c) == true; } internal static BirdForm For(Player p) { BirdForm component = ((Component)p).GetComponent<BirdForm>(); if (!Object.op_Implicit((Object)(object)component)) { return ((Component)p).gameObject.AddComponent<BirdForm>(); } return component; } private static RandomFlyingBird Prefab() { if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return null; } string[] array = new string[2] { "Crow", "Seagal" }; RandomFlyingBird val = default(RandomFlyingBird); foreach (string text in array) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if (Object.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent<RandomFlyingBird>(ref val) && Object.op_Implicit((Object)(object)val.m_flyingModel) && (val.m_singleModel || Object.op_Implicit((Object)(object)val.m_landedModel))) { return val; } } return null; } internal static bool HasModel() { return (Object)(object)Prefab() != (Object)null; } private void Awake() { player = ((Component)this).GetComponent<Player>(); body = ((Component)this).GetComponent<Rigidbody>(); controller = ((Component)this).GetComponent<PlayerController>(); } private GameObject CloneVisual(GameObject source) { GameObject val = Object.Instantiate<GameObject>(source, modelRoot.transform, false); MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } AudioSource[] componentsInChildren4 = val.GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } val.SetActive(true); return val; } private bool Begin() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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) RandomFlyingBird val = Prefab(); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)body)) { return false; } modelRoot = new GameObject("HearthSort Bird Visual"); modelRoot.SetActive(false); modelRoot.transform.SetParent(((Component)player).transform, false); flyingModel = CloneVisual(val.m_flyingModel); landedModel = (val.m_singleModel ? flyingModel : CloneVisual(val.m_landedModel)); if (modelRoot.GetComponentsInChildren<Renderer>(true).Length == 0) { Object.Destroy((Object)(object)modelRoot); modelRoot = null; return false; } oldGravity = body.useGravity; oldCollision = body.collisionDetectionMode; oldEye = ((Character)player).m_eye.localPosition; active = true; flying = !((Character)player).IsOnGround(); direction = ((Component)player).transform.forward; airspeed = (flying ? 4f : 0f); sprinting = false; sprintInput = default(BirdSprint); if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { body.collisionDetectionMode = (CollisionDetectionMode)2; ((Character)player).m_eye.localPosition = new Vector3(oldEye.x, 0.65f, oldEye.z); Crouch.Invoke(player) = false; player.m_autoRun = false; } modelRoot.SetActive(true); nextRenderScan = 0f; HidePlayer(); Puff(((Component)player).transform.position + Vector3.up * 0.5f); return true; } private void HidePlayer() { if (Time.unscaledTime >= nextRenderScan) { nextRenderScan = Time.unscaledTime + 0.25f; Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Component)val).transform.IsChildOf(modelRoot.transform) && !renderers.ContainsKey(val)) { renderers.Add(val, val.forceRenderingOff); } } Light[] componentsInChildren2 = ((Component)player).GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren2) { if (!((Component)val2).transform.IsChildOf(modelRoot.transform) && !lights.ContainsKey(val2)) { lights.Add(val2, ((Behaviour)val2).enabled); } } componentsInChildren = renderers.Keys.Where((Renderer r) => !Object.op_Implicit((Object)(object)r)).ToArray(); foreach (Renderer key in componentsInChildren) { renderers.Remove(key); } componentsInChildren2 = lights.Keys.Where((Light l) => !Object.op_Implicit((Object)(object)l)).ToArray(); foreach (Light key2 in componentsInChildren2) { lights.Remove(key2); } } foreach (Renderer key3 in renderers.Keys) { if (Object.op_Implicit((Object)(object)key3)) { key3.forceRenderingOff = true; } } foreach (Light key4 in lights.Keys) { if (Object.op_Implicit((Object)(object)key4)) { ((Behaviour)key4).enabled = false; } } } private void LateUpdate() { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)player)) { return; } bool flag = IsActive((Character)(object)player); if (flag && !active) { try { if (!Begin()) { if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { Plugin.Instance.Birds.StopLocal(); } return; } } catch (Exception e) { End(effect: false); Plugin.Instance.Error("Bird visual restored after an error", e); if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { Plugin.Instance.Birds.StopLocal(); } return; } } if (!flag) { if (active && (Object)(object)player == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)ZNet.instance)) { Plugin.Instance?.Birds?.StopLocal(); } End(effect: true); return; } HidePlayer(); bool flag2 = (((Object)(object)player == (Object)(object)Player.m_localPlayer) ? flying : (!((Component)player).GetComponent<ZNetView>().GetZDO().GetBool(LandedKey, true))); if ((Object)(object)flyingModel != (Object)(object)landedModel) { flyingModel.SetActive(flag2); landedModel.SetActive(!flag2); } Vector3 velocity = ((Character)player).GetVelocity(); Quaternion val = Quaternion.LookRotation((flag2 && ((Vector3)(ref velocity)).sqrMagnitude > 0.2f) ? ((Vector3)(ref velocity)).normalized : ((Component)player).transform.forward, Vector3.up); modelRoot.transform.rotation = Quaternion.Slerp(modelRoot.transform.rotation, val, Time.deltaTime * 10f); Animator[] componentsInChildren = modelRoot.GetComponentsInChildren<Animator>(true); foreach (Animator val2 in componentsInChildren) { AnimatorControllerParameter[] parameters = val2.parameters; foreach (AnimatorControllerParameter val3 in parameters) { if ((int)val3.type == 4) { if (val3.name == "flying") { val2.SetBool(val3.nameHash, flag2); } if (val3.name == "flapping") { val2.SetBool(val3.nameHash, flag2 && Mathf.Repeat(Time.time, 4f) < 2.8f); } } } } if ((Object)(object)player == (Object)(object)Player.m_localPlayer) { ((Component)player).GetComponent<ZNetView>().GetZDO().Set(LandedKey, !flying); if (((Character)player).IsAttached() || ((Character)player).InIntro() || ((Character)player).IsSwimming() || ((Character)player).IsDebugFlying()) { Plugin.Instance.Birds.StopLocal(); } } } internal void Controls(ref Vector3 movedir, bool jump, bool crouch) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (active || Begin()) { bool canInput = Object.op_Implicit((Object)(object)controller) && TakeInput(controller, arg2: false) && !InventoryGui.IsVisible() && !StoreGui.IsVisible() && !Minimap.IsOpen() && !Hud.InRadial(); sprinting = sprintInput.Update(ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"), ZInput.ToggleRun, canInput); takeoff |= jump && !flying && Plugin.Instance.Energy.CanFly; if (crouch && flying) { landing = true; } if (jump) { landing = false; } movedir = (Vector3)(flying ? Vector3.zero : new Vector3(0f, 0f, Mathf.Clamp01(movedir.z))); } } internal bool Motion(float dt) { //IL_002d: 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_008b: 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) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_0109: 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_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_03c4: Unknown result type (might be due to invalid IL or missing references) if (!active && !Begin()) { return true; } AirAltitude.Invoke((Character)(object)player) = ((Component)player).transform.position.y; FallTimer.Invoke((Character)(object)player) = 0f; Vector3 val; if (takeoff) { takeoff = false; flying = true; launchedAt = Time.time; airspeed = 4f; val = ((Component)player).transform.forward + Vector3.up * 0.65f; direction = ((Vector3)(ref val)).normalized; GroundTouch.Invoke((Character)(object)player) = 1f; } if (!flying && Time.time >= settlingUntil && !((Character)player).IsOnGround()) { flying = true; launchedAt = Time.time - 1f; direction = ((Component)player).transform.forward; airspeed = 4f; } if (flying && BirdFlight.CanLand(Time.time - launchedAt, ((Character)player).IsOnGround(), direction.y, landing)) { flying = false; airspeed = 0f; landing = false; body.useGravity = true; body.linearVelocity = new Vector3(0f, Mathf.Min(body.linearVelocity.y, 0f), 0f); } if (!flying) { airspeed = 0f; body.useGravity = true; return true; } if (!Plugin.Instance.Energy.CanFly) { Plugin.Instance.Birds.StopLocal(); End(effect: true); return true; } Vector3 lookDir = ((Character)player).GetLookDir(); Vector3 forward = default(Vector3); ((Vector3)(ref forward))..ctor(lookDir.x, 0f, lookDir.z); if (((Vector3)(ref forward)).sqrMagnitude < 0.001f) { forward = ((Component)player).transform.forward; } float num = BirdFlight.Pitch(lookDir.y); Vector3 val2 = ((Vector3)(ref forward)).normalized * Mathf.Cos(num) + Vector3.up * Mathf.Sin(num); if (landing) { val = ((Vector3)(ref forward)).normalized - Vector3.up * 0.45f; val2 = ((Vector3)(ref val)).normalized; } if (Time.time - launchedAt < 0.35f) { val = ((Vector3)(ref forward)).normalized + Vector3.up * 0.65f; val2 = ((Vector3)(ref val)).normalized; } val = Vector3.RotateTowards(direction, val2, 1.7453293f * dt, 1f); direction = ((Vector3)(ref val)).normalized; airspeed = BirdFlight.StepSpeed(airspeed, direction.y, sprinting, dt); float num2 = airspeed * dt; RaycastHit val3 = default(RaycastHit); bool flag = body.SweepTest(direction, ref val3, num2 + 0.04f, (QueryTriggerInteraction)1); if (flag && ((RaycastHit)(ref val3)).normal.y > 0.55f && direction.y < 0f && Time.time - launchedAt > 0.45f) { flying = false; airspeed = 0f; landing = false; settlingUntil = Time.time + 0.25f; body.useGravity = true; body.linearVelocity = Vector3.down; return true; } body.useGravity = false; airspeed = BirdFlight.SweptSpeed(airspeed, dt, flag ? new float?(((RaycastHit)(ref val3)).distance) : ((float?)null)); body.linearVelocity = direction * airspeed; body.angularVelocity = Vector3.zero; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(direction.x, 0f, direction.z); if (((Vector3)(ref val4)).sqrMagnitude > 0.001f) { body.MoveRotation(Quaternion.LookRotation(val4)); } GroundTouch.Invoke((Character)(object)player) += dt; JumpTimer.Invoke((Character)(object)player) += dt; return false; } internal void End(bool effect) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) if (active) { foreach (KeyValuePair<Renderer, bool> renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer.Key)) { renderer.Key.forceRenderingOff = renderer.Value; } } foreach (KeyValuePair<Light, bool> light in lights) { if (Object.op_Implicit((Object)(object)light.Key)) { ((Behaviour)light.Key).enabled = light.Value; } } if (Object.op_Implicit((Object)(object)player) && (Object)(object)player == (Object)(object)Player.m_localPlayer) { if (Object.op_Implicit((Object)(object)body)) { body.useGravity = oldGravity; body.collisionDetectionMode = oldCollision; } ((Character)player).m_eye.localPosition = oldEye; AirAltitude.Invoke((Character)(object)player) = ((Component)player).transform.position.y; FallTimer.Invoke((Character)(object)player) = 0f; } if (effect && Object.op_Implicit((Object)(object)player) && !((Character)player).IsDead()) { Puff(((Component)player).transform.position + Vector3.up * 0.5f); } } active = (flying = (takeoff = (landing = (sprinting = false)))); airspeed = 0f; sprintInput = default(BirdSprint); renderers.Clear(); lights.Clear(); if (Object.op_Implicit((Object)(object)modelRoot)) { modelRoot.SetActive(false); Object.Destroy((Object)(object)modelRoot); } modelRoot = null; } private void OnDestroy() { End(effect: false); } private static void Puff(Vector3 position) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0059: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("vfx_raven_despawn") : null); ParticleSystemRenderer val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponentInChildren<ParticleSystemRenderer>(true) : null); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)((Renderer)val2).sharedMaterial)) { GameObject val3 = new GameObject("Bird feather puff"); val3.transform.position = position; ParticleSystem val4 = val3.AddComponent<ParticleSystem>(); val4.Stop(true, (ParticleSystemStopBehavior)0); ((Renderer)((Component)val4).GetComponent<ParticleSystemRenderer>()).sharedMaterial = ((Renderer)val2).sharedMaterial; MainModule main = val4.main; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).duration = 0.3f; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.55f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.35f); ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.06f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.65f, 0.68f, 0.72f, 0.3f)); ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).maxParticles = 12; EmissionModule emission = val4.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)9) }); ShapeModule shape = val4.shape; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.3f; ColorOverLifetimeModule colorOverLifetime = val4.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val5 = new Gradient(); val5.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.gray, 0f), new GradientColorKey(Color.gray, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[2] { new GradientAlphaKey(0.3f, 0f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val5); val4.Play(); Object.Destroy((Object)(object)val3, 1.2f); } } } internal sealed class BirdNetwork { private const string QueryRpc = "HearthSort_BirdQuery"; private const string ToggleRpc = "HearthSort_BirdToggle"; private const string StateRpc = "HearthSort_BirdState"; private ZNet session; private readonly HashSet<ZRpc> registeredPeers = new HashSet<ZRpc>(); private readonly Dictionary<long, ZDOID> transformed = new Dictionary<long, ZDOID>(); private readonly Dictionary<long, float> requests = new Dictionary<long, float>(); private readonly Dictionary<long, float> toggleRequests = new Dictionary<long, float>(); private HashSet<ZDOID> visible = new HashSet<ZDOID>(); private float nextQuery; private float nextPublish; private float receivedAt = float.NegativeInfinity; private bool stopRequested; private float nextStop; private ZDOID localCharacter; private static long Self => ZNet.GetUID(); private static long Server { get { if (!ZNet.instance.IsServer()) { return ZNet.instance.GetServerPeer()?.m_uid ?? 0; } return Self; } } internal bool CanUse => Time.unscaledTime - receivedAt < 8f; internal bool IsBird(Character player) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (player is Player && !player.IsDead() && !player.IsTeleporting() && !player.InCutscene() && Time.unscaledTime - receivedAt < 8f) { return visible.Contains(player.GetZDOID()); } return false; } internal void Update() { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0098: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ZNet.instance)) { Reset(); return; } if ((Object)(object)session != (Object)(object)ZNet.instance) { Reset(); session = ZNet.instance; } foreach (ZNetPeer peer in session.GetPeers()) { if (peer.IsReady() && peer.m_rpc != null && registeredPeers.Add(peer.m_rpc)) { peer.m_rpc.Register("HearthSort_BirdQuery", new Method(PeerQuery)); peer.m_rpc.Register<bool>("HearthSort_BirdToggle", (Action<ZRpc, bool>)PeerToggle); peer.m_rpc.Register<ZPackage>("HearthSort_BirdState", (Action<ZRpc, ZPackage>)PeerState); } } Player localPlayer = Player.m_localPlayer; ZDOID val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Character)localPlayer).GetZDOID() : ZDOID.None); if (localCharacter != val) { localCharacter = val; receivedAt = float.NegativeInfinity; nextQuery = 0f; stopRequested = false; } if (Server != 0L && Time.unscaledTime >= nextQuery) { nextQuery = Time.unscaledTime + 2f; if (session.IsServer()) { Query(Self); } else { ZNetPeer serverPeer = session.GetServerPeer(); if (serverPeer != null) { serverPeer.m_rpc.Invoke("HearthSort_BirdQuery", Array.Empty<object>()); } } } if (stopRequested && Server != 0L && Time.unscaledTime >= nextStop) { nextStop = Time.unscaledTime + 0.5f; SendToggle(enable: false); } if (!ZNet.instance.IsServer()) { return; } bool flag = false; KeyValuePair<long, ZDOID>[] array = transformed.ToArray(); for (int i = 0; i < array.Length; i++) { KeyValuePair<long, ZDOID> keyValuePair = array[i]; if (!ConnectedPlayer(keyValuePair.Key) || CharacterId(keyValuePair.Key) != keyValuePair.Value || ZDOMan.instance.GetZDO(keyValuePair.Value) == null) { transformed.Remove(keyValuePair.Key); flag = true; } } if (flag || Time.unscaledTime >= nextPublish) { Publish(); } } private void Reset() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) session = null; registeredPeers.Clear(); transformed.Clear(); requests.Clear(); toggleRequests.Clear(); visible.Clear(); stopRequested = false; receivedAt = float.NegativeInfinity; nextQuery = (nextPublish = 0f); localCharacter = ZDOID.None; } private static ZDOID CharacterId(long sender) { //IL_0028: 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_0017: Unknown result type (might be due to invalid IL or missing references) if (sender != Self) { return ZNet.instance.GetPeer(sender)?.m_characterID ?? ZDOID.None; } return ZNet.instance.LocalPlayerCharacterID; } private static long AuthenticatedPeer(ZRpc connection) { return ((IEnumerable<ZNetPeer>)ZNet.instance.GetPeers()).FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer p) => p.IsReady() && p.m_rpc == connection))?.m_uid ?? 0; } private void PeerQuery(ZRpc connection) { if (ZNet.instance.IsServer()) { long num = AuthenticatedPeer(connection); if (num != 0L && num != Self) { Query(num); } } } private void PeerToggle(ZRpc connection, bool enable) { if (ZNet.instance.IsServer()) { long num = AuthenticatedPeer(connection); if (num != 0L && num != Self) { Toggle(num, enable); } } } private void PeerState(ZRpc connection, ZPackage packet) { if (!ZNet.instance.IsServer() && ZNet.instance.GetServerPeer()?.m_rpc == connection) { Receive(Server, packet); } } private void SendToggle(bool enable) { if (!Object.op_Implicit((Object)(object)session)) { return; } if (session.IsServer()) { Toggle(Self, enable); return; } ZNetPeer serverPeer = session.GetServerPeer(); if (serverPeer != null) { serverPeer.m_rpc.Invoke("HearthSort_BirdToggle", new object[1] { enable }); } } private static bool ConnectedPlayer(long sender) { if (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsServer()) { return false; } if (sender == Self) { return (Object)(object)Player.m_localPlayer != (Object)null; } ZNetPeer peer = ZNet.instance.GetPeer(sender); if (peer == null || !peer.IsReady() || peer.m_socket == null) { return false; } return true; } private bool Throttled(long sender, bool toggle = false) { if (sender != Self && ZNet.instance.GetPeer(sender) == null) { return true; } Dictionary<long, float> dictionary = (toggle ? toggleRequests : requests); if (dictionary.TryGetValue(sender, out var value) && Time.unscaledTime - value < 0.25f) { return true; } dictionary[sender] = Time.unscaledTime; return false; } private void Query(long sender) { if (ZNet.instance.IsServer() && !Throttled(sender)) { SendState(sender); } } private void Toggle(long sender, bool enable) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsServer() && !Throttled(sender, toggle: true)) { ZDOID val = CharacterId(sender); ZDO val2 = ((val != ZDOID.None) ? ZDOMan.instance.GetZDO(val) : null); if (enable && ConnectedPlayer(sender) && val2 != null && val2.GetOwner() == sender && val2.GetPrefab() == StringExtensionMethods.GetStableHashCode("Player")) { transformed[sender] = val; } else { transformed.Remove(sender); } Publish(); } } private void Publish() { nextPublish = Time.unscaledTime + 2f; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.IsReady()) { SendState(peer.m_uid); } } if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { SendState(Self); } long[] array = requests.Keys.ToArray(); foreach (long num in array) { if (num != Self && ZNet.instance.GetPeer(num) == null) { requests.Remove(num); } } array = toggleRequests.Keys.ToArray(); foreach (long num2 in array) { if (num2 != Self && ZNet.instance.GetPeer(num2) == null) { toggleRequests.Remove(num2); } } registeredPeers.RemoveWhere((ZRpc connection) => !ZNet.instance.GetPeers().Any((ZNetPeer peer) => peer.m_rpc == connection)); } private void SendState(long recipient) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //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_0033: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(transformed.Count); foreach (ZDOID value in transformed.Values) { val.Write(value); } val.SetPos(0); if (recipient == Self) { Receive(Self, val); return; } ZNetPeer peer = ZNet.instance.GetPeer(recipient); if (peer != null) { peer.m_rpc.Invoke("HearthSort_BirdState", new object[1] { val }); } } private void Receive(long sender, ZPackage packet) { //IL_0035: 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_0079: Unknown result type (might be due to invalid IL or missing references) if (sender != Server || Server == 0L) { return; } try { int num = packet.ReadInt(); if (num < 0 || num > 1024) { return; } HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); for (int i = 0; i < num; i++) { hashSet.Add(packet.ReadZDOID()); } if (packet.GetPos() != packet.Size()) { return; } if (stopRequested) { if (!hashSet.Contains(localCharacter)) { stopRequested = false; } else { hashSet.Remove(localCharacter); } } visible = hashSet; receivedAt = Time.unscaledTime; } catch (Exception e) { Plugin.Instance.Error("Bird state packet rejected", e); } } internal bool RequestToggle() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !CanUse || stopRequested || !Object.op_Implicit((Object)(object)session) || Server == 0L) { return false; } bool flag = !IsBird((Character)(object)localPlayer); if (flag && ((Character)localPlayer).IsDebugFlying()) { Plugin.Instance.Message("Turn off debug flight before using bird form."); return false; } if (flag && (((Character)localPlayer).IsDead() || ((Character)localPlayer).InIntro() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).InAttack() || ((Character)localPlayer).IsSwimming())) { Plugin.Instance.Message("Land and finish your current action first."); return false; } if (flag && !BirdForm.HasModel()) { Plugin.Instance.Message("Bird model is unavailable in this game version."); return false; } SendToggle(flag); return true; } internal void StopLocal() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) stopRequested = true; nextStop = Time.unscaledTime + 0.5f; if (Object.op_Implicit((Object)(object)session) && Server != 0L) { SendToggle(enable: false); } if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { visible.Remove(((Character)Player.m_localPlayer).GetZDOID()); } } } [HarmonyPatch] internal static class BirdPatches { private sealed class BirdCaption : IRadialConfig { public string LocalizedName { get { if (!BirdForm.IsActive((Character)(object)Player.m_localPlayer)) { return "Bird form"; } return "Return to Viking"; } } public Sprite Sprite { get { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab("Feathers") : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if (component == null) { return null; } return component.m_itemData.GetIcon(); } } public void InitRadialConfig(RadialBase radial) { } } [HarmonyPatch(typeof(RadialBase), "ConstructRadial")] [HarmonyPrefix] private static void Menu(RadialBase __instance, List<RadialMenuElement> elements) { if (!(__instance.CurrentConfig is ValheimRadialConfig) || elements == null) { return; } Plugin instance = Plugin.Instance; if (instance != null && instance.Birds?.CanUse == true) { GroupElement val = Object.Instantiate<GroupElement>(RadialData.SO.GroupElement); ((Object)val).name = "HearthSort Bird Toggle"; val.Init((IRadialConfig)(object)new BirdCaption(), (IRadialConfig)null, __instance); ((RadialMenuElement)val).Interact = delegate { Plugin instance2 = Plugin.Instance; return instance2 != null && instance2.Birds?.RequestToggle() == true; }; ((RadialMenuElement)val).CloseOnInteract = () => true; int num = elements.FindLastIndex((RadialMenuElement element) => element is EmptyElement); if (num >= 0) { Object.Destroy((Object)(object)((Component)elements[num]).gameObject); elements[num] = (RadialMenuElement)(object)val; } else { elements.Add((RadialMenuElement)(object)val); } } } [HarmonyPatch(typeof(Player), "SetControls")] [HarmonyPrefix] private static void Controls(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) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && BirdForm.IsActive((Character)(object)__instance)) { BirdForm.For(__instance).Controls(ref movedir, jump, crouch); attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = (jump = (crouch = (run = (autoRun = (dodge = false)))))))))); } } [HarmonyPatch(typeof(Character), "UpdateMotion")] [HarmonyPrefix] private static bool Motion(Character __instance, float dt) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && BirdForm.IsActive(__instance)) { return BirdForm.For((Player)__instance).Motion(dt); } return true; } [HarmonyPatch(typeof(Character), "CustomFixedUpdate")] [HarmonyPrefix] private static void PrepareVisual(Character __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown if (BirdForm.IsActive(__instance)) { BirdForm.For((Player)__instance); } } [HarmonyPatch(typeof(Character), "CustomFixedUpdate")] [HarmonyPostfix] private static void Energy(Character __instance, float dt) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { Plugin.Instance?.Energy?.Tick((Player)__instance, dt); } } [HarmonyPatch(typeof(Player), "Save")] [HarmonyPrefix] private static void SaveEnergy(Player __instance) { Plugin.Instance?.Energy?.Save(__instance); } [HarmonyPatch(typeof(Character), "UpdateGroundContact")] [HarmonyPrefix] private static void SafeBirdLanding(Character __instance, ref float ___m_maxAirAltitude) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (BirdForm.IsActive(__instance)) { ___m_maxAirAltitude = ((Component)__instance).transform.position.y; } } [HarmonyPatch(typeof(EnemyHud), "TestShow")] [HarmonyPrefix] private static bool Nameplate(Character c, ref bool __result) { if (!BirdForm.IsActive(c)) { return true; } __result = false; return false; } [HarmonyPatch(typeof(Player), "GetHoverName")] [HarmonyPostfix] private static void HoverName(Player __instance, ref string __result) { if (BirdForm.IsActive((Character)(object)__instance)) { __result = ""; } } [HarmonyPatch(typeof(Player), "GetHoverText")] [HarmonyPostfix] private static void HoverText(Player __instance, ref string __result) { if (BirdForm.IsActive((Character)(object)__instance)) { __result = ""; } } [HarmonyPatch(typeof(Player), "PlayerAttackInput")] [HarmonyPrefix] private static bool Attack(Player __instance) { return !BirdForm.IsActive((Character)(object)__instance); } [HarmonyPatch(typeof(Player), "Interact")] [HarmonyPrefix] private static bool Interact(Player __instance) { return !BirdForm.IsActive((Character)(object)__instance); } } internal sealed class ChestWindow { private sealed class Row { internal GameObject Object; internal Image Icon; internal Image Background; internal Image Accent; internal Text Name; internal Text State; internal Toggle Accept; internal Button Delete; internal int Index; internal string Id; } private const float Width = 720f; private const float Height = 680f; private const float RowHeight = 76f; private const float ViewHeight = 326f; private const float RowWidth = 638f; private static readonly Vector2 TopLeft = new Vector2(0f, 1f); private static readonly Color Ink = new Color(0.95f, 0.92f, 0.83f); private static readonly Color Muted = new Color(0.77f, 0.75f, 0.69f); private static readonly Color Gold = new Color(0.94f, 0.73f, 0.36f); private Container observed; private Container target; private GameObject panel; private GameObject openButton; private GameObject backdrop; private Text count; private Text status; private Text empty; private Text modeHint; private Image modeAccent; private Toggle distributor; private ScrollRect scroll; private RectTransform content; private Rules rules; private string encoded; private readonly List<Row> pool = new List<Row>(); private readonly List<string> ordered = new List<string>(); private bool binding; private bool blocked; private float nextRefresh; internal int EscapeFrame = -1; internal bool IsOpen => Object.op_Implicit((Object)(object)panel); internal void Observe(Container chest) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_0107: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) Close(); observed = chest; if (Object.op_Implicit((Object)(object)openButton)) { Object.Destroy((Object)(object)openButton); } openButton = null; if (!GameState.Supported(chest) || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront) || !Object.op_Implicit((Object)(object)InventoryGui.instance)) { return; } Plugin.Instance.Registry.Register(chest); object? value = AccessTools.Field(typeof(InventoryGui), "m_takeAllButton").GetValue(InventoryGui.instance); Button val = (Button)((value is Button) ? value : null); if (Object.op_Implicit((Object)(object)val)) { openButton = Object.Instantiate<GameObject>(((Component)val).gameObject, (Transform)(object)InventoryGui.instance.m_container, false); ((Object)openButton).name = "HearthSort Chest Rules"; Button component = openButton.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ((UnityEvent)component.onClick).AddListener(new UnityAction(Open)); ((Selectable)component).interactable = true; RectTransform component2 = openButton.GetComponent<RectTransform>(); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 1f); component2.anchorMax = val2; component2.anchorMin = val2; component2.pivot = new Vector2(0f, 1f); component2.anchoredPosition = new Vector2(10f, -10f); component2.sizeDelta = new Vector2(140f, 36f); Text componentInChildren = openButton.GetComponentInChildren<Text>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.text = "Chest rules"; componentInChildren.supportRichText = false; } TMP_Text componentInChildren2 = openButton.GetComponentInChildren<TMP_Text>(true); if (Object.op_Implicit((Object)(object)componentInChildren2)) { componentInChildren2.text = "Chest rules"; } UITooltip component3 = openButton.GetComponent<UITooltip>(); if (Object.op_Implicit((Object)(object)component3)) { component3.m_text = "Manage this chest's learned items."; } openButton.SetActive(true); } } private void Open() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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_0236: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)observed) || (Object)(object)Patches.Current(InventoryGui.instance) != (Object)(object)observed || !Editable(observed) || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { return; } Close(); target = observed; target.SetInUse(true); backdrop = new GameObject("Hearth Sort modal backdrop", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = backdrop.GetComponent<RectTransform>(); ((Transform)component).SetParent(GUIManager.CustomGUIFront.transform, false); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; Vector2 offsetMin = (component.offsetMax = Vector2.zero); component.offsetMin = offsetMin; Image component2 = backdrop.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.25f); ((Graphic)component2).raycastTarget = true; panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 720f, 680f, false); ((Object)panel).name = "Hearth Sort Chest Rules"; Surface(panel.transform, "Reading tint", 12f, 12f, 696f, 656f, new Color(0.1f, 0.08f, 0.055f, 0.48f)); Label(panel.transform, "Chest rules", 32f, 25f, 470f, 42f, 30, Ink, bold: true, (TextAnchor)3); MakeButton(panel.transform, "Close", 600f, 30f, 88f, Close); Label(panel.transform, Localization.instance.Localize(target.m_name), 34f, 70f, 580f, 28f, 18, Gold, bold: false, (TextAnchor)3); Surface(panel.transform, "Header divider", 34f, 106f, 652f, 1f, new Color(Gold.r, Gold.g, Gold.b, 0.22f)); Surface(panel.transform, "Header accent", 34f, 105f, 72f, 2f, new Color(Gold.r, Gold.g, Gold.b, 0.7f)); Surface(panel.transform, "Chest mode inset", 32f, 120f, 656f, 78f, new Color(0.035f, 0.03f, 0.022f, 0.45f)); modeAccent = Surface(panel.transform, "Chest mode accent", 32f, 120f, 3f, 78f, Muted); distributor = MakeToggle(panel.transform, 45f, 135f); Label(panel.transform, "Use as distributor", 92f, 128f, 560f, 34f, 20, Ink, bold: true, (TextAnchor)3); modeHint = Label(panel.transform, "", 92f, 165f, 560f, 24f, 15, Muted, bold: false, (TextAnchor)3); Tooltip(((Component)distributor).gameObject, "Send this chest's contents to nearby accepting chests when you close it."); ((UnityEvent<bool>)(object)distributor.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value) { if (!binding) { Edit(checked(delegate(Rules r) { r.Distributor = value; r.Revision++; })); } }); Label(panel.transform, "ACCEPTED ITEMS", 34f, 212f, 330f, 26f, 15, Ink, bold: true, (TextAnchor)3); count = Label(panel.transform, "", 414f, 212f, 270f, 26f, 14, Muted, bold: false, (TextAnchor)5); Label(panel.transform, "Item", 112f, 242f, 380f, 20f, 13, Muted, bold: false, (TextAnchor)3); Label(panel.transform, "Accept", 554f, 242f, 56f, 20f, 13, Muted, bold: false, (TextAnchor)4); Label(panel.transform, "Forget", 616f, 242f, 52f, 20f, 13, Muted, bold: false, (TextAnchor)4); BuildScroll(); Label(panel.transform, "Mouse wheel to scroll", 34f, 600f, 420f, 20f, 13, Muted, bold: false, (TextAnchor)3); Label(panel.transform, "Esc to close", 520f, 600f, 166f, 20f, 13, Muted, bold: false, (TextAnchor)5); Surface(panel.transform, "Footer divider", 34f, 625f, 652f, 1f, new Color(Gold.r, Gold.g, Gold.b, 0.18f)); status = Label(panel.transform, "Toggle to pause acceptance. X forgets an item.", 34f, 636f, 652f, 24f, 14, Muted, bold: false, (TextAnchor)3); Read(force: true); Scale(); GUIManager.BlockInput(true); blocked = true; EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)distributor).gameObject); } } internal void Close() { if (Object.op_Implicit((Object)(object)panel)) { Object.Destroy((Object)(object)panel); } if (Object.op_Implicit((Object)(object)backdrop)) { Object.Destroy((Object)(object)backdrop); } backdrop = null; panel = null; target = null; pool.Clear(); ordered.Clear(); scroll = null; content = null; rules = null; modeHint = null; modeAccent = null; if (blocked) { GUIManager.BlockInput(false); } blocked = false; EscapeFrame = Time.frameCount; } internal void Update() { //IL_00ac: 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) if (Object.op_Implicit((Object)(object)observed) && (!Object.op_Implicit((Object)(object)InventoryGui.instance) || (Object)(object)Patches.Current(InventoryGui.instance) != (Object)(object)observed)) { Observe(null); } if (!Object.op_Implicit((Object)(object)panel)) { if (Object.op_Implicit((Object)(object)observed) && Input.GetKeyDown((KeyCode)289)) { Open(); } return; } if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || ((Character)Player.m_localPlayer).IsDead() || !Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront) || !Editable(target) || Vector3.Distance(((Component)Player.m_localPlayer).transform.position, ((Component)target).transform.position) > 5f) { Close(); return; } if (Input.GetKeyDown((KeyCode)27) || ZInput.GetButtonDown("JoyButtonB")) { Close(); return; } Scale(); if (Time.unscaledTime >= nextRefresh) { nextRefresh = Time.unscaledTime + 0.25f; Read(force: false); } } private static bool Editable(Container c) { if (GameState.Supported(c) && c.IsOwner() && GameState.LocalAccess(c)) { return !Patches.Locked(c); } return false; } private void Scale() { //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_001b: 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) Rect rect = GUIManager.CustomGUIFront.GetComponent<RectTransform>().rect; panel.transform.localScale = Vector3.one * Mathf.Min(1f, Mathf.Min(((Rect)(ref rect)).width / 744f, ((Rect)(ref rect)).height / 704f)); } private void Read(bool force) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) string text = GameState.Encoded(GameState.Data(target)); if (!force && text == encoded) { return; } try { rules = Rules.Decode(text); encoded = text; ordered.Clear(); ordered.AddRange(rules.Items.Keys.OrderBy<string, string>(Name, StringComparer.CurrentCultureIgnoreCase).ThenBy<string, string>((string id) => id, StringComparer.Ordinal)); binding = true; distributor.SetIsOnWithoutNotify(rules.Distributor); binding = false; modeHint.text = (rules.Distributor ? "Distributes to nearby accepting chests when closed." : "Receives items matching the enabled rules below."); ((Graphic)modeAccent).color = (Color)(rules.Distributor ? Gold : new Color(0.55f, 0.49f, 0.36f, 0.7f)); count.text = ordered.Count + " entries"; ((Component)empty).gameObject.SetActive(ordered.Count == 0); content.sizeDelta = new Vector2(638f, Mathf.Max(314f, (float)ordered.Count * 76f)); Rect rect = content.rect; float height = ((Rect)(ref rect)).height; rect = scroll.viewport.rect; float num = Mathf.Max(0f, height - ((Rect)(ref rect)).height); content.anchoredPosition = new Vector2(0f, Mathf.Clamp(content.anchoredPosition.y, 0f, num)); scroll.StopMovement(); Render(); } catch (Exception e) { binding = false; status.text = "Chest rules could not be read. Saved data was preserved."; Plugin.Instance.Error("Acceptance list", e); } } private bool Edit(Action<Rules> change) { if (!Editable(target)) { status.text = "Chest ownership changed. Reopen chest rules to edit."; return false; } ZDO val = GameState.Data(target); if (GameState.Encoded(val) != encoded) { Read(force: true); status.text = "Rules changed. Please try again."; return false; } try { Rules rules = Rules.Decode(encoded); change(rules); string text = rules.Encode(); val.Set("hearthsort.rules.v1", text); if (GameState.Encoded(val) != text) { throw new InvalidOperationException("Rule write did not persist."); } Plugin.Instance.Network.Publish(val); Read(force: true); return true; } catch (Exception e) { Read(force: true); status.text = "Could not save that edit. Please try again."; Plugin.Instance.Error("Rule edit", e); return false; } } private void BuildScroll() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0188: 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_01a9: 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_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0552: Unknown result type (might be due to invalid IL or missing references) //IL_0560: Unknown result type (might be due to invalid IL or missing references) Image val = Surface(panel.transform, "Inset border", 28f, 264f, 664f, 326f, new Color(0.43f, 0.36f, 0.23f, 0.8f)); Surface(((Component)val).transform, "Inset", 1f, 1f, 662f, 324f, new Color(0.055f, 0.048f, 0.035f, 0.98f)); Image val2 = Surface(((Component)val).transform, "Viewport", 6f, 6f, 638f, 314f, Color.clear); ((Graphic)val2).raycastTarget = true; ((Component)val2).gameObject.AddComponent<RectMask2D>(); content = Rect(((Component)val2).transform, "Rows", 0f, 0f, 638f, 326f); empty = Label(((Component)val2).transform, "No items learned yet.\nPut an example item in this chest to teach it.", 14f, 20f, 610f, 64f, 18, Muted, bold: false, (TextAnchor)3); Image obj = Surface(((Component)val).transform, "Scroll track", 650f, 6f, 10f, 314f, new Color(0.18f, 0.16f, 0.12f)); ((Graphic)obj).raycastTarget = true; Image val3 = Surface(((Component)obj).transform, "Scroll thumb", 0f, 0f, 10f, 314f, new Color(0.66f, 0.55f, 0.35f)); ((Graphic)val3).rectTransform.anchorMin = Vector2.zero; ((Graphic)val3).rectTransform.anchorMax = Vector2.one; RectTransform rectTransform = ((Graphic)val3).rectTransform; Vector2 offsetMin = (((Graphic)val3).rectTransform.offsetMax = Vector2.zero); rectTransform.offsetMin = offsetMin; ((Graphic)val3).raycastTarget = true; Scrollbar val4 = ((Component)obj).gameObject.AddComponent<Scrollbar>(); val4.handleRect = ((Graphic)val3).rectTransform; ((Selectable)val4).targetGraphic = (Graphic)(object)val3; val4.direction = (Direction)2; scroll = ((Component)val).gameObject.AddComponent<ScrollRect>(); scroll.viewport = ((Graphic)val2).rectTransform; scroll.content = content; scroll.horizontal = false; scroll.vertical = true; scroll.inertia = false; scroll.movementType = (MovementType)2; scroll.scrollSensitivity = 360f; scroll.verticalScrollbar = val4; scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0; ((UnityEvent<Vector2>)(object)scroll.onValueChanged).AddListener((UnityAction<Vector2>)delegate { Render(); }); for (int num = 0; num < 8; num++) { Row row = new Row(); Image val5 = Surface((Transform)(object)content, "Acceptance row", 0f, 0f, 638f, 71f, new Color(0.09f, 0.095f, 0.085f, 0.96f)); row.Object = ((Component)val5).gameObject; row.Background = val5; row.Accent = Surface(((Component)val5).transform, "Acceptance accent", 0f, 8f, 2f, 55f, Gold); row.Icon = Surface(((Component)val5).transform, "Item icon", 14f, 12f, 46f, 46f, Color.white); row.Icon.preserveAspect = true; row.Name = Label(((Component)val5).transform, "", 78f, 4f, 431f, 46f, 20, Ink, bold: true, (TextAnchor)3); row.Name.supportRichText = false; row.Name.verticalOverflow = (VerticalWrapMode)0; ((Graphic)row.Name).raycastTarget = true; ((Component)row.Name).gameObject.AddComponent<UITooltip>(); row.State = Label(((Component)val5).transform, "", 78f, 53f, 420f, 16f, 12, Muted, bold: false, (TextAnchor)3); row.Accept = MakeToggle(((Component)val5).transform, 529f, 18f); row.Delete = MakeButton(((Component)val5).transform, "X", 587f, 18f, 40f, delegate { Delete(row); }); Tooltip(((Component)row.Accept).gameObject, "Enable or pause acceptance. Paused items stay on the list."); Tooltip(((Component)row.Delete).gameObject, "Forget this item completely. Stored items stay in the chest."); ((UnityEvent<bool>)(object)row.Accept.onValueChanged).AddListener((UnityAction<bool>)delegate(bool value) { if (!binding && row.Id != null) { string id = row.Id; if (Edit(delegate(Rules r) { r.Enable(id, value); })) { status.text = Name(id) + (value ? ": acceptance enabled." : ": acceptance paused."); } } }); Selectable[] array = (Selectable[])(object)new Selectable[2] { (Selectable)row.Accept, (Selectable)row.Delete }; foreach (Selectable val6 in array) { Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; val6.navigation = navigation; AcceptanceNavigation acceptanceNavigation = ((Component)val6).gameObject.AddComponent<AcceptanceNavigation>(); acceptanceNavigation.Window = this; acceptanceNavigation.RowIndex = () => row.Index; acceptanceNavigation.DeleteColumn = (Object)(object)val6 == (Object)(object)row.Delete; } pool.Add(row); } } private void Render() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)content) || rules == null) { return; } int num = Math.Max(0, (int)(content.anchoredPosition.y / 76f) - 1); binding = true; foreach (Row item in pool) { int num2 = (item.Index = num++); item.Id = ((num2 < ordered.Count) ? ordered[num2] : null); item.Object.SetActive(item.Id != null); if (item.Id != null) { item.Object.GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, (float)(-num2) * 76f); item.Name.text = Name(item.Id); ((Component)item.Name).GetComponent<UITooltip>().m_text = item.Name.text; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Id); ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); item.Icon.sprite = (Object.op_Implicit((Object)(object)val) ? val.m_itemData.GetIcon() : null); ((Graphic)item.Icon).color = (Color)(Object.op_Implicit((Object)(object)item.Icon.sprite) ? Color.white : new Color(0.6f, 0.57f, 0.48f, 0.25f)); bool flag = rules.Items[item.Id]; item.Accept.SetIsOnWithoutNotify(flag); item.State.text = (flag ? "Accepting" : "Paused"); ((Graphic)item.Background).color = ((num2 % 2 == 0) ? new Color(0.105f, 0.093f, 0.072f, 0.96f) : new Color(0.078f, 0.07f, 0.056f, 0.96f)); ((Graphic)item.Accent).color = (flag ? new Color(Gold.r, Gold.g, Gold.b, 0.5f) : new Color(Muted.r, Muted.g, Muted.b, 0.22f)); ((Graphic)item.Name).color = (flag ? Ink : Muted); ((Graphic)item.State).color = (Color)(flag ? new Color(0.77f, 0.67f, 0.46f) : Muted); if (!flag && Object.op_Implicit((Object)(object)item.Icon.sprite)) { ((Graphic)item.Icon).color = new Color(0.7f, 0.7f, 0.7f, 0.85f); } } } binding = false; } private void Delete(Row row) { string id = row.Id; int index = row.Index; if (id == null || !Edit(delegate(Rules r) { r.Delete(id); })) { return; } status.text = Name(id) + " removed. Stored items are unchanged."; if (ordered.Count > 0) { Select(Math.Min(index, ordered.Count - 1), delete: false); return; } EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(((Component)distributor).gameObject); } } internal void Navigate(int index, bool delete, MoveDirection direction) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 if ((int)direction == 1) { Select(Math.Max(0, index - 1), delete); } else if ((int)direction == 3) { Select(Math.Min(ordered.Count - 1, index + 1), delete); } else if ((int)direction == 0) { Select(index, delete: false); } else if ((int)direction == 2) { Select(index, delete: true); } } private void Select(int index, bool delete) { //IL_0030: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (index < 0 || index >= ordered.Count) { return; } float num = content.anchoredPosition.y; float num2 = (float)index * 76f; if (num2 < num) { num = num2; } else { float num3 = num2 + 76f; float num4 = num; Rect rect = scroll.viewport.rect; if (num3 > num4 + ((Rect)(ref rect)).height) { float num5 = num2 + 76f; rect = scroll.viewport.rect; num = num5 - ((Rect)(ref rect)).height; } } content.anchoredPosition = new Vector2(0f, num); Render(); Row row = pool.FirstOrDefault((Row r) => r.Index == index); if (row != null) { EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject(delete ? ((Component)row.Delete).gameObject : ((Component)row.Accept).gameObject); } } } private static string Name(string id) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(id) : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { return id; } return Localization.instance.Localize(val2.m_itemData.m_shared.m_name); } private static Toggle MakeToggle(Transform parent, float x, float y) { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) GameObject obj = GUIManager.Instance.CreateToggle(parent, 30f, 30f); RectTransform component = obj.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = (component.pivot = TopLeft); Vector2 anchorMin = (component.anchorMax = val); component.anchorMin = anchorMin; component.anchoredPosition = new Vector2(x, 0f - y); component.sizeDelta = new Vector2(36f, 36f); Transform val3 = obj.transform.Find("Label"); if (Object.op_Implicit((Object)(object)val3)) { ((Component)val3).gameObject.SetActive(false); } Transform obj2 = obj.transform.Find("Background"); RectTransform val4 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if (Object.op_Implicit((Object)(object)val4)) { ((Vector2)(ref val))..ctor(0.5f, 0.5f); val4.pivot = val; anchorMin = (val4.anchorMax = val); val4.anchorMin = anchorMin; val4.anchoredPosition = Vector2.zero; val4.sizeDelta = new Vector2(30f, 30f); } return obj.GetComponent<Toggle>(); } private static Button MakeButton(Transform parent, string text, float x, float y, float width, Action action) { //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_0031: 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: Expected O, but got Unknown Button component = GUIManager.Instance.CreateButton(text, parent, TopLeft, TopLeft, new Vector2(x + width / 2f, 0f - y - 18f), width, 36f).GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { action(); }); Button val = (Button)(Object.op_Implicit((Object)(object)InventoryGui.instance) ? /*isinst with value type is only supported in some contexts*/: null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((Selectable)val).image)) { ((Graphic)((Selectable)component).image).material = ((Graphic)((Selectable)val).image).material; } return component; } private static void Tooltip(GameObject control, string text) { (control.GetComponent<UITooltip>() ?? control.AddComponent<UITooltip>()).m_text = text; } private static RectTransform Rect(Transform parent, string name, float x, float y, float width, float height) { //IL_0014: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); Vector2 val = (component.pivot = TopLeft); Vector2 anchorMin = (component.anchorMax = val); component.anchorMin = anchorMin; component.anchoredPosition = new Vector2(x, 0f - y); component.sizeDelta = new Vector2(width, height); return component; } private static Image Surface(Transform parent, string name, float x, float y, float width, float height, Color color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)Rect(parent, name, x, y, width, height)).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; return obj; } private static Text Label(Transform parent, string text, float x, float y, float width, float height, int size, Color color, bool bold = false, TextAnchor alignment = (TextAnchor)3) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) Text component = GUIManager.Instance.CreateText(text, parent, TopLeft, TopLeft, new Vector2(x + width / 2f, 0f - y - height / 2f), bold ? GUIManager.Instance.AveriaSerifBold : GUIManager.Instance.AveriaSerif, size, color, false, Color.black, width, height, false).GetComponent<Text>(); component.alignment = alignment; ((Graphic)component).raycastTarget = false; component.horizontalOverflow = (HorizontalWrapMode)0; return component; } } public sealed class AcceptanceNavigation : MonoBehaviour, IMoveHandler, IEventSystemHandler { internal ChestWindow Window; internal Func<int> RowIndex; internal bool DeleteColumn; public void OnMove(AxisEventData data) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) Window.Navigate(RowIndex(), DeleteColumn, data.moveDir); ((AbstractEventData)data).Use(); } } internal static class GameState { internal const string RulesKey = "hearthsort.rules.v1"; private static readonly int PersonalChest = StringExtensionMethods.GetStableHashCode("piece_chest_private"); internal static readonly MethodInfo Load = AccessTools.Method(typeof(Container), "Load", Type.EmptyTypes, (Type[])null); internal static readonly MethodInfo Save = AccessTools.Method(typeof(Container), "Save", Type.EmptyTypes, (Type[])null); internal static readonly MethodInfo Changed = AccessTools.Method(typeof(Inventory), "Changed", new Type[2] { typeof(bool), typeof(bool) }, (Type[])null); private static readonly FieldInfo LastRevision = AccessTools.Field(typeof(Container), "m_lastRevision"); internal static ZNetView View(Container chest) { if (!Object.op_Implicit((Object)(object)chest)) { return null; } return ((Component)chest).GetComponent<ZNetView>(); } internal static ZDO Data(Container chest) { ZNetView obj = View(chest); if (obj == null) { return null; } return obj.GetZDO(); } internal static Container Template(ZDO z) { if (z == null || !Object.op_Implicit((Object)(object)ZNetScene.instance)) { return null; } GameObject prefab = ZNetScene.instance.GetPrefab(z.GetPrefab()); if (prefab == null) { return null; } return prefab.GetComponent<Container>(); } private static bool SharedStorage(Container chest, int prefab) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (Object.op_Implicit((Object)(object)chest)) { return StoragePolicy.Eligible((int)chest.m_privacy == 2, Object.op_Implicit((Object)(object)((Component)chest).GetComponent<Piece>()), Object.op_Implicit((Object)(object)((Component)chest).GetComponent<ZNetView>()), prefab == PersonalChest, Object.op_Implicit((Object)(object)chest.m_rootObjectOverride) || Object.op_Implicit((Object)(object)chest.m_wagon) || Object.op_Implicit((Object)(object)((Component)chest).GetComponent<Vagon>()) || Object.op_Implicit((Object)(object)((Component)chest).GetComponent<Ship>()), chest.m_autoDestroyEmpty || Object.op_Implicit((Object)(object)((Component)chest).GetComponent<TombStone>())); } return false; } internal static bool Supported(ZDO z) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (z == null || !z.IsValid() || !SharedStorage(Template(z), z.GetPrefab())) { return false; } Container val = Plugin.Instance?.Registry?.Find(z.m_uid); if (Object.op_Implicit((Object)(object)val)) { if (SharedStorage(val, z.GetPrefab())) { return val.GetInventory() != null; } return false; } return true; } internal static bool Supported(Container chest) { ZDO val = Data(chest); if (val != null && SharedStorage(chest, val.GetPrefab()) && Supported(val)) { return chest.GetInventory() != null; } return false; } internal static string Encoded(ZDO z) { return z.GetString("hearthsort.rules.v1", ""); } internal static Rules Read(ZDO z) { return Rules.Decode(Encoded(z)); } internal static bool InUse(Container c) { if (!c.IsInUse()) { ZDO obj = Data(c); if (obj == null) { return true; } return obj.GetInt(ZDOVars.s_inUse, 0) != 0; } return true; } internal static void Refresh(Container c) { if (Supported(c) && !c.IsInUse()) { Load.Invoke(c, null); } } internal static void Install(Container c, byte[] bytes) { Snapshot snapshot = Snapshot.Read(bytes, c.GetInventory().GetWidth(), c.GetInventory().GetHeight()); List<ItemData> allItems = c.GetInventory().GetAllItems(); allItems.Clear(); allItems.AddRange(snapshot.Materialize(snapshot.Stock)); LastRevision.SetValue(c, Data(c).DataRevision); Changed.Invoke(c.GetInventory(), new object[2] { false, false }); } internal static bool LocalAccess(Container chest) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!Supported(chest) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return false; } if (chest.m_checkGuardStone) { return PrivateArea.CheckAccess(((Component)chest).transform.position, 0f, false, false); } return true; } internal static bool Same(byte[] a, byte[] b) { if (a != null && b != null) { return ((ReadOnlySpan<byte>)a).SequenceEqual((ReadOnlySpan<byte>)b); } return false; } } internal sealed class Snapshot { internal readonly List<Stock> Stock = new List<Stock>(); private readonly Dictionary<string, ItemData> templates = new Dictionary<string, ItemData>(); private readonly Dictionary<string, byte[]> records = new Dictionary<string, byte[]>(); internal int Width; internal int Height; internal static Snapshot Read(byte[] bytes, int width, int height) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) if (bytes == null || bytes.Length > 1048576 || width < 1 || height < 1 || width > 256 || height > 256 || width * height > 1024) { throw new InvalidDataException("Unsupported inventory size."); } Snapshot snapshot = new Snapshot { Width = width, Height = height }; ZPackage val = new ZPackage(bytes); int num = val.ReadInt(); if (num != 109) { throw new InvalidDataException("This chest uses an older or unsupported inventory format. Open it normally first."); } int num2 = val.ReadUShort(); if (num2 > 1024) { throw new InvalidDataException("Too many item records."); } HashSet<Vector2i> hashSet = new HashSet<Vector2i>(); for (int i = 0; i < num2; i++) { int pos = val.GetPos(); (int, ItemData) tuple = ItemData.Load(val, (Item)num); byte[] array = new byte[val.GetPos() - pos]; Array.Copy(bytes, pos, array, 0, array.Length); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(tuple.Item1); ItemDrop val2 = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val2)) { throw new InvalidDataException("An item is missing on the server; contents were preserved."); } ItemData item = tuple.Item2; item.m_dropPrefab = itemPrefab; item.m_shared = val2.m_itemData.m_shared; if (item.m_stack <= 0 || item.m_stack > 65535 || item.m_gridPos.x < 0 || item.m_gridPos.y < 0 || item.m_gridPos.x >= width || item.m_gridPos.y >= height || !hashSet.Add(item.m_gridPos)) { throw new InvalidDataException("Unsupported or overlapping chest slots; contents were preserved."); } string text = Convert.ToBase64String(ItemRecord.Place(array, 1, 0, 0)); snapshot.templates[text] = item; snapshot.records[text] = array; snapshot.Stock.Add(new Stock { Id = ((Object)itemPrefab).name, Fingerprint = text, Quantity = item.m_stack, Limit = Math.Min(65535, item.m_shared.m_maxStackSize), X = item.m_gridPos.x, Y = item.m_gridPos.y }); } if (val.GetPos() != bytes.Length) { throw new InvalidDataException("Unexpected inventory data."); } return snapshot; } internal void Include(Snapshot other) { foreach (KeyValuePair<string, ItemData> template in other.templates) { if (!templates.ContainsKey(template.Key)) { templates.Add(template.Key, template.Value); records.Add(template.Key, other.records[template.Key]); } } } internal IEnumerable<ItemData> Materialize(IEnumerable<Stock> stocks) { foreach (Stock stock in stocks) { ItemData val = templates[stock.Fingerprint].Clone(); val.m_stack = stock.Quantity; val.m_gridPos = new Vector2i(stock.X, stock.Y); yield return val; } } internal byte[] Encode(IEnumerable<Stock> stocks) { Stock[] array = stocks.ToArray(); using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(109); binaryWriter.Write((ushort)array.Length); Stock[] array2 = array; foreach (Stock stock in array2) { binaryWriter.Write(ItemRecord.Place(records[stock.Fingerprint], stock.Quantity, stock.X, stock.Y)); } binaryWriter.Flush(); return memoryStream.ToArray(); } } internal sealed class ChestRegistry { private ZDOMan registeredWorld; private const float CellSize = 20f; private readonly Dictionary<ZDOID, Container> chests = new Dictionary<ZDOID, Container>(); private readonly Dictionary<(int, int), HashSet<ZDOID>> cells = new Dictionary<(int, int), HashSet<ZDOID>>(); private readonly Dictionary<ZDOID, (int, int)> positions = new Dictionary<ZDOID, (int, int)>(); internal Container Find(ZDOID id) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!chests.TryGetValue(id, out var value) || !Object.op_Implicit((Object)(object)value)) { return null; } return value; } private static (int, int) Cell(Vector3 p) { //IL_0000: 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) return ((int)Math.Floor(p.x / 20f), (int)Math.Floor(p.z / 20f)); }