// // Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. using System.Buffers.Binary; using System.Text; using Wonderking.Game.Data; using Wonderking.Game.Data.Item; namespace Wonderking.Game.Reader; public class ItemReader(string path) : DataReader(path) { public override uint GetAmountOfEntries() { return (uint)((DatFileContent.Length - 9) / SizeOfEntry); } public override ItemObject GetEntry(uint entryId) { var item = new ItemObject(); var arraySegment = new ArraySegment(DatFileContent, 9 + (int)entryId * SizeOfEntry, SizeOfEntry); var data = new Span(arraySegment.Array, arraySegment.Offset, arraySegment.Count); item.ItemID = BitConverter.ToUInt32(data.Slice(0, 4)); // 0 -> 4 item.Disabled = BitConverter.ToBoolean(data.Slice(4, 4)); // 4 -> 8 item.ItemType = BitConverter.ToUInt32(data.Slice(8, 4)); // 8 -> 12 item.Unknown2 = data.Slice(12, 4).ToArray(); // 12 -> 16 item.Unknown3 = data.Slice(16, 4).ToArray(); // 16 -> 20 item.ClassNo1 = BitConverter.ToUInt32(data.Slice(20, 4)); // 20 -> 24 item.ClassNo2 = BitConverter.ToUInt32(data.Slice(24, 4)); // 24 -> 28 item.ClassNo3 = BitConverter.ToUInt32(data.Slice(28, 4)); // 28 -> 32 item.ClassNo4 = BitConverter.ToUInt32(data.Slice(32, 4)); // 32 -> 36 item.SlotNo1 = BitConverter.ToUInt32(data.Slice(36, 4)); // 36 -> 40 item.SlotNo2 = BitConverter.ToUInt32(data.Slice(40, 4)); // 40 -> 44 item.Unknown4 = data.Slice(44, 4).ToArray(); // 44 -> 48 item.IsCash = BitConverter.ToUInt32(data.Slice(48, 4)); // 48 -> 52 item.Unknown5 = data.Slice(52, 4).ToArray(); // 52 -> 56 item.Price = BitConverter.ToUInt32(data.Slice(56, 4)); // 56 -> 60 item.Unknown7 = data.Slice(60, 4).ToArray(); // 60 -> 64 item.MaxNumber = BitConverter.ToUInt32(data.Slice(64, 4)); // 64 -> 68 item.Unknown17 = data.Slice(68, 12).ToArray(); // 68 -> 80 item.MaximumLevelRequirement = BitConverter.ToUInt32(data.Slice(80, 4)); // 80 -> 84 item.SexNo = BitConverter.ToUInt32(data.Slice(84, 4)); // 84 -> 88 item.WeaponSomething = BitConverter.ToUInt32(data.Slice(88, 4)); // 88 -> 92 item.Unknown8 = data.Slice(92, 4).ToArray(); // 92 -> 96 item.R2C = data.Slice(96, 16).ToArray(); // 96 -> 112 item.Unknown9 = data.Slice(112, 4).ToArray(); // 112 -> 116 item.Stats = new Stats { Strength = BitConverter.ToInt32(data.Slice(116, 4)), // 116 -> 120 Dexterity = BitConverter.ToInt32(data.Slice(120, 4)), // 120 -> 124 Intelligence = BitConverter.ToInt32(data.Slice(124, 4)), // 124 -> 128 Vitality = BitConverter.ToInt32(data.Slice(128, 4)), // 128 -> 132 Luck = BitConverter.ToInt32(data.Slice(132, 4)), // 132 -> 136 Wisdom = BitConverter.ToInt32(data.Slice(136, 4)) // 136 -> 140 }; // 116 -> 140 item.ElementalStats = new ElementalStats { MinimumFireDamage = BitConverter.ToInt32(data.Slice(140, 4)), // 140 -> 144 MinimumWaterDamage = BitConverter.ToInt32(data.Slice(144, 4)), // 144 -> 148 MinimumDarkDamage = BitConverter.ToInt32(data.Slice(148, 4)), // 148 -> 152 MinimumHolyDamage = BitConverter.ToInt32(data.Slice(152, 4)), // 152 -> 156 MaximumFireDamage = BitConverter.ToInt32(data.Slice(156, 4)), // 156 -> 160 MaximumWaterDamage = BitConverter.ToInt32(data.Slice(160, 4)), // 160 -> 164 MaximumDarkDamage = BitConverter.ToInt32(data.Slice(164, 4)), // 164 -> 168 MaximumHolyDamage = BitConverter.ToInt32(data.Slice(168, 4)), // 168 -> 172 ElementFire = BitConverter.ToUInt32(data.Slice(172, 4)), // 172 -> 176 ElementWater = BitConverter.ToUInt32(data.Slice(176, 4)), // 176 -> 180 ElementDark = BitConverter.ToUInt32(data.Slice(180, 4)), // 180 -> 184 ElementHoly = BitConverter.ToUInt32(data.Slice(184, 4)), // 184 -> 188 FireResistance = BitConverter.ToInt32(data.Slice(188, 4)), // 188 -> 192 WaterResistance = BitConverter.ToInt32(data.Slice(192, 4)), // 192 -> 196 DarkResistance = BitConverter.ToInt32(data.Slice(196, 4)), // 196 -> 200 HolyResistance = BitConverter.ToInt32(data.Slice(200, 4)) // 200 -> 204 }; // 140 -> 204 item.R7C = data.Slice(204, 4).ToArray(); // 204 -> 208 item.R8C = data.Slice(208, 8).ToArray(); // 208 -> 216 item.Speed = BinaryPrimitives.ReadSingleLittleEndian(data.Slice(216, 4)); // 216 -> 220 item.Jump = BinaryPrimitives.ReadSingleLittleEndian(data.Slice(220, 4)); // 220 -> 224 item.StatDefense = BitConverter.ToInt32(data.Slice(224, 4)); // 224 -> 228 item.MagicID = BitConverter.ToUInt32(data.Slice(228, 4)); // 228 -> 232 item.Unknown13 = data.Slice(232, 4).ToArray(); // 232 -> 236 item.Unknown14 = data.Slice(236, 4).ToArray(); // 236 -> 240 item.AdditionalHealthRecoveryVolume = BitConverter.ToInt32(data.Slice(240, 4)); // 240 -> 244 item.R9C_1 = data.Slice(244, 4).ToArray(); // 244 -> 248 item.AdditionalManaRecoveryVolume = BitConverter.ToInt32(data.Slice(248, 4)); // 248 -> 252 item.R9C_2 = data.Slice(252, 4).ToArray(); // 252 -> 256 item.R10C = data.Slice(256, 8).ToArray(); // 256 -> 264 item.AdditionalHealthPoints = BitConverter.ToInt32(data.Slice(264, 4)); // 264 -> 268 item.AdditionalManaPoints = BitConverter.ToInt32(data.Slice(268, 4)); // 268 -> 272 item.IsArrow = BitConverter.ToBoolean(data.Slice(272, 1)); // 272 -> 273 item.Unknown18 = data.Slice(273, 7).ToArray(); // 273 -> 280 item.AdditionalEvasionRate = BitConverter.ToInt32(data.Slice(280, 4)); // 280 -> 284 item.HitRate = BitConverter.ToInt32(data.Slice(284, 4)); // 284 -> 288 item.ChanceToHit = BitConverter.ToInt32(data.Slice(288, 4)); // 288 -> 292 item.MagicalDamage = BitConverter.ToInt32(data.Slice(292, 4)); // 292 -> 296 item.CriticalHitChance = BitConverter.ToInt32(data.Slice(296, 4)); // 296 -> 300 item.R12C = data.Slice(300, 4).ToArray(); // 300 -> 304 item.Unknown16 = data.Slice(304, 4).ToArray(); // 304 -> 308 item.MinimalAttackDamage = BitConverter.ToInt32(data.Slice(308, 4)); // 308 -> 312 item.MaximalAttackDamage = BitConverter.ToInt32(data.Slice(312, 4)); // 312 -> 316 item.PhysicalDamage = BitConverter.ToInt32(data.Slice(316, 4)); // 316 -> 320 item.CraftMaterial = new CraftMaterial[] { new() { ID = BitConverter.ToUInt32(data.Slice(320, 4)), // 320 -> 324 Amount = BitConverter.ToUInt32(data.Slice(336, 4)) // 336 -> 340 }, new() { ID = BitConverter.ToUInt32(data.Slice(324, 4)), // 324 -> 328 Amount = BitConverter.ToUInt32(data.Slice(340, 4)) // 340 -> 344 }, new() { ID = BitConverter.ToUInt32(data.Slice(328, 4)), // 328 -> 332 Amount = BitConverter.ToUInt32(data.Slice(344, 4)) // 344 -> 348 }, new() { ID = BitConverter.ToUInt32(data.Slice(332, 4)), // 332 -> 336 Amount = BitConverter.ToUInt32(data.Slice(348, 4)) // 348 -> 352 } }; // 320 -> 352 item.CraftResultAmount = BitConverter.ToUInt32(data.Slice(352, 4)); // 352 -> 356 item.R14C = data.Slice(356, 4).ToArray(); // 356 -> 360 item.CraftResultItem = BitConverter.ToUInt32(data.Slice(360, 4)); // 360 -> 364 item.R15C = data.Slice(364, 4).ToArray(); // 364 -> 368 item.R16C = data.Slice(368, 20).ToArray(); // 368 -> 388 item.InventoryX = BitConverter.ToInt32(data.Slice(388, 4)); // 388 -> 392 item.InventoryY = BitConverter.ToInt32(data.Slice(392, 4)); // 392 -> 396 item.InventoryWidth = BitConverter.ToInt32(data.Slice(396, 4)); // 396 -> 400 item.InventoryHeight = BitConverter.ToInt32(data.Slice(400, 4)); // 400 -> 404 item.SheetID = BitConverter.ToInt32(data.Slice(404, 4)); // 404 -> 408 item.Name = Encoding.ASCII.GetString(data.Slice(408, 20)); // 408 -> 428 item.Description = Encoding.ASCII.GetString(data.Slice(428, 85)); // 428 -> 513 item.Unknown1 = data.Slice(513, 175).ToArray(); // 513 -> 688 item.IsEnchantable = BitConverter.ToBoolean(data.Slice(688, 4)); // 688 -> 672 item.Unknown1_2 = data.Slice(692, 104).ToArray(); // 692 -> 796 item.SetItems = new[] { BitConverter.ToUInt32(data.Slice(796, 4)), // 796 -> 800 BitConverter.ToUInt32(data.Slice(800, 4)), // 800 -> 804 BitConverter.ToUInt32(data.Slice(804, 4)), // 804 -> 808 BitConverter.ToUInt32(data.Slice(808, 4)), // 808 -> 812 BitConverter.ToUInt32(data.Slice(812, 4)) // 812 -> 816 }; // 796 -> 816 item.SetID = BitConverter.ToUInt32(data.Slice(816, 4)); // 816 -> 820 item.Options = new ItemOptions { OptionIDs = new[] { BitConverter.ToUInt32(data.Slice(824, 4)), // 824 -> 828 BitConverter.ToUInt32(data.Slice(828, 4)), // 828 -> 832 BitConverter.ToUInt32(data.Slice(832, 4)), // 832 -> 836 BitConverter.ToUInt32(data.Slice(836, 4)) // 836 -> 840 }, OptionAvailable = BitConverter.ToBoolean(data.Slice(820, 4)) // 820 -> 824 }; // 820 -> 840 item.Unknown19 = data.Slice(840, 23).ToArray(); // 840 -> 863 item.PetID = data[863]; // 863 -> 864 item.Unknown20 = data.Slice(864, 20).ToArray(); // 864 -> 884 item.HitBoxScaling = data[884]; // 884 -> 885 item.Unknown20_2 = data.Slice(885, 13).ToArray(); // 885 -> 898 item.ContainedItems = new[] { new ContainedItem { ID = BitConverter.ToInt16(data.Slice(898, 2)), // 898 -> 900 ObtainChance = BitConverter.ToSingle(data.Slice(908, 4)) // 908 -> 912 }, new ContainedItem { ID = BitConverter.ToInt16(data.Slice(900, 2)), // 900 -> 902 ObtainChance = BitConverter.ToSingle(data.Slice(912, 4)) // 912 -> 916 }, new ContainedItem { ID = BitConverter.ToInt16(data.Slice(902, 2)), // 902 -> 904 ObtainChance = BitConverter.ToSingle(data.Slice(916, 4)) // 916 -> 920 }, new ContainedItem { ID = BitConverter.ToInt16(data.Slice(904, 2)), // 904 -> 906 ObtainChance = BitConverter.ToSingle(data.Slice(920, 4)) // 920 -> 924 }, new ContainedItem { ID = BitConverter.ToInt16(data.Slice(906, 2)), // 906 -> 908 ObtainChance = BitConverter.ToSingle(data.Slice(924, 4)) // 924 -> 928 } }; item.MinimumLevelRequirement = data[928]; // 928 -> 929 item.Unknown21_2 = data.Slice(929, 3).ToArray(); // 929 -> 932 return item; } }