public static void Write(BitWriter writer, ItemStatList itemStatList) { for (int i = 0; i < itemStatList.Stats.Count; i++) { var stat = itemStatList.Stats[i]; TXTRow property = ItemStat.GetStatRow(stat); UInt16 id = property["ID"].ToUInt16(); writer.WriteUInt16(id, 9); ItemStat.Write(writer, stat); //assume these stats are in order... //https://github.com/ThePhrozenKeep/D2MOO/blob/master/source/D2Common/src/Items/Items.cpp#L7332 if (id == 52 || //magicmindam id == 17 || //item_maxdamage_percent id == 48 || //firemindam id == 50) //lightmindam { ItemStat.Write(writer, itemStatList.Stats[++i]); } else if (id == 54 || //coldmindam id == 57 //poisonmindam ) { ItemStat.Write(writer, itemStatList.Stats[++i]); ItemStat.Write(writer, itemStatList.Stats[++i]); } } writer.WriteUInt16(0x1ff, 9); }
public static ItemStatList Read(BitReader reader) { ItemStatList itemStatList = new ItemStatList(); UInt16 id = reader.ReadUInt16(9); while (id != 0x1ff) { itemStatList.Stats.Add(ItemStat.Read(reader, id)); //https://github.com/ThePhrozenKeep/D2MOO/blob/master/source/D2Common/src/Items/Items.cpp#L7332 if (id == 52 || //magicmindam id == 17 || //item_maxdamage_percent id == 48 || //firemindam id == 50) //lightmindam { itemStatList.Stats.Add(ItemStat.Read(reader, (UInt16)(id + 1))); } else if (id == 54 || //coldmindam id == 57 //poisonmindam ) { itemStatList.Stats.Add(ItemStat.Read(reader, (UInt16)(id + 1))); itemStatList.Stats.Add(ItemStat.Read(reader, (UInt16)(id + 2))); } id = reader.ReadUInt16(9); } return(itemStatList); }
protected static void WriteComplete(BitWriter writer, Item item, UInt32 version) { writer.WriteUInt32(item.Id); writer.WriteByte(item.ItemLevel, 7); writer.WriteByte((byte)item.Quality, 4); writer.WriteBit(item.HasMultipleGraphics); if (item.HasMultipleGraphics) { writer.WriteByte(item.GraphicId, 3); } writer.WriteBit(item.IsAutoAffix); if (item.IsAutoAffix) { writer.WriteUInt16(item.AutoAffixId, 11); } switch (item.Quality) { case ItemQuality.Normal: break; case ItemQuality.Inferior: case ItemQuality.Superior: writer.WriteUInt32(item.FileIndex, 3); break; case ItemQuality.Magic: writer.WriteUInt16(item.MagicPrefixIds[0], 11); writer.WriteUInt16(item.MagicSuffixIds[0], 11); break; case ItemQuality.Rare: case ItemQuality.Craft: writer.WriteUInt16(item.RarePrefixId, 8); writer.WriteUInt16(item.RareSuffixId, 8); for (int i = 0; i < 3; i++) { var hasPrefix = item.MagicPrefixIds[i] > 0; var hasSuffix = item.MagicSuffixIds[i] > 0; writer.WriteBit(hasPrefix); if (hasPrefix) { writer.WriteUInt16(item.MagicPrefixIds[i], 11); } writer.WriteBit(hasSuffix); if (hasSuffix) { writer.WriteUInt16(item.MagicSuffixIds[i], 11); } } break; case ItemQuality.Set: case ItemQuality.Unique: writer.WriteUInt32(item.FileIndex, 12); break; } UInt16 propertyLists = 0; if (item.IsRuneword) { writer.WriteUInt32(item.RunewordId, 12); propertyLists |= 1 << 6; writer.WriteUInt16((UInt16)5, 4); } if (item.IsPersonalized) { WritePlayerName(writer, item.PlayerName); } if (item.Code.Trim() == "tbk" || item.Code.Trim() == "ibk") { writer.WriteUInt16(item.MagicSuffixIds[0], 5); } writer.WriteBit(item.HasRealmData); if (item.HasRealmData) { //todo 96 bits } ItemStatCostTXT itemStatCostTXT = Core.TXT.ItemStatCostTXT; TXTRow row = Core.TXT.ItemsTXT.GetByCode(item.Code); bool isArmor = Core.TXT.ItemsTXT.IsArmor(item.Code); bool isWeapon = Core.TXT.ItemsTXT.IsWeapon(item.Code); bool isStackable = row["stackable"].ToBool(); if (isArmor) { writer.WriteUInt16((UInt16)(item.Armor - itemStatCostTXT["armorclass"]["Save Add"].ToUInt16()), 11); } if (isArmor || isWeapon) { var maxDurabilityStat = itemStatCostTXT["maxdurability"]; var durabilityStat = itemStatCostTXT["maxdurability"]; writer.WriteUInt16((UInt16)(item.MaxDurability - maxDurabilityStat["Save Add"].ToUInt16()), maxDurabilityStat["Save Bits"].ToInt32()); if (item.MaxDurability > 0) { writer.WriteUInt16((UInt16)(item.Durability - durabilityStat["Save Add"].ToUInt16()), durabilityStat["Save Bits"].ToInt32()); ////what is this? writer.WriteBit(false); } } if (isStackable) { writer.WriteUInt16(item.Quantity, 9); } if (item.IsSocketed) { writer.WriteByte(item.TotalNumberOfSockets, 4); } if (item.Quality == ItemQuality.Set) { writer.WriteByte(item.SetItemMask, 5); propertyLists |= item.SetItemMask; } ItemStatList.Write(writer, item.StatLists[0]); var idx = 1; for (int i = 1; i <= 64; i <<= 1) { if ((propertyLists & i) != 0) { ItemStatList.Write(writer, item.StatLists[idx++]); } } }
protected static void ReadComplete(BitReader reader, Item item, UInt32 version) { item.Id = reader.ReadUInt32(); item.ItemLevel = reader.ReadByte(7); item.Quality = (ItemQuality)reader.ReadByte(4); item.HasMultipleGraphics = reader.ReadBit(); if (item.HasMultipleGraphics) { item.GraphicId = reader.ReadByte(3); } item.IsAutoAffix = reader.ReadBit(); if (item.IsAutoAffix) { item.AutoAffixId = reader.ReadUInt16(11); } switch (item.Quality) { case ItemQuality.Normal: break; case ItemQuality.Inferior: case ItemQuality.Superior: item.FileIndex = reader.ReadUInt16(3); break; case ItemQuality.Magic: item.MagicPrefixIds[0] = reader.ReadUInt16(11); item.MagicSuffixIds[0] = reader.ReadUInt16(11); break; case ItemQuality.Rare: case ItemQuality.Craft: item.RarePrefixId = reader.ReadUInt16(8); item.RareSuffixId = reader.ReadUInt16(8); for (int i = 0; i < 3; i++) { if (reader.ReadBit()) { item.MagicPrefixIds[i] = reader.ReadUInt16(11); } if (reader.ReadBit()) { item.MagicSuffixIds[i] = reader.ReadUInt16(11); } } break; case ItemQuality.Set: case ItemQuality.Unique: item.FileIndex = reader.ReadUInt16(12); break; } UInt16 propertyLists = 0; if (item.IsRuneword) { item.RunewordId = reader.ReadUInt32(12); propertyLists |= (UInt16)(1 << (reader.ReadUInt16(4) + 1)); } if (item.IsPersonalized) { item.PlayerName = ReadPlayerName(reader); } if (item.Code.Trim() == "tbk" || item.Code.Trim() == "ibk") { item.MagicSuffixIds[0] = reader.ReadByte(5); } item.HasRealmData = reader.ReadBit(); if (item.HasRealmData) { reader.ReadBits(96); } ItemStatCostTXT itemStatCostTXT = Core.TXT.ItemStatCostTXT; TXTRow row = Core.TXT.ItemsTXT.GetByCode(item.Code); bool isArmor = Core.TXT.ItemsTXT.IsArmor(item.Code); bool isWeapon = Core.TXT.ItemsTXT.IsWeapon(item.Code); bool isStackable = row["stackable"].ToBool(); if (isArmor) { //why do i need this cast? item.Armor = (UInt16)(reader.ReadUInt16(11) + itemStatCostTXT["armorclass"]["Save Add"].ToUInt16()); } if (isArmor || isWeapon) { var maxDurabilityStat = itemStatCostTXT["maxdurability"]; var durabilityStat = itemStatCostTXT["maxdurability"]; item.MaxDurability = (UInt16)(reader.ReadUInt16(maxDurabilityStat["Save Bits"].ToInt32()) + maxDurabilityStat["Save Add"].ToUInt16()); if (item.MaxDurability > 0) { item.Durability = (UInt16)(reader.ReadUInt16(durabilityStat["Save Bits"].ToInt32()) + durabilityStat["Save Add"].ToUInt16()); //what is this? reader.ReadBit(); } } if (isStackable) { item.Quantity = reader.ReadUInt16(9); } if (item.IsSocketed) { item.TotalNumberOfSockets = reader.ReadByte(4); } item.SetItemMask = 0; if (item.Quality == ItemQuality.Set) { item.SetItemMask = reader.ReadByte(5); propertyLists |= item.SetItemMask; } item.StatLists.Add(ItemStatList.Read(reader)); for (int i = 1; i <= 64; i <<= 1) { if ((propertyLists & i) != 0) { item.StatLists.Add(ItemStatList.Read(reader)); } } }