DS1 Objects

This forum is for discussions on how to edit what can not be edited through the txt files, needless to say this isn't about battle net hacking.

Moderators: Nefarius, Havvoric

Post Reply
User avatar
Myhrginoc
Retired Admin
Cherub
Posts: 12062
Joined: Sat May 25, 2002 7:28 am
Location: Percussion U

Hand-picked

DS1 Objects

Post by Myhrginoc » Sun Sep 01, 2002 9:02 pm

I found the function that loads a DS1 file into memory today. It is D2Common.6FD76520. The function sets up the file and calls D2Common.6FDB38A4 for the actual work of copying the file to memory. (The second function calls five Fog functions: 10102, 10105, 10042, 10104, 10103.) Then it processes the results.

I would like to point out this code sequence:

Code: Select all

6FD767D5  3D 3D020000      CMP EAX,23D                      ; Case 2 of switch 6FD7670A
6FD767DA  0F84 C8000000    JE D2Common.6FD768A8
6FD767E0  837C24 14 05     CMP [DWORD SS:ESP+14],5
6FD767E5  0F8E C4000000    JLE D2Common.6FD768AF
6FD767EB  3D 96000000      CMP EAX,96
6FD767F0  0F8D B2000000    JGE D2Common.6FD768A8
6FD767F6  8D0C52           LEA ECX,[DWORD DS:EDX+EDX*2]
6FD767F9  8D0C89           LEA ECX,[DWORD DS:ECX+ECX*4]
6FD767FC  8D0C89           LEA ECX,[DWORD DS:ECX+ECX*4]
6FD767FF  8D1448           LEA EDX,[DWORD DS:EAX+ECX*2]
6FD76802  8B0495 7C36DD6F  MOV EAX,[DWORD DS:EDX*4+6FDD367C]
6FD76809  E9 9D000000      JMP D2Common.6FD768AB
6FD7680E  837C24 14 04     CMP [DWORD SS:ESP+14],4          ; Case 1 of switch 6FD7670A
6FD76813  0F8E 80000000    JLE D2Common.6FD76899
6FD76819  8D0C52           LEA ECX,[DWORD DS:EDX+EDX*2]
6FD7681C  3BD5             CMP EDX,EBP
6FD7681E  8D0C89           LEA ECX,[DWORD DS:ECX+ECX*4]
6FD76821  8D0488           LEA EAX,[DWORD DS:EAX+ECX*4]
6FD76824  8B0485 3442DD6F  MOV EAX,[DWORD DS:EAX*4+6FDD4234]
6FD7682B  894424 2C        MOV [DWORD SS:ESP+2C],EAX
6FD7682F  75 2C            JNZ SHORT D2Common.6FD7685D
This sequence looks at the object from the DS1 object table. The switch case corresponds to the object type. The object number is then used to calculate the offset into a lookup table, see lines 6FD76802 and 6FD76824. The lookup retrieves the number which is used later on to get the record from one of several data tables.

I followed this through for a couple of Act 1 DS1 files and it seems to hold up. If I have indeed done this correctly, it should now be possible to add or change objects available to a map editor.
Do the right thing. It will gratify some people and astonish the rest.
~ Mark Twain
Run Diablo II in any version for mods: tutorial
The Terms of Service!! Know them, abide by them, and enjoy the forums at peace.
The Beginner's Guide v1.4: (MS Word | PDF) || Mod Running Scripts || TFW: Awakening

User avatar
Myhrginoc
Retired Admin
Cherub
Posts: 12062
Joined: Sat May 25, 2002 7:28 am
Location: Percussion U

Hand-picked

Post by Myhrginoc » Tue Sep 03, 2002 2:04 am

I was on the right track. I have found the entire lookup table for all Type 2 objects. :mrgreen: :mrgreen: :mrgreen: I sent a copy to Paul for his editor.

Each act is allowed up to 150 Type 2 object definitions, for a grand total of 750 entries. There is a lookup table in D2Common that starts at 6FDD367C. The dword at each location is the ID number from objects.txt! Unlike with Type 1 objects, you cannot reference earlier or later acts with negative numbers or numbers over the 150 limit. There are hardcoded checks in the Type 2 code. So the way some objects appear in multiple acts is to have an entry for it in each act. This is how your stash box follows you from act to act, there are actually five of them in the game (so to speak).

Act 1: ID 0-149 (6FDD367C - 6FDD38D0) 38 null values, 2 crash values
Act 2: ID 0-149 (6FDD38D4 - 6FDD3B28) 15 null values, 3 crash values
Act 3: ID 0-149 (6FDD3B2C - 6FDD3D80) 34 null values, 2 crash values
Act 4: ID 0-149 (6FDD3D84 - 6FDD3FD8) 84 null values, 5 crash values (not a lot happening here, eh?)
Act 5: ID 0-149 (6FDD3FDC - 6FDD4230) no null or crash values! Two numbers (411,412) unused in objects.txt

