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 ParchmentMap v0.3.0
ParchmentMap.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; 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 Splatform; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ParchmentMap")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0+330d2e5a67ae95d2e175d8f2ffb0f52d432a864f")] [assembly: AssemblyProduct("ParchmentMap")] [assembly: AssemblyTitle("ParchmentMap")] [assembly: AssemblyVersion("0.3.0.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 ParchmentMap { internal sealed class PinRecord { public string Name = ""; public Vector3 Pos; public int Type; public bool Checked; public PinRecord Clone() { //IL_0013: 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) return new PinRecord { Name = Name, Pos = Pos, Type = Type, Checked = Checked }; } } internal static class MapBits { public static byte[] Pack(BitArray bits) { byte[] array = new byte[(bits.Length + 7) / 8]; bits.CopyTo(array, 0); return array; } public static BitArray Unpack(byte[] bytes, int bitCount) { BitArray bitArray = new BitArray(bytes); if (bitArray.Length != bitCount) { bitArray.Length = bitCount; } return bitArray; } public static int Count(BitArray bits) { int[] array = new int[(bits.Length + 31) / 32]; bits.CopyTo(array, 0); int num = 0; for (int i = 0; i < array.Length; i++) { uint num2 = (uint)array[i]; num2 -= (num2 >> 1) & 0x55555555; num2 = (num2 & 0x33333333) + ((num2 >> 2) & 0x33333333); num += (int)(((num2 + (num2 >> 4)) & 0xF0F0F0F) * 16843009 >> 24); } return num; } public static bool Any(BitArray bits) { int[] array = new int[(bits.Length + 31) / 32]; bits.CopyTo(array, 0); for (int i = 0; i < array.Length; i++) { if (array[i] != 0) { return true; } } return false; } public static bool Centroid(BitArray bits, int size, out float x, out float y) { byte[] array = Pack(bits); double num = 0.0; double num2 = 0.0; long num3 = 0L; for (int i = 0; i < array.Length; i++) { int num4 = array[i]; if (num4 == 0) { continue; } for (int j = 0; j < 8; j++) { if ((num4 & (1 << j)) != 0) { int num5 = i * 8 + j; num += (double)(num5 % size); num2 += (double)(num5 / size); num3++; } } } x = ((num3 > 0) ? ((float)(num / (double)num3)) : 0f); y = ((num3 > 0) ? ((float)(num2 / (double)num3)) : 0f); return num3 > 0; } public static BitArray Added(BitArray before, BitArray after) { return new BitArray(after).And(new BitArray(before).Not()); } public static byte[] Compress(byte[] raw) { using MemoryStream memoryStream = new MemoryStream(); using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionLevel.Optimal)) { gZipStream.Write(raw, 0, raw.Length); } return memoryStream.ToArray(); } public static byte[] Decompress(byte[] packed, int offset) { using MemoryStream stream = new MemoryStream(packed, offset, packed.Length - offset); using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress); using MemoryStream memoryStream = new MemoryStream(); gZipStream.CopyTo(memoryStream); return memoryStream.ToArray(); } } internal static class PinMerge { public const float SameRadius = 1f; public const int MaxTombstones = 256; public static bool Near(Vector3 a, Vector3 b, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = a.x - b.x; float num2 = a.z - b.z; return num * num + num2 * num2 < radius * radius; } public static int IndexNear(List<PinRecord> pins, Vector3 pos) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < pins.Count; i++) { if (Near(pins[i].Pos, pos, 1f)) { return i; } } return -1; } public static bool IsBuried(List<Vector3> tombstones, Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < tombstones.Count; i++) { if (Near(tombstones[i], pos, 1f)) { return true; } } return false; } public static void Bury(List<Vector3> tombstones, Vector3 pos) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!IsBuried(tombstones, pos)) { tombstones.Add(pos); if (tombstones.Count > 256) { tombstones.RemoveRange(0, tombstones.Count - 256); } } } public static void Unbury(List<Vector3> tombstones, Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) tombstones.RemoveAll((Vector3 t) => Near(t, pos, 1f)); } public static List<PinRecord> FromTable(List<PinRecord> mapPins, List<Vector3> tombstones, List<PinRecord> tablePins) { //IL_0019: 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_0036: Unknown result type (might be due to invalid IL or missing references) List<PinRecord> list = new List<PinRecord>(); foreach (PinRecord tablePin in tablePins) { if (!IsBuried(tombstones, tablePin.Pos) && IndexNear(mapPins, tablePin.Pos) < 0 && IndexNear(list, tablePin.Pos) < 0) { list.Add(tablePin.Clone()); } } return list; } public static void IntoTable(List<PinRecord> tablePins, List<PinRecord> mapPins, List<Vector3> tombstones) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) tablePins.RemoveAll((PinRecord p) => IsBuried(tombstones, p.Pos)); foreach (PinRecord mapPin in mapPins) { int num = IndexNear(tablePins, mapPin.Pos); if (num >= 0) { tablePins[num] = mapPin.Clone(); } else { tablePins.Add(mapPin.Clone()); } } } } internal sealed class ZoneRevs { private const int Offset = 512; private const int Bits = 10; private readonly Dictionary<int, int> revs = new Dictionary<int, int>(); public int Count => revs.Count; public static bool InRange(int zoneX, int zoneY) { if (zoneX > -512 && zoneX < 512 && zoneY > -512) { return zoneY < 512; } return false; } public static int Key(int zoneX, int zoneY) { return (zoneY + 512 << 10) | (zoneX + 512); } public static void Split(int key, out int zoneX, out int zoneY) { zoneX = (key & 0x3FF) - 512; zoneY = (key >> 10) - 512; } public int Get(int zoneX, int zoneY) { if (!InRange(zoneX, zoneY) || !revs.TryGetValue(Key(zoneX, zoneY), out var value)) { return 0; } return value; } public bool Raise(int zoneX, int zoneY, int rev) { if (InRange(zoneX, zoneY)) { return RaiseKey(Key(zoneX, zoneY), rev); } return false; } public bool RaiseAll(ZoneRevs other) { bool flag = false; foreach (KeyValuePair<int, int> rev in other.revs) { flag |= RaiseKey(rev.Key, rev.Value); } return flag; } public int GetKey(int key) { if (!revs.TryGetValue(key, out var value)) { return 0; } return value; } public bool RaiseKey(int key, int rev) { if (rev <= 0 || (revs.TryGetValue(key, out var value) && value >= rev)) { return false; } revs[key] = rev; return true; } public void Clear() { revs.Clear(); } public int CountAlsoIn(ZoneRevs other) { int num = 0; foreach (int key in revs.Keys) { num += (other.revs.ContainsKey(key) ? 1 : 0); } return num; } public ZoneRevs Clone() { ZoneRevs zoneRevs = new ZoneRevs(); foreach (KeyValuePair<int, int> rev in revs) { zoneRevs.revs[rev.Key] = rev.Value; } return zoneRevs; } public void Write(BinaryWriter w) { List<int> list = new List<int>(revs.Keys); list.Sort(); MapIO.WriteVar(w, list.Count); int num = 0; foreach (int item in list) { MapIO.WriteVar(w, item - num); MapIO.WriteVar(w, revs[item]); num = item; } } public static ZoneRevs Read(BinaryReader r) { ZoneRevs zoneRevs = new ZoneRevs(); int num = MapIO.ReadVar(r); if (num > 1048576) { throw new InvalidDataException("zone snapshot list of " + num); } int num2 = 0; for (int i = 0; i < num; i++) { num2 += MapIO.ReadVar(r); int num3 = MapIO.ReadVar(r); if (num2 >= 1048576) { throw new InvalidDataException("zone snapshot list runs out of the world"); } if (num3 > 0) { zoneRevs.revs[num2] = num3; } } return zoneRevs; } } internal static class ZoneGrid { public const float ZoneSize = 64f; public const float Overhang = 64f; public static int ZoneOf(float w) { return (int)Math.Floor(((double)w + 32.0) / 64.0); } public static List<int> Touching(float x, float z, float radius) { List<int> list = new List<int>(); for (int i = ZoneOf(z - radius); i <= ZoneOf(z + radius); i++) { for (int j = ZoneOf(x - radius); j <= ZoneOf(x + radius); j++) { float num = Math.Max((float)j * 64f - 32f, Math.Min(x, (float)j * 64f + 32f)); float num2 = Math.Max((float)i * 64f - 32f, Math.Min(z, (float)i * 64f + 32f)); if ((num - x) * (num - x) + (num2 - z) * (num2 - z) <= radius * radius && ZoneRevs.InRange(j, i)) { list.Add(ZoneRevs.Key(j, i)); } } } return list; } public static List<int> WithoutRev(BitArray cells, int textureSize, float pixelSize, ZoneRevs revs) { HashSet<int> hashSet = new HashSet<int>(); byte[] array = MapBits.Pack(cells); float num = textureSize / 2; int num2 = -1; for (int i = 0; i < array.Length; i++) { int num3 = array[i]; if (num3 == 0) { continue; } for (int j = 0; j < 8; j++) { if ((num3 & (1 << j)) != 0) { int num4 = i * 8 + j; int zoneX = ZoneOf(((float)(num4 % textureSize) - num) * pixelSize); int zoneY = ZoneOf(((float)(num4 / textureSize) - num) * pixelSize); int num5 = ZoneRevs.Key(zoneX, zoneY); if (num5 != num2 && ZoneRevs.InRange(zoneX, zoneY)) { num2 = num5; hashSet.Add(num5); } } } } HashSet<int> hashSet2 = new HashSet<int>(); foreach (int item in hashSet) { ZoneRevs.Split(item, out var zoneX2, out var zoneY2); for (int k = -1; k <= 1; k++) { for (int l = -1; l <= 1; l++) { if (ZoneRevs.InRange(zoneX2 + l, zoneY2 + k) && revs.Get(zoneX2 + l, zoneY2 + k) == 0) { hashSet2.Add(ZoneRevs.Key(zoneX2 + l, zoneY2 + k)); } } } } List<int> list = new List<int>(hashSet2); list.Sort(); return list; } } internal sealed class MapData { public const string CustomDataKey = "q8pm_map"; public const string StatsKey = "q8pm_stats"; private const byte FormatVersion = 2; public long WorldUid; public int TextureSize; public BitArray Explored; public BitArray Pending; public List<PinRecord> Pins = new List<PinRecord>(); public List<Vector3> Tombstones = new List<Vector3>(); public bool HasView; public float ViewX; public float ViewZ; public ZoneRevs DrawnRevs = new ZoneRevs(); public ZoneRevs PendingRevs = new ZoneRevs(); public bool SurveyChecked; public static MapData CreateNew(long worldUid, int textureSize) { return new MapData { WorldUid = worldUid, TextureSize = textureSize, Explored = new BitArray(textureSize * textureSize), Pending = new BitArray(textureSize * textureSize) }; } public string ToBlob() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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) using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(WorldUid); binaryWriter.Write(TextureSize); MapIO.WriteBits(binaryWriter, Explored); bool flag = MapBits.Any(Pending); binaryWriter.Write(flag); if (flag) { MapIO.WriteBits(binaryWriter, Pending); } MapIO.WritePins(binaryWriter, Pins); binaryWriter.Write(Tombstones.Count); foreach (Vector3 tombstone in Tombstones) { binaryWriter.Write(tombstone.x); binaryWriter.Write(tombstone.z); } binaryWriter.Write(HasView); binaryWriter.Write(ViewX); binaryWriter.Write(ViewZ); DrawnRevs.Write(binaryWriter); PendingRevs.Write(binaryWriter); binaryWriter.Flush(); return Convert.ToBase64String(MapIO.Wrap(2, memoryStream.ToArray())); } public static MapData FromBlob(string blob, out string error) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) error = null; try { byte version; using BinaryReader binaryReader = new BinaryReader(new MemoryStream(MapIO.Unwrap(Convert.FromBase64String(blob), 2, out version))); MapData mapData = new MapData(); mapData.WorldUid = binaryReader.ReadInt64(); mapData.TextureSize = binaryReader.ReadInt32(); int num = mapData.TextureSize * mapData.TextureSize; mapData.Explored = MapIO.ReadBits(binaryReader, num); mapData.Pending = (binaryReader.ReadBoolean() ? MapIO.ReadBits(binaryReader, num) : new BitArray(num)); mapData.Pins = MapIO.ReadPins(binaryReader); int num2 = binaryReader.ReadInt32(); for (int i = 0; i < num2; i++) { float num3 = binaryReader.ReadSingle(); float num4 = binaryReader.ReadSingle(); mapData.Tombstones.Add(new Vector3(num3, 0f, num4)); } mapData.HasView = binaryReader.ReadBoolean(); mapData.ViewX = binaryReader.ReadSingle(); mapData.ViewZ = binaryReader.ReadSingle(); if (version >= 2) { mapData.DrawnRevs = ZoneRevs.Read(binaryReader); mapData.PendingRevs = ZoneRevs.Read(binaryReader); } return mapData; } catch (Exception ex) { error = ex.GetType().Name + ": " + ex.Message; return null; } } } internal sealed class TableData { public const string ZdoKey = "q8pm_table"; private const byte FormatVersion = 2; public int TextureSize; public BitArray Explored; public List<PinRecord> Pins = new List<PinRecord>(); public ZoneRevs Revs = new ZoneRevs(); public static TableData CreateNew(int textureSize) { return new TableData { TextureSize = textureSize, Explored = new BitArray(textureSize * textureSize) }; } public byte[] ToBytes() { using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(TextureSize); MapIO.WriteBits(binaryWriter, Explored); MapIO.WritePins(binaryWriter, Pins); Revs.Write(binaryWriter); binaryWriter.Flush(); return MapIO.Wrap(2, memoryStream.ToArray()); } public static TableData FromBytes(byte[] bytes, out string error) { error = null; try { byte version; using BinaryReader binaryReader = new BinaryReader(new MemoryStream(MapIO.Unwrap(bytes, 2, out version))); TableData tableData = new TableData(); tableData.TextureSize = binaryReader.ReadInt32(); tableData.Explored = MapIO.ReadBits(binaryReader, tableData.TextureSize * tableData.TextureSize); tableData.Pins = MapIO.ReadPins(binaryReader); if (version >= 2) { tableData.Revs = ZoneRevs.Read(binaryReader); } return tableData; } catch (Exception ex) { error = ex.GetType().Name + ": " + ex.Message; return null; } } } internal static class MapIO { public static byte[] Wrap(byte version, byte[] raw) { byte[] array = MapBits.Compress(raw); byte[] array2 = new byte[array.Length + 1]; array2[0] = version; Buffer.BlockCopy(array, 0, array2, 1, array.Length); return array2; } public static byte[] Unwrap(byte[] bytes, byte newestVersion, out byte version) { if (bytes == null || bytes.Length < 2) { throw new InvalidDataException("empty data"); } version = bytes[0]; if (version < 1 || version > newestVersion) { throw new InvalidDataException("unknown format version " + version); } return MapBits.Decompress(bytes, 1); } public static void WriteVar(BinaryWriter w, int value) { uint num; for (num = (uint)value; num >= 128; num >>= 7) { w.Write((byte)(num | 0x80)); } w.Write((byte)num); } public static int ReadVar(BinaryReader r) { int num = 0; for (int i = 0; i <= 28; i += 7) { byte b = r.ReadByte(); num |= (b & 0x7F) << i; if ((b & 0x80) == 0) { if (num < 0) { throw new InvalidDataException("negative number"); } return num; } } throw new InvalidDataException("number too long"); } public static void WriteBits(BinaryWriter w, BitArray bits) { byte[] array = MapBits.Pack(bits); w.Write(array.Length); w.Write(array); } public static BitArray ReadBits(BinaryReader r, int bitCount) { int num = r.ReadInt32(); if (num != (bitCount + 7) / 8) { throw new InvalidDataException("bitmap size " + num + " does not match map size"); } return MapBits.Unpack(r.ReadBytes(num), bitCount); } public static void WritePins(BinaryWriter w, List<PinRecord> pins) { w.Write(pins.Count); foreach (PinRecord pin in pins) { w.Write(pin.Name ?? ""); w.Write(pin.Pos.x); w.Write(pin.Pos.y); w.Write(pin.Pos.z); w.Write(pin.Type); w.Write(pin.Checked); } } public static List<PinRecord> ReadPins(BinaryReader r) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) int num = r.ReadInt32(); List<PinRecord> list = new List<PinRecord>(num); for (int i = 0; i < num; i++) { PinRecord pinRecord = new PinRecord(); pinRecord.Name = r.ReadString(); float num2 = r.ReadSingle(); float num3 = r.ReadSingle(); float num4 = r.ReadSingle(); pinRecord.Pos = new Vector3(num2, num3, num4); pinRecord.Type = r.ReadInt32(); pinRecord.Checked = r.ReadBoolean(); list.Add(pinRecord); } return list; } } internal static class MapItem { public const string PrefabName = "Q8_ParchmentMap"; public const string NameToken = "$item_q8pm_parchment"; public const string DescriptionToken = "$item_q8pm_parchment_desc"; private const string BasePrefabName = "DeerHide"; private const string HandModelName = "model"; private const float SheetWidth = 0.44f; private const float SheetHeight = 0.33f; private static readonly FieldRef<VisEquipment, GameObject> RightItemInstanceRef = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static Transform handModel; internal static bool IsParchment(ItemData item) { if (item != null && item.m_shared != null) { return item.m_shared.m_name == "$item_q8pm_parchment"; } return false; } internal static void Register() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown PrefabManager.OnVanillaPrefabsAvailable -= Register; GameObject val = PrefabManager.Instance.CreateClonedPrefab("Q8_ParchmentMap", "DeerHide"); if ((Object)(object)val == (Object)null) { ParchmentMapPlugin.Log.LogError((object)"Base prefab DeerHide not found, the parchment map is not added."); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { ParchmentMapPlugin.Log.LogError((object)"Base prefab DeerHide has no ItemDrop, the parchment map is not added."); return; } bool flag = (int)SystemInfo.graphicsDeviceType == 4; if (!flag) { try { BuildVisuals(val); } catch (Exception ex) { ParchmentMapPlugin.Log.LogWarning((object)("Could not build the parchment model: " + ex.Message)); } } component.m_autoDestroy = false; SharedData shared = component.m_itemData.m_shared; shared.m_itemType = (ItemType)19; shared.m_animationState = (AnimationState)5; shared.m_attachOverride = (ItemType)0; shared.m_maxStackSize = 1; shared.m_autoStack = false; shared.m_maxQuality = 1; shared.m_weight = 0.3f; shared.m_value = 0; shared.m_teleportable = true; shared.m_questItem = false; shared.m_equipDuration = 0.5f; shared.m_useDurability = false; shared.m_canBeReparied = false; shared.m_buildPieces = null; shared.m_equipStatusEffect = null; shared.m_attackStatusEffect = null; shared.m_consumeStatusEffect = null; shared.m_setStatusEffect = null; shared.m_setName = ""; shared.m_setSize = 0; shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodEitr = 0f; shared.m_variants = 0; shared.m_attack = (Attack)(((object)shared.m_attack) ?? ((object)new Attack())); shared.m_secondaryAttack = (Attack)(((object)shared.m_secondaryAttack) ?? ((object)new Attack())); shared.m_attack.m_attackAnimation = ""; shared.m_secondaryAttack.m_attackAnimation = ""; ItemConfig val2 = new ItemConfig { Name = "$item_q8pm_parchment", Description = "$item_q8pm_parchment_desc" }; if (!flag) { val2.CraftingStation = CraftingStations.Workbench; val2.MinStationLevel = 1; val2.Amount = 1; val2.Icons = (Sprite[])(object)new Sprite[1] { LoadIcon() }; val2.Requirements = ParseRecipe(ParchmentMapPlugin.Recipe.Value).ToArray(); } if (!ItemManager.Instance.AddItem(new CustomItem(val, false, val2))) { ParchmentMapPlugin.Log.LogError((object)"Jotunn rejected the parchment map item."); } } internal static List<RequirementConfig> ParseRecipe(string text) { //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown List<RequirementConfig> list = new List<RequirementConfig>(); string[] array = (text ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { string[] array2 = text2.Split(new char[1] { ':' }); if (array2.Length != 2 || array2[0].Trim().Length == 0 || !int.TryParse(array2[1].Trim(), out var result) || result < 1) { ParchmentMapPlugin.Log.LogWarning((object)("Recipe entry '" + text2 + "' is ignored, expected Item:amount.")); } else { list.Add(new RequirementConfig(array2[0].Trim(), result, 0, true)); } } if (list.Count == 0) { list.Add(new RequirementConfig("DeerHide", 2, 0, true)); } return list; } internal static void ApplyRecipeToObjectDB() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown if ((Object)(object)ObjectDB.instance == (Object)null) { return; } Recipe val = ObjectDB.instance.m_recipes.Find((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)((Component)r.m_item).gameObject).name == "Q8_ParchmentMap"); if ((Object)(object)val == (Object)null) { return; } List<Requirement> list = new List<Requirement>(); foreach (RequirementConfig item in ParseRecipe(ParchmentMapPlugin.Recipe.Value)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Item); ItemDrop val2 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 == (Object)null) { ParchmentMapPlugin.Log.LogWarning((object)("Recipe item '" + item.Item + "' does not exist and is ignored.")); continue; } list.Add(new Requirement { m_resItem = val2, m_amount = item.Amount, m_amountPerLevel = 0, m_recover = true }); } if (list.Count > 0) { val.m_resources = list.ToArray(); } } private static void BuildVisuals(GameObject prefab) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0059: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) MeshRenderer componentInChildren = prefab.GetComponentInChildren<MeshRenderer>(true); Material val = (((Object)(object)componentInChildren != (Object)null && (Object)(object)((Renderer)componentInChildren).sharedMaterial != (Object)null) ? new Material(((Renderer)componentInChildren).sharedMaterial) : new Material(Shader.Find("Standard"))); ((Object)val).name = "q8pm_parchment"; val.mainTexture = (Texture)(object)LoadTexture("parchment.png", repeat: false); val.color = Color.white; if (val.HasProperty("_Cull")) { val.SetFloat("_Cull", 0f); } string[] array = new string[3] { "_BumpMap", "_MetallicGlossMap", "_EmissionMap" }; foreach (string text in array) { if (val.HasProperty(text)) { val.SetTexture(text, (Texture)null); } } array = new string[2] { "_Metallic", "_Glossiness" }; foreach (string text2 in array) { if (val.HasProperty(text2)) { val.SetFloat(text2, 0f); } } for (int num = prefab.transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)prefab.transform.GetChild(num)).gameObject); } LODGroup component = prefab.GetComponent<LODGroup>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } Mesh mesh = BuildSheetMesh(); GameObject obj = CreateSheet("ground", prefab.transform, mesh, val); obj.transform.localPosition = new Vector3(0f, 0.02f, 0f); obj.transform.localRotation = Quaternion.Euler(90f, 0f, 0f); GameObject val2 = new GameObject("attach"); val2.layer = prefab.layer; val2.transform.SetParent(prefab.transform, false); handModel = CreateSheet("model", val2.transform, mesh, val).transform; val2.SetActive(false); ApplyHandPose(); if ((Object)(object)prefab.GetComponentInChildren<Collider>(true) == (Object)null) { BoxCollider obj2 = prefab.AddComponent<BoxCollider>(); obj2.size = new Vector3(0.44f, 0.04f, 0.33f); obj2.center = new Vector3(0f, 0.02f, 0f); } } private static GameObject CreateSheet(string name, Transform parent, Mesh mesh, Material material) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown GameObject val = new GameObject(name) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); val.AddComponent<MeshFilter>().sharedMesh = mesh; ((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = material; return val; } private static Mesh BuildSheetMesh() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //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_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_0148: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown int num = 9; Vector3[] array = (Vector3[])(object)new Vector3[num * 2]; Vector3[] array2 = (Vector3[])(object)new Vector3[num * 2]; Vector2[] array3 = (Vector2[])(object)new Vector2[num * 2]; for (int i = 0; i < num; i++) { float num2 = (float)i / 8f; float num3 = (num2 - 0.5f) * 0.44f; float num4 = -0.018f * Mathf.Sin(num2 * (float)Math.PI); for (int j = 0; j < 2; j++) { int num5 = i * 2 + j; array[num5] = new Vector3(num3, ((float)j - 0.5f) * 0.33f, num4); array2[num5] = Vector3.back; array3[num5] = new Vector2(num2, (float)j); } } int[] array4 = new int[48]; int num6 = 0; for (int k = 0; k < 8; k++) { int num7 = k * 2; int num8 = num7 + 1; int num9 = num7 + 2; int num10 = num7 + 3; array4[num6++] = num7; array4[num6++] = num8; array4[num6++] = num9; array4[num6++] = num9; array4[num6++] = num8; array4[num6++] = num10; } Mesh val = new Mesh { name = "q8pm_sheet", vertices = array, normals = array2, uv = array3, triangles = array4 }; val.RecalculateBounds(); return val; } internal static void ApplyHandPose() { if ((Object)(object)handModel != (Object)null) { SetPose(handModel); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && IsParchment(((Humanoid)localPlayer).RightItem)) { VisEquipment component = ((Component)localPlayer).GetComponent<VisEquipment>(); GameObject val = (((Object)(object)component != (Object)null) ? RightItemInstanceRef.Invoke(component) : null); Transform val2 = (((Object)(object)val != (Object)null) ? val.transform.Find("model") : null); if ((Object)(object)val2 != (Object)null) { SetPose(val2); } } } private static void SetPose(Transform model) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) model.localPosition = ParchmentMapPlugin.HandPosition.Value; model.localRotation = Quaternion.Euler(ParchmentMapPlugin.HandRotation.Value); model.localScale = Vector3.one * Mathf.Clamp(ParchmentMapPlugin.HandScale.Value, 0.1f, 5f); } private static Sprite LoadIcon() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture("icon.png", repeat: false); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } private static Texture2D LoadTexture(string resourceName, bool repeat) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0122: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); if (stream == null) { throw new FileNotFoundException("embedded resource is missing"); } byte[] array = new byte[stream.Length]; int num; for (int i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule"); MethodInfo methodInfo = ((type != null) ? type.GetMethod("LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }) : null); if (methodInfo == null || !(bool)methodInfo.Invoke(null, new object[2] { val, array })) { throw new InvalidDataException("the image could not be decoded"); } } catch (Exception ex) { ParchmentMapPlugin.Log.LogWarning((object)("Could not load " + resourceName + ": " + ex.Message)); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.85f, 0.75f, 0.55f, 1f); val.SetPixels((Color[])(object)new Color[4] { val2, val2, val2, val2 }); val.Apply(); } ((Object)val).name = "q8pm_" + resourceName; ((Texture)val).wrapMode = (TextureWrapMode)(!repeat); return val; } } internal static class MapSession { private static readonly FieldRef<Minimap, BitArray> ExploredRef = AccessTools.FieldRefAccess<Minimap, BitArray>("m_explored"); private static readonly FieldRef<Minimap, BitArray> ExploredOthersRef = AccessTools.FieldRefAccess<Minimap, BitArray>("m_exploredOthers"); private static readonly FieldRef<Minimap, Texture2D> FogTextureRef = AccessTools.FieldRefAccess<Minimap, Texture2D>("m_fogTexture"); private static readonly FieldRef<Minimap, bool> HasGeneratedRef = AccessTools.FieldRefAccess<Minimap, bool>("m_hasGenerated"); private static readonly FieldRef<Minimap, List<PinData>> PinsRef = AccessTools.FieldRefAccess<Minimap, List<PinData>>("m_pins"); private static readonly FieldRef<Minimap, Vector3> MapOffsetRef = AccessTools.FieldRefAccess<Minimap, Vector3>("m_mapOffset"); private static readonly FieldRef<Minimap, bool> PinUpdateRequiredRef = AccessTools.FieldRefAccess<Minimap, bool>("m_pinUpdateRequired"); private static readonly MethodInfo LoadMapDataMethod = AccessTools.Method(typeof(Minimap), "LoadMapData", (Type[])null, (Type[])null); private static readonly Func<Minimap, Vector3, bool> IsExploredMethod = AccessTools.MethodDelegate<Func<Minimap, Vector3, bool>>(AccessTools.Method(typeof(Minimap), "IsExplored", (Type[])null, (Type[])null), (object)null, true); private static readonly Color32 FogHidden = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue); private static readonly Color32 FogSeen = new Color32((byte)0, byte.MaxValue, byte.MaxValue, byte.MaxValue); private const double WorldRadius = 10500.0; internal static bool InTouchZoom; private static MapData data; private static bool dirty; private static bool noMapByRule; private static bool wasManaging; private static bool fogLoaded; private static ItemData cachedItem; private static string cachedBlob; private static ItemData rejectedItem; private static Color32[] fogBuffer; private static bool faulted; private const float SurveyAgainAfter = 120f; private const int CheckBatch = 96; private const float CheckTimeout = 20f; private const float AskAgainAfter = 300f; private static readonly Dictionary<int, float> surveyedAt = new Dictionary<int, float>(); private static List<int> checkQueue; private static bool checkInFlight; private static float checkSentAt; private static float surveysOffUntil; internal static ItemData Held { get; private set; } internal static bool IsActive => Held != null; internal static bool Loading { get; private set; } internal static bool PictureMode { get { if (IsActive) { return !ParchmentMapPlugin.LiveMarkers.Value; } return false; } } internal static Vector3 Anchor { get; private set; } internal static void ResetSession() { faulted = false; Held = null; data = null; dirty = false; wasManaging = false; fogLoaded = false; cachedItem = null; cachedBlob = null; rejectedItem = null; fogBuffer = null; Loading = false; surveyedAt.Clear(); checkQueue = null; checkInFlight = false; surveysOffUntil = 0f; } internal static void Tick(Minimap minimap) { if (faulted) { return; } try { TickCore(minimap); } catch (Exception ex) { faulted = true; Held = null; ParchmentMapPlugin.Log.LogError((object)("Parchment map is switched off until you re-enter the world: " + ex)); } } private static void TickCore(Minimap minimap) { if (!HasGeneratedRef.Invoke(minimap)) { return; } if (ParchmentMapPlugin.ReplaceVanillaMap.Value) { ApplyReplaceRule(); } else if (noMapByRule) { Game.UpdateNoMap(); } bool noMap = Game.m_noMap; if (noMap != wasManaging) { wasManaging = noMap; if (noMap) { BeginManaging(minimap); } else { EndManaging(minimap); } } if (noMap) { Player localPlayer = Player.m_localPlayer; ItemData val = (((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead()) ? ((Humanoid)localPlayer).RightItem : null); if (Held != null && val != Held) { Deactivate(); } if (val != rejectedItem) { rejectedItem = null; } if (Held == null && val != null && rejectedItem == null && MapItem.IsParchment(val)) { Activate(minimap, localPlayer, val); } if (Held != null) { PumpSurveyCheck(); } } } internal static void OnNoMapUpdated() { noMapByRule = false; ApplyReplaceRule(); } private static void ApplyReplaceRule() { if (!Game.m_noMap && ParchmentMapPlugin.ReplaceVanillaMap.Value) { Game.m_noMap = true; noMapByRule = true; Minimap instance = Minimap.instance; if ((Object)(object)instance != (Object)null) { instance.SetMapMode((MapMode)0); } } } private static void BeginManaging(Minimap minimap) { minimap.Reset(); RemoveSavedPins(minimap); fogLoaded = false; cachedItem = null; cachedBlob = null; ParchmentMapPlugin.Log.LogInfo((object)(noMapByRule ? "This world has the map enabled: the parchment map replaces it (rule ReplaceVanillaMap)" : "This world has no map: the only map is the parchment map")); } private static void EndManaging(Minimap minimap) { Deactivate(); fogLoaded = false; cachedItem = null; cachedBlob = null; fogBuffer = null; if ((Object)(object)Game.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } try { minimap.Reset(); LoadMapDataMethod.Invoke(minimap, null); } catch (Exception ex) { ParchmentMapPlugin.Log.LogWarning((object)("Could not restore the character's own map: " + ex.Message)); } } private static void Activate(Minimap minimap, Player player, ItemData item) { //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) int textureSize = minimap.m_textureSize; long num = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetWorldUID() : 0); item.m_customData.TryGetValue("q8pm_map", out var value); if (!fogLoaded || data == null || item != cachedItem || !(value == cachedBlob)) { MapData mapData; if (string.IsNullOrEmpty(value)) { mapData = MapData.CreateNew(num, textureSize); } else { mapData = MapData.FromBlob(value, out var error); if (mapData == null || mapData.TextureSize != textureSize) { ParchmentMapPlugin.Log.LogWarning((object)("Map data of this parchment cannot be read: " + (error ?? ("map size " + mapData.TextureSize + " instead of " + textureSize)))); Reject(player, item, "$q8pm_msg_unreadable"); return; } if (mapData.WorldUid != num) { Reject(player, item, "$q8pm_msg_otherworld"); return; } } data = mapData; SetExplored(minimap, data.Explored); cachedItem = item; cachedBlob = value; fogLoaded = true; dirty = false; ParchmentMapPlugin.Log.LogInfo((object)("Parchment map in hand: " + Describe())); } Held = item; Anchor = (Vector3)(data.HasView ? new Vector3(data.ViewX, 0f, data.ViewZ) : CentreOf(minimap, data.Explored)); MapOffsetRef.Invoke(minimap) = Vector3.zero; ReplacePins(minimap, data.Pins); if (!ParchmentMapPlugin.RevealAtTableOnly.Value && (MapBits.Any(data.Pending) || data.PendingRevs.Count > 0) && CommitPending(minimap)) { UploadFog(minimap); } surveyedAt.Clear(); StartSurveyCheck(minimap); SurveyAround(((Component)player).transform.position, minimap.m_exploreRadius * ParchmentMapPlugin.ExploreRadiusMultiplier.Value); } private static void Reject(Player player, ItemData item, string message) { rejectedItem = item; ((Character)player).Message((MessageType)2, message, 0, (Sprite)null, false); } internal static void Deactivate() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (Held != null) { Flush(); Held = null; checkQueue = null; checkInFlight = false; Minimap instance = Minimap.instance; if ((Object)(object)instance != (Object)null) { RemoveSavedPins(instance); MapOffsetRef.Invoke(instance) = Vector3.zero; instance.SetMapMode((MapMode)0); } } } internal static void MarkDirty() { dirty = true; } internal static void Flush() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if (Held != null && data != null && !((Object)(object)instance == (Object)null)) { FoldView(instance); List<PinRecord> list = CapturePins(instance); if (dirty || !SamePins(list, data.Pins)) { data.Explored = new BitArray(ExploredRef.Invoke(instance)); data.Pins = list; data.HasView = true; data.ViewX = Anchor.x; data.ViewZ = Anchor.z; string text = data.ToBlob(); Held.m_customData["q8pm_map"] = text; Held.m_customData["q8pm_stats"] = BuildStats(instance); cachedItem = Held; cachedBlob = text; dirty = false; ParchmentMapPlugin.Log.LogInfo((object)("Map saved into the parchment: " + Describe() + ", " + text.Length / 1024 + " KB")); } } } internal static void FoldView(Minimap minimap) { //IL_0013: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0026: Unknown result type (might be due to invalid IL or missing references) if (PictureMode) { Vector3 val = MapOffsetRef.Invoke(minimap); if (val.x != 0f || val.z != 0f) { Anchor = new Vector3(Anchor.x + val.x, 0f, Anchor.z + val.z); MapOffsetRef.Invoke(minimap) = Vector3.zero; dirty = true; } } } internal static void LookAt(Minimap minimap, Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Anchor = new Vector3(point.x, 0f, point.z); MapOffsetRef.Invoke(minimap) = Vector3.zero; dirty = true; } internal static void RebaseTouchOffset(Minimap minimap, Player player) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0026: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_0056: Unknown result type (might be due to invalid IL or missing references) Vector3 val = MapOffsetRef.Invoke(minimap); Vector3 val2 = Anchor - ((Component)player).transform.position; MapOffsetRef.Invoke(minimap) = new Vector3(val.x - val2.x, 0f, val.z - val2.z); } internal static bool IsDrawn(Minimap minimap, Vector3 pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return IsExploredMethod(minimap, pos); } private static Vector3 CentreOf(Minimap minimap, BitArray cells) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!MapBits.Centroid(cells, minimap.m_textureSize, out var x, out var y)) { return Vector3.zero; } float num = minimap.m_textureSize / 2; return new Vector3((x - num) * minimap.m_pixelSize, 0f, (y - num) * minimap.m_pixelSize); } private static bool SamePins(List<PinRecord> a, List<PinRecord> b) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (a.Count != b.Count) { return false; } for (int i = 0; i < a.Count; i++) { if (a[i].Name != b[i].Name || a[i].Pos != b[i].Pos || a[i].Type != b[i].Type || a[i].Checked != b[i].Checked) { return false; } } return true; } private static string Describe() { return MapBits.Count(data.Explored) + " cells drawn, " + MapBits.Count(data.Pending) + " noted, " + data.Pins.Count + " marks, " + data.DrawnRevs.Count + " zone snapshots drawn, " + data.PendingRevs.Count + " noted"; } internal static int RevisionOf(int zoneX, int zoneY) { if (Held == null || data == null) { return -1; } return data.DrawnRevs.Get(zoneX, zoneY); } internal static void SurveyAround(Vector3 position, float radius) { //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) if (Held == null || data == null || Time.time < surveysOffUntil || !SatelliteLink.CanSurvey) { return; } float time = Time.time; List<int> list = null; foreach (int item in ZoneGrid.Touching(position.x, position.z, radius + 64f)) { if (!surveyedAt.TryGetValue(item, out var value) || time - value > 120f) { (list ?? (list = new List<int>())).Add(item); } } if (list == null || !RequestSurvey(list, walked: true)) { return; } foreach (int item2 in list) { surveyedAt[item2] = time; } } private static bool RequestSurvey(List<int> keys, bool walked) { int[] array = new int[keys.Count]; int[] array2 = new int[keys.Count]; for (int i = 0; i < keys.Count; i++) { ZoneRevs.Split(keys[i], out array[i], out array2[i]); } ItemData item = Held; bool toNotes = walked && ParchmentMapPlugin.RevealAtTableOnly.Value; return SatelliteLink.Survey(array, array2, delegate(int[] zoneXs, int[] zoneYs, int[] revs) { OnSurveyed(item, zoneXs, zoneYs, revs, toNotes, !walked); }); } private static void OnSurveyed(ItemData item, int[] zoneXs, int[] zoneYs, int[] revs, bool toNotes, bool isCheck) { if (isCheck) { checkInFlight = false; if (zoneXs.Length == 0) { surveysOffUntil = Time.time + 300f; checkQueue = null; } } if (Held == null || Held != item || data == null) { return; } bool flag = false; for (int i = 0; i < zoneXs.Length; i++) { if (!toNotes) { flag |= data.DrawnRevs.Raise(zoneXs[i], zoneYs[i], revs[i]); } else if (revs[i] > data.DrawnRevs.Get(zoneXs[i], zoneYs[i])) { dirty |= data.PendingRevs.Raise(zoneXs[i], zoneYs[i], revs[i]); } } if (flag) { dirty = true; SatelliteLink.NotifyExploredChanged(); } } private static void StartSurveyCheck(Minimap minimap) { checkQueue = null; checkInFlight = false; if (data != null && !data.SurveyChecked && !(Time.time < surveysOffUntil) && SatelliteLink.CanSurvey) { List<int> list = ZoneGrid.WithoutRev(ExploredRef.Invoke(minimap), minimap.m_textureSize, minimap.m_pixelSize, data.DrawnRevs); if (list.Count == 0) { data.SurveyChecked = true; return; } checkQueue = list; ParchmentMapPlugin.Log.LogInfo((object)(list.Count + " zones of this map have no snapshot yet: they are being recorded as they are now")); } } private static void PumpSurveyCheck() { if (checkQueue == null) { return; } if (checkInFlight) { if (Time.time - checkSentAt > 20f) { checkInFlight = false; checkQueue = null; surveysOffUntil = Time.time + 300f; } return; } if (checkQueue.Count == 0) { checkQueue = null; data.SurveyChecked = true; return; } int num = Math.Min(96, checkQueue.Count); List<int> range = checkQueue.GetRange(checkQueue.Count - num, num); checkQueue.RemoveRange(checkQueue.Count - num, num); checkInFlight = true; checkSentAt = Time.time; if (!RequestSurvey(range, walked: false)) { checkInFlight = false; checkQueue = null; } } internal static void AddPending(Minimap minimap, int x, int y) { int num = y * minimap.m_textureSize + x; if (num >= 0 && num < data.Pending.Length && !ExploredRef.Invoke(minimap)[num] && !data.Pending[num]) { data.Pending[num] = true; dirty = true; } } internal static void ForgetPin(Vector3 pos) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (data != null) { PinMerge.Bury(data.Tombstones, pos); dirty = true; } } internal static void RememberPin(Vector3 pos) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (data != null) { PinMerge.Unbury(data.Tombstones, pos); dirty = true; } } internal static bool UseTable(MapTable table, Humanoid user, bool write) { //IL_0039: 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_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: 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_0225: Unknown result type (might be due to invalid IL or missing references) Minimap instance = Minimap.instance; if ((Object)(object)instance == (Object)null) { return false; } if (!IsActive || data == null) { ((Character)user).Message((MessageType)2, "$q8pm_msg_needmap", 0, (Sprite)null, false); return false; } if (write && !PrivateArea.CheckAccess(((Component)table).transform.position, 0f, true, false)) { return true; } ZNetView component = ((Component)table).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } ZDO zDO = component.GetZDO(); int stableHashCode = StringExtensionMethods.GetStableHashCode("q8pm_table"); int textureSize = instance.m_textureSize; BitArray before = new BitArray(ExploredRef.Invoke(instance)); bool flag = CommitPending(instance); TableData tableData = null; byte[] byteArray = zDO.GetByteArray(stableHashCode, (byte[])null); if (byteArray != null) { tableData = TableData.FromBytes(byteArray, out var error); if (tableData == null || tableData.TextureSize != textureSize) { ParchmentMapPlugin.Log.LogWarning((object)("Records of this cartography table cannot be read: " + (error ?? ("map size " + tableData.TextureSize + " instead of " + textureSize)))); ((Character)user).Message((MessageType)2, "$q8pm_msg_tableunreadable", 0, (Sprite)null, false); if (flag) { UploadFog(instance); Flush(); } return false; } } if (tableData != null) { BitArray obj = ExploredRef.Invoke(instance); int num = MapBits.Count(obj); obj.Or(tableData.Explored); if (MapBits.Count(obj) != num) { flag = true; data.SurveyChecked = false; } if (data.DrawnRevs.RaiseAll(tableData.Revs)) { flag = true; } List<PinRecord> list = PinMerge.FromTable(CapturePins(instance), data.Tombstones, tableData.Pins); if (list.Count > 0) { flag = true; Loading = true; try { foreach (PinRecord item in list) { AddPin(instance, item); } } finally { Loading = false; } } } if (flag) { UploadFog(instance); dirty = true; BitArray bitArray = MapBits.Added(before, ExploredRef.Invoke(instance)); if (PictureMode && MapBits.Any(bitArray)) { LookAt(instance, CentreOf(instance, bitArray)); } } if (write) { if (tableData == null) { tableData = TableData.CreateNew(textureSize); } tableData.Explored.Or(ExploredRef.Invoke(instance)); tableData.Revs.RaiseAll(data.DrawnRevs); PinMerge.IntoTable(tableData.Pins, CapturePins(instance), data.Tombstones); component.ClaimOwnership(); zDO.Set(stableHashCode, tableData.ToBytes()); table.m_writeEffects.Create(((Component)table).transform.position, ((Component)table).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); } Flush(); StartSurveyCheck(instance); ParchmentMapPlugin.Log.LogInfo((object)("Cartography table " + (write ? "write" : "read") + ": " + Describe() + ((tableData != null) ? (", table has " + MapBits.Count(tableData.Explored) + " cells and " + tableData.Pins.Count + " marks") : ", table is empty"))); string text = (write ? "$q8pm_msg_written" : ((!flag) ? ((tableData == null) ? "$q8pm_msg_tableempty" : "$q8pm_msg_uptodate") : "$q8pm_msg_updated")); ((Character)user).Message((MessageType)2, text, 0, (Sprite)null, false); return true; } private static bool CommitPending(Minimap minimap) { if (data == null) { return false; } bool flag = false; if (MapBits.Any(data.Pending)) { ExploredRef.Invoke(minimap).Or(data.Pending); data.Pending.SetAll(value: false); data.SurveyChecked = false; flag = true; } if (data.PendingRevs.Count > 0) { flag |= data.DrawnRevs.RaiseAll(data.PendingRevs); data.PendingRevs.Clear(); dirty = true; } if (flag) { dirty = true; } return flag; } private static void SetExplored(Minimap minimap, BitArray explored) { ExploredRef.Invoke(minimap) = new BitArray(explored); ExploredOthersRef.Invoke(minimap).SetAll(value: false); if ((Object)(object)minimap.m_sharedMapHint != (Object)null) { minimap.m_sharedMapHint.gameObject.SetActive(false); } UploadFog(minimap); } private static void UploadFog(Minimap minimap) { //IL_006d: 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_0072: Unknown result type (might be due to invalid IL or missing references) BitArray obj = ExploredRef.Invoke(minimap); Texture2D val = FogTextureRef.Invoke(minimap); int length = obj.Length; if (fogBuffer == null || fogBuffer.Length != length) { fogBuffer = (Color32[])(object)new Color32[length]; } byte[] array = MapBits.Pack(obj); int num = 0; for (int i = 0; i < array.Length; i++) { if (num >= length) { break; } int num2 = array[i]; int num3 = 0; while (num3 < 8 && num < length) { fogBuffer[num] = (((num2 & (1 << num3)) != 0) ? FogSeen : FogHidden); num3++; num++; } } val.SetPixels32(fogBuffer); val.Apply(); PinUpdateRequiredRef.Invoke(minimap) = true; SatelliteLink.NotifyExploredChanged(); } internal static bool IsHiddenPin(Minimap minimap, PinData pin) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0015: 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_001a: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (pin.m_save) { return false; } PinType type = pin.m_type; if ((int)type == 7 || type - 10 <= 3) { return true; } return !IsDrawn(minimap, pin.m_pos); } internal static List<PinData> Pins(Minimap minimap) { return PinsRef.Invoke(minimap); } private static List<PinRecord> CapturePins(Minimap minimap) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected I4, but got Unknown List<PinRecord> list = new List<PinRecord>(); foreach (PinData item in PinsRef.Invoke(minimap)) { if (item.m_save) { list.Add(new PinRecord { Name = (item.m_name ?? ""), Pos = item.m_pos, Type = (int)item.m_type, Checked = item.m_checked }); } } return list; } private static void ReplacePins(Minimap minimap, List<PinRecord> pins) { Loading = true; try { RemoveSavedPinsCore(minimap); foreach (PinRecord pin in pins) { AddPin(minimap, pin); } } finally { Loading = false; } } private static void RemoveSavedPins(Minimap minimap) { Loading = true; try { RemoveSavedPinsCore(minimap); } finally { Loading = false; } } private static void RemoveSavedPinsCore(Minimap minimap) { List<PinData> list = PinsRef.Invoke(minimap); for (int num = list.Count - 1; num >= 0; num--) { if (list[num].m_save) { minimap.RemovePin(list[num]); } } } private static void AddPin(Minimap minimap, PinRecord pin) { //IL_0002: 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_0024: Unknown result type (might be due to invalid IL or missing references) minimap.AddPin(pin.Pos, (PinType)pin.Type, pin.Name, true, pin.Checked, 0L, default(PlatformUserID)); } private static string BuildStats(Minimap minimap) { double num = Math.PI * Math.Pow(10500.0 / (double)minimap.m_pixelSize, 2.0); double num2 = (double)MapBits.Count(data.Explored) * 100.0 / num; double num3 = (double)MapBits.Count(data.Pending) * 100.0 / num; return string.Format(CultureInfo.InvariantCulture, "{0:0.0};{1:0.0};{2};{3}", num2, num3, data.Pins.Count, data.PendingRevs.CountAlsoIn(data.DrawnRevs)); } internal static bool TryReadStats(ItemData item, out string explored, out string pending, out string pins, out string changes) { explored = (pending = (pins = (changes = null))); if (item == null || !item.m_customData.TryGetValue("q8pm_stats", out var value)) { return false; } string[] array = value.Split(new char[1] { ';' }); if (array.Length < 3) { return false; } explored = array[0]; pending = array[1]; pins = array[2]; changes = ((array.Length > 3) ? array[3] : "0"); return true; } } [HarmonyPatch(typeof(Game), "UpdateNoMap")] internal static class Game_UpdateNoMap_Patch { private static void Postfix() { MapSession.OnNoMapUpdated(); } } [HarmonyPatch(typeof(PersistentEventSystemDirectionHelper), "UpdatePersistentEventSystemParticleHelper")] internal static class PersistentEventSystemDirectionHelper_Update_Patch { private static PersistentEventSystemDirectionHelper unlocked; private static void Prefix(PersistentEventSystemDirectionHelper __instance) { if (__instance.m_onlyOnNoMap && ParchmentMapPlugin.ReplaceVanillaMap.Value) { __instance.m_onlyOnNoMap = false; unlocked = __instance; } } private static void Finalizer() { if (unlocked != null) { unlocked.m_onlyOnNoMap = true; unlocked = null; } } } [HarmonyPatch(typeof(Minimap), "Awake")] internal static class Minimap_Awake_Patch { private static void Postfix() { MapSession.ResetSession(); } } [HarmonyPatch(typeof(Minimap), "Update")] internal static class Minimap_Update_Patch { private static void Postfix(Minimap __instance) { MapSession.Tick(__instance); } } [HarmonyPatch(typeof(Minimap), "SetMapMode")] internal static class Minimap_SetMapMode_Patch { private static bool noMapBefore; private static void Prefix(Minimap __instance, MapMode mode) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 noMapBefore = Game.m_noMap; if (noMapBefore && MapSession.IsActive) { Game.m_noMap = false; if ((int)__instance.m_mode == 2 && (int)mode != 2) { MapSession.FoldView(__instance); } } } private static void Finalizer(Minimap __instance) { Game.m_noMap = noMapBefore; if (noMapBefore && MapSession.IsActive && __instance.m_smallRoot.activeSelf && (!ParchmentMapPlugin.ShowMinimap.Value || MapSession.PictureMode)) { __instance.m_smallRoot.SetActive(false); } } } [HarmonyPatch(typeof(Minimap), "UpdateExplore")] internal static class Minimap_UpdateExplore_Patch { private static bool Prefix() { if (Game.m_noMap) { return MapSession.IsActive; } return true; } } [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(Vector3), typeof(float) })] internal static class Minimap_ExploreArea_Patch { private static void Prefix(Vector3 p, ref float radius) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Game.m_noMap && MapSession.IsActive) { radius *= ParchmentMapPlugin.ExploreRadiusMultiplier.Value; MapSession.SurveyAround(p, radius); } } } [HarmonyPatch(typeof(Minimap), "Explore", new Type[] { typeof(int), typeof(int) })] internal static class Minimap_ExploreCell_Patch { private static bool Prefix(Minimap __instance, int x, int y, ref bool __result) { if (!Game.m_noMap || !MapSession.IsActive || MapSession.Loading || !ParchmentMapPlugin.RevealAtTableOnly.Value) { return true; } MapSession.AddPending(__instance, x, y); __result = false; return false; } private static void Postfix(bool __result) { if (__result && MapSession.IsActive) { MapSession.MarkDirty(); } } } [HarmonyPatch(typeof(Minimap), "SaveMapData")] internal static class Minimap_SaveMapData_Patch { private static bool Prefix() { return !Game.m_noMap; } } [HarmonyPatch(typeof(Minimap), "AddPin")] internal static class Minimap_AddPin_Patch { private static void Postfix(Vector3 pos, bool save) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (save && MapSession.IsActive && !MapSession.Loading) { MapSession.RememberPin(pos); } } } [HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })] internal static class Minimap_RemovePin_Patch { private static void Prefix(PinData pin) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (pin != null && pin.m_save && MapSession.IsActive && !MapSession.Loading) { MapSession.ForgetPin(pin.m_pos); } } } [HarmonyPatch(typeof(Minimap), "OnMapLeftClick")] internal static class Minimap_OnMapLeftClick_Patch { private static void Postfix() { if (MapSession.IsActive) { MapSession.MarkDirty(); } } } [HarmonyPatch(typeof(Minimap), "OnPinTextEntered")] internal static class Minimap_OnPinTextEntered_Patch { private static void Postfix() { if (MapSession.IsActive) { MapSession.MarkDirty(); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] internal static class Humanoid_UnequipItem_Patch { private static void Prefix(Humanoid __instance, ItemData item) { if (item != null && item == MapSession.Held && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { MapSession.Deactivate(); } } } [HarmonyPatch(typeof(Player), "Save")] internal static class Player_Save_Patch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { MapSession.Flush(); } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] internal static class Humanoid_StartAttack_Patch { private static bool Prefix(Humanoid __instance, ref bool __result) { if (!ParchmentMapPlugin.BlockAttacks.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !MapItem.IsParchment(__instance.RightItem)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(MapTable), "OnRead", new Type[] { typeof(Switch), typeof(Humanoid), typeof(ItemData), typeof(bool) })] internal static class MapTable_OnRead_Patch { private static bool Prefix(MapTable __instance, Humanoid user, ItemData item, ref bool __result) { if (!Game.m_noMap || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } __result = item == null && MapSession.UseTable(__instance, user, write: false); return false; } } [HarmonyPatch(typeof(MapTable), "OnWrite")] internal static class MapTable_OnWrite_Patch { private static bool Prefix(MapTable __instance, Humanoid user, ItemData item, ref bool __result) { if (!Game.m_noMap || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } __result = item == null && MapSession.UseTable(__instance, user, write: true); return false; } } [HarmonyPatch(typeof(MapTable), "GetReadHoverText")] internal static class MapTable_GetReadHoverText_Patch { private static void Postfix(MapTable __instance, ref string __result) { TableHover.Replace(__instance, "$q8pm_hover_read", ref __result); } } [HarmonyPatch(typeof(MapTable), "GetWriteHoverText")] internal static class MapTable_GetWriteHoverText_Patch { private static void Postfix(MapTable __instance, ref string __result) { TableHover.Replace(__instance, "$q8pm_hover_write", ref __result); } } internal static class TableHover { internal static void Replace(MapTable table, string action, ref string result) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (Game.m_noMap && PrivateArea.CheckAccess(((Component)table).transform.position, 0f, false, false)) { string text = (MapSession.IsActive ? (table.m_name + "\n[<color=yellow><b>$KEY_Use</b></color>] " + action) : (table.m_name + "\n<color=#AAAAAA>$q8pm_hover_needmap</color>")); result = Localization.instance.Localize(text); } } } [HarmonyPatch(typeof(Minimap), "ShowPinNameInput")] internal static class Minimap_ShowPinNameInput_Patch { private static bool Prefix(Minimap __instance, Vector3 pos) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!Game.m_noMap || !MapSession.IsActive || !ParchmentMapPlugin.PinsOnlyOnExplored.Value || MapSession.IsDrawn(__instance, pos)) { return true; } if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$q8pm_msg_pin_unexplored", 0, (Sprite)null, false); } return false; } } [HarmonyPatch(typeof(Minimap), "DiscoverLocation")] internal static class Minimap_DiscoverLocation_Patch { private static bool Prefix(Minimap __instance, Vector3 pos, ref bool __result) { //IL_0028: 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) //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) if (!Game.m_noMap) { return true; } Player localPlayer = Player.m_localPlayer; if (!MapSession.IsActive) { __result = false; return false; } if (!ParchmentMapPlugin.PinsOnlyOnExplored.Value || MapSession.IsDrawn(__instance, pos)) { return true; } if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "$q8pm_msg_pin_unexplored", 0, (Sprite)null, false); ((Character)localPlayer).SetLookDir(pos - ((Component)localPlayer).transform.position, 3.5f); } __result = false; return false; } } [HarmonyPatch(typeof(Minimap), "CenterMap")] internal static class Minimap_CenterMap_Patch { private static void Prefix(ref Vector3 centerPoint) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (MapSession.PictureMode && !MapSession.InTouchZoom && !((Object)(object)localPlayer == (Object)null)) { Vector3 val = MapSession.Anchor - ((Component)localPlayer).transform.position; centerPoint = new Vector3(centerPoint.x + val.x, centerPoint.y, centerPoint.z + val.z); } } } [HarmonyPatch(typeof(Minimap), "TouchZoom")] internal static class Minimap_TouchZoom_Patch { private static void Prefix() { MapSession.InTouchZoom = true; } private static void Finalizer(Minimap __instance, Player player) { MapSession.InTouchZoom = false; if (MapSession.PictureMode && (Object)(object)player != (Object)null) { MapSession.RebaseTouchOffset(__instance, player); } } } [HarmonyPatch(typeof(Minimap), "ShowPointOnMap")] internal static class Minimap_ShowPointOnMap_Patch { private static void Postfix(Minimap __instance, Vector3 point) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (MapSession.PictureMode) { MapSession.LookAt(__instance, point); } } } [HarmonyPatch(typeof(Minimap), "UpdatePlayerMarker")] internal static class Minimap_UpdatePlayerMarker_Patch { private static bool smallMarkerHidden; private static void Postfix(Minimap __instance) { if (!MapSession.PictureMode) { if (smallMarkerHidden) { smallMarkerHidden = false; ((Component)__instance.m_smallMarker).gameObject.SetActive(true); } } else { smallMarkerHidden = true; ((Component)__instance.m_smallMarker).gameObject.SetActive(false); ((Component)__instance.m_largeMarker).gameObject.SetActive(false); ((Component)__instance.m_smallShipMarker).gameObject.SetActive(false); ((Component)__instance.m_largeShipMarker).gameObject.SetActive(false); } } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] internal static class Minimap_UpdatePins_Patch { private static readonly Vector3 Nowhere = new Vector3(1000000f, 0f, 1000000f); private static readonly List<KeyValuePair<PinData, Vector3>> moved = new List<KeyValuePair<PinData, Vector3>>(); private static void Prefix(Minimap __instance) { //IL_0038: 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) moved.Clear(); if (!MapSession.PictureMode) { return; } foreach (PinData item in MapSession.Pins(__instance)) { if (MapSession.IsHiddenPin(__instance, item)) { moved.Add(new KeyValuePair<PinData, Vector3>(item, item.m_pos)); item.m_pos = Nowhere; } } } private static void Finalizer() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<PinData, Vector3> item in moved) { item.Key.m_pos = item.Value; } moved.Clear(); } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class ItemData_GetTooltip_Patch { private static void Postfix(ItemData item, bool crafting, ref string __result) { if (crafting || !MapItem.IsParchment(item)) { return; } StringBuilder stringBuilder = new StringBuilder(__result); if (MapSession.TryReadStats(item, out var explored, out var pending, out var pins, out var changes)) { stringBuilder.Append("\n\n$q8pm_tip_explored: <color=orange>").Append(explored).Append("%</color>"); if (pending != "0.0") { stringBuilder.Append("\n$q8pm_tip_pending: <color=orange>").Append(pending).Append("%</color>"); } if (changes != "0") { stringBuilder.Append("\n$q8pm_tip_changes: <color=orange>").Append(changes).Append("</color>"); } stringBuilder.Append("\n$q8pm_tip_pins: <color=orange>").Append(pins).Append("</color>"); } else { stringBuilder.Append("\n\n<color=orange>$q8pm_tip_blank</color>"); } __result = stringBuilder.ToString(); } } [BepInPlugin("qua8ion.valheim.parchmentmap", "ParchmentMap", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ParchmentMapPlugin : BaseUnityPlugin { public const string PluginGuid = "qua8ion.valheim.parchmentmap"; public const string PluginName = "ParchmentMap"; public const string PluginVersion = "0.3.0"; internal static ManualLogSource Log; internal static ConfigEntry<bool> ReplaceVanillaMap; internal static ConfigEntry<bool> RevealAtTableOnly; internal static ConfigEntry<float> ExploreRadiusMultiplier; internal static ConfigEntry<bool> ShowMinimap; internal static ConfigEntry<bool> BlockAttacks; internal static ConfigEntry<bool> PinsOnlyOnExplored; internal static ConfigEntry<bool> LiveMarkers; internal static ConfigEntry<int> DetailLevel; internal static ConfigEntry<string> Recipe; internal static ConfigEntry<Vector3> HandPosition; internal static ConfigEntry<Vector3> HandRotation; internal static ConfigEntry<float> HandScale; private FileSystemWatcher configWatcher; private volatile bool configChanged; private void Awake() { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ReplaceVanillaMap = Rule("Rules", "ReplaceVanillaMap", value: true, "The parchment map replaces the game's own map in every world. A world that has the map enabled is then played like a no-map world: without a parchment in hand there is no map and no minimap, and nothing gets charted. If false, the mod works only in worlds without a map (the 'nomap' world modifier) and does nothing elsewhere."); RevealAtTableOnly = Rule("Rules", "RevealAtTableOnly", value: true, "What you walk through with the map in hand is only noted down. It appears on the map when you use a cartography table. If false, the map is revealed right away while you walk."); ExploreRadiusMultiplier = Rule("Rules", "ExploreRadiusMultiplier", 1f, "Multiplier for the radius that gets recorded around you while the map is in hand.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f)); ShowMinimap = Rule("Rules", "ShowMinimap", value: false, "Also show the small corner map while the parchment map is in hand. If false, only the big map (M) is available."); BlockAttacks = Rule("Rules", "BlockAttacks", value: true, "No punching while the map is in hand: put it away to fight."); PinsOnlyOnExplored = Rule("Rules", "PinsOnlyOnExplored", value: true, "Marks can be placed only where the map is already drawn. The same goes for boss and other location marks from runestones: no mark appears if that place is not on the map in your hand."); LiveMarkers = Rule("Rules", "LiveMarkers", value: false, "If false the map is just a picture: it shows neither you nor other players, pings, shouts or raids, game-made marks (bed, traders) appear only on drawn land, and the view stays where you left it instead of following you. If true the map behaves like the vanilla one."); DetailLevel = Rule("Rules", "DetailLevel", 3, "Works together with the SatelliteMap mod (optional): how detailed the picture of the drawn part of the map is when you zoom in. 0: the plain game map only. 1: a sketch (relief, water, paths, fields, buildings, ruins, boss altars). 2: a good map (also the forest and large rocks). 3: the best map (everything down to bushes). Planned: the level will come from the grade of the parchment instead of this setting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3)); Recipe = Rule("Rules", "Recipe", "DeerHide:2,Coal:1,Feathers:1", "Workbench recipe as Item:amount pairs separated by commas (prefab names)."); HandPosition = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Visual", "HandPosition", new Vector3(-0.02f, -0.15f, 0.17f), "Position of the sheet in the right hand, metres: X away from you, Y to your right, Z up out of the fist. Applied on the fly when this file is saved."); HandRotation = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Visual", "HandRotation", new Vector3(-180f, -90f, -90f), "Rotation of the sheet in the right hand, degrees. The default turns the drawn side towards you."); HandScale = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "HandScale", 1f, "Size of the sheet in hand."); HandPosition.SettingChanged += delegate { MapItem.ApplyHandPose(); }; HandRotation.SettingChanged += delegate { MapItem.ApplyHandPose(); }; HandScale.SettingChanged += delegate { MapItem.ApplyHandPose(); }; Recipe.SettingChanged += delegate { MapItem.ApplyRecipeToObjectDB(); }; SynchronizationManager.OnConfigurationSynchronized += delegate { MapItem.ApplyRecipeToObjectDB(); }; AddLocalization(); SatelliteLink.Register(); PrefabManager.OnVanillaPrefabsAvailable += MapItem.Register; new Harmony("qua8ion.valheim.parchmentmap").PatchAll(Assembly.GetExecutingAssembly()); WatchConfigFile(); } private ConfigEntry<T> Rule<T>(string section, string key, T value, string description, AcceptableValueBase range = null) { //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_0022: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } })); } private void WatchConfigFile() { try { configWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)); configWatcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime; configWatcher.Changed += delegate { configChanged = true; }; configWatcher.Created += delegate { configChanged = true; }; configWatcher.EnableRaisingEvents = true; } catch (Exception ex) { Log.LogWarning((object)("Config file will not be reloaded on the fly: " + ex.Message)); } } private void Update() { if (!configChanged) { return; } configChanged = false; try { ((BaseUnityPlugin)this).Config.Reload(); } catch (Exception ex) { Log.LogWarning((object)("Could not reload the config file: " + ex.Message)); } } private void OnDestroy() { if (configWatcher != null) { configWatcher.Dispose(); } } private static void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "item_q8pm_parchment", "Parchment map" }, { "item_q8pm_parchment_desc", "A sheet of hide and a piece of coal. Hold it in your hand to chart the land as you walk and to look at the map. What you have seen goes onto the map at a cartography table." }, { "q8pm_tip_explored", "Charted" }, { "q8pm_tip_pending", "Not yet drawn" }, { "q8pm_tip_changes", "Places charted anew, not yet drawn" }, { "q8pm_tip_pins", "Marks" }, { "q8pm_tip_blank", "Blank" }, { "q8pm_hover_read", "Draw your notes on the map and copy the table's records" }, { "q8pm_hover_write", "Add your map to the table's records" }, { "q8pm_hover_needmap", "Hold a parchment map in your hand" }, { "q8pm_msg_needmap", "Hold a parchment map in your hand" }, { "q8pm_msg_updated", "The map has been updated" }, { "q8pm_msg_uptodate", "Nothing new for this map" }, { "q8pm_msg_tableempty", "The table has no records yet" }, { "q8pm_msg_written", "The map has been recorded on the table" }, { "q8pm_msg_otherworld", "This map shows some other world" }, { "q8pm_msg_unreadable", "The drawings on this map cannot be read" }, { "q8pm_msg_tableunreadable", "The table's records cannot be read" }, { "q8pm_msg_pin_unexplored", "This place is not on the map yet" } }); text = "Russian"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "item_q8pm_parchment", "Карта на пергаменте" }, { "item_q8pm_parchment_desc", "Кусок шкуры и уголёк. Держите карту в руке, чтобы отмечать пройденное и смотреть на неё. Увиденное наносится на карту у стола картографа." }, { "q8pm_tip_explored", "Нанесено" }, { "q8pm_tip_pending", "Ещё не нанесено" }, { "q8pm_tip_changes", "Мест обойдено заново, ещё не нанесено" }, { "q8pm_tip_pins", "Меток" }, { "q8pm_tip_blank", "Чистая" }, { "q8pm_hover_read", "Нанести заметки на карту и переписать записи стола" }, { "q8pm_hover_write", "Добавить свою карту в записи стола" }, { "q8pm_hover_needmap", "Возьмите карту в руку" }, { "q8pm_msg_needmap", "Возьмите карту в руку" }, { "q8pm_msg_updated", "Карта обновлена" }, { "q8pm_msg_uptodate", "Для этой карты нет ничего нового" }, { "q8pm_msg_tableempty", "На столе пока нет записей" }, { "q8pm_msg_written", "Карта записана на стол" }, { "q8pm_msg_otherworld", "На этой карте какой-то другой мир" }, { "q8pm_msg_unreadable", "Рисунки на этой карте не разобрать" }, { "q8pm_msg_tableunreadable", "Записи стола не разобрать" }, { "q8pm_msg_pin_unexplored", "Этого места на карте ещё нет" } }); } } internal static class SatelliteLink { private const string ApiType = "SatelliteMap.SatelliteMapApi"; private static Action notifyExploredChanged; private static Func<int[], int[], Action<int[], int[], int[]>, bool> survey; internal static bool CanSurvey => survey != null; internal static void Register() { try { Type type = null; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType("SatelliteMap.SatelliteMapApi", throwOnError: false); if (type != null) { break; } } if (type == null) { return; } MethodInfo method = type.GetMethod("AddDetailLimit", BindingFlags.Static | BindingFlags.Public); MethodInfo method2 = type.GetMethod("NotifyExploredChanged", BindingFlags.Static | BindingFlags.Public); if (method == null || method2 == null) { ParchmentMapPlugin.Log.LogWarning((object)"SatelliteMap is installed, but its interface is not the expected one"); return; } method.Invoke(null, new object[1] { new Func<int>(DetailLimit) }); notifyExploredChanged = (Action)Delegate.CreateDelegate(typeof(Action), method2); MethodInfo method3 = type.GetMethod("SetZoneRevisionProvider", BindingFlags.Static | BindingFlags.Public); MethodInfo method4 = type.GetMethod("Survey", BindingFlags.Static | BindingFlags.Public); if (method3 != null && method4 != null) { method3.Invoke(null, new object[1] { new Func<int, int, int>(MapSession.RevisionOf) }); survey = (Func<int[], int[], Action<int[], int[], int[]>, bool>)Delegate.CreateDelegate(typeof(Func<int[], int[], Action<int[], int[], int[]>, bool>), method4); ParchmentMapPlugin.Log.LogInfo((object)"SatelliteMap found: the parchment map gets the detailed picture, drawn as the land was when you charted it"); } else { ParchmentMapPlugin.Log.LogWarning((object)"SatelliteMap found, but it is older than 0.2.0: the detailed picture will show the world as it is now, not as it was when you charted it"); } } catch (Exception ex) { ParchmentMapPlugin.Log.LogWarning((object)("Could not link to SatelliteMap: " + ex.Message)); } } internal static int DetailLevelOf(ItemData parchment) { return Mathf.Clamp(ParchmentMapPlugin.DetailLevel.Value, 0, 3); } private static int DetailLimit() { if (!MapSession.IsActive) { return -1; } return DetailLevelOf(MapSession.Held); } internal static void NotifyExploredChanged() { if (notifyExploredChanged != null) { notifyExploredChanged(); } } internal static bool Survey(int[] zoneXs, int[] zoneYs, Action<int[], int[], int[]> done) { if (survey == null) { return false; } try { return survey(zoneXs, zoneYs, done); } catch (Exception ex) { ParchmentMapPlugin.Log.LogWarning((object)("Could not ask SatelliteMap for zone snapshots: " + ex.Message)); return false; } } } }