FF6 Hacking
Ignore Imp check on a specific character - Printable Version

+- FF6 Hacking (https://www.ff6hacking.com/forums)
+-- Forum: Discussion Forums (https://www.ff6hacking.com/forums/forum-5.html)
+--- Forum: Magitek Research Facility (https://www.ff6hacking.com/forums/forum-9.html)
+--- Thread: Ignore Imp check on a specific character (/thread-4094.html)



Ignore Imp check on a specific character - PowerPanda - 04-04-2021

I am posting this in regards to finshing off Divergent Paths. As you can see from my posts recently, I've been on a bit of a roll with the small tasks that are needed to finish it up. However, there is one piece that I'm hitting a wall on, and I'm hoping someone can help. After integrating Kappa as my 16th character, I had her set up to use existing code for interesting effect. She is a strong fighter and a strong mage, but she has to use the imp spell to switch between them. This works technically, but it's not as fun as I originally envisioned it being. I would instead like her to just skip the imp check on equipment, and get the attack/defense regardless of whether she has the imp status or not.

I've identified the code that I need to edit, which is this:
Code:
Fork: Define item's Bat.Pwr or Defense
C2/1016:    E220        SEP #$20       ; 8-bit A
C2/1018:    BF1450D8    LDA $D85014,X  ; Item's power
C2/101C:    EB          XBA            ; Put it in B
C2/101D:    BF0250D8    LDA $D85002,X  ; Compatibility
C2/1021:    0A          ASL A          ; Shift bits
C2/1022:    0A          ASL A          ; Helps Imps?
C2/1023:    A5FE        LDA $FE        ; Status LB
C2/1025:    B002        BCS $1029      ; Branch if so
C2/1027:    4920        EOR #$20       ; Toggle Imp
C2/1029:    8920        BIT #$20       ; Imp's set now?
C2/102B:    D003        BNE $1030      ; Branch if so
C2/102D:    A901        LDA #$01       ; Power: 1
C2/102F:    EB          XBA            ; Replace item's
C2/1030:    EB          XBA            ; Item's power
C2/1031:    85FD        STA $FD        ; Memorize it

I have relocated that code to free space in C2 (C2/6469, if it become relevant later). In it's place, I've tried to put in the following code:
Code:
BD D8 3E     LDA $3ED8,X  (Which character is it?)
C9 0E        CMP #$0E     (Is it Kappa?)
D0 0A        BNE ??       (If it's anyone else, branch to JSR $6469)
E2 20        SEP #$20     (8-Bit A)
BF 14 50 D8  LDA $DB5014,X (Get Item's Power)
85 FD        STA $FD      (Memorize it)
80 0C        BRA ??       (Skip to the end of the NOPs)
20 69 64     JSR $6469    (All other characters jump here, and load the subroutine that contains the original code)
80 07        BRA ??       (Skip to the end of the NOPs)
EA EA        NOP
EA EA        NOP
EA EA EA     NOP
The problem with this code is that the character check doesn't seem to be working. What's happened is that I've successfully removed the imp check, but for all characters. It's something to do with the LDA $3ED8,X. For some reason, I'm not able to check which character it is at this point in the code. I've tried loading it to Y instead of X, but that's not doing it either. Any other ideas on how I can check which character it is at this point in the code?


RE: Ignore Imp check on a specific character - C-Dude - 04-05-2021

Hmm... before this equipment JSR is called some character data is checked, but then X gets pushed onto the register during this subroutine.

Try
Code:
*5A              PHY   (Protect the Y Variable for now)
*9B              TXY    (Use Y to store the current X)
*FA              PLX   (Get back the previous X to do the character check)
BD D8 3E      LDA $3ED8,X  (Which character is it?)
*DA              PHX (Put the previous X back on the stack)
*BB              TYX (Put the current X value back into X)
*7A              PLY (Get the Y value back off the stack)
C9 0E        CMP #$0E     (Is it Kappa?)
...
<From here, resume your code post Kappa check>

I suspect this will temporarily give you the X that you need to check the character ID, before putting it back to what it was before the code injection. Make sure you have a back-up save file in case the stack shenanigans are wrong and cause a save-damaging crash.


RE: Ignore Imp check on a specific character - assassin - 04-05-2021

look at the several instructions starting at C2/0E8D.  why is Square multiplying numbers and using $15DB,X to get the Actor ID when they could just use $3ED8,Other_X ??  answer: C2/0E77 isn't always called from Bank C2, so you can't rely on $3ED8,Other_X holding what you want!  and Other_X (which is what i'm calling the 0, 2, 4, 6, etc. value that indexes in-battle entities) hasn't necessarily been defined or preserved.

the index for the character's 37-byte data block in X (REVISED: well, more or less) is put on the stack at the start of Function C2/0F9A, right before pushing Y.  so you want to mimic Square in your code by using $15DB,index *after* switching to 8-bit mode.  even if you did have ready access to Other_X, you'd want this code to run properly in the main menus, not just in battle.

all registers are in 16-bit mode, so do "LDA $03,S" right *before* C2/1016 to get the desired value.  because C2/1076 or the branch to C2/10B2 will both overwrite Y, you should probably be fine modifying it here, as opposed to needing to preserve X.

in a decent, fair world:

Code:
LDA $03,S    ; get (index+1)*37 for character's 37-byte data block
TAY
SEP #$20
LDA $15DB,Y  ; get Actor ID
CMP #$0E
{blah blah}

* nearly posted that, proudly brushing my hands together.  nearly.  hahaha. *

oh, but that's not where we live!

see, Square is constantly changing X in the loop that calls C2/0F9A, to access different equipment/relic slots.  (they change it regularly in C2/0E77, to access many parts of the character data block.)  but we always want the FIRST, Actor slot of the data block!  what to do?!

if you could make space in Function C2/0E77, you'd want to preserve the result of C2/0E97 somewhere (e.g. stack, a scratch variable like $FF) to access from your code.

or we can try to reverse engineer the proper X.  see, these clowns also change Y in the calling loop, so that can provide us valuable info:

Code:
LDA #$0005
SEC
SBC $01,S    ; combine with former Y of 0-5 equip/relic slot, which
            ;   looping caller decrements in tandem with X.
            ; consider A our normalizer for the pain in the arse value
            ;   that we'll be encountering two instructions from now.
CLC
ADC $03,S    ; combine with former X, which equals:
            ;  ((roster index + 1) * 37) for character's 37-byte
            ;   data block ,
            ;  Plus 4  (due to recent C2/0EDC loop) ,
            ;  Minus 0 thru 5  (due to ongoing C2/0EF1 loop)
TAY
SEP #$20
LDA $15D7,Y  ; i sure HOPE this is our Actor ID.  not accessing
            ;   via $15DB,index, because i did NOT attempt to
            ;   normalize out the +4 !  (as i didn't want A
            ;   negative even momentarily.)
CMP #$0E     ; single out our designated character ... ideally
            ;   so we can put a bullet between their eyes as
            ;   gratitude for this tangent.



RE: Ignore Imp check on a specific character - PowerPanda - 04-05-2021

Assasin, I mean this in the best way. You are truly frightening. How you managed to figure that out I can't comprehend, but it's working. Now we'll see if I have to use the same process to make magic work regardless. At least I know how to get the actor number now!