Here is a step-by-step guide on how to implement a charm zone in 1.09x. I'm writing this guide since a lot of mods and other modders like to increase inventory size but you may not want to allow charms to work in the new larger inventory. There are some guides out there on how to do this in 1.10+ but none for 1.09x and the code is different enough that the 1.10+ guides won't work for 1.09x.
GOAL:
Implement two areas in your inventory space, one that allows charm bonuses to be applied, and one that does not. This allows the character to carry a full compliment of charms without removing the ability to pick up drops. I will lay this out in a step-by-step format that anyone should be able to do, regardless of prior knowledge.
Assumptions:
This guide assumes that you have already successfully increased your inventory size. There are other guides for that as well as individual mods that specifically do that for you. In order to not make this guide a novel, I won't be covering the process of changing inventory size. However if you want a stand alone adjustment mod to increase your inventory size, you can use this mod https://www.moddb.com/games/diablo-2/do ... -inventory This mod includes cube size increase and merc equippables, but you can exclude that stuff if you just want to increase inventory size. Note: this mod is for 1.10+ txt files but can easily be adjusted for 1.09. If you can't do those last steps, then I'm assuming you won't be looking to do code edits.
Files you will need:
D2Common.dll
Tools You Will Need:
OllyDBG or some other dll editor. The images in this guide will be for Olly as that is what I used.
Without further ado, let's get started.
To give you an idea of where I'm starting from, below is my inventory space. I've included column and row numbers, this will make sense later.
Here you can see that I doubled the height of original inventory. I want my charms to work in the top half, the highlighted zone. And I don't want them to work in the bottom half. I want the bottom half to be my drops pick up zone.
So let's fire up OllyDBG and get this working. This will literally be step-by-step on how I know it will work. You may have more experience with OllyDBG and have a more efficient way to go about it. If so, hats off to you and I hope to be at that level some day.
1. Open OllyDBG as administrator. If you don't know how to do that, just right click the executable and click run as administrator.
2. Open D2Common.dll by clicking File->Open. Then navigate to your Diablo 2 root folder (where diablo 2 is installed). You will then need to change the Files Type to Dynamic Link Library in order to see the dll values.
3. This will bring up the CPU main thread window and an executable modules window. However, we want to open up the D2Common executable. To do that click the execute till return button (Ctrl+F9 hotkey) This will refresh the executables module showing D2Common
4. Double click the D2Commmon.dll line in the executables module. This line should show in red.
5. This shows us the D2Common code in a format that looks familiar. However it is massive and doesn't tell us much. Maybe you want to sift through tens of thousands of lines of assembly code, but I don't. Fortunately for us, I know where we need to go. What we want to do is navigate to the #10840 function. This is the CharmRequirements function. What it does is check whether a charm is usable or not. To find this function do the following Right Click -> Search For -> Name (label) in Current Module
6. Scroll down in the new window until you find #10840 and double click on it. This takes you to the function and if you widen the address bar on the right side of the main thread you will see #10840 there
Alternatively you can just search for this address but that will only work for 1.09b dll file. The method I laid out above will work for any 1.09 dll file and will also work for finding any desired function within a dll file from any version. e.g. #10840 is also the CharmRequirements function in 1.10 but obviously sits at a different address.
Code: Select all
6FD92820 #10840 /$ 56 PUSH ESI
6FD92821 |. 8B7424 08 MOV ESI,DWORD PTR SS:[ESP+8]
6FD92825 |. 85F6 TEST ESI,ESI
6FD92827 |. 0F84 85000000 JE D2Common.6FD928B2
6FD9282D |. 833E 04 CMP DWORD PTR DS:[ESI],4
6FD92830 |. 75 5B JNZ SHORT D2Common.6FD9288D
6FD92832 |. 8B46 70 MOV EAX,DWORD PTR DS:[ESI+70]
6FD92835 |. 85C0 TEST EAX,EAX
6FD92837 |. 75 1E JNZ SHORT D2Common.6FD92857
6FD92839 |. 68 E3030000 PUSH 3E3
6FD9283E |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD92843 |. 68 4472DD6F PUSH D2Common.6FDD7244 ; ASCII "ptItemData"
6FD92848 |. E8 25110200 CALL <JMP.&Fog.#10023>
6FD9284D |. 83C4 0C ADD ESP,0C
6FD92850 |. 6A FF PUSH -1
6FD92852 |. E8 44120200 CALL D2Common.6FDB3A9B
6FD92857 |> 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18]
6FD9285A |. 25 00010000 AND EAX,100
6FD9285F |. 85C0 TEST EAX,EAX
6FD92861 |. 75 4F JNZ SHORT D2Common.6FD928B2
6FD92863 |> 833E 04 CMP DWORD PTR DS:[ESI],4
6FD92866 |. 75 50 JNZ SHORT D2Common.6FD928B8
6FD92868 |. 8B46 70 MOV EAX,DWORD PTR DS:[ESI+70]
6FD9286B |. 85C0 TEST EAX,EAX
6FD9286D |. 75 37 JNZ SHORT D2Common.6FD928A6
6FD9286F |. 68 E3030000 PUSH 3E3
6FD92874 |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD92879 |. 68 4472DD6F PUSH D2Common.6FDD7244 ; ASCII "ptItemData"
6FD9287E |. E8 EF100200 CALL <JMP.&Fog.#10023>
6FD92883 |. 83C4 0C ADD ESP,0C
6FD92886 |. 6A FF PUSH -1
6FD92888 |. E8 0E120200 CALL D2Common.6FDB3A9B
6FD9288D |> 68 9C140000 PUSH 149C
6FD92892 |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD92897 |. 68 0074DD6F PUSH D2Common.6FDD7400 ; ASCII " ----- JONM NOTE: Would have crashed, see code at ITEMSDataTestFlags. From FILE: %s LINE: %d"
6FD9289C |. E8 25110200 CALL <JMP.&Fog.#10029>
6FD928A1 |. 83C4 0C ADD ESP,0C
6FD928A4 |.^EB BD JMP SHORT D2Common.6FD92863
6FD928A6 |> 8B40 18 MOV EAX,DWORD PTR DS:[EAX+18]
6FD928A9 |. 25 00400000 AND EAX,4000
6FD928AE |. 85C0 TEST EAX,EAX
6FD928B0 |. 74 1D JE SHORT D2Common.6FD928CF
6FD928B2 |> 33C0 XOR EAX,EAX
6FD928B4 |. 5E POP ESI
6FD928B5 |. C2 0800 RETN 8
6FD928B8 |> 68 9D140000 PUSH 149D
6FD928BD |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD928C2 |. 68 0074DD6F PUSH D2Common.6FDD7400 ; ASCII " ----- JONM NOTE: Would have crashed, see code at ITEMSDataTestFlags. From FILE: %s LINE: %d"
6FD928C7 |. E8 FA100200 CALL <JMP.&Fog.#10029>
6FD928CC |. 83C4 0C ADD ESP,0C
6FD928CF |> 6A 0D PUSH 0D
6FD928D1 |. 56 PUSH ESI
6FD928D2 |. E8 E9D7FFFF CALL D2Common.#10731
6FD928D7 |. 85C0 TEST EAX,EAX
6FD928D9 |. 75 04 JNZ SHORT D2Common.6FD928DF
6FD928DB |. 5E POP ESI
6FD928DC |. C2 0800 RETN 8
6FD928DF |> 833E 04 CMP DWORD PTR DS:[ESI],4
6FD928E2 |. 75 32 JNZ SHORT D2Common.6FD92916
6FD928E4 |. 8B46 70 MOV EAX,DWORD PTR DS:[ESI+70]
6FD928E7 |. 85C0 TEST EAX,EAX
6FD928E9 |. 75 1E JNZ SHORT D2Common.6FD92909
6FD928EB |. 68 90040000 PUSH 490
6FD928F0 |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD928F5 |. 68 4472DD6F PUSH D2Common.6FDD7244 ; ASCII "ptItemData"
6FD928FA |. E8 73100200 CALL <JMP.&Fog.#10023>
6FD928FF |. 83C4 0C ADD ESP,0C
6FD92902 |. 6A FF PUSH -1
6FD92904 |. E8 92110200 CALL D2Common.6FDB3A9B
6FD92909 |> 8A40 41 MOV AL,BYTE PTR DS:[EAX+41]
6FD9290C |. 84C0 TEST AL,AL
6FD9290E |. 74 23 JE SHORT D2Common.6FD92933
6FD92910 |. 33C0 XOR EAX,EAX
6FD92912 |. 5E POP ESI
6FD92913 |. C2 0800 RETN 8
6FD92916 |> 68 8B040000 PUSH 48B
6FD9291B |. 68 AC72DD6F PUSH D2Common.6FDD72AC ; ASCII "C:\Projects\Diablo2\Source\D2Common\ITEMS\Items.cpp"
6FD92920 |. 68 C474DD6F PUSH D2Common.6FDD74C4 ; ASCII " ----- JONM NOTE: Would have crashed, see code at ITEMSDataGetPage. From FILE: %s LINE: %d"
6FD92925 |. E8 9C100200 CALL <JMP.&Fog.#10029>
6FD9292A |. 83C4 0C ADD ESP,0C
6FD9292D |. 33C0 XOR EAX,EAX
6FD9292F |. 5E POP ESI
6FD92930 |. C2 0800 RETN 8
6FD92933 |> 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C]
6FD92937 |. 6A 00 PUSH 0 ; /Arg6 = 00000000
6FD92939 |. 6A 00 PUSH 0 ; |Arg5 = 00000000
6FD9293B |. 6A 00 PUSH 0 ; |Arg4 = 00000000
6FD9293D |. 6A 00 PUSH 0 ; |Arg3 = 00000000
6FD9293F |. 50 PUSH EAX ; |Arg2
6FD92940 |. 56 PUSH ESI ; |Arg1
6FD92941 |. E8 6A88FFFF CALL D2Common.#10756 ; \#10756
6FD92946 |. F7D8 NEG EAX
6FD92948 |. 1BC0 SBB EAX,EAX
6FD9294A |. 5E POP ESI
6FD9294B |. F7D8 NEG EAX
6FD9294D \. C2 0800 RETN 8
8. This gives us the space to add our Jump. So let's do that. For my addition, I jump down to slack space all the way at the bottom. If you wanted to, you could actually fill slack spack all along the way and have multiple jumps, but this gets messy and hard to follow. If you are using 1.09d, you may need to use a different address but if you go all the way to the bottom, just find some slack space that you are happy with and jump there. So change the first NOP here to JMP 6FDBC9CE
Code: Select all
6FD9294B E9 7EA00200 JMP D2Common.6FDBC9CE
Code: Select all
6FDBC9CE F7D8 NEG EAX
6FDBC9D0 85C0 TEST EAX,EAX
6FDBC9D2 75 03 JNZ SHORT D2Common.6FDBC9D7
6FDBC9D4 C2 0800 RETN 8
6FDBC9D7 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] ; ptUnit
6FDBC9DB 8B40 38 MOV EAX,DWORD PTR DS:[EAX+38] ; ptUnit -> hPath
6FDBC9DE 8378 08 00 CMP DWORD PTR DS:[EAX+8],0 ; left side x border
6FDBC9E2 72 1A JB SHORT D2Common.6FDBC9FE
6FDBC9E4 8378 08 09 CMP DWORD PTR DS:[EAX+8],9 ; right side x border
6FDBC9E8 77 14 JA SHORT D2Common.6FDBC9FE
6FDBC9EA 8378 0C 00 CMP DWORD PTR DS:[EAX+C],0 ; top y border
6FDBC9EE 72 0E JB SHORT D2Common.6FDBC9FE
6FDBC9F0 8378 0C 03 CMP DWORD PTR DS:[EAX+C],3 ; bottom y border
6FDBC9F4 77 08 JA SHORT D2Common.6FDBC9FE
6FDBC9F6 B8 01000000 MOV EAX,1
6FDBC9FB C2 0800 RETN 8
6FDBC9FE 33C0 XOR EAX,EAX
6FDBCA00 C2 0800 RETN 8
9. We are almost done, but first we have to save this so it is implemented in the game. To do that Right-click -> copy -> select all. Rick-click -> copy to executable -> all modifications. Click Copy All. Right-click one more time -> save file. You can save your copy in your root folder or in a different location if you want to patch it in later.
You now have a charm zone in your 1.09x mod. I hope this has helped you and good luck.
Last note: you may want to make sure that you don't have your D2.exe running silent in the background when you do this to avoid any issues. Just check your task manager and close if it is there before you implement the new file.