示例#1
0
        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);
        }
示例#2
0
        public static ItemStat Read(BitReader reader, UInt16 id)
        {
            ItemStat itemStat = new ItemStat();
            TXTRow   property = Core.TXT.ItemStatCostTXT[id];

            if (property == null)
            {
                throw new Exception($"No ItemStatCost record found for id: {id} at bit {reader.Position - 9}");
            }
            itemStat.Id   = id;
            itemStat.Stat = property["Stat"].Value;
            Int32 saveParamBitCount = property["Save Param Bits"].ToInt32();
            Int32 encode            = property["Encode"].ToInt32();

            if (saveParamBitCount != 0)
            {
                Int32 saveParam = reader.ReadInt32(saveParamBitCount);
                //todo is there a better way to identify skill tab stats.
                switch (property["descfunc"].ToInt32())
                {
                case 14:     //+[value] to [skilltab] Skill Levels ([class] Only) : stat id 188
                    itemStat.SkillTab   = saveParam & 0x7;
                    itemStat.SkillLevel = (saveParam >> 3) & 0x1fff;
                    break;

                default:
                    break;
                }
                switch (encode)
                {
                case 2:     //chance to cast skill
                case 3:     //skill charges
                    itemStat.SkillLevel = saveParam & 0x3f;
                    itemStat.SkillId    = (saveParam >> 6) & 0x3ff;
                    break;

                case 1:
                case 4:     //by times
                default:
                    itemStat.Param = saveParam;
                    break;
                }
            }
            Int32 saveBits = reader.ReadInt32(property["Save Bits"].ToInt32());

            saveBits -= property["Save Add"].ToInt32();
            switch (encode)
            {
            case 3:     //skill charges
                itemStat.MaxCharges = (saveBits >> 8) & 0xff;
                itemStat.Value      = saveBits & 0xff;
                break;

            default:
                itemStat.Value = saveBits;
                break;
            }
            return(itemStat);
        }
示例#3
0
        public static void Write(BitWriter writer, ItemStat stat)
        {
            TXTRow property = GetStatRow(stat);

            if (property == null)
            {
                throw new Exception($"No ItemStatCost record found for id: {stat.Id}");
            }
            Int32 saveParamBitCount = property["Save Param Bits"].ToInt32();
            Int32 encode            = property["Encode"].ToInt32();

            if (saveParamBitCount != 0)
            {
                if (stat.Param != null)
                {
                    writer.WriteInt32((Int32)stat.Param, saveParamBitCount);
                }
                else
                {
                    Int32 saveParamBits = 0;
                    switch (property["descfunc"].ToInt32())
                    {
                    case 14:     //+[value] to [skilltab] Skill Levels ([class] Only) : stat id 188
                        saveParamBits |= (stat.SkillTab ?? 0 & 0x7);
                        saveParamBits |= ((stat.SkillLevel ?? 0 & 0x1fff) << 3);
                        break;

                    default:
                        break;
                    }
                    switch (encode)
                    {
                    case 2:     //chance to cast skill
                    case 3:     //skill charges
                        saveParamBits |= (stat.SkillLevel ?? 0 & 0x3f);
                        saveParamBits |= ((stat.SkillId ?? 0 & 0x3ff) << 6);
                        break;

                    case 4:     //by times
                    case 1:
                    default:
                        break;
                    }
                    //always use param if it is there.
                    if (stat.Param != null)
                    {
                        saveParamBits = (Int32)stat.Param;
                    }
                    writer.WriteInt32(saveParamBits, saveParamBitCount);
                }
            }
            Int32 saveBits = stat.Value;

            saveBits += property["Save Add"].ToInt32();
            switch (encode)
            {
            case 3:     //skill charges
                saveBits &= 0xff;
                saveBits |= ((stat.MaxCharges ?? 0 & 0xff) << 8);
                break;

            default:
                break;
            }
            writer.WriteInt32(saveBits, property["Save Bits"].ToInt32());
        }
示例#4
0
        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++]);
                }
            }
        }
示例#5
0
        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));
                }
            }
        }