Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Exe editing for ai
#1
How to copy an id's property to another id...
Example : Julian's AI, 3x Enemies, Faster MP recover to another id: 400
Plz help....
Reply
Thanks given by:
#2
I have almost zero knowledge of Hex only DC ...

But here is something which you should try or you might have tried ... anyways.

To copy the ai behavior edit the data.txt in data folder..

id:52 type: 3 data\julian.dat
id:52 type: 3 data\abc.dat #yourcharctername

This will make your character react as same as julian in every aspect but when it comes to opoint itself it will fail ..

I happen to have same problem in my mod
I wanted to add Felix with AI but instead of that I provided him Dennis id and worked pretty well ..

I guess it might help you (sorry for bad english)
Have a Good Day !!!
Stuff you might like (Click to View)
Reply
Thanks given by: Nithin6777
#3
(06-07-2020, 05:50 AM)sssks6070 Wrote:  I have almost zero knowledge of Hex only DC ...

But here is something which you should try or you might have tried ... anyways.

To copy the ai behavior edit the data.txt in data folder..

id:52 type: 3 data\julian.dat
id:52 type: 3 data\abc.dat  #yourcharctername

This will make your character react as same as julian in every aspect but when it comes to opoint itself it will fail ..

I happen to have same problem in my mod
I wanted to add Felix with AI but instead of that I provided him Dennis id and worked pretty well ..

I guess it might help you (sorry for bad english)

Yes, I knew about this but anyway thanks for your suggestion. :D
Reply
Thanks given by:
#4
I did not expect to ramble this much but I ran some tests and left with more knowledge than I had hoped for. Therefore, obligatory long-post-warning.



The above solution works as long as you don't plan on spawning objects with that ID. For instance, Julian's mirror images (run+D or DJA) might be broken this way; same with who you're facing against in stage 5-5 or survival. I'd guess it'll always spawn the last entry of data.txt with that ID (or the first one, no idea, really, would need to be tested), so you could exploit that in a way.




In terms of exe-editing (I'm assuming you have a rough idea about how assembler-code works, otherwise this will probably make zero sense; so in case you don't, please read a few tutorials on that matter first), there are several things that you'd need to copy to truly replicate all ID properties. Just had a look into the exe file; for Julian, there are a few things which might be of interest...




AI
If I'm not mistaken, the AI-check should be located at 00405D1Ah:

    ASM-Code:
00405D14  MOV ECX,DWORD PTR DS:[EAX+368]  ; load pointer of object or smth
00405D1A  CMP DWORD PTR DS:[ECX+6F4],34   ; ID = Julian? (34h = 52d)
00405D21  JNE 00405FC2                    ; if this is not the case, yeet out


It's immensely helpful to use the DLL Framework as opposed to making your edits directly inside the exe so that things become more easily maintainable. In that case, you could do something like
    ASM-Code:
invoke JmpPatch, 00405D14h, addr julian_ai_stuff
 
NOT_JULIAN_AI		dd 00405D27h
JULIAN_AI		dd 0042FE52h
 
 
julian_ai_stuff proc
		MOV ECX,DWORD PTR DS:[EAX+368]   ; line over written
		CMP DWORD PTR DS:[ECX+6F4],34
		je short return
		cmp ecx,id            ; ENTER YOUR NEW ID HERE, i.e. 400 or 190h (RadASM/MASM is defaulted to decimal)
		je short return
		jmp  dword ptr [NOT_JULIAN_AI]
        return: jmp  dword ptr [JULIAN_AI]
 
julian_ai_stuff endp

If you directly hardcode your stuff inside the exe, you'd have to find some empty space, add the code there and adjust the JMPs accordingly (also you could probably write the addresses directly instead of constants). For the sake of brevity, I'm not going to write down the exact formula.




ARMOR
The coding for armor works similarly to AI. Note that IDs 208 (Henry arrow2) and 214 (John biscuit) are treated special, those always break the armor. Changing one of them to any other ID gives them the insta-armor-break-property. Look at 0042E7CEh:

    ASM-Code:
