Chrono Trigger (SNES), bug with 4x critical attribute

Started by Sierrus, August 03, 2014, 12:56:02 PM

Previous topic - Next topic


I don't know how relevant this will be but in CT there is a certain bug with 4x critical damage attribute.

after some calculation this routine is called only if a weapon with the attribute is equipped:
normal x2 multiplication for critical was already applied before
$C1/F1C7 AD 9B AE    LDA $AE9B  [$7E:AE9B]   A:0026 X:0026 Y:000B P:envMxdizc <- was set to 80 if a critical is confirmed
$C1/F1CA 89 80       BIT #$80                A:0080 X:0026 Y:000B P:eNvMxdizc
$C1/F1CC F0 20       BEQ $20    [$F1EE]      A:0080 X:0026 Y:000B P:eNvMxdizc
$C1/F1CE A5 1E       LDA $1E    [$00:001E]   A:0080 X:0026 Y:000B P:eNvMxdizc
$C1/F1D0 C9 01       CMP #$01                A:0000 X:0026 Y:000B P:envMxdiZc
$C1/F1D2 F0 14       BEQ $14    [$F1E8]      A:0000 X:0026 Y:000B P:eNvMxdizc
$C1/F1D4 AE 89 AD    LDX $AD89  [$7E:AD89]   A:0000 X:0026 Y:000B P:eNvMxdizc <- contains damage value
$C1/F1D7 86 28       STX $28    [$00:0028]   A:0000 X:0326 Y:000B P:envMxdizc
$C1/F1D9 A2 02 00    LDX #$0002              A:0000 X:0326 Y:000B P:envMxdizc
$C1/F1DC 86 2A       STX $2A    [$00:002A]   A:0000 X:0002 Y:000B P:envMxdizc
$C1/F1DE 20 0B C9    JSR $C90B  [$C1:C90B]   A:0000 X:0002 Y:000B P:envMxdizc <- multiplication routine
$C1/F1E1 A6 2C       LDX $2C    [$00:002C]   A:0000 X:0000 Y:000B P:envMxdiZc
$C1/F1E3 8E 89 AD    STX $AD89  [$7E:AD89]   A:0000 X:064C Y:000B P:envMxdizc
$C1/F1E6 80 06       BRA $06    [$F1EE]      A:0000 X:064C Y:000B P:envMxdizc
$C1/F1EE 60          RTS                     A:0000 X:064C Y:000B P:envMxdizc

In short if $7E:AE9B's 80-bit is set the damage gets doubled.
The bug is that this bit is not always reset.

From observations I can say that it is reset when:
-a normal attack is started by the player
-an enemy uses any attack
-the target survives the attack

it wasn't reset when:
-the attack was a counter
-the target enemy died
-when any tech is used by the player

the last one is where the problem lies; when a (pure) physical normal, dual or triple tech is used and (one of) the user has a weapon with the 4x crit attribute the damage gets doubled although it shouldn't.
E.g. Confuse, X Strike and Spin Strike would profit, but spells and the likes of Flame Sword behave normally.

In the original you would be hard pressed to encounter this bug; e.g. counter with a Frenzy Band (80%) and get a critical with Shiva Edge (7%) and then use a physical tech.

As for a fix, I'd say the routine where the tech information is loaded would be a good place a place as any to fit the STZ $AE9B in.
(I've no idea where it really starts...)
$C1/D5C3 C2 20       REP #$20                A:0000 X:0528 Y:0000 P:envMxdiZC
$C1/D5C5 18          CLC                     A:0000 X:0528 Y:0000 P:envmxdiZC
$C1/D5C6 6D C3 B2    ADC $B2C3  [$7E:B2C3]   A:0000 X:0528 Y:0000 P:envmxdiZc
$C1/D5C9 AA          TAX                     A:0528 X:0528 Y:0000 P:envmxdizc
$C1/D5CA 7B          TDC                     A:0528 X:0528 Y:0000 P:envmxdizc
$C1/D5CB E2 20       SEP #$20                A:0000 X:0528 Y:0000 P:envmxdiZc
$C1/D5CD BF F0 1B CC LDA $CC1BF0,x[$CC:2118] A:0000 X:0528 Y:0000 P:envMxdiZc
$C1/D5D1 8D C8 B2    STA $B2C8  [$7E:B2C8]   A:003A X:0528 Y:0000 P:envMxdizc
$C1/D5D4 89 80       BIT #$80                A:003A X:0528 Y:0000 P:envMxdizc
$C1/D5D6 F0 03       BEQ $03    [$D5DB]      A:003A X:0528 Y:0000 P:envMxdiZc
$C1/D5DB AA          TAX                     A:003A X:0528 Y:0000 P:envMxdiZc
$C1/D5DC 8E 28 00    STX $0028  [$7E:0028]   A:003A X:003A Y:0000 P:envMxdizc
$C1/D5DF A9 0C       LDA #$0C                A:003A X:003A Y:0000 P:envMxdizc
$C1/D5E1 AA          TAX                     A:000C X:003A Y:0000 P:envMxdizc
$C1/D5E2 8E 2A 00    STX $002A  [$7E:002A]   A:000C X:000C Y:0000 P:envMxdizc
$C1/D5E5 20 0B C9    JSR $C90B  [$C1:C90B]   A:000C X:000C Y:0000 P:envMxdizc
$C1/D5E8 A6 2C       LDX $2C    [$00:002C]   A:0000 X:0000 Y:0000 P:envMxdiZc
$C1/D5EA 8E C5 B2    STX $B2C5  [$7E:B2C5]   A:0000 X:02B8 Y:0000 P:envMxdizc
$C1/D5ED 7B          TDC                     A:0000 X:02B8 Y:0000 P:envMxdizc
$C1/D5EE A8          TAY                     A:0000 X:02B8 Y:0000 P:envMxdiZc
$C1/D5EF BF 3F 21 CC LDA $CC213F,x[$CC:23F7] A:0000 X:02B8 Y:0000 P:envMxdiZc <- loop returns here
$C1/D5F3 99 E6 AE    STA $AEE6,y[$7E:AEE6]   A:0003 X:02B8 Y:0000 P:envMxdizc
$C1/D5F6 E8          INX                     A:0003 X:02B8 Y:0000 P:envMxdizc
$C1/D5F7 C8          INY                     A:0003 X:02B9 Y:0000 P:envMxdizc
$C1/D5F8 C0 0C 00    CPY #$000C              A:0003 X:02B9 Y:0001 P:envMxdizc <- loops over all 12 bytes, $7E:AEEF holds the damage multiplication
$C1/D5FB 90 F2       BCC $F2    [$D5EF]      A:0003 X:02B9 Y:0001 P:eNvMxdizc

Better ideas are always welcome.