Objects.txt is expandable. But to make a new object mappable, you have to add its ID to the lookup table. Fortunately there are quite a few null entries you can use. There are also a few entries with ID numbers that exceed the highest ID in Objects.txt, that must be why certain entries from a level editor's obj.txt file can cause crashes. So we could use those entries for new or copied objects, too. On the other hand, perhaps those values have other trigger effects, so use nulls first. This will be a big problem in Act 5, since there are no extra slots, so you might have to sacrifice visual diversity if you want other objects. Do you really need five jar entries for Ice Caves?.

Keep in mind that objects can have functions, as called by the four function columns in Objects.txt. If you use an object inappropriately you will cause a crash, or at best no apparent effect. So when you clone objects, be sure you look at those four columns!

I haven't gone through Type 1 objects yet, but I think its lookup table starts immediately above the Type 2 lookup table, at address 6FDD4234. If so, there are at least 295 records there, that go on up to 6FDD46D0.

I hope Patch 1.10 provides more slots. :) These tables are not expandable in their current location. They could be expanded if copied intact to the new DLL, but that would be a lot of work.
Last edited by Myhrginoc on Tue Sep 03, 2002 2:08 am, edited 1 time in total.
Do the right thing. It will gratify some people and astonish the rest.
~ Mark Twain
Run Diablo II in any version for mods: tutorial
The Terms of Service!! Know them, abide by them, and enjoy the forums at peace.
The Beginner's Guide v1.4: (MS Word | PDF) || Mod Running Scripts || TFW: Awakening

User avatar
Apocalypse Demon
Forum Legend
Arch-Angel
Posts: 1701
Joined: Thu May 23, 2002 2:45 am
Location: Mississauga, Ontario, Canada

Hand-picked

Post by Apocalypse Demon » Tue Sep 03, 2002 2:08 am

Good work. I'm going to look into this some more.
Human beings are foolish. They lack the ability to learn. They make the same mistakes over and over, yet still they do not change. They live each day only to consume, like a repeating loop in a program...

User avatar
Myhrginoc
Retired Admin
Cherub
Posts: 12062
Joined: Sat May 25, 2002 7:28 am
Location: Percussion U

Hand-picked

Post by Myhrginoc » Tue Sep 03, 2002 5:25 am

Okay, I have a handle on Type 1 objects now. The lookup table does start at 6FDD4234. The correspondence for NPCs and critters in Rogue Camp is with Monstats.txt (no big surprise). I suspect there is a mechanism for seeing if the ID corresponds with an entry in SuperUniques, and loads one of them instead of an ordinary monster/NPC where one is available. Since there are only 295 slots, only some of the monsters are represented. I'll be looking deeper at this tomorrow.

[EDIT: Bah! I spoke too soon. Only some of the values correspond with Monstats. Most are far too high. This will take even more work.]

So much for the good news. :(

Curiouser and curiouser. I cloned a row in Objects.txt, gave it a legitimate ID, and made sure it had a valid string key. Then I put the new string into String.tbl. I went into D2Common and added the new ID to a vacant position in the Act 1 block. Then I added the position index to Paul's obj.txt file, along with the name of the new object. I fired up Paul's editor for Rogue Camp, and was able to insert the new object just fine. I also inserted an already-defined object that does not belong in Rogue Camp, so I could tell I was showing the right map in game of the four.

I fired up D2 and indeed got that map. The already-defined object came in just fine. But my new object wasn't there! :cry:

Here is the strangest part. I checked all sorts of code and memory locations on the second pass. D2Common.6FC60C00 is the function that loads the Objects.txt file to memory, and that correctly loads the file with my new object. The string key match-up works just fine. Then I checked the ds1 loader, D2Common.6FD76520. That function grabs my Rogue Camp file and brings it in just fine. All of the objects are correctly matched through the lookup table! I am truly mystified.

Never do I see a graphics function called, so I need to check a different thread. The problem with multithreaded apps is you can be debugging one thread and not see what is happening in another.

:2c:

If in fact the Superuniques table and the Monstats table will become expandable in Patch 1.10, I hope Blizzard replaces this cumbersome lookup system with a direct use of monster and object ID numbers.
Do the right thing. It will gratify some people and astonish the rest.
~ Mark Twain
Run Diablo II in any version for mods: tutorial
The Terms of Service!! Know them, abide by them, and enjoy the forums at peace.
The Beginner's Guide v1.4: (MS Word | PDF) || Mod Running Scripts || TFW: Awakening

Post Reply

Return to “Code Editing”