The game are using a bitsystem to store the info in what is known as flags. In ptItem->ptItemData +18 (Flags) they store this info.
First we can look at the different flags:
As we can see here there are several flags that are familar to us like Ethereal, Socketed, Runeword e.tc. Those flags are set/reset and checked all the time when we do anything, or then the game create/delete anything. Then you understand how these flags works, it will help you to change the way item generation are done, like remove all socketed or ethereal items from the game.ITEMFLAG_NEWITEM = 0x00000001,
ITEMFLAG_TARGETING = 0x00000004,
ITEMFLAG_IS_IDENTIFIED = 0x00000010,
ITEMFLAG_QUANTITY = 0x00000020,
ITEMFLAG_DURABILITY = 0x00000100,
ITEMFLAG_UNKNOWN2 = 0x00000400,
ITEMFLAG_SOCKETED = 0x00000800,
ITEMFLAG_NON_SELLABLE = 0x00001000,
ITEMFLAG_NEWITEM2 = 0x00002000,
ITEMFLAG_UNKNOWN3 = 0x00004000,
ITEMFLAG_CHECKSECPRICE = 0x00010000,
ITEMFLAG_CHECKGAMBLEPRICE = 0x00020000,
ITEMFLAG_UNKNOWN4 = 0x00080000,
ITEMFLAG_ETHERAL = 0x00400000,
ITEMFLAG_UNKNOWN5 = 0x00800000,
ITEMFLAG_FROMPLAYER = 0x01000000,
ITEMFLAG_RUNEWORD = 0x04000000
As a note: The flag itself just gives information about the item and doesn't make the item ethereal, socket. There are special functions that are called if you want your item to be spawned as ethereal, or with sockets.
D2Common #10707 Check Flags and return a result
Arg1 = ptItem
Arg2 = Flag to check (See the above table what to use)
Arg3 = _LINE_ (Not used any more)
Arg4 = _FILE_ (Not used any more)
With this function above we can check if a flag is set or not. For arg3, I have no idea what it's used for. Have played a bit with different values and doesn't have get any result at all of it. Maybe someone knows what it's used for?
To change the flags we use D2Common.#10708. With this function we can either remove or add a flag.
D2Common.#10708
Arg1 = ptItem
Arg2 = Flag to set/remove (See the above table what to use)
Arg3 = 1 = Set flag, 0 = Remove Flag
There are more functions that are used for test/set/remove flags also, those are D2Common #10709 Test flag, D2Common #10710 Get Flag, D2Common #10711 Set/Remove flag. I havn't looked into those functions yet to se more specific what arguments they use and what difference it is between the other two flags. But, I know these flags are involved with identify process.
The flags on client side plays an important part to choose what to display on the item. I will give an example how they test the flag and display socketed if the item has that flag set.
Code: Select all
6FAE3F7F 68 4C97B76F PUSH D2Client.6FB7974C
6FAE3F84 68 C7060000 PUSH 6C7 ; Unknown
6FAE3F89 68 00080000 PUSH 800 ; Socket flag
6FAE3F8E 53 PUSH EBX : ptItem
6FAE3F8F E8 EA6E0800 CALL <JMP.&D2Common.#10707> : Check flag and return result
6FAE3F94 85C0 TEST EAX,EAX ; test if EAX == 0
6FAE3F96 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10]
6FAE3F9A 0F84 A9000000 JE D2Client.6FAE4049 ; Jump if NULL, flag isn't set
6FAE3FA0 85C0 TEST EAX,EAX ; Do test if "," is needed to be added EAX == 0
6FAE3FA2 74 15 JE SHORT D2Client.6FAE3FB9 ; Jump if NULL, no "," is needed to add
6FAE3FA4 6A 0F PUSH 0F
6FAE3FA6 BA 1899B76F MOV EDX,D2Client.6FB79918 ; ASCII ", "
6FAE3FAB 8D4C24 40 LEA ECX,DWORD PTR SS:[ESP+40]
6FAE3FAF FFD5 CALL EBP
6FAE3FB1 8D5424 3C LEA EDX,DWORD PTR SS:[ESP+3C]
6FAE3FB5 8BCE MOV ECX,ESI
6FAE3FB7 FFD7 CALL EDI
6FAE3FB9 B9 7D0D0000 MOV ECX,0D7D ; Get strinkey for "Socketed: "
6FAE3FBE E8 157E0800 CALL <JMP.&D2Lang.#10004>
We will also look how the game decides if it should create sockets or not on server side then the item are generated.
I don't explain how they do the choose if the item is going to be socketed or not. The code that handles that is above and this code is part of the superior item generation.
Code: Select all
6FC4D7A0 6A 01 PUSH 1 ; Set flag
6FC4D7A2 68 00080000 PUSH 800 ; We will generate socketed item, so the flag needs to be set to socketed.
6FC4D7A7 56 PUSH ESI ; ptItem
6FC4D7A8 E8 29E00C00 CALL <JMP.&D2Common.#10708> ; Set Flag
6FC4D7AD 56 PUSH ESI ; ptItem
6FC4D7AE E8 C5E30C00 CALL <JMP.&D2Common.#10875> ; Get Version
6FC4D7B3 66:3D 0100 CMP AX,1 ; if classic version ax < 1
6FC4D7B7 72 18 JB SHORT D2Game.6FC4D7D1 ; then jump
6FC4D7B9 56 PUSH ESI ; ptItem
6FC4D7BA E8 5FE30C00 CALL <JMP.&D2Common.#10693> ; Get start Seed
6FC4D7BF 33D2 XOR EDX,EDX ; Make sure EDX is 0
6FC4D7C1 F7F7 DIV EDI ; The rest of the division is stored in EDX (EAX = EAX/DIV) and we use the rest for decide randomly how many sockets to add
6FC4D7C3 42 INC EDX ; Make sure sockets is never 0
6FC4D7C4 52 PUSH EDX ; Number of Sockets
6FC4D7C5 56 PUSH ESI ; ptItem
6FC4D7C6 E8 0DE40C00 CALL <JMP.&D2Common.#10817> ; Set number of sockets
26/11 minor update: renamed UNID to IS_IDENTIFIED