03-16-2004, 01:25 PM
I have been looking a bit on objects and how they spawn items. In the process a few other tidbits have surfaced too, so I thought I could share them.
First off, I will mainly talk about the objects in groups of their initiation and operation function. That is not necessarily the same as object types. The game really has a list of some almost 600 object types. Although some might look the same (like a chest or something else), it might in fact be different objects with different functions for initiation and/or operation. In the same way, many different objects will in fact use the very same functions for initiation and operation. For more information on this, I would turn people towards the objects.txt which hold all items, has a brief description of them and also list the various functions. I will in some cases try to give examples of the objects though.
First, lets look at what functions I have looked at. The initiation routines (run when the game create a map area and places the object there) are:
initfn 2, this function handle most object types not handled specifically by some other function. The only interesting thing done is setting up a trap. The chance for this is (monlvl1/8 + 5) %. Monlvl1 is from levels.txt and is the level for each map (even in act 5) of the non expansion game in normal difficulty. If we have a trap, it pick among the 8 existing at random with equal chance for all.
Want to mod the chance? Here we go:
:6FC70D75 0FBF4210 movsx eax, word ptr [edx+10]
Fetches the monlvl, one can change this (0x10) if one want, but if one want different chances for different difficulties, some more code editing is needed, on the other hand, there is some room below due to conversion between variable types not really needed. One get the difficulty from ptGame which is found at [esi]. If you don't understand all this, don't worry and don't bother :)
The different levels are at:
Monlvl1: edx+10
Monlvl2: edx+12
Monlvl3: edx+14
Monlvl1Ex: edx+16
Monlvl2Ex: edx+18
Monlvl3Ex: edx+1a
:6FC70D79 99 cdq
:6FC70D7A 83E207 and edx, 00000007
:6FC70D7D 03C2 add eax, edx
These are as far as I can see just to handle negative numbers. We really know there isn't any (or shouldn't be any), and that leaves room for code editing should one want difficulty for example.
:6FC70D7F C1F803 sar eax, 03
:6FC70D82 83C005 add eax, 00000005
:6FC70D85 25FFFF0000 and eax, 0000FFFF
Again, the last instruction can be skipped.
:6FC70D8A 3BC8 cmp ecx, eax
ecx holds the Rnd[100] value previously rolled.
:6FC70D8C 7D20 jge 6FC70DAE
That concludes this part.
initfn 3, this is for chests (mostly). It do the exact same for setting up a trap, with same chance.
Then it will check if it is lockable. If it is, there is a (monlvl1/2 + 8) % chance for it actually being locked.
Finally, and here I am a bit concerned, although I have to check how the game uses the seed in the TC pick function for objects, it will set the chests own seed to a 16 bit random value (based on global object seed). I don't know why this initialization is done, nor why it is done in the way it is. Seems very strange. If this seed is indeed used for picking items and quality, I can possibly see some problems. More to come later when I have checked a few things.
For modding, here are the relevant code sections, first for traps, then for being locked, for comments, see above :)
:6FC70E50 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70E54 8BCA mov ecx, edx
:6FC70E56 99 cdq
:6FC70E57 83E207 and edx, 00000007
:6FC70E5A 03C2 add eax, edx
:6FC70E5C C1F803 sar eax, 03
:6FC70E5F 83C005 add eax, 00000005
:6FC70E62 25FFFF0000 and eax, 0000FFFF
:6FC70E67 3BC8 cmp ecx, eax
:6FC70E69 7D0E jge 6FC70E79
:6FC70ED8 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70EDC 8BCA mov ecx, edx
:6FC70EDE 99 cdq
:6FC70EDF 2BC2 sub eax, edx
:6FC70EE1 D1F8 sar eax, 1
:6FC70EE3 83C008 add eax, 00000008
:6FC70EE6 3BC8 cmp ecx, eax
:6FC70EE8 7D05 jge 6FC70EEF
initfn 57, this is used for sparkling chest object and also special chest. I don't know were those two object types can occur though. In any case, sparkling chests are the ones using the special item drop functions, special chests don't. In any case, the setup is the exact same as for normal chests.
For mod purposes, here is relevant code sections.
:6FC70F70 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70F74 8BCA mov ecx, edx
:6FC70F76 99 cdq
:6FC70F77 83E207 and edx, 00000007
:6FC70F7A 03C2 add eax, edx
:6FC70F7C C1F803 sar eax, 03
:6FC70F7F 83C005 add eax, 00000005
:6FC70F82 25FFFF0000 and eax, 0000FFFF
:6FC70F87 3BC8 cmp ecx, eax
:6FC70F89 7D0E jge 6FC70F99
:6FC70FF8 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70FFC 8BCA mov ecx, edx
:6FC70FFE 99 cdq
:6FC70FFF 2BC2 sub eax, edx
:6FC71001 D1F8 sar eax, 1
:6FC71003 83C008 add eax, 00000008
:6FC71006 3BC8 cmp ecx, eax
:6FC71008 7D05 jge 6FC7100F
initfn 27, this is used for the goo piles in the sand maggot lair. Here, it is a 33.3% chance that the object will have a trap set (trap number 3).
For modders, here is relevant code section.
:6FC70DE2 BEE8030000 mov esi, 000003E8
:6FC70DE7 F7F6 div esi
:6FC70DE9 81FA4D010000 cmp edx, 0000014D
:6FC70DEF 7D02 jge 6FC70DF3
:6FC70DF1 B303 mov bl, 03
That is mostly it for initialization. One noteworthy function is initfn 28 for gold. I won't go through it, but for interested ones, it starts of at 6fc708b0.
In addition to the above, it is worth noticing a few more initializations. There is a flag (lets call it flag78), might not be a flag but value, but lets not dig to much into it. In any case, it is set in a selected very few cases, but do have importance. I really have not looked at it so much though that I can really tell when it is set, why or in what cases. I need to actually play more to be sure.
One case is when spawning special preset objects (objects with number following the ones in objects.txt, 574-582)). There are 9 such special ones, which have special initialization functions set up through a hard coded internal table (for modders, search for assertion on presetstuff). It seems this is set for special objects (chest?) on level 5 of the countess tower and also in the maggot lair for some (one or more?) objects. Might also exist for other cases. In addition it seems to be set for some fire "traps" but on a quick check it almost seemed to be set AFTER you operated an object so not sure if it really matters. IN any case, this is something that has to be looked a bit more at, but the end result of it will be explained below for item generation. If anyone is interested in the presetfunction that is of concern, it is the one at 6fc70470, for object 580. I have not looked at the other preset ones, but the first 6 ones are at 6fc70180 and do some interesting initialization too. Sorry for not having more info now.
Now, on to the more interesting stuff. How to spawn items from objects. To make it easier, I will make some general definitions and explanations first. For many purposes, all objects will drop like a "chest" in the sense that they use the chest TCs.
A chest TC drop is a "normal" drop, just like for monsters but from the corresponding chest TC. I think all chest TCs has a pick value of 4 and hence can drop up to 4 items (there is a "no drop" chance though). Chest TCs can either drop equipable items, junk items or good items. Junk and some good items (runes for example) can't have a quality and will always be considered of "normal" quality for that purpose.
A chest TC drop (and technically a monster one though although I don't think it happens) will use normal calculations to determine the quality of the item. But it can also have as a parameter a desired quality. If it has a desired quality, any item generated will get (if possible) that quality. If it can't get the desired quality, it can be of a failed quality /(for example rare instead of unique or magic instead of set) or if it is an item that can't be magical (such as a rune or potion) it will be of normal quality.
A test for magical+ item below, will check if the FIRST item generated from a chest TC drop (excluding "no drop results") is of quality magic, rare, set or unique. Items that can't have magical properties, such as runes, potions, keys and such are as already mentioned considered of normal quality. By the way, although I did not check specifically for this post, a "no drop" item should NOT count as one of the 6 items and the first item generated should thus always be an actual item. Otherwise some slight changes need to be done to the below explanations.
As with the initiation functions, I will base my explanation on the operation function.
operatefn 4, This is used for most chests, including sparkling chests, but also for some other objects such as ratnest, caskets in arcane sanctuary, hidden stashes in act 5, tombs, and some dead bodies. Please check objects.txt for full list. IN any case, this is one of the more complicated operation functions, although most of it is for the sparkling chest object.
First, the sparkling chests, the most complex one. There are 6 different options with the chance of being picked as below.
1. 2% chance
2. 4% chance
3. 6% chance
4. 20% chance
5. 30% chance
6. 38% chance
Note that the last option is also what I call the "fail" option. That is, for many of the other cases, if some requirement has not been fulfilled with the drops done, there will be additional drop according to option 6.
1. The game will make a chest TC drop with a desired quality of unique. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of unique. If that drop also fail for a magical+ test, the game will also make a drop according to option 6. Note that a chest TC drop can still generate, say 3 unique items for each of the two attempts and yet fail, as long as the first item in those two attempts was items that can't be magical.
2. The game will make a chest TC drop with a desired quality of set. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of set. If that drop also fail for a magical+ test, the game will also make a drop according to option 6.
3. The game will make a chest TC drop with a desired quality of rare. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of rare. If that drop also fail for a magical+ test, the game will also make a drop according to option 6.
4. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 3 of them pass a magical+ test, the 10 attempts are aborted.
5. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 2 of them pass a magical+ test, the 10 attempts are aborted. It will then drop a number of gold piles equalling 7 minus the numbers of failed magical+ attempts done so far.
6. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 1 of them pass a magical+ test, the 10 attempts are aborted. It will make a number of chest TC drops with no desired quality (thus normal quality probabilities including MF occurs) equalling 4 minus the numbers of failed magical+ attempts done so far. Next it makes 5 gold drops, 2 heal potion drops and 2 mana potion drops.
Phew :)
Now, for modders. Here are some relevant things one might want to change.
:6FC76176 B910270000 mov ecx, 00002710
:6FC7617B F7F1 div ecx
Just a Rnd[10000]
:6FC7617D 81FAC8000000 cmp edx, 000000C8
Chance for option 1.
:6FC76183 0F8DD1000000 jnl 6FC7625A
:6FC76189 BA07000000 mov edx, 00000007
:6FC7618E 8BCE mov ecx, esi
:6FC76190 E88B400000 call 6FC7A220
A chest TC drop with unique quality (7) desired.
:6FC76195 85C0 test eax, eax
:6FC76197 742C je 6FC761C5
Tests if an item spawned at all in first position. I don't think that should ever be possible (see above).
:6FC76199 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC7619A E86D560A00 Call 6FD1B80C
:6FC7619F 85C0 test eax, eax
:6FC761A1 0F856E020000 jne 6FC76415
Test for a magical+ item.
:6FC761A7 BA07000000 mov edx, 00000007
Set up for next unique chest TC drop (you should start to feel familiar with this now :) ).
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76289(U), :6FC762BD(U)
|
:6FC761AC 8BCE mov ecx, esi
:6FC761AE E86D400000 call 6FC7A220
:6FC761B3 85C0 test eax, eax
:6FC761B5 740E je 6FC761C5
:6FC761B7 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC761B8 E84F560A00 Call 6FD1B80C
:6FC761BD 85C0 test eax, eax
:6FC761BF 0F8550020000 jne 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76197©, :6FC761B5©, :6FC76270©, :6FC762A4©, :6FC762FC©
|:6FC7630D©
|
This is were option 6 starts.
:6FC761C5 8B5C2414 mov ebx, dword ptr [esp+14]
:6FC761C9 33FF xor edi, edi
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761EA©
|
:6FC761CB BA04000000 mov edx, 00000004
:6FC761D0 8BCE mov ecx, esi
:6FC761D2 E849400000 call 6FC7A220
Magic desired quality for chest TC drop. I will stop pointing it out from now on.
:6FC761D7 85C0 test eax, eax
:6FC761D9 740B je 6FC761E6
:6FC761DB 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC761DC E82B560A00 Call 6FD1B80C
:6FC761E1 85C0 test eax, eax
:6FC761E3 7507 jne 6FC761EC
:6FC761E5 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761D9©
|
:6FC761E6 47 inc edi
:6FC761E7 83FF0A cmp edi, 0000000A
:6FC761EA 7CDF jl 6FC761CB
The 10 attempts.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761E3©
|
:6FC761EC 83FB04 cmp ebx, 00000004
:6FC761EF 7D19 jge 6FC7620A
:6FC761F1 B804000000 mov eax, 00000004
:6FC761F6 2BC3 sub eax, ebx
:6FC761F8 85C0 test eax, eax
:6FC761FA 7E0E jle 6FC7620A
:6FC761FC 8BF8 mov edi, eax
The 4-fails attempts.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76208©
|
:6FC761FE 33D2 xor edx, edx
:6FC76200 8BCE mov ecx, esi
:6FC76202 E819400000 call 6FC7A220
:6FC76207 4F dec edi
:6FC76208 75F4 jne 6FC761FE
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC761EF©, :6FC761FA©
|
:6FC7620A BF05000000 mov edi, 00000005
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76221©
|
:6FC7620F 8B5604 mov edx, dword ptr [esi+04]
:6FC76212 8B0E mov ecx, dword ptr [esi]
:6FC76214 6A00 push 00000000
:6FC76216 68676C6420 push 20646C67
:6FC7621B E8203F0000 call 6FC7A140
:6FC76220 4F dec edi
:6FC76221 75EC jne 6FC7620F
Five gold drops.
:6FC76223 BF02000000 mov edi, 00000002
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7623A©
|
:6FC76228 8B5604 mov edx, dword ptr [esi+04]
:6FC7622B 8B0E mov ecx, dword ptr [esi]
:6FC7622D 6A00 push 00000000
:6FC7622F 6868703320 push 20337068
:6FC76234 E8073F0000 call 6FC7A140
:6FC76239 4F dec edi
:6FC7623A 75EC jne 6FC76228
2 potions.
:6FC7623C BF02000000 mov edi, 00000002
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76253©
|
:6FC76241 8B5604 mov edx, dword ptr [esi+04]
:6FC76244 8B0E mov ecx, dword ptr [esi]
:6FC76246 6A00 push 00000000
:6FC76248 686D703320 push 2033706D
:6FC7624D E8EE3E0000 call 6FC7A140
:6FC76252 4F dec edi
:6FC76253 75EC jne 6FC76241
:6FC76255 E9BB010000 jmp 6FC76415
The other 2 potions.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76183©
|
:6FC7625A 81FA58020000 cmp edx, 00000258
:6FC76260 7D2C jge 6FC7628E
Chance for option 2. Note that if edx was below C8 it went to unique. SO chance for this is 4%.
:6FC76262 BA05000000 mov edx, 00000005
:6FC76267 8BCE mov ecx, esi
:6FC76269 E8B23F0000 call 6FC7A220
:6FC7626E 85C0 test eax, eax
:6FC76270 0F844FFFFFFF je 6FC761C5
:6FC76276 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC76277 E890550A00 Call 6FD1B80C
:6FC7627C 85C0 test eax, eax
:6FC7627E 0F8591010000 jne 6FC76415
:6FC76284 BA05000000 mov edx, 00000005
:6FC76289 E91EFFFFFF jmp 6FC761AC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76260©
|
:6FC7628E 81FAB0040000 cmp edx, 000004B0
:6FC76294 7D2C jge 6FC762C2
Chance for option 3, rare drop.
:6FC76296 BA06000000 mov edx, 00000006
:6FC7629B 8BCE mov ecx, esi
:6FC7629D E87E3F0000 call 6FC7A220
:6FC762A2 85C0 test eax, eax
:6FC762A4 0F841BFFFFFF je 6FC761C5
:6FC762AA 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC762AB E85C550A00 Call 6FD1B80C
:6FC762B0 85C0 test eax, eax
:6FC762B2 0F855D010000 jne 6FC76415
:6FC762B8 BA06000000 mov edx, 00000006
:6FC762BD E9EAFEFFFF jmp 6FC761AC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76294©
|
:6FC762C2 81FA800C0000 cmp edx, 00000C80
Chance for option 4.
:6FC762C8 7D3D jge 6FC76307
:6FC762CA 33DB xor ebx, ebx
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762F4©
|
:6FC762CC BA04000000 mov edx, 00000004
:6FC762D1 8BCE mov ecx, esi
:6FC762D3 E8483F0000 call 6FC7A220
:6FC762D8 85C0 test eax, eax
:6FC762DA 740F je 6FC762EB
:6FC762DC 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC762DD E82A550A00 Call 6FD1B80C
:6FC762E2 85C0 test eax, eax
:6FC762E4 7401 je 6FC762E7
:6FC762E6 47 inc edi
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762E4©
|
:6FC762E7 FF442414 inc [esp+14]
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762DA©
|
:6FC762EB 83FF03 cmp edi, 00000003
:6FC762EE 7D06 jge 6FC762F6
The "abort after 3 successful magical+ tests".
:6FC762F0 43 inc ebx
:6FC762F1 83FB0A cmp ebx, 0000000A
:6FC762F4 7CD6 jl 6FC762CC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762EE©
|
:6FC762F6 8B442414 mov eax, dword ptr [esp+14]
:6FC762FA 85C0 test eax, eax
:6FC762FC 0F84C3FEFFFF je 6FC761C5
:6FC76302 E90E010000 jmp 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762C8©
|
:6FC76307 81FA38180000 cmp edx, 00001838
:6FC7630D 0F8DB2FEFFFF jnl 6FC761C5
Chance for option 5, otherwise, back to option 6.
:6FC76313 8B5C2414 mov ebx, dword ptr [esp+14]
:6FC76317 33ED xor ebp, ebp
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76340©
|
:6FC76319 BA04000000 mov edx, 00000004
:6FC7631E 8BCE mov ecx, esi
:6FC76320 E8FB3E0000 call 6FC7A220
:6FC76325 85C0 test eax, eax
:6FC76327 740E je 6FC76337
:6FC76329 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC7632A E8DD540A00 Call 6FD1B80C
:6FC7632F 85C0 test eax, eax
:6FC76331 7403 je 6FC76336
:6FC76333 47 inc edi
:6FC76334 EB01 jmp 6FC76337
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76331©
|
:6FC76336 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76327©, :6FC76334(U)
|
:6FC76337 83FF02 cmp edi, 00000002
:6FC7633A 7D06 jge 6FC76342
:6FC7633C 45 inc ebp
:6FC7633D 83FD0A cmp ebp, 0000000A
:6FC76340 7CD7 jl 6FC76319
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7633A©
|
:6FC76342 85DB test ebx, ebx
:6FC76344 7514 jne 6FC7635A
Test for number of failed magical+. If it was 0, the game below make a normal chest TC drop. I merged this with the case of lower than 7 but above 0,since the end result is the same. One can possibly toy around with this though.
:6FC76346 33D2 xor edx, edx
:6FC76348 8BCE mov ecx, esi
:6FC7634A E8D13E0000 call 6FC7A220
:6FC7634F 85C0 test eax, eax
:6FC76351 7410 je 6FC76363
:6FC76353 BB01000000 mov ebx, 00000001
:6FC76358 EB09 jmp 6FC76363
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76344©
|
:6FC7635A 83FB07 cmp ebx, 00000007
:6FC7635D 0F8DB2000000 jnl 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76351©, :6FC76358(U)
|
:6FC76363 B807000000 mov eax, 00000007
:6FC76368 2BC3 sub eax, ebx
:6FC7636A 85C0 test eax, eax
:6FC7636C 0F8EA3000000 jle 6FC76415
:6FC76372 8BF8 mov edi, eax
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76386©
|
:6FC76374 8B5604 mov edx, dword ptr [esi+04]
:6FC76377 8B0E mov ecx, dword ptr [esi]
:6FC76379 6A00 push 00000000
:6FC7637B 68676C6420 push 20646C67
:6FC76380 E8BB3D0000 call 6FC7A140
:6FC76385 4F dec edi
:6FC76386 75EC jne 6FC76374
:6FC76388 E988000000 jmp 6FC76415
The actual gold drops.
Ok, that was it for modders for now. Back to the other "chests". Here, the game will first set up a few things that we need to sort out. First of all, the game will check if it was locked, and if so, unlock it if you have a key or is an assassin. IN that case it also set the number of drops to 2, otherwise to 1.
Next, the game test for the flag78 I have mentioned above in the initialization routines. If it is set, there is a 5% chance that the game will make the desired quality of the drops to be rare, and otherwise (95% chance) the desired chance will be magic. If the flag is not set, there is no desired quality and the game pick it normally, applying MF and so on.
After that, the game will make a random chance to drop at all. 75% of the time it will drop. The other 25% of the time, it will only drop if flag78 is set or if the object was locked.
Now it will make the actual chest TC drop (either 1 or 2 depending on if the chest was locked), with a possible desired quality as mentioned above.
Then, if either flag78 is set or none of the previous chest TC drops (1 or 2) passed a magical+ test, it will make up to 10 chest TC drops with a possible desired quality as mentioned above. As soon as 1 of them pass a magical+ test, the 10 attempts are aborted.
Slightly more easy than the sparkling chests, no? Now, for modders.
:6FC76081 837A0406 cmp dword ptr [edx+04], 00000006
:6FC76085 7424 je 6FC760AB
Test for assassin unlocking chests.
:6FC760D5 B801000000 mov eax, 00000001
Setting eax to 1 causing it to be 2 drops for locked chests. Otherwise it is 0 since:
:6FC76065 33C0 xor eax, eax
:6FC760DD 40 inc eax
And this turns it into 1 or 2 for final number of drops.
:6FC760F6 E8F5760400 call 6FCBD7F0
:6FC760FB A801 test al, 01
:6FC760FD 743B je 6FC7613A
:6FC760FF 8B4E0C mov ecx, dword ptr [esi+0C]
:6FC76102 BAC590C66A mov edx, 6AC690C5
:6FC76107 33ED xor ebp, ebp
:6FC76109 C744241401000000 mov [esp+14], 00000001
:6FC76111 8B01 mov eax, dword ptr [ecx]
:6FC76113 8B7904 mov edi, dword ptr [ecx+04]
:6FC76116 F7E2 mul edx
:6FC76118 03C7 add eax, edi
:6FC7611A 13D5 adc edx, ebp
:6FC7611C 8901 mov dword ptr [ecx], eax
:6FC7611E 895104 mov dword ptr [ecx+04], edx
:6FC76121 33D2 xor edx, edx
:6FC76123 B964000000 mov ecx, 00000064
:6FC76128 F7F1 div ecx
:6FC7612A 33C0 xor eax, eax
:6FC7612C 83FA05 cmp edx, 00000005
:6FC7612F 0F9CC0 setl al
:6FC76132 8D440004 lea eax, dword ptr [eax+eax+04]
:6FC76136 8BF8 mov edi, eax
:6FC76138 EB02 jmp 6FC7613C
Above is the test for the flag78, and if so, sets a variable indicating it ([esp+14]), roll a Rnd[100] and with 5% chance set desired quality to 6 otherwise 4.
:6FC7613A 33FF xor edi, edi
And if no such flag is set, desired quality is 0, meaning it is checked for normally.
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76141©, :6FC7614E©
|
:6FC7638D 8B4E0C mov ecx, dword ptr [esi+0C]
:6FC76390 BAC590C66A mov edx, 6AC690C5
:6FC76395 33ED xor ebp, ebp
:6FC76397 8B01 mov eax, dword ptr [ecx]
:6FC76399 8B5904 mov ebx, dword ptr [ecx+04]
:6FC7639C F7E2 mul edx
:6FC7639E 03C3 add eax, ebx
:6FC763A0 13D5 adc edx, ebp
:6FC763A2 8901 mov dword ptr [ecx], eax
:6FC763A4 895104 mov dword ptr [ecx+04], edx
:6FC763A7 33D2 xor edx, edx
:6FC763A9 B964000000 mov ecx, 00000064
:6FC763AE F7F1 div ecx
:6FC763B0 83FA19 cmp edx, 00000019
:6FC763B3 7D10 jge 6FC763C5
The 25% chance to possibly abort the drop
:6FC763B5 8B442414 mov eax, dword ptr [esp+14]
:6FC763B9 85C0 test eax, eax
:6FC763BB 7508 jne 6FC763C5
:6FC763BD 8A442412 mov al, byte ptr [esp+12]
:6FC763C1 84C0 test al, al
:6FC763C3 7450 je 6FC76415
Test for flag or locked chest.
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC763B3©, :6FC763BB©
|
:6FC763C5 8B442418 mov eax, dword ptr [esp+18]
This is number of drops (1 or 2)
:6FC763C9 33DB xor ebx, ebx
:6FC763CB 85C0 test eax, eax
:6FC763CD 761D jbe 6FC763EC
:6FC763CF 8BE8 mov ebp, eax
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC763EA©
|
:6FC763D1 8BD7 mov edx, edi
:6FC763D3 8BCE mov ecx, esi
:6FC763D5 E8463E0000 call 6FC7A220
Do chest drop with previously determined quality desirability (0, 4 or 6).
:6FC763DA 85C0 test eax, eax
:6FC763DC 740B je 6FC763E9
:6FC763DE 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC763DF E828540A00 Call 6FD1B80C
:6FC763E4 85C0 test eax, eax
:6FC763E6 7401 je 6FC763E9
:6FC763E8 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC763DC©, :6FC763E6©
|
:6FC763E9 4D dec ebp
:6FC763EA 75E5 jne 6FC763D1
You should manage to understand this now.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC763CD©
|
:6FC763EC 8B442414 mov eax, dword ptr [esp+14]
:6FC763F0 85C0 test eax, eax
:6FC763F2 7421 je 6FC76415
:6FC763F4 85DB test ebx, ebx
:6FC763F6 751D jne 6FC76415
Exit if flag not set or no drop passing the magical+ test.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76413©
|
:6FC763F8 8BD7 mov edx, edi
:6FC763FA 8BCE mov ecx, esi
:6FC763FC E81F3E0000 call 6FC7A220
:6FC76401 85C0 test eax, eax
:6FC76403 740A je 6FC7640F
:6FC76405 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC76406 E801540A00 Call 6FD1B80C
:6FC7640B 85C0 test eax, eax
:6FC7640D 7506 jne 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76403©
|
:6FC7640F 43 inc ebx
:6FC76410 83FB0A cmp ebx, 0000000A
:6FC76413 72E3 jb 6FC763F8
The 10 attempts for a magical+ drop.
Chest drops are done. Now it is just a few simple things left in this post :)
operatefn 1, for some/most caskets, beds and sarcophaguses. Here the game always make a chest TC drop with no desired quality. In addition, it might spawn a monster from the object.
Modding:
:6FC77E95 33D2 xor edx, edx
:6FC77E97 8BCE mov ecx, esi
:6FC77E99 E882230000 call 6FC7A220
The drop.
:6FC77F1C B910270000 mov ecx, 00002710
:6FC77F21 F7F1 div ecx
:6FC77F23 F7C200E0FFFF test edx, FFFFE000
The 18.08% chance to spawn a monster.
operatefn 3, some/most urns, rock piles, baskets and jars. There is a 21% chance for making a chest TC drop.
Modding:
:6FC78248 B964000000 mov ecx, 00000064
:6FC7824D F7F1 div ecx
:6FC7824F 83FA14 cmp edx, 00000014
:6FC78252 7709 ja 6FC7825D
Find the drop code yourself :)
operatefn 5, barrels. There is a 21% chance for making a chest TC drop. In addition, it might spawn a monster from the object.
Modding:
:6FC78762 B910270000 mov ecx, 00002710
:6FC78767 F7F1 div ecx
:6FC78769 F7C200E0FFFF test edx, FFFFE000
:6FC7876F 7412 je 6FC78783
and:
:6FC787A0 B964000000 mov ecx, 00000064
:6FC787A5 5B pop ebx
:6FC787A6 F7F1 div ecx
:6FC787A8 83FA14 cmp edx, 00000014
:6FC787AB 7709 ja 6FC787B6
Soon you can recognize this in your sleep :)
operatefn 14, some/many crates, rogue corpses, jugs, rock piles, logs, boulders, stashes, cocoons, goo piles, dead guards and some more. Here the game always make a chest TC drop with no desired quality.
:6FC782A6 33D2 xor edx, edx
:6FC782A8 8BCE mov ecx, esi
:6FC782AA E8711F0000 call 6FC7A220
Just so you find the function!
operatefn 26, bookshelves. 65% chance for scroll, 35% for book (or is it the other way around?). Always 50/50 for town portal or identify.
For modding:
:6FC7853A B914000000 mov ecx, 00000014
:6FC7853F F7F1 div ecx
Doing a Rnd[20]
:6FC78549 83FA0C cmp edx, 0000000C
:6FC7854C BAC590C66A mov edx, 6AC690C5
:6FC78551 7E2D jle 6FC78580
Doing a check for 0-12 (don't bother with the middle instruction, part of next random roll)
:6FC7855B A801 test al, 01
:6FC7855D 895104 mov dword ptr [ecx+04], edx
:6FC78560 740F je 6FC78571
:6FC78562 8B4604 mov eax, dword ptr [esi+04]
:6FC78565 C780B800000069626B20 mov dword ptr [ebx+000000B8], 206B6269
:6FC7856F EB3A jmp 6FC785AB
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC78560©
|
:6FC78571 8B4E04 mov ecx, dword ptr [esi+04]
:6FC78574 C781B800000074626B20 mov dword ptr [ebx+000000B8], 206B6274
:6FC7857E EB2B jmp 6FC785AB
50/50 for TP and identify.
:6FC78588 A801 test al, 01
:6FC7858A 895104 mov dword ptr [ecx+04], edx
:6FC7858D 740F je 6FC7859E
:6FC7858F 8B4604 mov eax, dword ptr [esi+04]
:6FC78592 C780B800000069736320 mov dword ptr [ebx+000000B8], 20637369
:6FC7859C EB0D jmp 6FC785AB
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7858D©
|
:6FC7859E 8B4E04 mov ecx, dword ptr [esi+04]
:6FC785A1 C781B800000074736320 mov dword ptr [ebx+000000B8], 20637374
And again for books (or is it scroll? I leave it as an exercise for the reader).
That is basically it. I might have missed some, I might have goofed on other things, not all might be correct, but hey, we have to have something to do in the follow up posts, right?
The internal list of function pointers for the operation, initiation and so on are found at:
6fd2fb78 for operation, 6fd2f578 for the initiation, 6fd2f6b8 for the population (all these three are from objects.txt). At 6fd2f6e4 for the preset stuff and 6fd2fb48 for the trap stuff.
Enjoy.
First off, I will mainly talk about the objects in groups of their initiation and operation function. That is not necessarily the same as object types. The game really has a list of some almost 600 object types. Although some might look the same (like a chest or something else), it might in fact be different objects with different functions for initiation and/or operation. In the same way, many different objects will in fact use the very same functions for initiation and operation. For more information on this, I would turn people towards the objects.txt which hold all items, has a brief description of them and also list the various functions. I will in some cases try to give examples of the objects though.
First, lets look at what functions I have looked at. The initiation routines (run when the game create a map area and places the object there) are:
initfn 2, this function handle most object types not handled specifically by some other function. The only interesting thing done is setting up a trap. The chance for this is (monlvl1/8 + 5) %. Monlvl1 is from levels.txt and is the level for each map (even in act 5) of the non expansion game in normal difficulty. If we have a trap, it pick among the 8 existing at random with equal chance for all.
Want to mod the chance? Here we go:
:6FC70D75 0FBF4210 movsx eax, word ptr [edx+10]
Fetches the monlvl, one can change this (0x10) if one want, but if one want different chances for different difficulties, some more code editing is needed, on the other hand, there is some room below due to conversion between variable types not really needed. One get the difficulty from ptGame which is found at [esi]. If you don't understand all this, don't worry and don't bother :)
The different levels are at:
Monlvl1: edx+10
Monlvl2: edx+12
Monlvl3: edx+14
Monlvl1Ex: edx+16
Monlvl2Ex: edx+18
Monlvl3Ex: edx+1a
:6FC70D79 99 cdq
:6FC70D7A 83E207 and edx, 00000007
:6FC70D7D 03C2 add eax, edx
These are as far as I can see just to handle negative numbers. We really know there isn't any (or shouldn't be any), and that leaves room for code editing should one want difficulty for example.
:6FC70D7F C1F803 sar eax, 03
:6FC70D82 83C005 add eax, 00000005
:6FC70D85 25FFFF0000 and eax, 0000FFFF
Again, the last instruction can be skipped.
:6FC70D8A 3BC8 cmp ecx, eax
ecx holds the Rnd[100] value previously rolled.
:6FC70D8C 7D20 jge 6FC70DAE
That concludes this part.
initfn 3, this is for chests (mostly). It do the exact same for setting up a trap, with same chance.
Then it will check if it is lockable. If it is, there is a (monlvl1/2 + 8) % chance for it actually being locked.
Finally, and here I am a bit concerned, although I have to check how the game uses the seed in the TC pick function for objects, it will set the chests own seed to a 16 bit random value (based on global object seed). I don't know why this initialization is done, nor why it is done in the way it is. Seems very strange. If this seed is indeed used for picking items and quality, I can possibly see some problems. More to come later when I have checked a few things.
For modding, here are the relevant code sections, first for traps, then for being locked, for comments, see above :)
:6FC70E50 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70E54 8BCA mov ecx, edx
:6FC70E56 99 cdq
:6FC70E57 83E207 and edx, 00000007
:6FC70E5A 03C2 add eax, edx
:6FC70E5C C1F803 sar eax, 03
:6FC70E5F 83C005 add eax, 00000005
:6FC70E62 25FFFF0000 and eax, 0000FFFF
:6FC70E67 3BC8 cmp ecx, eax
:6FC70E69 7D0E jge 6FC70E79
:6FC70ED8 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70EDC 8BCA mov ecx, edx
:6FC70EDE 99 cdq
:6FC70EDF 2BC2 sub eax, edx
:6FC70EE1 D1F8 sar eax, 1
:6FC70EE3 83C008 add eax, 00000008
:6FC70EE6 3BC8 cmp ecx, eax
:6FC70EE8 7D05 jge 6FC70EEF
initfn 57, this is used for sparkling chest object and also special chest. I don't know were those two object types can occur though. In any case, sparkling chests are the ones using the special item drop functions, special chests don't. In any case, the setup is the exact same as for normal chests.
For mod purposes, here is relevant code sections.
:6FC70F70 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70F74 8BCA mov ecx, edx
:6FC70F76 99 cdq
:6FC70F77 83E207 and edx, 00000007
:6FC70F7A 03C2 add eax, edx
:6FC70F7C C1F803 sar eax, 03
:6FC70F7F 83C005 add eax, 00000005
:6FC70F82 25FFFF0000 and eax, 0000FFFF
:6FC70F87 3BC8 cmp ecx, eax
:6FC70F89 7D0E jge 6FC70F99
:6FC70FF8 0FBF4710 movsx eax, word ptr [edi+10]
:6FC70FFC 8BCA mov ecx, edx
:6FC70FFE 99 cdq
:6FC70FFF 2BC2 sub eax, edx
:6FC71001 D1F8 sar eax, 1
:6FC71003 83C008 add eax, 00000008
:6FC71006 3BC8 cmp ecx, eax
:6FC71008 7D05 jge 6FC7100F
initfn 27, this is used for the goo piles in the sand maggot lair. Here, it is a 33.3% chance that the object will have a trap set (trap number 3).
For modders, here is relevant code section.
:6FC70DE2 BEE8030000 mov esi, 000003E8
:6FC70DE7 F7F6 div esi
:6FC70DE9 81FA4D010000 cmp edx, 0000014D
:6FC70DEF 7D02 jge 6FC70DF3
:6FC70DF1 B303 mov bl, 03
That is mostly it for initialization. One noteworthy function is initfn 28 for gold. I won't go through it, but for interested ones, it starts of at 6fc708b0.
In addition to the above, it is worth noticing a few more initializations. There is a flag (lets call it flag78), might not be a flag but value, but lets not dig to much into it. In any case, it is set in a selected very few cases, but do have importance. I really have not looked at it so much though that I can really tell when it is set, why or in what cases. I need to actually play more to be sure.
One case is when spawning special preset objects (objects with number following the ones in objects.txt, 574-582)). There are 9 such special ones, which have special initialization functions set up through a hard coded internal table (for modders, search for assertion on presetstuff). It seems this is set for special objects (chest?) on level 5 of the countess tower and also in the maggot lair for some (one or more?) objects. Might also exist for other cases. In addition it seems to be set for some fire "traps" but on a quick check it almost seemed to be set AFTER you operated an object so not sure if it really matters. IN any case, this is something that has to be looked a bit more at, but the end result of it will be explained below for item generation. If anyone is interested in the presetfunction that is of concern, it is the one at 6fc70470, for object 580. I have not looked at the other preset ones, but the first 6 ones are at 6fc70180 and do some interesting initialization too. Sorry for not having more info now.
Now, on to the more interesting stuff. How to spawn items from objects. To make it easier, I will make some general definitions and explanations first. For many purposes, all objects will drop like a "chest" in the sense that they use the chest TCs.
A chest TC drop is a "normal" drop, just like for monsters but from the corresponding chest TC. I think all chest TCs has a pick value of 4 and hence can drop up to 4 items (there is a "no drop" chance though). Chest TCs can either drop equipable items, junk items or good items. Junk and some good items (runes for example) can't have a quality and will always be considered of "normal" quality for that purpose.
A chest TC drop (and technically a monster one though although I don't think it happens) will use normal calculations to determine the quality of the item. But it can also have as a parameter a desired quality. If it has a desired quality, any item generated will get (if possible) that quality. If it can't get the desired quality, it can be of a failed quality /(for example rare instead of unique or magic instead of set) or if it is an item that can't be magical (such as a rune or potion) it will be of normal quality.
A test for magical+ item below, will check if the FIRST item generated from a chest TC drop (excluding "no drop results") is of quality magic, rare, set or unique. Items that can't have magical properties, such as runes, potions, keys and such are as already mentioned considered of normal quality. By the way, although I did not check specifically for this post, a "no drop" item should NOT count as one of the 6 items and the first item generated should thus always be an actual item. Otherwise some slight changes need to be done to the below explanations.
As with the initiation functions, I will base my explanation on the operation function.
operatefn 4, This is used for most chests, including sparkling chests, but also for some other objects such as ratnest, caskets in arcane sanctuary, hidden stashes in act 5, tombs, and some dead bodies. Please check objects.txt for full list. IN any case, this is one of the more complicated operation functions, although most of it is for the sparkling chest object.
First, the sparkling chests, the most complex one. There are 6 different options with the chance of being picked as below.
1. 2% chance
2. 4% chance
3. 6% chance
4. 20% chance
5. 30% chance
6. 38% chance
Note that the last option is also what I call the "fail" option. That is, for many of the other cases, if some requirement has not been fulfilled with the drops done, there will be additional drop according to option 6.
1. The game will make a chest TC drop with a desired quality of unique. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of unique. If that drop also fail for a magical+ test, the game will also make a drop according to option 6. Note that a chest TC drop can still generate, say 3 unique items for each of the two attempts and yet fail, as long as the first item in those two attempts was items that can't be magical.
2. The game will make a chest TC drop with a desired quality of set. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of set. If that drop also fail for a magical+ test, the game will also make a drop according to option 6.
3. The game will make a chest TC drop with a desired quality of rare. If the drop fail for a magical+ test, it will make another chest TC drop with a desired quality of rare. If that drop also fail for a magical+ test, the game will also make a drop according to option 6.
4. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 3 of them pass a magical+ test, the 10 attempts are aborted.
5. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 2 of them pass a magical+ test, the 10 attempts are aborted. It will then drop a number of gold piles equalling 7 minus the numbers of failed magical+ attempts done so far.
6. The game will make up to 10 chest TC drops with a desired quality of magic. As soon as 1 of them pass a magical+ test, the 10 attempts are aborted. It will make a number of chest TC drops with no desired quality (thus normal quality probabilities including MF occurs) equalling 4 minus the numbers of failed magical+ attempts done so far. Next it makes 5 gold drops, 2 heal potion drops and 2 mana potion drops.
Phew :)
Now, for modders. Here are some relevant things one might want to change.
:6FC76176 B910270000 mov ecx, 00002710
:6FC7617B F7F1 div ecx
Just a Rnd[10000]
:6FC7617D 81FAC8000000 cmp edx, 000000C8
Chance for option 1.
:6FC76183 0F8DD1000000 jnl 6FC7625A
:6FC76189 BA07000000 mov edx, 00000007
:6FC7618E 8BCE mov ecx, esi
:6FC76190 E88B400000 call 6FC7A220
A chest TC drop with unique quality (7) desired.
:6FC76195 85C0 test eax, eax
:6FC76197 742C je 6FC761C5
Tests if an item spawned at all in first position. I don't think that should ever be possible (see above).
:6FC76199 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC7619A E86D560A00 Call 6FD1B80C
:6FC7619F 85C0 test eax, eax
:6FC761A1 0F856E020000 jne 6FC76415
Test for a magical+ item.
:6FC761A7 BA07000000 mov edx, 00000007
Set up for next unique chest TC drop (you should start to feel familiar with this now :) ).
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76289(U), :6FC762BD(U)
|
:6FC761AC 8BCE mov ecx, esi
:6FC761AE E86D400000 call 6FC7A220
:6FC761B3 85C0 test eax, eax
:6FC761B5 740E je 6FC761C5
:6FC761B7 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC761B8 E84F560A00 Call 6FD1B80C
:6FC761BD 85C0 test eax, eax
:6FC761BF 0F8550020000 jne 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76197©, :6FC761B5©, :6FC76270©, :6FC762A4©, :6FC762FC©
|:6FC7630D©
|
This is were option 6 starts.
:6FC761C5 8B5C2414 mov ebx, dword ptr [esp+14]
:6FC761C9 33FF xor edi, edi
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761EA©
|
:6FC761CB BA04000000 mov edx, 00000004
:6FC761D0 8BCE mov ecx, esi
:6FC761D2 E849400000 call 6FC7A220
Magic desired quality for chest TC drop. I will stop pointing it out from now on.
:6FC761D7 85C0 test eax, eax
:6FC761D9 740B je 6FC761E6
:6FC761DB 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC761DC E82B560A00 Call 6FD1B80C
:6FC761E1 85C0 test eax, eax
:6FC761E3 7507 jne 6FC761EC
:6FC761E5 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761D9©
|
:6FC761E6 47 inc edi
:6FC761E7 83FF0A cmp edi, 0000000A
:6FC761EA 7CDF jl 6FC761CB
The 10 attempts.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC761E3©
|
:6FC761EC 83FB04 cmp ebx, 00000004
:6FC761EF 7D19 jge 6FC7620A
:6FC761F1 B804000000 mov eax, 00000004
:6FC761F6 2BC3 sub eax, ebx
:6FC761F8 85C0 test eax, eax
:6FC761FA 7E0E jle 6FC7620A
:6FC761FC 8BF8 mov edi, eax
The 4-fails attempts.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76208©
|
:6FC761FE 33D2 xor edx, edx
:6FC76200 8BCE mov ecx, esi
:6FC76202 E819400000 call 6FC7A220
:6FC76207 4F dec edi
:6FC76208 75F4 jne 6FC761FE
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC761EF©, :6FC761FA©
|
:6FC7620A BF05000000 mov edi, 00000005
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76221©
|
:6FC7620F 8B5604 mov edx, dword ptr [esi+04]
:6FC76212 8B0E mov ecx, dword ptr [esi]
:6FC76214 6A00 push 00000000
:6FC76216 68676C6420 push 20646C67
:6FC7621B E8203F0000 call 6FC7A140
:6FC76220 4F dec edi
:6FC76221 75EC jne 6FC7620F
Five gold drops.
:6FC76223 BF02000000 mov edi, 00000002
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7623A©
|
:6FC76228 8B5604 mov edx, dword ptr [esi+04]
:6FC7622B 8B0E mov ecx, dword ptr [esi]
:6FC7622D 6A00 push 00000000
:6FC7622F 6868703320 push 20337068
:6FC76234 E8073F0000 call 6FC7A140
:6FC76239 4F dec edi
:6FC7623A 75EC jne 6FC76228
2 potions.
:6FC7623C BF02000000 mov edi, 00000002
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76253©
|
:6FC76241 8B5604 mov edx, dword ptr [esi+04]
:6FC76244 8B0E mov ecx, dword ptr [esi]
:6FC76246 6A00 push 00000000
:6FC76248 686D703320 push 2033706D
:6FC7624D E8EE3E0000 call 6FC7A140
:6FC76252 4F dec edi
:6FC76253 75EC jne 6FC76241
:6FC76255 E9BB010000 jmp 6FC76415
The other 2 potions.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76183©
|
:6FC7625A 81FA58020000 cmp edx, 00000258
:6FC76260 7D2C jge 6FC7628E
Chance for option 2. Note that if edx was below C8 it went to unique. SO chance for this is 4%.
:6FC76262 BA05000000 mov edx, 00000005
:6FC76267 8BCE mov ecx, esi
:6FC76269 E8B23F0000 call 6FC7A220
:6FC7626E 85C0 test eax, eax
:6FC76270 0F844FFFFFFF je 6FC761C5
:6FC76276 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC76277 E890550A00 Call 6FD1B80C
:6FC7627C 85C0 test eax, eax
:6FC7627E 0F8591010000 jne 6FC76415
:6FC76284 BA05000000 mov edx, 00000005
:6FC76289 E91EFFFFFF jmp 6FC761AC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76260©
|
:6FC7628E 81FAB0040000 cmp edx, 000004B0
:6FC76294 7D2C jge 6FC762C2
Chance for option 3, rare drop.
:6FC76296 BA06000000 mov edx, 00000006
:6FC7629B 8BCE mov ecx, esi
:6FC7629D E87E3F0000 call 6FC7A220
:6FC762A2 85C0 test eax, eax
:6FC762A4 0F841BFFFFFF je 6FC761C5
:6FC762AA 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC762AB E85C550A00 Call 6FD1B80C
:6FC762B0 85C0 test eax, eax
:6FC762B2 0F855D010000 jne 6FC76415
:6FC762B8 BA06000000 mov edx, 00000006
:6FC762BD E9EAFEFFFF jmp 6FC761AC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76294©
|
:6FC762C2 81FA800C0000 cmp edx, 00000C80
Chance for option 4.
:6FC762C8 7D3D jge 6FC76307
:6FC762CA 33DB xor ebx, ebx
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762F4©
|
:6FC762CC BA04000000 mov edx, 00000004
:6FC762D1 8BCE mov ecx, esi
:6FC762D3 E8483F0000 call 6FC7A220
:6FC762D8 85C0 test eax, eax
:6FC762DA 740F je 6FC762EB
:6FC762DC 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC762DD E82A550A00 Call 6FD1B80C
:6FC762E2 85C0 test eax, eax
:6FC762E4 7401 je 6FC762E7
:6FC762E6 47 inc edi
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762E4©
|
:6FC762E7 FF442414 inc [esp+14]
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762DA©
|
:6FC762EB 83FF03 cmp edi, 00000003
:6FC762EE 7D06 jge 6FC762F6
The "abort after 3 successful magical+ tests".
:6FC762F0 43 inc ebx
:6FC762F1 83FB0A cmp ebx, 0000000A
:6FC762F4 7CD6 jl 6FC762CC
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762EE©
|
:6FC762F6 8B442414 mov eax, dword ptr [esp+14]
:6FC762FA 85C0 test eax, eax
:6FC762FC 0F84C3FEFFFF je 6FC761C5
:6FC76302 E90E010000 jmp 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC762C8©
|
:6FC76307 81FA38180000 cmp edx, 00001838
:6FC7630D 0F8DB2FEFFFF jnl 6FC761C5
Chance for option 5, otherwise, back to option 6.
:6FC76313 8B5C2414 mov ebx, dword ptr [esp+14]
:6FC76317 33ED xor ebp, ebp
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76340©
|
:6FC76319 BA04000000 mov edx, 00000004
:6FC7631E 8BCE mov ecx, esi
:6FC76320 E8FB3E0000 call 6FC7A220
:6FC76325 85C0 test eax, eax
:6FC76327 740E je 6FC76337
:6FC76329 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC7632A E8DD540A00 Call 6FD1B80C
:6FC7632F 85C0 test eax, eax
:6FC76331 7403 je 6FC76336
:6FC76333 47 inc edi
:6FC76334 EB01 jmp 6FC76337
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76331©
|
:6FC76336 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76327©, :6FC76334(U)
|
:6FC76337 83FF02 cmp edi, 00000002
:6FC7633A 7D06 jge 6FC76342
:6FC7633C 45 inc ebp
:6FC7633D 83FD0A cmp ebp, 0000000A
:6FC76340 7CD7 jl 6FC76319
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7633A©
|
:6FC76342 85DB test ebx, ebx
:6FC76344 7514 jne 6FC7635A
Test for number of failed magical+. If it was 0, the game below make a normal chest TC drop. I merged this with the case of lower than 7 but above 0,since the end result is the same. One can possibly toy around with this though.
:6FC76346 33D2 xor edx, edx
:6FC76348 8BCE mov ecx, esi
:6FC7634A E8D13E0000 call 6FC7A220
:6FC7634F 85C0 test eax, eax
:6FC76351 7410 je 6FC76363
:6FC76353 BB01000000 mov ebx, 00000001
:6FC76358 EB09 jmp 6FC76363
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76344©
|
:6FC7635A 83FB07 cmp ebx, 00000007
:6FC7635D 0F8DB2000000 jnl 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76351©, :6FC76358(U)
|
:6FC76363 B807000000 mov eax, 00000007
:6FC76368 2BC3 sub eax, ebx
:6FC7636A 85C0 test eax, eax
:6FC7636C 0F8EA3000000 jle 6FC76415
:6FC76372 8BF8 mov edi, eax
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76386©
|
:6FC76374 8B5604 mov edx, dword ptr [esi+04]
:6FC76377 8B0E mov ecx, dword ptr [esi]
:6FC76379 6A00 push 00000000
:6FC7637B 68676C6420 push 20646C67
:6FC76380 E8BB3D0000 call 6FC7A140
:6FC76385 4F dec edi
:6FC76386 75EC jne 6FC76374
:6FC76388 E988000000 jmp 6FC76415
The actual gold drops.
Ok, that was it for modders for now. Back to the other "chests". Here, the game will first set up a few things that we need to sort out. First of all, the game will check if it was locked, and if so, unlock it if you have a key or is an assassin. IN that case it also set the number of drops to 2, otherwise to 1.
Next, the game test for the flag78 I have mentioned above in the initialization routines. If it is set, there is a 5% chance that the game will make the desired quality of the drops to be rare, and otherwise (95% chance) the desired chance will be magic. If the flag is not set, there is no desired quality and the game pick it normally, applying MF and so on.
After that, the game will make a random chance to drop at all. 75% of the time it will drop. The other 25% of the time, it will only drop if flag78 is set or if the object was locked.
Now it will make the actual chest TC drop (either 1 or 2 depending on if the chest was locked), with a possible desired quality as mentioned above.
Then, if either flag78 is set or none of the previous chest TC drops (1 or 2) passed a magical+ test, it will make up to 10 chest TC drops with a possible desired quality as mentioned above. As soon as 1 of them pass a magical+ test, the 10 attempts are aborted.
Slightly more easy than the sparkling chests, no? Now, for modders.
:6FC76081 837A0406 cmp dword ptr [edx+04], 00000006
:6FC76085 7424 je 6FC760AB
Test for assassin unlocking chests.
:6FC760D5 B801000000 mov eax, 00000001
Setting eax to 1 causing it to be 2 drops for locked chests. Otherwise it is 0 since:
:6FC76065 33C0 xor eax, eax
:6FC760DD 40 inc eax
And this turns it into 1 or 2 for final number of drops.
:6FC760F6 E8F5760400 call 6FCBD7F0
:6FC760FB A801 test al, 01
:6FC760FD 743B je 6FC7613A
:6FC760FF 8B4E0C mov ecx, dword ptr [esi+0C]
:6FC76102 BAC590C66A mov edx, 6AC690C5
:6FC76107 33ED xor ebp, ebp
:6FC76109 C744241401000000 mov [esp+14], 00000001
:6FC76111 8B01 mov eax, dword ptr [ecx]
:6FC76113 8B7904 mov edi, dword ptr [ecx+04]
:6FC76116 F7E2 mul edx
:6FC76118 03C7 add eax, edi
:6FC7611A 13D5 adc edx, ebp
:6FC7611C 8901 mov dword ptr [ecx], eax
:6FC7611E 895104 mov dword ptr [ecx+04], edx
:6FC76121 33D2 xor edx, edx
:6FC76123 B964000000 mov ecx, 00000064
:6FC76128 F7F1 div ecx
:6FC7612A 33C0 xor eax, eax
:6FC7612C 83FA05 cmp edx, 00000005
:6FC7612F 0F9CC0 setl al
:6FC76132 8D440004 lea eax, dword ptr [eax+eax+04]
:6FC76136 8BF8 mov edi, eax
:6FC76138 EB02 jmp 6FC7613C
Above is the test for the flag78, and if so, sets a variable indicating it ([esp+14]), roll a Rnd[100] and with 5% chance set desired quality to 6 otherwise 4.
:6FC7613A 33FF xor edi, edi
And if no such flag is set, desired quality is 0, meaning it is checked for normally.
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC76141©, :6FC7614E©
|
:6FC7638D 8B4E0C mov ecx, dword ptr [esi+0C]
:6FC76390 BAC590C66A mov edx, 6AC690C5
:6FC76395 33ED xor ebp, ebp
:6FC76397 8B01 mov eax, dword ptr [ecx]
:6FC76399 8B5904 mov ebx, dword ptr [ecx+04]
:6FC7639C F7E2 mul edx
:6FC7639E 03C3 add eax, ebx
:6FC763A0 13D5 adc edx, ebp
:6FC763A2 8901 mov dword ptr [ecx], eax
:6FC763A4 895104 mov dword ptr [ecx+04], edx
:6FC763A7 33D2 xor edx, edx
:6FC763A9 B964000000 mov ecx, 00000064
:6FC763AE F7F1 div ecx
:6FC763B0 83FA19 cmp edx, 00000019
:6FC763B3 7D10 jge 6FC763C5
The 25% chance to possibly abort the drop
:6FC763B5 8B442414 mov eax, dword ptr [esp+14]
:6FC763B9 85C0 test eax, eax
:6FC763BB 7508 jne 6FC763C5
:6FC763BD 8A442412 mov al, byte ptr [esp+12]
:6FC763C1 84C0 test al, al
:6FC763C3 7450 je 6FC76415
Test for flag or locked chest.
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC763B3©, :6FC763BB©
|
:6FC763C5 8B442418 mov eax, dword ptr [esp+18]
This is number of drops (1 or 2)
:6FC763C9 33DB xor ebx, ebx
:6FC763CB 85C0 test eax, eax
:6FC763CD 761D jbe 6FC763EC
:6FC763CF 8BE8 mov ebp, eax
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC763EA©
|
:6FC763D1 8BD7 mov edx, edi
:6FC763D3 8BCE mov ecx, esi
:6FC763D5 E8463E0000 call 6FC7A220
Do chest drop with previously determined quality desirability (0, 4 or 6).
:6FC763DA 85C0 test eax, eax
:6FC763DC 740B je 6FC763E9
:6FC763DE 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC763DF E828540A00 Call 6FD1B80C
:6FC763E4 85C0 test eax, eax
:6FC763E6 7401 je 6FC763E9
:6FC763E8 43 inc ebx
* Referenced by a (U)nconditional or ©onditional Jump at Addresses:
|:6FC763DC©, :6FC763E6©
|
:6FC763E9 4D dec ebp
:6FC763EA 75E5 jne 6FC763D1
You should manage to understand this now.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC763CD©
|
:6FC763EC 8B442414 mov eax, dword ptr [esp+14]
:6FC763F0 85C0 test eax, eax
:6FC763F2 7421 je 6FC76415
:6FC763F4 85DB test ebx, ebx
:6FC763F6 751D jne 6FC76415
Exit if flag not set or no drop passing the magical+ test.
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76413©
|
:6FC763F8 8BD7 mov edx, edi
:6FC763FA 8BCE mov ecx, esi
:6FC763FC E81F3E0000 call 6FC7A220
:6FC76401 85C0 test eax, eax
:6FC76403 740A je 6FC7640F
:6FC76405 50 push eax
* Reference To: D2Common.Ordinal:2A4A, Ord:2A4Ah
|
:6FC76406 E801540A00 Call 6FD1B80C
:6FC7640B 85C0 test eax, eax
:6FC7640D 7506 jne 6FC76415
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC76403©
|
:6FC7640F 43 inc ebx
:6FC76410 83FB0A cmp ebx, 0000000A
:6FC76413 72E3 jb 6FC763F8
The 10 attempts for a magical+ drop.
Chest drops are done. Now it is just a few simple things left in this post :)
operatefn 1, for some/most caskets, beds and sarcophaguses. Here the game always make a chest TC drop with no desired quality. In addition, it might spawn a monster from the object.
Modding:
:6FC77E95 33D2 xor edx, edx
:6FC77E97 8BCE mov ecx, esi
:6FC77E99 E882230000 call 6FC7A220
The drop.
:6FC77F1C B910270000 mov ecx, 00002710
:6FC77F21 F7F1 div ecx
:6FC77F23 F7C200E0FFFF test edx, FFFFE000
The 18.08% chance to spawn a monster.
operatefn 3, some/most urns, rock piles, baskets and jars. There is a 21% chance for making a chest TC drop.
Modding:
:6FC78248 B964000000 mov ecx, 00000064
:6FC7824D F7F1 div ecx
:6FC7824F 83FA14 cmp edx, 00000014
:6FC78252 7709 ja 6FC7825D
Find the drop code yourself :)
operatefn 5, barrels. There is a 21% chance for making a chest TC drop. In addition, it might spawn a monster from the object.
Modding:
:6FC78762 B910270000 mov ecx, 00002710
:6FC78767 F7F1 div ecx
:6FC78769 F7C200E0FFFF test edx, FFFFE000
:6FC7876F 7412 je 6FC78783
and:
:6FC787A0 B964000000 mov ecx, 00000064
:6FC787A5 5B pop ebx
:6FC787A6 F7F1 div ecx
:6FC787A8 83FA14 cmp edx, 00000014
:6FC787AB 7709 ja 6FC787B6
Soon you can recognize this in your sleep :)
operatefn 14, some/many crates, rogue corpses, jugs, rock piles, logs, boulders, stashes, cocoons, goo piles, dead guards and some more. Here the game always make a chest TC drop with no desired quality.
:6FC782A6 33D2 xor edx, edx
:6FC782A8 8BCE mov ecx, esi
:6FC782AA E8711F0000 call 6FC7A220
Just so you find the function!
operatefn 26, bookshelves. 65% chance for scroll, 35% for book (or is it the other way around?). Always 50/50 for town portal or identify.
For modding:
:6FC7853A B914000000 mov ecx, 00000014
:6FC7853F F7F1 div ecx
Doing a Rnd[20]
:6FC78549 83FA0C cmp edx, 0000000C
:6FC7854C BAC590C66A mov edx, 6AC690C5
:6FC78551 7E2D jle 6FC78580
Doing a check for 0-12 (don't bother with the middle instruction, part of next random roll)
:6FC7855B A801 test al, 01
:6FC7855D 895104 mov dword ptr [ecx+04], edx
:6FC78560 740F je 6FC78571
:6FC78562 8B4604 mov eax, dword ptr [esi+04]
:6FC78565 C780B800000069626B20 mov dword ptr [ebx+000000B8], 206B6269
:6FC7856F EB3A jmp 6FC785AB
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC78560©
|
:6FC78571 8B4E04 mov ecx, dword ptr [esi+04]
:6FC78574 C781B800000074626B20 mov dword ptr [ebx+000000B8], 206B6274
:6FC7857E EB2B jmp 6FC785AB
50/50 for TP and identify.
:6FC78588 A801 test al, 01
:6FC7858A 895104 mov dword ptr [ecx+04], edx
:6FC7858D 740F je 6FC7859E
:6FC7858F 8B4604 mov eax, dword ptr [esi+04]
:6FC78592 C780B800000069736320 mov dword ptr [ebx+000000B8], 20637369
:6FC7859C EB0D jmp 6FC785AB
* Referenced by a (U)nconditional or ©onditional Jump at Address:
|:6FC7858D©
|
:6FC7859E 8B4E04 mov ecx, dword ptr [esi+04]
:6FC785A1 C781B800000074736320 mov dword ptr [ebx+000000B8], 20637374
And again for books (or is it scroll? I leave it as an exercise for the reader).
That is basically it. I might have missed some, I might have goofed on other things, not all might be correct, but hey, we have to have something to do in the follow up posts, right?
The internal list of function pointers for the operation, initiation and so on are found at:
6fd2fb78 for operation, 6fd2f578 for the initiation, 6fd2f6b8 for the population (all these three are from objects.txt). At 6fd2f6e4 for the preset stuff and 6fd2fb48 for the trap stuff.
Enjoy.
There are three types of people in the world. Those who can count and those who can't.