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 RavenPost v1.2.1
plugins/RavenPost.dll
Decompiled 16 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.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("RavenPost")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.1.0")] [assembly: AssemblyInformationalVersion("1.2.1+8d1a4f08d0304d348a00e83ec809b52a9c363672")] [assembly: AssemblyProduct("RavenPost")] [assembly: AssemblyTitle("RavenPost")] [assembly: AssemblyVersion("1.2.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RavenPost { internal static class LetterItem { private class LetterWriter : TextReceiver { private readonly Player _player; private readonly ItemData _item; private readonly bool _reopen; public LetterWriter(Player player, ItemData item, bool reopen) { _player = player; _item = item; _reopen = reopen; } public string GetText() { return LetterItem.GetText(_item).Replace("\n", "\\n"); } public void SetText(string text) { if (Object.op_Implicit((Object)(object)_player) && ((Humanoid)_player).GetInventory().ContainsItem(_item)) { LetterItem.SetText(_item, text, _player.GetPlayerName()); ((Character)_player).Message((MessageType)2, string.IsNullOrEmpty(text) ? "Letter cleared" : "Letter written", 0, (Sprite)null, false); if (_reopen && Object.op_Implicit((Object)(object)InventoryGui.instance)) { InventoryGui.instance.Show((Container)null, 1); } } } } public const string PrefabName = "RavenLetter"; public const int MaxLength = 500; private const string TextKey = "ravenpost_text"; private const string AuthorKey = "ravenpost_author"; private const string DayKey = "ravenpost_day"; private const string FromKey = "ravenpost_from"; private const string AuthorIdKey = "ravenpost_authorid"; private const string ReadOnlyId = "locked"; private static SharedData s_shared; private static string LocalPlayerId() { if (!Object.op_Implicit((Object)(object)Game.instance)) { return ""; } return Game.instance.GetPlayerProfile().GetPlayerID().ToString(); } public static bool CanEdit(ItemData item) { if (!item.m_customData.TryGetValue("ravenpost_authorid", out var value) || string.IsNullOrEmpty(value)) { return true; } if (value != "locked") { return value == LocalPlayerId(); } return false; } public static void Register() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown ItemConfig val = new ItemConfig(); val.Name = "Letter"; val.Description = "Write on it, keep it as a journal, or send it with a raven."; val.CraftingStation = "piece_workbench"; val.Amount = 2; val.Icon = CreateIcon(); val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig("LeatherScraps", 1, 0, true), new RequirementConfig("Coal", 1, 0, true) }; ItemConfig val2 = val; CustomItem val3 = new CustomItem("RavenLetter", "LeatherScraps", val2); SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_maxStackSize = 1; shared.m_weight = 0.1f; shared.m_teleportable = true; s_shared = shared; ItemManager.Instance.AddItem(val3); } public static bool IsLetter(ItemData item) { if (item != null) { if (!Object.op_Implicit((Object)(object)item.m_dropPrefab) || !(((Object)item.m_dropPrefab).name == "RavenLetter")) { if (s_shared != null) { return item.m_shared == s_shared; } return false; } return true; } return false; } public static string GetText(ItemData item) { if (!item.m_customData.TryGetValue("ravenpost_text", out var value)) { return ""; } return value; } public static void SetText(ItemData item, string text, string author) { text = (text ?? "").Trim(); if (text.Length > 500) { text = text.Substring(0, 500); } item.m_customData["ravenpost_text"] = text; item.m_customData["ravenpost_author"] = author ?? ""; item.m_customData["ravenpost_day"] = RavenMail.Day(PostOffice.Now).ToString(); item.m_customData["ravenpost_authorid"] = ((text.Length > 0) ? LocalPlayerId() : ""); } public static string Tooltip(ItemData item) { string text = GetText(item); if (string.IsNullOrEmpty(text)) { return "\n\n<color=grey>Blank - use it to write.</color>"; } item.m_customData.TryGetValue("ravenpost_author", out var value); item.m_customData.TryGetValue("ravenpost_day", out var value2); item.m_customData.TryGetValue("ravenpost_from", out var value3); string text2 = (string.IsNullOrEmpty(value) ? "" : ("From " + value)); if (!string.IsNullOrEmpty(value3)) { text2 = text2 + " @ " + value3; } string text3 = (string.IsNullOrEmpty(value2) ? "" : ("Day " + value2)); string text4 = string.Join(", ", new string[2] { text2, text3 }.Where((string s) => s.Length > 0)); string value4; bool flag = item.m_customData.TryGetValue("ravenpost_authorid", out value4) && value4 == "locked"; string text5 = (CanEdit(item) ? "Use it to edit." : (flag ? "A kept letter can't be changed." : "Only the author can change it.")); return "\n\n<color=orange>" + text4 + "</color>\n<color=#e8dcc0>" + Escape(text) + "</color>\n\n<color=grey>" + text5 + "</color>"; } private static string Escape(string text) { return text.Replace("<", "<\u200b"); } public static bool GiveCopy(Player player, Letter letter) { GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab("RavenLetter") : null); ItemDrop val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)player) || !Object.op_Implicit((Object)(object)val2)) { return false; } ItemData val3 = val2.m_itemData.Clone(); val3.m_stack = 1; val3.m_dropPrefab = val; val3.m_customData["ravenpost_text"] = letter.Text ?? ""; val3.m_customData["ravenpost_author"] = letter.FromPlayer ?? ""; val3.m_customData["ravenpost_from"] = letter.From ?? ""; val3.m_customData["ravenpost_day"] = RavenMail.Day(letter.SentAt).ToString(); val3.m_customData["ravenpost_authorid"] = "locked"; Inventory inventory = ((Humanoid)player).GetInventory(); if (!inventory.CanAddItem(val3, -1) || !inventory.AddItem(val3)) { ((Character)player).Message((MessageType)2, "Your bag is full", 0, (Sprite)null, false); return false; } ((Character)player).Message((MessageType)2, "Letter added to your bag", 0, (Sprite)null, false); return true; } public static void OpenWriter(Player player, ItemData item) { if (!Object.op_Implicit((Object)(object)TextInput.instance)) { return; } if (!CanEdit(item)) { item.m_customData.TryGetValue("ravenpost_author", out var value); string value2; bool flag = item.m_customData.TryGetValue("ravenpost_authorid", out value2) && value2 == "locked"; ((Character)player).Message((MessageType)2, (flag || string.IsNullOrEmpty(value)) ? "This letter can't be changed" : ("Only " + value + " can change this letter"), 0, (Sprite)null, false); return; } bool flag2 = InventoryGui.IsVisible(); if (flag2) { InventoryGui.instance.Hide(); } TextInput.instance.RequestText((TextReceiver)(object)new LetterWriter(player, item, flag2), "Write your letter (type \\\u200bn for a new line)", 500); } private static Sprite CreateIcon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0206: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.87f, 0.78f, 0.58f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.62f, 0.5f, 0.32f); Color val5 = default(Color); ((Color)(ref val5))..ctor(0.55f, 0.41f, 0.24f); Color val6 = default(Color); ((Color)(ref val6))..ctor(0.72f, 0.57f, 0.36f); Color val7 = default(Color); ((Color)(ref val7))..ctor(0.25f, 0.17f, 0.1f); Color val8 = default(Color); ((Color)(ref val8))..ctor(0.66f, 0.1f, 0.08f); Color val9 = default(Color); ((Color)(ref val9))..ctor(0.85f, 0.25f, 0.18f); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { Color val10 = val2; if (j >= 12 && j <= 51 && i >= 9 && i <= 54) { val10 = ((j == 12 || j == 51) ? val4 : val3); if (j >= 17 && j <= 46 && (i == 42 || i == 36 || i == 30 || i == 24) && (i != 24 || j <= 36)) { val10 = val7; } } if (j >= 8 && j <= 55 && ((i >= 52 && i <= 58) || (i >= 5 && i <= 11))) { int num = ((i >= 52) ? 55 : 8); val10 = ((Mathf.Abs(i - num) <= 1) ? val6 : val5); } float num2 = j - 44; float num3 = i - 17; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); if (num4 <= 6.5f) { val10 = ((num4 <= 3f) ? val9 : val8); } val.SetPixel(j, i, val10); } } val.Apply(); ((Texture)val).filterMode = (FilterMode)1; return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f)); } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class ContainerHoverTextPatch { private static void Postfix(Container __instance, ref string __result) { RavenPerch component = ((Component)__instance).GetComponent<RavenPerch>(); if (Object.op_Implicit((Object)(object)component)) { __result += component.GetExtraHoverText(); } } } [HarmonyPatch(typeof(Game), "Start")] internal static class GameStartPatch { private static void Postfix() { RavenNet.Register(); } } [HarmonyPatch(typeof(Humanoid), "UseItem")] internal static class LetterUsePatch { private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item) { if (LetterItem.IsLetter(item)) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { if (inventory != null && inventory != ((Humanoid)val).GetInventory()) { return true; } LetterItem.OpenWriter(val, item); return false; } } return true; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class LetterTooltipPatch { private static void Postfix(ItemData item, ref string __result) { if (LetterItem.IsLetter(item)) { __result += LetterItem.Tooltip(item); } } } [HarmonyPatch(typeof(Container), "Awake")] internal static class ContainerAwakePatch { private static void Prefix(Container __instance) { if (Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<RavenPerch>())) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); ZDO val = (Object.op_Implicit((Object)(object)component) ? component.GetZDO() : null); int index = ((val != null) ? val.GetInt("ravenpost_tier", 0) : 0); RavenPerch.ApplyTier(__instance, PerchTiers.Get(index)); } } } [HarmonyPatch(typeof(Container), "UseItem")] internal static class ContainerUseItemPatch { private static bool Prefix(Container __instance, Humanoid user, ItemData item, ref bool __result) { RavenPerch component = ((Component)__instance).GetComponent<RavenPerch>(); if (Object.op_Implicit((Object)(object)component)) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null) { __result = component.Feed(val, item); return false; } } return true; } } [HarmonyPatch(typeof(Container), "CanBeRemoved")] internal static class ContainerCanBeRemovedPatch { private static void Postfix(Container __instance, ref bool __result) { if (__result && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<RavenPerch>())) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && PostOffice.ReadInbox(component.GetZDO()).Count > 0) { __result = false; } } } } internal static class PerchModel { private static readonly string[] s_poleCandidates = new string[3] { "wood_pole2", "wood_pole", "wood_pole_log" }; private const float PoleHeight = 1.7f; private const float PoleThickness = 0.2f; private const float BirdScale = 1f; public static void Decorate(GameObject perch) { //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_000e: Unknown result type (might be due to invalid IL or missing references) Bounds chestBounds = LocalBounds(perch, perch.transform); Vector3? poleTop = AddPole(perch, chestBounds); AddBird(perch, poleTop); } private static Vector3? AddPole(GameObject perch, Bounds chestBounds) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_018d: 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_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: 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_0206: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; string[] array = s_poleCandidates; foreach (string text in array) { val = PrefabManager.Instance.GetPrefab(text); if (Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogInfo((object)("Perch post uses prefab '" + text + "'")); break; } } if (!Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogWarning((object)"No wooden pole prefab found; perch keeps the plain chest look."); return null; } WearNTear component = val.GetComponent<WearNTear>(); GameObject val2 = Object.Instantiate<GameObject>((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_new)) ? component.m_new : val, perch.transform); ((Object)val2).name = "RavenPost_Pole"; val2.SetActive(true); MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; Bounds val3 = LocalBounds(val2, perch.transform); if (((Bounds)(ref val3)).size.y < 0.01f) { Object.DestroyImmediate((Object)(object)val2); return null; } float num = Mathf.Max(new float[3] { ((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.z, 0.01f }); float num2 = 0.2f / num; val2.transform.localScale = new Vector3(num2, 1.7f / ((Bounds)(ref val3)).size.y, num2); val3 = LocalBounds(val2, perch.transform); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(((Bounds)(ref chestBounds)).max.x + ((Bounds)(ref val3)).extents.x + 0.05f - ((Bounds)(ref val3)).center.x, ((Bounds)(ref chestBounds)).min.y - ((Bounds)(ref val3)).min.y, ((Bounds)(ref chestBounds)).center.z - ((Bounds)(ref val3)).center.z); Transform transform = val2.transform; transform.localPosition += val4; val3 = LocalBounds(val2, perch.transform); return new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).max.y, ((Bounds)(ref val3)).center.z); } private static void AddBird(GameObject perch, Vector3? poleTop) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) GameObject perchedTemplate = RavenFlight.PerchedTemplate; if (Object.op_Implicit((Object)(object)perchedTemplate)) { GameObject obj = Object.Instantiate<GameObject>(perchedTemplate, perch.transform); ((Object)obj).name = "RavenPost_PerchedRaven"; obj.SetActive(true); obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = perchedTemplate.transform.localScale * 1f; obj.transform.localPosition = Vector3.zero; Bounds val = LocalBounds(obj, perch.transform); Vector3 value = default(Vector3); if (poleTop.HasValue) { value = poleTop.Value; } else { Bounds val2 = LocalBounds(perch, perch.transform); ((Vector3)(ref value))..ctor(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).max.y, ((Bounds)(ref val2)).center.z); } obj.transform.localPosition = value - new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).min.y, ((Bounds)(ref val)).center.z); } } public static Bounds LocalBounds(GameObject part, Transform space) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) bool any = false; Bounds result = default(Bounds); Matrix4x4 toSpace = space.worldToLocalMatrix; MeshFilter[] componentsInChildren = part.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (Object.op_Implicit((Object)(object)((Component)val).GetComponent<MeshRenderer>()) && IsShown(((Component)val).transform, part.transform)) { Add(val.sharedMesh, ((Component)val).transform); } } SkinnedMeshRenderer[] componentsInChildren2 = part.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if (IsShown(((Component)val2).transform, part.transform)) { Add(val2.sharedMesh, ((Component)val2).transform); } } return result; void Add(Mesh mesh, Transform t) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)mesh)) { Matrix4x4 val3 = toSpace * t.localToWorldMatrix; Bounds bounds = mesh.bounds; for (int j = 0; j < 8; j++) { Vector3 val4 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))); Vector3 val5 = ((Matrix4x4)(ref val3)).MultiplyPoint3x4(val4); if (!any) { result = new Bounds(val5, Vector3.zero); any = true; } else { ((Bounds)(ref result)).Encapsulate(val5); } } } } } private static bool IsShown(Transform t, Transform root) { while (Object.op_Implicit((Object)(object)t) && (Object)(object)t != (Object)(object)root) { if (!((Component)t).gameObject.activeSelf) { return false; } t = t.parent; } return true; } } internal class PerchTier { public int Index; public string Name; public string Biome; public ConfigEntry<string> Cost; public ConfigEntry<int> Width; public ConfigEntry<int> Height; public ConfigEntry<float> Speed; public ConfigEntry<float> MaxWeight; public float SpeedMultiplier => Mathf.Max(0.1f, Speed.Value); public float CargoWeightLimit { get { if (!(MaxWeight.Value > 0f)) { return Mathf.Max(0f, Plugin.MaxCargoWeight.Value); } return MaxWeight.Value; } } public int CargoWidth => Mathf.Clamp(Width.Value, 1, 8); public int CargoHeight => Mathf.Clamp(Height.Value, 1, 10); public List<KeyValuePair<string, int>> Requirements() { List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(); string[] array = (Cost.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2 && int.TryParse(array2[1].Trim(), out var result) && result > 0 && array2[0].Trim().Length > 0) { list.Add(new KeyValuePair<string, int>(array2[0].Trim(), result)); } } return list; } public List<string> MissingItems() { return (from r in Requirements() select r.Key into name where PerchTiers.ItemData(name) == null select name).ToList(); } } internal static class PerchTiers { public const string TierKey = "ravenpost_tier"; private static readonly List<PerchTier> s_tiers = new List<PerchTier>(); public static IReadOnlyList<PerchTier> All => s_tiers; public static int Max => s_tiers.Count - 1; public static PerchTier Get(int index) { return s_tiers[Mathf.Clamp(index, 0, s_tiers.Count - 1)]; } public static void Bind(ConfigFile config) { Add(config, "Wooden Perch", "Meadows", "", 2, 2, 1f); Add(config, "Bronze Perch", "Black Forest", "Bronze:5,BronzeNails:10", 3, 2, 1.2f); Add(config, "Iron Perch", "Swamp", "Iron:10,Guck:5", 4, 2, 1.4f); Add(config, "Silver Perch", "Mountains", "Silver:10,WolfPelt:4", 5, 3, 1.7f); Add(config, "Black Metal Perch", "Plains", "BlackMetal:10,LinenThread:10", 6, 3, 2f); Add(config, "Eitr Perch", "Mistlands", "BlackCore:2,Eitr:10,Carapace:10", 7, 4, 2.5f); Add(config, "Flametal Perch", "Ashlands", "FlametalNew:10,CelestialFeather:3", 8, 4, 3f); Add(config, "Deep North Perch", "Deep North", "FlametalNew:30,MoltenCore:2", 8, 6, 4f); } private static void Add(ConfigFile config, string name, string biome, string cost, int w, int h, float speed) { int count = s_tiers.Count; string text = $"Tier {count} - {name}"; s_tiers.Add(new PerchTier { Index = count, Name = name, Biome = biome, Cost = config.Bind<string>(text, "UpgradeCost", cost, Plugin.Synced((count == 0) ? "Not used: this is the tier you build." : "Items to upgrade to this tier, as PrefabName:Amount, comma-separated.")), Width = config.Bind<int>(text, "CargoWidth", w, Plugin.Synced("Cargo slots per row (max 8).")), Height = config.Bind<int>(text, "CargoHeight", h, Plugin.Synced("Cargo rows (scrolls when tall).")), Speed = config.Bind<float>(text, "Speed", speed, Plugin.Synced("Flight speed multiplier; multiplies with the meal's speed.")), MaxWeight = config.Bind<float>(text, "MaxCargoWeight", 0f, Plugin.Synced("Heaviest cargo per flight at this tier, so upgrades can carry more. 0 = use the general Cargo/MaxCargoWeight.")) }); } public static void ValidateItems() { foreach (PerchTier item in s_tiers.Skip(1)) { List<string> list = item.MissingItems(); if (list.Count > 0) { Plugin.Log.LogWarning((object)(item.Name + ": unknown upgrade item(s) " + string.Join(", ", list) + " - this tier can't be reached until its UpgradeCost is changed in the config.")); } } } public static ItemData ItemData(string prefabName) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance)) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); ItemDrop val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } return val.m_itemData; } public static string DisplayName(string prefabName) { ItemData val = ItemData(prefabName); if (val == null) { return prefabName; } return Localization.instance.Localize(val.m_shared.m_name); } } [BepInPlugin("com.ravenpost.valheim", "Raven Post", "1.2.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal enum HungryBehaviour { FlySlowly, Refuse } public const string ModGuid = "com.ravenpost.valheim"; public const string ModName = "Raven Post"; public const string ModVersion = "1.2.1"; public const string PerchPrefabName = "piece_ravenperch"; internal static ManualLogSource Log; internal static ConfigEntry<float> SecondsPer100m; internal static ConfigEntry<float> MinFlightSeconds; internal static ConfigEntry<float> WeightSlowdown; internal static ConfigEntry<bool> AllowNonTeleportable; internal static ConfigEntry<float> MaxCargoWeight; internal static ConfigEntry<int> MaxFlightsPerPeriod; internal static ConfigEntry<int> PeriodDays; internal static ConfigEntry<bool> LettersCountAsFlights; internal static ConfigEntry<float> MaxFoodSpeed; internal static ConfigEntry<bool> UseFood; internal static ConfigEntry<HungryBehaviour> Hungry; internal static ConfigEntry<float> HungrySpeed; internal static ConfigEntry<int> MaxMeals; internal static ConfigEntry<float> RawMeatSpeed; internal static ConfigEntry<string> RawMeatItems; internal static ConfigEntry<KeyCode> NextDestinationKey; internal static ConfigEntry<KeyCode> SendKey; internal static ConfigEntry<KeyCode> RenameKey; private Harmony _harmony; internal static ConfigDescription Synced(string description) { //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_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } private void Awake() { //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; SecondsPer100m = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "SecondsPer100m", 10f, Synced("Real seconds a raven needs to fly 100 metres (in-game time, so sleeping speeds it up).")); MinFlightSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "MinFlightSeconds", 5f, Synced("Shortest possible delivery time, in seconds.")); WeightSlowdown = ((BaseUnityPlugin)this).Config.Bind<float>("Flight", "WeightSlowdown", 0.5f, Synced("Extra flight time per 100 weight of cargo. 0.5 = +50% per 100 weight.")); AllowNonTeleportable = ((BaseUnityPlugin)this).Config.Bind<bool>("Cargo", "AllowNonTeleportable", true, Synced("Let ravens carry ore and metals that portals block.")); MaxCargoWeight = ((BaseUnityPlugin)this).Config.Bind<float>("Cargo", "MaxCargoWeight", 0f, Synced("Heaviest cargo a raven will carry in one flight. 0 = no limit (500 is a good balanced value).")); MaxFlightsPerPeriod = ((BaseUnityPlugin)this).Config.Bind<int>("Limits", "MaxFlightsPerPeriod", 0, Synced("How many ravens each perch can send per period. 0 = unlimited.")); PeriodDays = ((BaseUnityPlugin)this).Config.Bind<int>("Limits", "PeriodDays", 1, Synced("Length of the period in in-game days (1 = per day). Resets when a new period starts; sleeping counts.")); LettersCountAsFlights = ((BaseUnityPlugin)this).Config.Bind<bool>("Limits", "LettersCountAsFlights", false, Synced("Whether a letter sent without cargo uses up one of the perch's flights.")); UseFood = ((BaseUnityPlugin)this).Config.Bind<bool>("Food", "UseFood", true, Synced("Ravens eat one stored meal per flight; better food flies faster. Turn off to ignore food entirely.")); Hungry = ((BaseUnityPlugin)this).Config.Bind<HungryBehaviour>("Food", "HungryRaven", HungryBehaviour.FlySlowly, Synced("What a raven does with no meals stored: FlySlowly (at HungrySpeed) or Refuse to fly.")); HungrySpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "HungrySpeed", 0.5f, Synced("Speed multiplier for a hungry raven when HungryRaven = FlySlowly. 0.5 = takes twice as long.")); MaxMeals = ((BaseUnityPlugin)this).Config.Bind<int>("Food", "MaxMeals", 10, Synced("How many meals a perch can store.")); MaxFoodSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "MaxFoodSpeed", 4f, Synced("Fastest a meal can make a raven. Cooked food gives 1 + health / 50, e.g. 30 hp = x1.6, 75 hp = x2.5.")); RawMeatSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Food", "RawMeatSpeed", 1.25f, Synced("Speed multiplier for raw meat.")); RawMeatItems = ((BaseUnityPlugin)this).Config.Bind<string>("Food", "RawMeatItems", "RawMeat,DeerMeat,NeckTail,WolfMeat,LoxMeat,SerpentMeat,BugMeat,HareMeat,ChickenMeat,AsksvinMeat,VoltureMeat,BoneMawSerpentMeat", Synced("Comma-separated item prefab names ravens eat raw.")); NextDestinationKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "NextDestination", (KeyCode)106, "While looking at a perch: choose the next destination."); SendKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "Send", (KeyCode)107, "While looking at a perch: send its cargo."); RenameKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "Rename", (KeyCode)110, "While looking at a perch: rename it."); PerchTiers.Bind(((BaseUnityPlugin)this).Config); PrefabManager.OnVanillaPrefabsAvailable += AddPerchPiece; _harmony = new Harmony("com.ravenpost.valheim"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"Raven Post 1.2.1 loaded"); } private void AddPerchPiece() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= AddPerchPiece; PieceConfig val = new PieceConfig(); val.Name = "Raven Perch"; val.Description = "Ravens carry cargo from here to your other perches."; val.PieceTable = "Hammer"; val.Category = "Misc"; val.CraftingStation = "piece_workbench"; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("FineWood", 4, 0, true), new RequirementConfig("Feathers", 4, 0, true), new RequirementConfig("BronzeNails", 5, 0, true) }; PieceConfig val2 = val; CustomPiece val3 = new CustomPiece("piece_ravenperch", "piece_chest_wood", val2); GameObject piecePrefab = val3.PiecePrefab; Container component = piecePrefab.GetComponent<Container>(); component.m_name = "Raven Perch"; component.m_width = PerchTiers.Get(0).CargoWidth; component.m_height = PerchTiers.Get(0).CargoHeight; piecePrefab.AddComponent<RavenPerch>(); RavenFlight.Prepare(); try { PerchModel.Decorate(piecePrefab); } catch (Exception arg) { Log.LogError((object)$"Couldn't build the perch model, using the plain chest look: {arg}"); } PieceManager.Instance.AddPiece(val3); LetterItem.Register(); } private void Update() { SendWindow.Tick(); if (PostOffice.IsActive) { RavenNet.ServerTick(); HandleKeys(); } } private static void HandleKeys() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || InventoryGui.IsVisible() || Menu.IsVisible() || TextInput.IsVisible() || Console.IsVisible() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus())) { return; } GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); RavenPerch ravenPerch = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<RavenPerch>() : null); if (Object.op_Implicit((Object)(object)ravenPerch)) { if (ZInput.GetKeyDown(NextDestinationKey.Value, false)) { ravenPerch.NextDestination(); } else if (ZInput.GetKeyDown(SendKey.Value, false)) { ravenPerch.Send(localPlayer); } else if (ZInput.GetKeyDown(RenameKey.Value, false)) { TextInput.instance.RequestText((TextReceiver)(object)ravenPerch, "Name this perch", 24); } } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal class Delivery { public double ArriveAt; public string From; public bool Notified; public byte[] Items; public Vector3 FromPos; public string Note = ""; public string FromPlayer = ""; public double SentAt; public bool HasNote => !string.IsNullOrEmpty(Note); public bool HasCargo => PostOffice.UnpackItems(Items).NrOfItems() > 0; public bool HasArrived(double now) { return now >= ArriveAt; } public string Key(ZDOID perch) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return $"{perch}:{ArriveAt:R}"; } } internal class PerchInfo { public ZDOID Id; public string Name; public Vector3 Position; } internal static class PostOffice { public const string NameKey = "ravenpost_name"; public const string InboxKey = "ravenpost_inbox"; private const int InboxVersion = 3; private static readonly List<ZDO> s_perches = new List<ZDO>(); private static float s_perchesRefreshedAt = -999f; private static List<PerchInfo> s_clientPerches = new List<PerchInfo>(); private static float s_clientPerchesRequestedAt = -999f; public static bool IsActive { get { if (Object.op_Implicit((Object)(object)ZNet.instance) && ZDOMan.instance != null) { return ZRoutedRpc.instance != null; } return false; } } public static bool IsServer { get { if (Object.op_Implicit((Object)(object)ZNet.instance)) { return ZNet.instance.IsServer(); } return false; } } public static double Now => ZNet.instance.GetTimeSeconds(); public static List<ZDO> GetAllPerchZdos() { if (Time.time - s_perchesRefreshedAt > 3f) { s_perches.Clear(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative("piece_ravenperch", s_perches, ref num)) { } s_perchesRefreshedAt = Time.time; } s_perches.RemoveAll((ZDO z) => z == null || !z.IsValid()); return s_perches; } public static List<PerchInfo> GetPerches() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (IsServer) { List<PerchInfo> list = new List<PerchInfo>(); foreach (ZDO allPerchZdo in GetAllPerchZdos()) { list.Add(new PerchInfo { Id = allPerchZdo.m_uid, Name = GetName(allPerchZdo), Position = allPerchZdo.GetPosition() }); } list.Sort((PerchInfo a, PerchInfo b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); return list; } if (Time.time - s_clientPerchesRequestedAt > 3f) { s_clientPerchesRequestedAt = Time.time; RavenNet.RequestPerches(); } return s_clientPerches; } public static void SetClientPerches(List<PerchInfo> perches) { perches.Sort((PerchInfo a, PerchInfo b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)); s_clientPerches = perches; } public static void InvalidatePerches() { s_perchesRefreshedAt = -999f; s_clientPerchesRequestedAt = -999f; } public static void ResetForNewWorld() { s_perches.Clear(); s_clientPerches = new List<PerchInfo>(); InvalidatePerches(); } public static string GetName(ZDO zdo) { string text = zdo.GetString("ravenpost_name", ""); if (!string.IsNullOrEmpty(text)) { return text; } return "Unnamed Perch"; } public static List<Delivery> ReadInbox(ZDO zdo) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown List<Delivery> list = new List<Delivery>(); byte[] byteArray = zdo.GetByteArray("ravenpost_inbox", (byte[])null); if (byteArray == null || byteArray.Length == 0) { return list; } ZPackage val = new ZPackage(byteArray); int num = val.ReadInt(); if (num < 1 || num > 3) { Plugin.Log.LogWarning((object)$"Unknown inbox version {num}; ignoring."); return list; } int num2 = val.ReadInt(); for (int i = 0; i < num2; i++) { list.Add(ReadDelivery(val, num)); } return list; } public static void WriteInbox(ZDO zdo, List<Delivery> inbox) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(3); val.Write(inbox.Count); foreach (Delivery item in inbox) { WriteDelivery(val, item); } zdo.Set("ravenpost_inbox", val.GetArray()); } public static void AppendToInbox(ZDO zdo, Delivery d) { List<Delivery> list = ReadInbox(zdo); list.Add(d); WriteInbox(zdo, list); } private static Delivery ReadDelivery(ZPackage pkg, int version) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Delivery delivery = new Delivery { ArriveAt = pkg.ReadDouble(), From = pkg.ReadString(), Notified = pkg.ReadBool(), Items = pkg.ReadByteArray() }; if (version >= 2) { delivery.FromPos = pkg.ReadVector3(); } if (version >= 3) { delivery.Note = pkg.ReadString(); delivery.FromPlayer = pkg.ReadString(); delivery.SentAt = pkg.ReadDouble(); } return delivery; } private static void WriteDelivery(ZPackage pkg, Delivery d) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) pkg.Write(d.ArriveAt); pkg.Write(d.From ?? ""); pkg.Write(d.Notified); pkg.Write(d.Items ?? new byte[0]); pkg.Write(d.FromPos); pkg.Write(d.Note ?? ""); pkg.Write(d.FromPlayer ?? ""); pkg.Write(d.SentAt); } public static ZPackage Serialize(Delivery d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0014: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(3); WriteDelivery(val, d); return val; } public static Delivery Deserialize(ZPackage pkg) { pkg.SetPos(0); int version = pkg.ReadInt(); return ReadDelivery(pkg, version); } public static byte[] PackItems(List<ItemData> items) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Inventory val = NewCargoInventory(); foreach (ItemData item in items) { val.AddItem(item.Clone()); } ZPackage val2 = new ZPackage(); val.Save(val2); return val2.GetArray(); } public static Inventory UnpackItems(byte[] data) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown Inventory val = NewCargoInventory(); if (data != null && data.Length != 0) { val.Load(new ZPackage(data)); } return val; } private static Inventory NewCargoInventory() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown return new Inventory("RavenCargo", (Sprite)null, 8, 10); } public static float FlightSeconds(float distance, float weight) { float num = distance / 100f * Plugin.SecondsPer100m.Value; num *= 1f + weight / 100f * Plugin.WeightSlowdown.Value; return Mathf.Max(Plugin.MinFlightSeconds.Value, num); } public static string FormatDuration(double seconds) { if (seconds < 0.0) { seconds = 0.0; } int num = Mathf.CeilToInt((float)seconds); if (num < 3600) { return $"{num / 60}:{num % 60:00}"; } return $"{num / 3600}h {num % 3600 / 60:00}m"; } public static string FormatDistance(float metres) { if (!(metres >= 1000f)) { return $"{Mathf.RoundToInt(metres)} m"; } return $"{metres / 1000f:0.0} km"; } public static string ArrivalMessage(Delivery d, string at) { bool hasCargo = d.HasCargo; if (d.HasNote && !hasCargo) { return "Letter from " + d.From + " has landed at " + at; } if (!d.HasNote) { return "Raven from " + d.From + " has landed at " + at; } return "Raven from " + d.From + " has landed at " + at + " with a letter"; } } internal class RavenFlight : MonoBehaviour { private enum Mode { TakeOff, Land } public const float LandingSeconds = 6f; public const float TakeOffSeconds = 12f; private const float MinTakeOffSeconds = 3f; private const float CruiseSpeed = 5f; private const float MaxCruiseSpeed = 30f; private const float ClimbSpeed = 1.6f; private const float CircleSeconds = 3f; private const float FadeSeconds = 1.5f; private const float LandingDistance = 30f; private const float LandingHeight = 14f; private static readonly string[] s_candidatePrefabs = new string[3] { "Crow", "Raven", "Seagal" }; private static GameObject s_template; private static GameObject s_perchedTemplate; private static bool s_warned; private Mode _mode; private Vector3 _origin; private Vector3 _target; private Vector3 _heading; private float _duration; private float _circleSeconds = 3f; private float _cruiseSpeed = 5f; private float _age; private Vector3 _baseScale; public static GameObject Template { get { Prepare(); return s_template; } } public static GameObject PerchedTemplate { get { Prepare(); return s_perchedTemplate; } } public static void Prepare() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)s_template)) { return; } GameObject val = null; string[] array = s_candidatePrefabs; foreach (string text in array) { val = PrefabManager.Instance.GetPrefab(text); if (Object.op_Implicit((Object)(object)val)) { Plugin.Log.LogInfo((object)("Raven visual uses prefab '" + text + "'")); break; } } if (!Object.op_Implicit((Object)(object)val)) { if (!s_warned) { s_warned = true; Plugin.Log.LogWarning((object)"No bird prefab found; ravens will be invisible."); } } else { GameObject val2 = new GameObject("RavenPost_Templates"); val2.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val2); s_template = BuildTemplate(val, val2.transform, landed: false); s_perchedTemplate = BuildTemplate(val, val2.transform, landed: true); } } private static GameObject BuildTemplate(GameObject source, Transform holder, bool landed) { GameObject val = Object.Instantiate<GameObject>(source, holder); ((Object)val).name = (landed ? "RavenPost_RavenPerched" : "RavenPost_Raven"); RandomFlyingBird component = val.GetComponent<RandomFlyingBird>(); if (Object.op_Implicit((Object)(object)component) && !component.m_singleModel && Object.op_Implicit((Object)(object)component.m_flyingModel) && Object.op_Implicit((Object)(object)component.m_landedModel)) { component.m_flyingModel.SetActive(!landed); component.m_landedModel.SetActive(landed); } 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]); } val.AddComponent<BirdPose>().Flying = !landed; return val; } private static RavenFlight Spawn(Vector3 position, Vector3 facing) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)s_template)) { Prepare(); if (!Object.op_Implicit((Object)(object)s_template)) { return null; } } facing.y = 0f; if (((Vector3)(ref facing)).sqrMagnitude < 0.01f) { facing = Vector3.forward; } GameObject val = Object.Instantiate<GameObject>(s_template, position, Quaternion.LookRotation(((Vector3)(ref facing)).normalized)); val.SetActive(true); RavenFlight ravenFlight = val.AddComponent<RavenFlight>(); ravenFlight._baseScale = val.transform.localScale; return ravenFlight; } public static float Launch(Vector3 from, Vector3 to, float flightSeconds, float speedMultiplier) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(flightSeconds * 0.8f, 3f, 12f); Vector3 val = to - from; val.y = 0f; val = ((((Vector3)(ref val)).sqrMagnitude < 0.01f) ? Vector3.forward : ((Vector3)(ref val)).normalized); RavenFlight ravenFlight = Spawn(from, val); if (!Object.op_Implicit((Object)(object)ravenFlight)) { return 0f; } ravenFlight._mode = Mode.TakeOff; ravenFlight._origin = from; ravenFlight._heading = val; ravenFlight._duration = num; ravenFlight._circleSeconds = Mathf.Min(3f, num * 0.3f); ravenFlight._cruiseSpeed = Mathf.Min(30f, 5f * Mathf.Max(1f, speedMultiplier)); return num; } public static void Land(Vector3 perch, Vector3 senderPos, float seconds) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0034: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_00a2: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) Vector3 val = senderPos - perch; val.y = 0f; if (senderPos == Vector3.zero || ((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Random.insideUnitSphere; val.y = 0f; } val = ((((Vector3)(ref val)).sqrMagnitude < 0.01f) ? Vector3.back : ((Vector3)(ref val)).normalized); Vector3 val2 = perch + val * 30f + Vector3.up * 14f; RavenFlight ravenFlight = Spawn(val2, -val); if (Object.op_Implicit((Object)(object)ravenFlight)) { ravenFlight._mode = Mode.Land; ravenFlight._origin = val2; ravenFlight._target = perch; ravenFlight._heading = -val; ravenFlight._duration = Mathf.Max(1f, seconds); } } private void Update() { _age += Time.deltaTime; if (_mode == Mode.TakeOff) { UpdateTakeOff(); } else { UpdateLanding(); } } private void UpdateTakeOff() { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_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_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) Vector3 position; Vector3 val2; if (_age < _circleSeconds) { float num = _age / _circleSeconds; float num2 = num * (float)Math.PI * 2f; float num3 = Mathf.Lerp(0.5f, 3f, num); Vector3 val = Quaternion.LookRotation(_heading) * new Vector3(Mathf.Sin(num2), 0f, 0f - Mathf.Cos(num2)) * num3; position = _origin + val + Vector3.up * (_age * 1.6f * 1.5f); val2 = Quaternion.LookRotation(_heading) * new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)); } else { float num4 = _age - _circleSeconds; position = _origin + Quaternion.LookRotation(_heading) * new Vector3(0f, 0f, -3f) + Vector3.up * (_circleSeconds * 1.6f * 1.5f) + _heading * (num4 * _cruiseSpeed) + Vector3.up * (num4 * 1.6f); val2 = _heading; } ((Component)this).transform.position = position; ((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, Quaternion.LookRotation(val2), Time.deltaTime * 6f); FadeAndExpire(_duration); } private void UpdateLanding() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(_age / _duration); float num2 = 1f - (1f - num) * (1f - num); Vector3 position = Vector3.Lerp(_origin, _target, num2); position.y += Mathf.Sin(num * (float)Math.PI) * 2f; ((Component)this).transform.position = position; ((Component)this).transform.rotation = Quaternion.LookRotation(_heading); if (_age >= _duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void FadeAndExpire(float lifetime) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) float num = lifetime - _age; if (num <= 0f) { Object.Destroy((Object)(object)((Component)this).gameObject); } else if (num < 1.5f) { ((Component)this).transform.localScale = _baseScale * (num / 1.5f); } } } internal class BirdPose : MonoBehaviour { private static readonly int s_flyingHash = Animator.StringToHash("flying"); private static readonly int s_flappingHash = Animator.StringToHash("flapping"); public bool Flying; private Animator _animator; private bool _hasFlying; private bool _hasFlapping; private void Start() { _animator = ((Component)this).GetComponentInChildren<Animator>(); if (Object.op_Implicit((Object)(object)_animator)) { AnimatorControllerParameter[] parameters = _animator.parameters; foreach (AnimatorControllerParameter val in parameters) { _hasFlying |= val.nameHash == s_flyingHash; _hasFlapping |= val.nameHash == s_flappingHash; } Apply(); } } private void Update() { Apply(); } private void Apply() { if (Object.op_Implicit((Object)(object)_animator) && ((Behaviour)_animator).isActiveAndEnabled) { if (_hasFlying) { _animator.SetBool(s_flyingHash, Flying); } if (_hasFlapping) { _animator.SetBool(s_flappingHash, Flying); } } } } internal static class RavenFood { public const string MealsKey = "ravenpost_meals"; private static HashSet<string> s_rawMeats; private static string s_rawMeatsSource; public static float SpeedFor(ItemData item) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 if (item == null) { return 0f; } SharedData shared = item.m_shared; if ((int)shared.m_itemType == 2 && shared.m_food > 0f) { return Mathf.Min(Plugin.MaxFoodSpeed.Value, 1f + shared.m_food / 50f); } string item2 = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : ""); if (!RawMeats().Contains(item2)) { return 0f; } return Plugin.RawMeatSpeed.Value; } private static HashSet<string> RawMeats() { string text = Plugin.RawMeatItems.Value ?? ""; if (s_rawMeats == null || text != s_rawMeatsSource) { s_rawMeatsSource = text; s_rawMeats = new HashSet<string>(from x in text.Split(new char[1] { ',' }) select x.Trim() into x where x.Length > 0 select x); } return s_rawMeats; } public static ItemData BestFood(Inventory inventory) { ItemData result = null; float num = 0f; foreach (ItemData allItem in inventory.GetAllItems()) { float num2 = SpeedFor(allItem); if (num2 > num && !allItem.m_equipped) { result = allItem; num = num2; } } return result; } public static List<float> ReadMeals(ZDO zdo) { List<float> list = new List<float>(); string[] array = zdo.GetString("ravenpost_meals", "").Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { if (float.TryParse(array[i], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0f) { list.Add(result); } } list.Sort((float a, float b) => b.CompareTo(a)); return list; } public static void WriteMeals(ZDO zdo, List<float> meals) { meals.Sort((float a, float b) => b.CompareTo(a)); zdo.Set("ravenpost_meals", string.Join(";", meals.Select((float m) => m.ToString("0.###", CultureInfo.InvariantCulture)))); } public static string FormatSpeed(float speed) { return $"x{speed:0.##}"; } } internal class Letter { public double SentAt; public string From = ""; public string FromPlayer = ""; public Vector3 FromPos; public string Text = ""; public bool Read; } internal static class RavenMail { public const string MailKey = "ravenpost_mail"; public const string DraftKey = "ravenpost_draft"; public const int MaxNoteLength = 200; private const int MaxLetters = 50; private const int MailVersion = 1; public static List<Letter> Read(ZDO zdo) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) List<Letter> list = new List<Letter>(); byte[] byteArray = zdo.GetByteArray("ravenpost_mail", (byte[])null); if (byteArray == null || byteArray.Length == 0) { return list; } ZPackage val = new ZPackage(byteArray); int num = val.ReadInt(); if (num != 1) { Plugin.Log.LogWarning((object)$"Unknown mailbox version {num}; ignoring."); return list; } int num2 = val.ReadInt(); for (int i = 0; i < num2; i++) { list.Add(new Letter { SentAt = val.ReadDouble(), From = val.ReadString(), FromPlayer = val.ReadString(), FromPos = val.ReadVector3(), Text = val.ReadString(), Read = val.ReadBool() }); } return list; } public static void Write(ZDO zdo, List<Letter> letters) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) while (letters.Count > 50) { int num = letters.FindIndex((Letter l) => l.Read); letters.RemoveAt((num >= 0) ? num : 0); } ZPackage val = new ZPackage(); val.Write(1); val.Write(letters.Count); foreach (Letter letter in letters) { val.Write(letter.SentAt); val.Write(letter.From ?? ""); val.Write(letter.FromPlayer ?? ""); val.Write(letter.FromPos); val.Write(letter.Text ?? ""); val.Write(letter.Read); } zdo.Set("ravenpost_mail", val.GetArray()); } public static void Deliver(ZDO zdo, Delivery d) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) List<Letter> list = Read(zdo); list.Add(new Letter { SentAt = d.SentAt, From = d.From, FromPlayer = d.FromPlayer, FromPos = d.FromPos, Text = d.Note, Read = false }); Write(zdo, list); } public static int UnreadCount(ZDO zdo) { int num = 0; foreach (Letter item in Read(zdo)) { if (!item.Read) { num++; } } return num; } public static int Day(double time) { if (!Object.op_Implicit((Object)(object)EnvMan.instance)) { return 0; } return EnvMan.instance.GetDay(time); } public static string Preview(string text, int max = 28) { text = (text ?? "").Replace('\n', ' '); if (text.Length > max) { return text.Substring(0, max - 1) + "…"; } return text; } public static PerchInfo FindSender(Letter letter) { //IL_0031: 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) PerchInfo result = null; float num = float.MaxValue; foreach (PerchInfo perch in PostOffice.GetPerches()) { if (!(perch.Name != letter.From)) { float num2 = Vector3.Distance(perch.Position, letter.FromPos); if (num2 < num) { result = perch; num = num2; } } } return result; } } internal class NoteWriter : TextReceiver { private readonly RavenPerch _perch; private NoteWriter(RavenPerch perch) { _perch = perch; } public static void Open(RavenPerch perch, string topic) { if (Object.op_Implicit((Object)(object)perch) && Object.op_Implicit((Object)(object)TextInput.instance)) { if (Object.op_Implicit((Object)(object)InventoryGui.instance)) { InventoryGui.instance.Hide(); } TextInput.instance.RequestText((TextReceiver)(object)new NoteWriter(perch), topic, MaxNoteLength()); } } private static int MaxNoteLength() { return 200; } public string GetText() { if (!Object.op_Implicit((Object)(object)_perch)) { return ""; } return _perch.Draft; } public void SetText(string text) { if (Object.op_Implicit((Object)(object)_perch)) { _perch.Draft = text; Player localPlayer = Player.m_localPlayer; Container component = ((Component)_perch).GetComponent<Container>(); if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)component)) { SendWindow.OpenOnSendTabNext(); component.Interact((Humanoid)(object)localPlayer, false, false); } } } } internal static class RavenNet { private class PendingNotice { public double At; public string Recipient; public string Message; } private const string RpcRequestPerches = "RavenPost_RequestPerches"; private const string RpcPerches = "RavenPost_Perches"; private const string RpcDeliver = "RavenPost_Deliver"; private const string RpcAddToInbox = "RavenPost_AddToInbox"; private const string RpcServerWrite = "RavenPost_ServerWrite"; private const string RpcNotify = "RavenPost_Notify"; private const string RpcTakeOff = "RavenPost_TakeOff"; private const float TakeOffViewDistance = 150f; private static readonly List<PendingNotice> s_pending = new List<PendingNotice>(); private static readonly HashSet<string> s_scheduled = new HashSet<string>(); private static bool s_scannedWorld; private static float s_nextTick; public static void Register() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { s_pending.Clear(); s_scheduled.Clear(); s_scannedWorld = false; PostOffice.ResetForNewWorld(); instance.Register("RavenPost_RequestPerches", (Action<long>)OnRequestPerches); instance.Register<ZPackage>("RavenPost_Perches", (Action<long, ZPackage>)OnPerches); instance.Register<ZDOID, ZDOID, ZPackage>("RavenPost_Deliver", (Action<long, ZDOID, ZDOID, ZPackage>)OnDeliver); instance.Register<ZDOID, ZPackage>("RavenPost_AddToInbox", (Action<long, ZDOID, ZPackage>)OnAddToInbox); instance.Register<ZDOID, ZPackage>("RavenPost_ServerWrite", (Action<long, ZDOID, ZPackage>)OnServerWrite); instance.Register<string>("RavenPost_Notify", (Action<long, string>)OnNotify); instance.Register<Vector3, Vector3, ZPackage>("RavenPost_TakeOff", (Action<long, Vector3, Vector3, ZPackage>)OnTakeOff); } } public static void RequestPerches() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { instance.InvokeRoutedRPC("RavenPost_RequestPerches", Array.Empty<object>()); } } private static void OnRequestPerches(long sender) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!PostOffice.IsServer) { return; } List<PerchInfo> perches = PostOffice.GetPerches(); ZPackage val = new ZPackage(); val.Write(perches.Count); foreach (PerchInfo item in perches) { val.Write(item.Id); val.Write(item.Name); val.Write(item.Position); } ZRoutedRpc.instance.InvokeRoutedRPC(sender, "RavenPost_Perches", new object[1] { val }); } private static void OnPerches(long sender, ZPackage pkg) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!PostOffice.IsServer) { List<PerchInfo> list = new List<PerchInfo>(); int num = pkg.ReadInt(); for (int i = 0; i < num; i++) { list.Add(new PerchInfo { Id = pkg.ReadZDOID(), Name = pkg.ReadString(), Position = pkg.ReadVector3() }); } PostOffice.SetClientPerches(list); } } public static void SendDelivery(ZDOID destination, ZDOID source, Delivery d) { //IL_0012: 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) ZRoutedRpc.instance.InvokeRoutedRPC("RavenPost_Deliver", new object[3] { destination, source, PostOffice.Serialize(d) }); } private static void OnDeliver(long sender, ZDOID destination, ZDOID source, ZPackage pkg) { //IL_0014: 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_008b: Unknown result type (might be due to invalid IL or missing references) if (!PostOffice.IsServer) { return; } Delivery delivery = PostOffice.Deserialize(pkg); ZDO zDO = ZDOMan.instance.GetZDO(destination); string name; if (zDO == null || !zDO.IsValid()) { zDO = ZDOMan.instance.GetZDO(source); if (zDO == null || !zDO.IsValid()) { Plugin.Log.LogWarning((object)("Delivery from '" + delivery.From + "' has nowhere to go; both perches are gone.")); return; } name = PostOffice.GetName(zDO); Notify(delivery.FromPlayer, "The perch was gone - your raven flew back to " + name); } else { name = PostOffice.GetName(zDO); } WriteToOwner(zDO, delivery); Schedule(zDO.m_uid, name, delivery); } private static void WriteToOwner(ZDO zdo, Delivery d) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) long owner = zdo.GetOwner(); long sessionID = ZDOMan.GetSessionID(); if (owner != 0L && owner != sessionID && ZNet.instance.GetPeer(owner) != null) { ZRoutedRpc.instance.InvokeRoutedRPC(owner, "RavenPost_AddToInbox", new object[2] { zdo.m_uid, PostOffice.Serialize(d) }); } else { PostOffice.AppendToInbox(zdo, d); } } private static void OnAddToInbox(long sender, ZDOID id, ZPackage pkg) { //IL_0005: 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) ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO != null && zDO.IsOwner()) { PostOffice.AppendToInbox(zDO, PostOffice.Deserialize(pkg)); return; } pkg.SetPos(0); ZRoutedRpc.instance.InvokeRoutedRPC("RavenPost_ServerWrite", new object[2] { id, pkg }); } private static void OnServerWrite(long sender, ZDOID id, ZPackage pkg) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (PostOffice.IsServer) { ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO != null && zDO.IsValid()) { PostOffice.AppendToInbox(zDO, PostOffice.Deserialize(pkg)); } } } private static void Schedule(ZDOID perch, string perchName, Delivery d) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (s_scheduled.Add(d.Key(perch))) { string message = PostOffice.ArrivalMessage(d, perchName); s_pending.Add(new PendingNotice { At = d.ArriveAt, Recipient = (d.HasNote ? null : d.FromPlayer), Message = message }); } } public static void ServerTick() { //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (!PostOffice.IsServer || !PostOffice.IsActive || Time.time < s_nextTick) { return; } s_nextTick = Time.time + 1f; if (!s_scannedWorld) { s_scannedWorld = true; double now = PostOffice.Now; foreach (ZDO allPerchZdo in PostOffice.GetAllPerchZdos()) { foreach (Delivery item in PostOffice.ReadInbox(allPerchZdo)) { if (!item.HasArrived(now)) { Schedule(allPerchZdo.m_uid, PostOffice.GetName(allPerchZdo), item); } } } } double now2 = PostOffice.Now; for (int num = s_pending.Count - 1; num >= 0; num--) { PendingNotice pendingNotice = s_pending[num]; if (pendingNotice.At <= now2) { s_pending.RemoveAt(num); Notify(pendingNotice.Recipient, pendingNotice.Message); } } } private static void Notify(string playerName, string message) { if (playerName == null) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "RavenPost_Notify", new object[1] { message }); return; } if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && Player.m_localPlayer.GetPlayerName() == playerName) { OnNotify(0L, message); } foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.m_playerName == playerName) { ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "RavenPost_Notify", new object[1] { message }); } } } private static void OnNotify(long sender, string message) { if (Object.op_Implicit((Object)(object)MessageHud.instance)) { MessageHud.instance.ShowMessage((MessageType)1, message, 0, (Sprite)null, false, true); } } public static void BroadcastTakeOff(Vector3 from, Vector3 to, float flightSeconds, float speed) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0028: 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) ZPackage val = new ZPackage(); val.Write(flightSeconds); val.Write(speed); ZRoutedRpc.instance.InvokeRoutedRPC(0L, "RavenPost_TakeOff", new object[3] { from, to, val }); } private static void OnTakeOff(long sender, Vector3 from, Vector3 to, ZPackage pkg) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (sender == ZDOMan.GetSessionID() || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || Vector3.Distance(((Component)Player.m_localPlayer).transform.position, from) > 150f) { return; } float flightSeconds = pkg.ReadSingle(); float speedMultiplier = pkg.ReadSingle(); float num = RavenFlight.Launch(from, to, flightSeconds, speedMultiplier); RavenPerch[] array = Object.FindObjectsByType<RavenPerch>((FindObjectsSortMode)0); foreach (RavenPerch ravenPerch in array) { if (Vector3.Distance(ravenPerch.SeatPosition, from) < 0.5f) { ravenPerch.HideSeatedRaven(num + 1f); } } } } public class RavenPerch : MonoBehaviour, TextReceiver { private ZNetView _nview; private Container _container; private ZDOID _selectedDestination = ZDOID.None; private int _appliedTier; private static readonly HashSet<string> s_landingsShown = new HashSet<string>(); private const float LandingViewDistance = 80f; private static bool s_validatedTiers; private static readonly FieldInfo s_invWidth = AccessTools.Field(typeof(Inventory), "m_width"); private static readonly FieldInfo s_invHeight = AccessTools.Field(typeof(Inventory), "m_height"); private static readonly FieldInfo s_invName = AccessTools.Field(typeof(Inventory), "m_name"); private const string FlightLogKey = "ravenpost_flights"; public int TierIndex { get { if (Zdo == null) { return 0; } return Mathf.Clamp(Zdo.GetInt("ravenpost_tier", 0), 0, PerchTiers.Max); } } internal PerchTier Tier => PerchTiers.Get(TierIndex); internal PerchTier NextTier { get { if (TierIndex >= PerchTiers.Max) { return null; } return PerchTiers.Get(TierIndex + 1); } } private ZDO Zdo { get { if (!Object.op_Implicit((Object)(object)_nview) || !_nview.IsValid()) { return null; } return _nview.GetZDO(); } } public string PerchName { get { if (Zdo == null) { return "Raven Perch"; } return PostOffice.GetName(Zdo); } } public float CargoWeight { get { Inventory inventory = _container.GetInventory(); if (inventory == null) { return 0f; } return inventory.GetTotalWeight(); } } public List<float> Meals { get { if (Zdo == null) { return new List<float>(); } return RavenFood.ReadMeals(Zdo); } } public float NextMealSpeed { get { if (!Plugin.UseFood.Value) { return 1f; } List<float> meals = Meals; if (meals.Count <= 0) { return Mathf.Max(0.05f, Plugin.HungrySpeed.Value); } return meals[0]; } } public bool IsHungry { get { if (Plugin.UseFood.Value) { return Meals.Count == 0; } return false; } } public bool RefusesToFly { get { if (IsHungry) { return Plugin.Hungry.Value == Plugin.HungryBehaviour.Refuse; } return false; } } public string MealsStatus { get { if (!Plugin.UseFood.Value) { return ""; } List<float> meals = Meals; if (meals.Count > 0) { return $"Meals: {meals.Count}/{Mathf.Max(1, Plugin.MaxMeals.Value)} (next {RavenFood.FormatSpeed(meals[0])} speed)"; } if (!RefusesToFly) { return "<color=#ff9a40>Hungry - flies slowly (" + RavenFood.FormatSpeed(NextMealSpeed) + ")</color>"; } return "<color=#ff6060>Hungry - won't fly until fed</color>"; } } public float MaxCargoWeight => Tier.CargoWeightLimit; public bool WeightLimited => MaxCargoWeight > 0f; public static bool FlightsLimited => Plugin.MaxFlightsPerPeriod.Value > 0; private static int PeriodDays => Mathf.Max(1, Plugin.PeriodDays.Value); private static int CurrentPeriod => RavenMail.Day(PostOffice.Now) / PeriodDays; public int FlightsUsed { get { ZDO zdo = Zdo; string[] array = (((zdo != null) ? zdo.GetString("ravenpost_flights", "") : null) ?? "").Split(new char[1] { ':' }); if (array.Length == 2 && int.TryParse(array[0], out var result) && int.TryParse(array[1], out var result2) && result == CurrentPeriod) { return result2; } return 0; } } public int FlightsLeft { get { if (!FlightsLimited) { return int.MaxValue; } return Mathf.Max(0, Plugin.MaxFlightsPerPeriod.Value - FlightsUsed); } } private static string PeriodName { get { if (PeriodDays != 1) { return $"these {PeriodDays} days"; } return "today"; } } public string FlightsStatus { get { if (!FlightsLimited) { return ""; } int value = Plugin.MaxFlightsPerPeriod.Value; if (FlightsLeft > 0) { return $"Flights {PeriodName}: {FlightsUsed}/{value}"; } int num = (CurrentPeriod + 1) * PeriodDays; return $"<color=#ff6060>Tired ({value}/{value} {PeriodName}) - flies again on day {num}</color>"; } } public string Draft { get { ZDO zdo = Zdo; return ((zdo != null) ? zdo.GetString("ravenpost_draft", "") : null) ?? ""; } set { if (Zdo != null && EnsureOwner(Player.m_localPlayer)) { string text = (value ?? "").Trim(); if (text.Length > 200) { text = text.Substring(0, 200); } Zdo.Set("ravenpost_draft", text); } } } internal List<Letter> Mailbox { get { if (Zdo == null) { return new List<Letter>(); } return RavenMail.Read(Zdo); } } public int UnreadLetters { get { if (Zdo == null) { return 0; } return RavenMail.UnreadCount(Zdo); } } private Transform SeatedRaven => ((Component)this).transform.Find("RavenPost_PerchedRaven"); public Vector3 SeatPosition { get { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Transform seatedRaven = SeatedRaven; if (!Object.op_Implicit((Object)(object)seatedRaven)) { return ((Component)this).transform.position + Vector3.up * 1.2f; } return seatedRaven.position; } } private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _container = ((Component)this).GetComponent<Container>(); if (Object.op_Implicit((Object)(object)_nview) && _nview.GetZDO() != null) { WearNTear component = ((Component)this).GetComponent<WearNTear>(); if (Object.op_Implicit((Object)(object)component)) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } if (!s_validatedTiers) { s_validatedTiers = true; PerchTiers.ValidateItems(); } PostOffice.InvalidatePerches(); _appliedTier = TierIndex; ((MonoBehaviour)this).InvokeRepeating("CollectArrivals", 1f, 2f); ((MonoBehaviour)this).InvokeRepeating("CheckLandings", 0.5f, 0.5f); ((MonoBehaviour)this).InvokeRepeating("SyncTier", 2f, 2f); } } private void SyncTier() { int tierIndex = TierIndex; if (tierIndex != _appliedTier) { _appliedTier = tierIndex; ApplyTier(_container, Tier); } } private void CheckLandings() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Zdo == null || !Object.op_Implicit((Object)(object)localPlayer) || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) > 80f) { return; } double now = PostOffice.Now; foreach (Delivery item in PostOffice.ReadInbox(Zdo)) { double num = item.ArriveAt - now; if (!(num < 0.0) && !(num > (double)LandingLeadFor(item)) && s_landingsShown.Add(item.Key(Zdo.m_uid))) { float seconds = (float)Math.Max(0.5, num); HideSeatedRaven(seconds); RavenFlight.Land(SeatPosition, item.FromPos, seconds); } } } private static float LandingLeadFor(Delivery d) { if (d.SentAt <= 0.0) { return 6f; } return Mathf.Clamp((float)(d.ArriveAt - d.SentAt) * 0.5f, 1.5f, 6f); } internal static void ApplyTier(Container container, PerchTier tier) { container.m_name = tier.Name; int num = tier.CargoWidth; int num2 = tier.CargoHeight; Inventory inventory = container.GetInventory(); if (inventory == null) { container.m_width = num; container.m_height = num2; return; } foreach (ItemData allItem in inventory.GetAllItems()) { num = Mathf.Max(num, allItem.m_gridPos.x + 1); num2 = Mathf.Max(num2, allItem.m_gridPos.y + 1); } container.m_width = num; container.m_height = num2; s_invWidth?.SetValue(inventory, num); s_invHeight?.SetValue(inventory, num2); s_invName?.SetValue(inventory, tier.Name); } public void Upgrade(Player player) { PerchTier nextTier = NextTier; if (Zdo == null || !Object.op_Implicit((Object)(object)player) || nextTier == null || !EnsureOwner(player)) { return; } if (nextTier.MissingItems().Count > 0) { ((Character)player).Message((MessageType)2, nextTier.Name + " needs items this game doesn't have yet (see config)", 0, (Sprite)null, false); return; } Inventory inventory = ((Humanoid)player).GetInventory(); foreach (KeyValuePair<string, int> item in nextTier.Requirements()) { ItemData val = PerchTiers.ItemData(item.Key); if (inventory.CountItems(val.m_shared.m_name, -1, true) < item.Value) { ((Character)player).Message((MessageType)2, Localization.instance.Localize($"Not enough {val.m_shared.m_name} ({item.Value} needed)"), 0, (Sprite)null, false); return; } } foreach (KeyValuePair<string, int> item2 in nextTier.Requirements()) { inventory.RemoveItem(PerchTiers.ItemData(item2.Key).m_shared.m_name, item2.Value, -1, true); } Zdo.Set("ravenpost_tier", nextTier.Index); ApplyTier(_container, nextTier); ((Character)player).Message((MessageType)2, $"Upgraded to {nextTier.Name}: {nextTier.CargoWidth}x{nextTier.CargoHeight} cargo, {RavenFood.FormatSpeed(nextTier.SpeedMultiplier)} speed", 0, (Sprite)null, false); Plugin.Log.LogInfo((object)("'" + PerchName + "' upgraded to " + nextTier.Name)); } public string GetText() { ZDO zdo = Zdo; return ((zdo != null) ? zdo.GetString("ravenpost_name", "") : null) ?? ""; } public void SetText(string text) { if (Zdo != null && EnsureOwner(Player.m_localPlayer)) { text = (text ?? "").Trim(); Zdo.Set("ravenpost_name", text); PostOffice.InvalidatePerches(); } } internal List<PerchInfo> Destinations() { if (Zdo != null) { return (from p in PostOffice.GetPerches() where p.Id != Zdo.m_uid select p).ToList(); } return new List<PerchInfo>(); } internal PerchInfo SelectedDestination(List<PerchInfo> destinations) { //IL_002a: 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) if (destinations.Count == 0) { return null; } PerchInfo perchInfo = destinations.FirstOrDefault((PerchInfo p) => p.Id == _selectedDestination); if (perchInfo == null) { perchInfo = destinations[0]; _selectedDestination = perchInfo.Id; } return perchInfo; } public void Select(ZDOID destination) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) _selectedDestination = destination; } internal float DistanceTo(PerchInfo destination) { //IL_0006: 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) return Vector3.Distance(((Component)this).transform.position, destination.Position); } private bool EnsureOwner(Player player) { if (Zdo == null) { return false; } if (_nview.IsOwner()) { return true; } if (!_container.IsInUse() && Zdo.GetInt(ZDOVars.s_inUse, 0) == 0) { _nview.ClaimOwnership(); } if (!_nview.IsOwner()) { if (Object.op_Implicit((Object)(object)player)) { ((Character)player).Message((MessageType)2, "Someone else is using this perch", 0, (Sprite)null, false); } return false; } return true; } public bool TooHeavy(float weight) { if (WeightLimited) { return weight > MaxCargoWeight + 0.001f; } return false; } private void RecordFlight() { if (FlightsLimited && Zdo != null) { Zdo.Set("ravenpost_flights", $"{CurrentPeriod}:{FlightsUsed + 1}"); } } internal float FlightSecondsTo(PerchInfo destination) { return PostOffice.FlightSeconds(DistanceTo(destination), CargoWeight) / (NextMealSpeed * Tier.SpeedMultiplier); } internal float LetterSecondsTo(PerchInfo destination) { return PostOffice.FlightSeconds(DistanceTo(destination), 0f) / Tier.SpeedMultiplier; } public bool Feed(Player player, ItemData item) { if (Zdo == null || !Object.op_Implicit((Object)(object)player)) { return false; } float num = RavenFood.SpeedFor(item); if (num <= 0f) { return false; } if (!EnsureOwner(player)) { return true; } List<float> meals = Meals; int num2 = Mathf.Max(1, Plugin.MaxMeals.Value); if (meals.Count >= num2) { ((Character)player).Message((MessageType)2, "The raven is full", 0, (Sprite)null, false); return true; } if (!((Humanoid)player).GetInventory().RemoveOneItem(item)) { return true; } meals.Add(num); RavenFood.WriteMeals(Zdo, meals); ((Character)player).Message((MessageType)2, Localization.instance.Localize($"The raven ate {item.m_shared.m_name} ({RavenFood.FormatSpeed(num)} speed) - {meals.Count}/{num2} meals"), 0, (Sprite)null, false); return true; } public void FeedBest(Player player) { ItemData val = RavenFood.BestFood(((Humanoid)player).GetInventory()); if (val == null) { ((Character)player).Message((MessageType)2, "You have nothing the raven will eat", 0, (Sprite)null, false); } else { Feed(player, val); } } public void NextDestination() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (Zdo == null) { return; } List<PerchInfo> list = Destinations(); if (list.Count != 0) { int num = list.FindIndex((PerchInfo p) => p.Id == _selectedDestination); _selectedDestination = list[(num + 1) % list.Count].Id; } } public void Send(Player player) { //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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_0241: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: 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_02d3: Unknown result type (might be due to invalid IL or missing references) if (Zdo == null || !PostOffice.IsActive || !EnsureOwner(player)) { return; } PerchInfo perchInfo = SelectedDestination(Destinations()); if (perchInfo == null) { ((Character)player).Message((MessageType)2, "Build another Raven Perch to send to", 0, (Sprite)null, false); return; } Inventory inventory = _container.GetInventory(); List<ItemData> list = inventory.GetAllItems().ToList(); string draft = Draft; bool flag = !string.IsNullOrEmpty(draft); if (list.Count == 0 && !flag) { ((Character)player).Message((MessageType)2, "Put some cargo in the perch or write a note first", 0, (Sprite)null, false); return; } bool flag2 = list.Count == 0; if (!Plugin.AllowNonTeleportable.Value && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)35)) { ItemData val = ((IEnumerable<ItemData>)list).FirstOrDefault((Func<ItemData, bool>)((ItemData i) => !i.m_shared.m_teleportable)); if (val != null) { ((Character)player).Message((MessageType)2, Localization.instance.Localize("Ravens refuse to carry " + val.m_shared.m_name), 0, (Sprite)null, false); return; } } float totalWeight = inventory.GetTotalWeight(); if (!flag2 && TooHeavy(totalWeight)) { ((Character)player).Message((MessageType)2, $"Too heavy for the raven: {totalWeight:0.#} / {MaxCargoWeight:0.#}", 0, (Sprite)null, false); return; } bool flag3 = !flag2 || Plugin.LettersCountAsFlights.Value; if (flag3 && FlightsLimited && FlightsLeft <= 0) { ((Character)player).Message((MessageType)2, "The raven is tired - it rests until the next day", 0, (Sprite)null, false); return; } if (!flag2 && RefusesToFly) { ((Character)player).Message((MessageType)2, "Your raven is hungry - feed it first", 0, (Sprite)null, false); return; } List<float> meals = Meals; float num = (flag2 ? 1f : NextMealSpeed); float num2 = DistanceTo(perchInfo); float num3 = PostOffice.FlightSeconds(num2, totalWeight) / (num * Tier.SpeedMultiplier); Delivery d = new Delivery { ArriveAt = PostOffice.Now + (double)num3, From = PerchName, Notified = false, Items = PostOffi