Hello.
Thanks to the help given by Necrolis, I managed to finish a small addon to the Shadow Master’s AI. As you probably have read from another thread of mine, since 1.10 the Shadow Master’s AI became bugged and has problems in matter of targeting: your pets using this AI will always try to attack your same target. In order to fix this odd behaviour feel free to take a look at this link: viewtopic.php?f=8&t=62883&hilit=fixing+shadow
If you want to add this feature, fix it as written in the aforementioned thread except for the point “B.changing the target switching via click” , since we’re going to work on this one.
The addon I’m talking about consists, in fact, to exploit this target-switching bug to let the player tell specific pets to attack his/her target, possibily leading to a more strategic and dynamic gameplay.
Now, before starting with code editing, there is a thing you have to do, and that’s creating a dummy skill with Enchant as base (with all of the bonuses removed) if you want to target a single minion or Battle Orders if you want to spread your orders screenwide. This dummy skill will have to give your target a dummy state (thus create it in States.txt).
Once you’ve done this, you can proceed:
Let’s take a look at the piece of code that interest us:
Code: Select all
6FCEB63F 74 27 JE SHORT 6FCEB668
6FCEB641 BCF MOV ECX,EDI
6FCEB643 E8 6822FDFF CALL 6FCBD8B0
6FCEB648 85C0 TEST EAX,EAX
Edit the code above as it follows:
Code: Select all
6FCEB63F 74 27 JE SHORT 6FCEB668
6FCEB641 0F85 03B40300 JNE 6FD26A4A
6FCEB647 90 NOP
6FCEB648 90 NOP
6FCEB649 90 NOP
Code: Select all
6FD26A4A 8B47 04 MOV EAX,DWORD PTR DS:[EDI+4]
6FD26A4D 68 F1000000 PUSH 0F1 ; check if your pet has your custom state
6FD26A52 56 PUSH ESI
6FD26A53 E8 704CFFFF CALL <JMP.&D2Common.#10487>
6FD26A58 85C0 TEST EAX,EAX
6FD26A5A 74 0E JE SHORT 6FD26A6A
6FD26A5C 89F9 MOV ECX,EDI
6FD26A5E E8 4D6EF9FF CALL 6FCBD8B0
6FD26A63 85C0 TEST EAX,EAX
6FD26A65 E9 E04BFCFF JMP 6FCEB64A
6FD26A6A E9 F94BFCFF JMP 6FCEB668
Edit: here you are!
Part II : Wait/Follow orders
Playing around with the Shadow Master’s AI, I managed to use the method stated above to make the player able to send waiting / following orders to his/her pets.
As mentioned before, you need two (new) dummy states, one for following, and one for waiting, because we will tell the code to check if the pet has one of the two states and then make it perform the corresponding action. Remember that the waiting and following states must be set as “curse” in states.txt, as I haven’t found another way to let one dispel the other -,- this means that if there are cursing monsters (i.e Oblivion Knights or Succubi) your waiting/following states will get overwritten. I will work better on this issue when I’ll have more free time.
You will also need two dummy skills, with Enchant as base if you want to target a single pet or with Battle Order if you want to tell your orders screenwide.
Let’s take a look at the code we’re going to rework:
Code: Select all
6FCE370A 74 11 JE SHORT 6FCE371D
6FCE370C 83FF 02 CMP EDI,2
6FCE370F 75 0C JNE SHORT 6FCE371D
6FCE3711 5F POP EDI
6FCE3712 5E POP ESI
6FCE3713 5D POP EBP
6FCE3714 33C0 XOR EAX,EAX
6FCE3716 5B POP EBX
6FCE3717 83C4 14 ADD ESP,14
6FCE371A C2 1800 RETN 18
This is the part which interests us: we basically have to (again) hijack this block to our custom code made in a custom address: the mechanic of our modification is very similar, if not identical, to the one we used for the targeting function above:
1. Check if a unit has a specific state from states.txt
2. If not, the unit will follow the player (vanilla behaviour, handled by the AIP’s in monstats.txt)
3. If yes, the unit will not follow the player (but will react and use its skills/attacks against nearby enemies)
Here’s the modification I made:
Code: Select all
6FCE370A E9 60330400 JMP 6FD26A6F ; jump to custom address
6FCE370F 90 NOP
6FCE3710 90 NOP
6FCE3711 5F POP EDI
6FCE3712 5E POP ESI
6FCE3713 5D POP EBP
And in our custom address:
Code: Select all
6FD26A6F 8B43 04 MOV EAX,DWORD PTR DS:[EBX+4]
6FD26A72 68 F2000000 PUSH 0F2 ; check for custom state ID(hex) from states.txt
6FD26A77 53 PUSH EBX
6FD26A78 E8 4B4CFFFF CALL <JMP.&D2Common.#10487>
6FD26A7D 85C0 TEST EAX,EAX
6FD26A7F 0F85 8CCCFBFF JNE 6FCE3711
6FD26A85 E9 93CCFBFF JMP 6FCE371D
Part III : "Wait" orders for Revived monsters
This third part concerns the following ability of the monsters you resurrect via skills. To improve their pathing AI try taking a look at this thread: viewtopic.php?f=8&t=63031
Now, we'll be using the same mechanic as before:
Code: Select all
6FCF0E1A B8 01000000 MOV EAX,1
Code: Select all
6FCF0E1A E9 935C0300 JMP 6FD26AB2 (jmp to custom address)
Code: Select all
6FD26AB2 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
6FD26AB5 68 F2000000 PUSH 0F2 ; check if the revived has the "waiting state"
6FD26ABA 57 PUSH EDI
6FD26ABB E8 084CFFFF CALL <JMP.&D2Common.#10487> ; Jump to d2common.#10487
6FD26AC0 85C0 TEST EAX,EAX
6FD26AC2 75 0A JNE SHORT 6FD26ACE ; if "waiting state" is on, then mov eax,1 , else mov eax,0
6FD26AC4 B8 01000000 MOV EAX,1 ; follow
6FD26AC9 E9 51A3FCFF JMP 6FCF0E1F ; return to vanilla code
6FD26ACE B8 00000000 MOV EAX,0 ; don't follow
6FD26AD3 E9 47A3FCFF JMP 6FCF0E1F ; return to vanilla code
This part will manipolate the teleport's code. It will prevent your minions to teleport along with you provided that you have a custom dummy state.
Before starting, you have to create a dummy state in states.txt and a dummy skill based on Frozen armor which will grant the character our new "No Teleport" state. It is important to set the new state as a "curse" in states.txt.
*NOTE* : The Code edits of this fourth part influences all of your minions regardless of their AI, be it NecroPet, ShadowMaster, Hireling or something else.
After you've done that, go to the following address:
Code: Select all
6FC7E32E 0F84 0D020000 JE 6FC7E541
Code: Select all
6FC7E32E 0F84 57870A00 JE 6FD26A8B
Code: Select all
6FD26A8B 8B42 04 MOV EAX,DWORD PTR DS:[EDX+4]
6FD26A8E 68 F2000000 PUSH 0F4 ; check if the player has the "NoMinionTeleport" state
6FD26A93 52 PUSH EDX
6FD26A94 E8 2F4CFFFF CALL <JMP.&D2Common.#10487> ; Jump to d2common.#10487
6FD26A99 85C0 TEST EAX,EAX
6FD26A9B 0F84 A07AF5FF JE 6FC7E541
6FD26AA1 E9 8E78F5FF JMP 6FC7E334
Therefore, before changing act or before entering a dungeon be sure to override your "NoTeleportState" with the following skill cast on yourself [doable since they're both flagged as "curses"]