Unknowns:
Unknown1
May be part of version... never seen those bits set.
Runeword ID
The first 12 bits need to be shifted / added by a value depending on last 4 bits...
What is currently got is if second value is 5, subtract 26 is value is under 100, or 25.
Only seen one case where it wasn't 5 so I can't really say, but I tried a lot of runewords with which this works...
Also (more on these later):
A couple unknown action types, flags and other enum values.
(BYTE) Action
(BYTE) Length
(BYTE) Category
(DWORD) Item Unit ID
0x9D only:
(BYTE) Owner Unit Type
(DWORD) Owner Unit ID
(DWORD) Flags
(BYTE) Version
(2 bits) Unknown1
(3 bits) Destination
If Destination == 3 (Ground):
(WORD) X
(WORD) Y
Else:
(4 bits) EquipmentLocation
(4 bits) X
(3 bits) Y
(4 bits) Container
If Flags & Ear:
(3 bits) Character Class
(7 bits) Level
(NULLSTRING*) Character Name
END
(DWORD) Base Item Code
If Base Item == Gold
(1 bit) Big Pile
If Big Pile:
(32 bits) Quantity
Else:
(12 bits) Quantity
END
(3 bits) Used Sockets
If Flags & (SimpleItem | Gamble):
END
(7 bits) Item Level
(4 bits) Item Quality
(1 bit) Has Graphic
If Has Graphic:
(3 bits) Graphic
(1 bit) Has Color
If Has Color:
(11 bits) Color
If Flags & Identified:
Switch (Quality):
Inferior:
(3 bits) Inferior Prefix
Superior:
(3 bits) Superior Type
Magic:
(11 bits) Magic Prefix
(11 bits) Magic Suffix
Rare:
Crafted:
(8 bits) Rare Prefix
(8 bits) Rare Suffix
Set:
(12 bits) Set ID
Unique:
(12 bits) Unique ID
If Quality == Rare || Crafted:
For i=0; i<3; i++:
(1 bit) Has Magic Prefix
If Has Magic Prefix:
(11 bits) Magic Prefix
(1 bit) Has Magic Suffix
If Has Magic Suffix:
(11 bits) Magic Suffix
Done
If Flags & Runeword:
(16 bits) Runeword ID
If Flags & Personlized:
(NULLSTRING*) Name
If BaseItem comes from Armor.txt:
(ArmorClass saveBits) Armor Class + ArmorClass saveAdd
If BaseItem comes from Armor.txt or Weapon.txt:
(MaxDurability savebits) Max Durability
If Max Durability != 0:
(Durability savebits) Durability
If Flags & Socketed:
(NumSockets saveBits) Sockets
If BaseItem.Stackable:
If BaseItem.Useable:
(5 bits) Use
(9 bits) Quantity
If Flags & Identified == 0:
END
If Quality == Set:
(5 bits) Set Bonuses
ReadStats
If Flag & Runeword:
ReadStats
If Quality == Set:
For i=0; i < 5; i++
If SetBonuses & (1 << i):
ReadStats
Done
*NULLSTRING: 7 bits per character.
ReadStats:
Repeat:
(9 bits) Stat ID
If Stat Id == 0x1FF:
BREAK
If SaveParamBits != -1:
Switch (Stat):
ChargedSkill:
(6 bits) Skill Level
(10 bits) Skill
(8 bits) Current Charges
(8 bits) Max Charges
SkillOnAttack:
SkillOnKill:
SkillOnDeath:
SkillOnStriking:
SkillOnLevelUp:
SkillOnGetHit:
(6 bits) Skill Level
(10 bits) Skill
(SaveBits) % Chance
SkillTabBonus:
(3 bits) Skill Tab
(3 bits) Character Class
(10 bits) Unknown
(SaveBits) Bonus
Default:
(SaveParamBits) Param
(SaveBits) Value
Else:
If Stat.OpBase == Level:
(SaveBits) Value / (1 << stat.OpParam) per Level
Else:
Switch (Stat):
MinDamagePercent:
MaxDamagePercent:
(SaveBits) Min
(SaveBits) Max
FireMinDamage:
LightMinDamage:
MagicMinDamage:
(SaveBits) Min
((Stat.Index+1).SaveBits) Max
ColdMinDamage:
(SaveBits) Min
(ColdMaxDamage.SaveBits) Max
(ColdLength.SaveBits) Length
PoisonMinDamage:
(SaveBits) Min
(PoisonMaxDamage.SaveBits) Max
(PoisonLength.SaveBits) Length
ReplenishDurability:
ReplenishQuantity:
(SaveBits) 1 in 100 / Value seconds
Default:
(SaveBits) Value - (SaveAdd != -1 ? SaveAdd : 0)
Done
Parsing stats:
Savebits and other "BaseStat" values associated with stat IDs come from itemstatcost.txt.
Another thing you may need to worry about is if the stat is signed or unsigned. For item stats, I don't think it would cause problems if you parse them all as signed, but that is not the case for all stats; some are unsigned and their value can be higher than a 32 signed integer will allow... the signed column in itemstatcost.txt determines if the stat is signed or not.
Fields description:
Destination
I call it that instead of Location not to be confused with my Equipment Location enum or, more importantly, the Container and X, Y fields, which are not necessarly related. See there is not really a "now" in item action packets, but rather a before and an after: the destination is always where the item will end up, but the rest of the info may be about where it previously was, depending on action type.
E.g. picking an item from inventory means both removing it from there and adding to cursor:
Action: RemoveFromContainer (5)
Destination: Cursor (4)
Container: Inventory (2)
X: 1
Y: 1
Values:
Unspecified = 0
Equipment = 1
Belt = 2
Ground = 3
Cursor = 4
Item = 6
If 0, the destination can be determined from the action type / and or container fields instead...
5 and 7 are unknown, if used...
Base Item Code
This is a DWORD built from the 3 letters item codes, with space as the filler character. One could build it such:
For int i = 0; i < 4; i++:
id |= (i < code.Length ? code[ i].CharCode : 0x20) << ( i*8 );
Gold
If amount is larger than 4095, the Big Pile bit will be set and the value will be 32 bits in length instead of 12.
The game will only displays up to 9 characters (999 999 999, 30 bits) but will parse and show the first numbers only if it's longer...
The 32nd bit is the sign; the client will indeed display negative piles of gold.
Durability
Even items marked NoDurability have one, it just normally isn't used...
0 Max Durability means the item is indestructible and doesn't have a current Durablity.
Graphic
Set on items having a variable graphic like rings and charms.
Color
Set on items having a variable color like some class specific items (sorceress orbs...)
Set Bonuses
This is a bit field, each bit indicating if there are bonus stats for (offset + 2) items of the set worn.
Edit: Corrected set bonuses information.
Edit2: Added extra information and simplified description a bit.
Edit3: Corrected used sockets info: bits are present even if Socketed flag is not set...
Edit4: Corrected the gold, color and unidentified rare information, cleaned up info some more and added some field descriptions.
Edit5: Corrected Item Code and noted that quality specific info should only be read if item is identified.
I might look into updating the D2GS stuff aswell as UDP game stuff sometime soon, thanks for the input.
You can parse items using several excel files found inside Patch_D2.mpq or d2exp.mpq. I was actually just implementing some of this again as I was porting my d2 single player character editor to mono/gtk#, and the format is the same.
The most important files are
data\global\excel\ItemStatCost.txt - tells you the number of bits for each magical property (save bits), what to subtract to get the actual value of the property (add bits), and if there are additional bits (save param bits).
Keep in mind that if you find some magical properties (ie, + min cold dmg, + max cold dmg, +min fire dmg, + max dmg %, etc), the next 9 bit code will be missing and should be assumed to be the next property in the list (+ max cold dmg, cold duration, +max file dmg, +min dmg%).
You can find magical properties in data\global\excel\UniqueItems.txt - look up the name / image of a unique item given it's Unique Item ID. (start at line 0, do not count the line that says "Expansion")
Edit: From what I've looked at, the set_bonus_count is a bitfield with each bit indicating that there is an additional magical property list.
I handle it like so:
// where prop_lists is a list of lists of magical properties.
for(int i = 0; i < 5; ++i)
if ((set_bitfield & (1 << i)) != 0) // if the bit is set, read a magical property list
{
// read properties until we find 0x1ff as the property code
prop_lists.Add(MagicalPropertyDatabase.ReadList(bitreader));
}
Oh yes that's it, thanks. Each bit indicates if there are bonuses for the next number of set items worn (starting at 2, up to 6.)
SetItem: Tal Rasha's Adjudication
SetBonuses: , , (Faster Cast Rate: 10), ,
1 mod for 4 items
SetItem: Tal Rasha's Howling Wind
SetBonuses: (Faster Cast Rate: 10), , , ,
1 mod for 2 items
SetItem: Tal Rasha's Horadric Crest
no mods
SetItem: Tal Rasha's Lidless Eye
SetBonuses: (+1 To Sorceress Skills), (Passive Fire Pierce: 15), (Passive Lightning Pierce: 15), (Passive Cold Mastery: 15),
1 mod for 2, 3, 4 and 5 items
SetItem: Tal Rasha's Fire-Spun Cloth
SetBonuses: (Armor Class: 60), (Faster Cast Rate: 10), , ,
1 mod for 2 and 3 items
I'll update the description later...
Quote from: UserLoser on February 12, 2007, 05:55 PM
I might look into updating the D2GS stuff aswell as UDP game stuff sometime soon, thanks for the input.
afaik, they dont need updating, they need adding :)
I remember krad putting 1.09 D2GS C > S Packets on bnet docs, and not my 1.10/1.11 research found here (http://forum.valhallalegends.com/index.php?topic=11756.0)
Also, my UDP research I posted a year or so ago, is also good and indate and needs adding to Bnet docs.
I remember arta saying these things dont get added over night :P
That was a few years ago :)
Thats partly why all my main research now goes onto a private forum, and not this one :-\
I corrected the gold, color and unidentified rare information, cleaned up info some more and added some field descriptions.
Ringo: that's too bad. I guess forums do as well for reference and your research threads helped me a lot to get started anyways...