0042E7CE   CMP DWORD PTR SS:[ESP+14],34               ; is ID 52?
0042E7D3   JNE SHORT 0042E80A                         ; if not, go somewhere else
0042E7D5   MOV EAX,DWORD PTR DS:[EDI*4+ESI+194]       ; 
0042E7DC   CMP DWORD PTR DS:[EAX+0B8],0F              ; something with shaking...
0042E7E3   JG SHORT 0042E80A                          ; ...char will take normal dmg if >15*
0042E7E5   MOV EAX,DWORD PTR DS:[EBX*4+ESI+194]       ; get object-slot of the attacker
0042E7EC   MOV EAX,DWORD PTR DS:[EAX+368]             ;
0042E7F2   MOV EAX,DWORD PTR DS:[EAX+6F4]             ;
0042E7F8   CMP EAX,0D6                                ; D6h = 214d = john_biscuit
0042E7FD   JE SHORT 0042E80A                          ; if ^, go to armor broken
0042E7FF   CMP EAX,0D0                                ; do the same with D0h = 208 = henry_arrow2
0042E804   JNE 0042FDF2                               ; armor unbroken, proceed with Julian normal armor behavior

*The bdefend-values of itr's hitting the character are piling up in this "shaking"-slot (decreases back to 0 over time). Once the value indicated at 42e7dc is surpassed, the next hit will do the damage a normal character would receive. That means: any subsequent itr will also accumulate points in the "fall"-slot which will ultimately lead to a knock-down once 70 is reached (also counts down over time). For the record, I have adopted the terminology used in the LF2 Info spreadsheet.



MP REGEN
Julian recovers his MP by taking the base MP regen rate (+1/TU) and adding stuff on top of that (+2/TU, so +3/TU in total). The check for the respective ID is located at 0041FAC9h (note that Firzen and Julian share the same MP recovery rate), so you would add an additional ID-check there:
    ASM-Code:
0041FAC9   CMP EDX,33            ; 33h = 51d = Firzen
0041FACC   JE SHORT 0041FAD3     ; 
0041FACE   CMP EDX,34            ; 34h = 52d = Julian
0041FAD1   JNE SHORT 0041FAD8    ; neither of those two. JMP out to normal MP regen
0041FAD3   CDQ                   ; magic, sets EDX to 0, ignore
0041FAD4   SUB EAX,EDX           ; effectively does nothing, ignore
0041FAD6   SAR EAX,1             ; <- this causes the extra-MP regen, would be 0 otherwise*
0041FAD8   MOV EDX,1F4           ; rest of MP regen code
....

*after a bit of tinkering around (didn't bother trying to understand the whole code), the additional mp/TU can be approximately defined by writing
MOV EAX,val
at 41fad3 where
val=500/ExtraMP
(the "MOV r,imm"-command occupies all 3 lines -- i.e. CDQ, SUB, & SAR -- in the above code). So, if you want +2 (which is exactly what the above code does), you'd write
mov eax,fa
(FAh = 250d), for even faster regen, you go with lower values such as
mov eax,64
. Fun fact: it seems capped at +5 which is only obtained when EAX = 0. Some weird nonlinear magic, not willing to investigate any further...




STAGE MULTIPLIER
The multipliers are determined starting at 00437964h:
    ASM-Code:
00437964  ADD EAX,1           ; x1 for normal chars
00437967  CMP ECX,33          ; Firzen?
0043796A  JNE SHORT 0043796F  ; nope, check for more two lines down
0043796C  ADD EAX,1           ; it's Firzen! Add 1 to the multiplier (now x2)
0043796F  CMP ECX,34          ; Julian?
00437972  JNE SHORT 00437977  ; nope, proceed with actual multiplier-magic
00437974  ADD EAX,2           ; it's Julian! Add 2 to the multiplier (now x3)
00437977  ...

Basically, the code iterates through all characters in the selection screen and increases this multiplier for each.
Example: You pick 4 characters in the selection screen, Davis (1), Template (1), Julian (3), Firzen (2). The total counter will be
1+1+3+2=7
, so when you end up in a phase of the stage which spawns Bandits with something like
ratio: 1.2
, you'll end up with
floor(1.2*7) = 8
Bandits on the enemy team. Fun-fact: this is capped to 40, by the way.




Well, all for now, old man's getting tired.
Silverthorn / Blue Phoenix
~ Breaking LFE since 2008 ~

"Freeze, you're under vrest!" - Mark, probably.

» Gallery | » Sprites | » DeviantArt
Reply
Thanks given by: Nithin6777 , darkfiren




Users browsing this thread: 1 Guest(s)