Knockback Calculation

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
No Parameters  - Returns nothing
 
If Target is knocked  See Notes
 Update Current Ability Data
 - 0x801938ed : 0x80 in all cases ("Fall damage not calculated yet" flag)
                + 0x01 if unit is not flying/is a frog or a chicken
                + 0x02 if Unit is flying
 - 0x801938ca : Target Destination Tile X coordinate
 - 0x801938cb : Target Destination Tile Y coordinate
 - 0x801938cc : Target Destination Tile Elevation
 
 Update Target Current Action data
 - Special flags 2 updated with 0x40 (knockedback flag)
------------------------------------------------------------------------------------------
001843ec: 27bdffe0 addiu r29,r29,-0x0020    |
001843f0: 3c038019 lui r3,0x8019            |
001843f4: 906338ec lbu r3,0x38ec(r3)        |r3 = Current Ability Target counter     0x801938ec / 801938ec 
001843f8: 34020001 ori r2,r0,0x0001         |r2 = 0x01
001843fc: afbf001c sw r31,0x001c(r29)       |
00184400: afb20018 sw r18,0x0018(r29)       |
00184404: afb10014 sw r17,0x0014(r29)       |

CHECK KNOCKBACK USABILITY
00184408: 1462007a bne r3,r2,0x001845f4     #If Target Counter = 0x01 /Else Branch to  END
0018440c: afb00010 sw r16,0x0010(r29)           |
00184410: 3c058019 lui r5,0x8019                |
00184414: 8ca52d98 lw r5,0x2d98(r5)             |r2 = Target's Data Pointer
00184418: 00000000 nop                          |
0018441c: 90a30005 lbu r3,0x0005(r5)            |r3 = Target ENTD flags
00184420: 00000000 nop                          |
00184424: 30620004 andi r2,r3,0x0004            |r2 = 0x04 if Target is immortal
00184428: 14400072 bne r2,r0,0x001845f4         #If Target is Immortal /Else Branch to  END
0018442c: 30630003 andi r3,r3,0x0003                |r3 = 0x03 if ENTD flags 0x01 and 0x02 are enabled
00184430: 34020003 ori r2,r0,0x0003                 |r2 = 0x03
00184434: 1062006f beq r3,r2,0x001845f4             #If Target ENTD flags 0x01 and 0x02 are enabled (Ramza related ?) /Else Branch to  END
00184438: 00000000 nop                                  |
0018443c: 3c048019 lui r4,0x8019                        |
00184440: 8c842d94 lw r4,0x2d94(r4)                     |r4 = Attacker data pointer
00184444: 00000000 nop                                  |
00184448: 10a4006a beq r5,r4,0x001845f4                 #If Target is not Attacker /Else Branch to  END
0018444c: 00000000 nop                                      |
00184450: 90a20182 lbu r2,0x0182(r5)                        |r2 = Target's mount info
00184454: 00000000 nop                                      |
00184458: 14400066 bne r2,r0,0x001845f4                     #If Target is not riding/beeing ridden /Else Branch to  END
0018445c: 00000000 nop                                          |

SET DESTINATION TILE
00184460: 90a90047 lbu r9,0x0047(r5)                            |r9 = Target's X Coord.
00184464: 90830047 lbu r3,0x0047(r4)                            |r3 = Attacker's X Coord.
00184468: 90a60048 lbu r6,0x0048(r5)                            |r6 = Target's Y Coord.
0018446c: 90820048 lbu r2,0x0048(r4)                            |r2 = Attacker's X Coord.
00184470: 01234023 subu r8,r9,r3                                |r8 = X difference (Target - Attacker)
00184474: 00c23823 subu r7,r6,r2                                |r7 = Y difference (Target - Attacker)
00184478: 05010002 bgez r8,0x00184484                           #If X diffrence < 0x00
0018447c: 01002021 addu r4,r8,r0                                |r4 = X difference
00184480: 00042023 subu r4,r0,r4                                    |r4 = Positive X difference
00184484: 04e10002 bgez r7,0x00184490                           #If Y difference < 0x00
00184488: 00e01821 addu r3,r7,r0                                |r3 = Y difference
0018448c: 00031823 subu r3,r0,r3                                    |r3 = Positive X difference
00184490: 00831021 addu r2,r4,r3                                |r2 = X diff. + Y diff.
00184494: 10400057 beq r2,r0,0x001845f4                         #If Target and Attacker are not at same coordinate #If Target is on the same X/Y (above or below), branch to END
00184498: 01208021 addu r16,r9,r0                               |r16 = Target X
0018449c: 0064102a slt r2,r3,r4                                     |r2 = 0x01 if Y diff < X diff
001844a0: 10400008 beq r2,r0,0x001844c4                             #If Y Diff < X Diff (X coordinate has more weight)
001844a4: 00c08821 addu r17,r6,r0                                   |r17 = Target Y
001844a8: 19000003 blez r8,0x001844b8                                   #If X diff. > 0x00 (Target is Eastward)
001844ac: 34040003 ori r4,r0,0x0003                                         |r4 = 0x03 (Knocked to East)
001844b0: 08061137 j 0x001844dc                                             >>jump to Destination Tile Check
001844b4: 26100001 addiu r16,r16,0x0001                                     |r16 = Destination Tile X coord (Target X + 1)
                                                                        #Else X diff < 0x00 (Target is Westward)
001844b8: 34040001 ori r4,r0,0x0001                                         |r4 = 1 (Knocked to West)
001844bc: 08061137 j 0x001844dc                                             >>jump to Destination Tile Check
001844c0: 2610ffff addiu r16,r16,-0x0001                                    |r16 = Destination Tile X coord (Target X - 1)
                                                                    #Else Y Coord. Has more weight
001844c4: 18e00003 blez r7,0x001844d4                                   #If Y diff. > 0x00 (Target is Northward)
001844c8: 34040002 ori r4,r0,0x0002                                         |r4 = 0x02 (Knocked to North)
001844cc: 08061137 j 0x001844dc                                             >>jump to Destination Tile Check
001844d0: 26310001 addiu r17,r17,0x0001                                     |r17 = Destination Tile Y coord (Target Y + 1)
                                                                        #Else Y diff < 0x00 (Target is Westward)
001844d4: 00002021 addu r4,r0,r0                                            |r4 = 0x00 (Knocked to South)
001844d8: 2631ffff addiu r17,r17,-0x0001                                    |r17 = Destination Tile Y coord (Target Y - 1)

CHECK DESTINATION TILE
001844dc: 02002821 addu r5,r16,r0           |r5 = Destination X Coord
001844e0: 0c061184 jal 0x184610             |-->Knockback 2   Returns r2 = Tile Elevation if OK (else -0x01)
001844e4: 02203021 addu r6,r17,r0           |r5 = Destination Y Coord
001844e8: 00409021 addu r18,r2,r0           |r18 = Tile Elevation or -0x01 if Tile is invalid/unreachable
001844ec: 06400041 bltz r18,0x001845f4      #If Tile Elevation is valid /Else Branch to  END (Knockback is impossible)
001844f0: 00000000 nop                          |
001844f4: 3c02800e lui r2,0x800e                |
001844f8: 90424e9c lbu r2,0x4e9c(r2)            |r2 = Map Max X
001844fc: 00000000 nop                          |
00184500: 02220018 mult r17,r2                  |Destination Y * Max X
00184504: 00121200 sll r2,r18,0x08              |r2 = 0x00 or 0x100
00184508: 00001812 mflo r3                      |r3 = Destination Y * Max X
0018450c: 00431021 addu r2,r2,r3                |r3 = (Destination Y * Max X) + Destination X
00184510: 00501021 addu r2,r2,r16               |r3 = Tile ID  (Destination Y * Max X) + Destination X + Elevation offset
00184514: 000210c0 sll r2,r2,0x03               |r3 = Tile ID*8
00184518: 3c038019 lui r3,0x8019                |
0018451c: 2463f8cc addiu r3,r3,0xf8cc           |r3 = 1st Tile data pointer
00184520: 00432021 addu r4,r2,r3                |r4 = Destination Tile Data pointer
00184524: 90830000 lbu r3,0x0000(r4)            |r3 = Destination Tile Type
00184528: 90820006 lbu r2,0x0006(r4)            |r2 = Destination Tile Flags [0x06]
0018452c: 00000000 nop                          |
00184530: 30420002 andi r2,r2,0x0002            |r2 = 0x02 if destination tile is not targetable
00184534: 1440002f bne r2,r0,0x001845f4         #If destination Tile is targetable /Else Branch to  END (Knockback is impossible)
00184538: 3063003f andi r3,r3,0x003f                |r3 = Destination Tile Type (0x01 to 0x3f)
0018453c: 90820003 lbu r2,0x0003(r4)                |r2 = Destination Tile Halves/Depht
00184540: 00000000 nop                              |
00184544: 304200e0 andi r2,r2,0x00e0                |r2 <> 0x00 If Tile has depht
00184548: 1440002a bne r2,r0,0x001845f4             #If Destination Tile depht = 0x00 /Else Branch to  END (Knockback is impossible)
0018454c: 00000000 nop                                  |
00184550: 90820003 lbu r2,0x0003(r4)                    |r2 = Destination Tile Halves/Depht
00184554: 00000000 nop                                  |
00184558: 3042001f andi r2,r2,0x001f                    |r2 = Destination Tile Halves
0018455c: 28420003 slti r2,r2,0x0003                    |r2 = 0x01 if Halves < 0x03
00184560: 10400024 beq r2,r0,0x001845f4                 #If Destination Tile Halves < 0x03 /Else Branch to  END (Knockback is impossible)
00184564: 306300ff andi r3,r3,0x00ff                        |r3 = Destination Tile Type
00184568: 34020012 ori r2,r0,0x0012                         |r2 = 0x12 (Type Lava)
0018456c: 10620021 beq r3,r2,0x001845f4                     #If Destination Tile is not  Lava /If Lava : branch END (Knockback is impossible)
00184570: 3402001c ori r2,r0,0x001c                             |r2 = 0x1c (Obstacle Type)
00184574: 1062001f beq r3,r2,0x001845f4                         #If Destination Tile is not Obstacle /Else Branch to  END (Knockback is impossible)
00184578: 00000000 nop                                              |

ENABLE KNOCKBACK
0018457c: 3c048019 lui r4,0x8019                                    |
00184580: 8c842d98 lw r4,0x2d98(r4)                                 |r4 = Target data pointer
00184584: 0c05fc08 jal 0x0017f020                                   |-->Float/Float/Fly_movements Returns r2 with movement info
00184588: 00000000 nop                                              |
0018458c: 30420080 andi r2,r2,0x0080                                |r2 = 0x80 if Unit is flying
00184590: 1040000a beq r2,r0,0x001845bc                             #If Unit is flying /If not flying branch with r2 = 0x81
00184594: 34020081 ori r2,r0,0x0081                                 |r2 = 0x81
00184598: 3c028019 lui r2,0x8019                                        |
0018459c: 8c422d98 lw r2,0x2d98(r2)                                     |r2 = Target data pointer
001845a0: 00000000 nop                                                  |
001845a4: 9042005a lbu r2,0x005a(r2)                                    |r2 =  Target 3rd set of current Statuses
001845a8: 00000000 nop                                                  |
001845ac: 30420006 andi r2,r2,0x0006                                    |r2 = 0x06 if Target is a frog or a chicken
001845b0: 14400002 bne r2,r0,0x001845bc                                 #If Target is not a frog nor a chicken /Else branch (r2 = 0x81)
001845b4: 34020081 ori r2,r0,0x0081                                     |r2 = 0x81
001845b8: 34020082 ori r2,r0,0x0082                                         |r2 = 0x82
001845bc: 3c018019 lui r1,0x8019                                    |
001845c0: a02238ed sb r2,0x38ed(r1)                                 |Store r2 at 0x801938ed  801938ed
001845c4: 3c038019 lui r3,0x8019                                    |
001845c8: 8c632d90 lw r3,0x2d90(r3)                                 |r3 = Target current action data pointer
001845cc: 3c018019 lui r1,0x8019                                    |
001845d0: a03038ca sb r16,0x38ca(r1)                                |Store Destination Tile X at 0x801938ca (Current ability Target New X)  801938ca
001845d4: 3c018019 lui r1,0x8019                                    |
001845d8: a03138cb sb r17,0x38cb(r1)                                |Store Destination Tile Y at 0x801938cb (Current ability Target New Y)  801938cb
001845dc: 3c018019 lui r1,0x8019                                    |
001845e0: a03238cc sb r18,0x38cc(r1)                                |Store Destination Tile elevation at 0x801938cc (Current ability Target New elevation)  801938cc
001845e4: 94620010 lhu r2,0x0010(r3)                                |r2 = Target Current Action special flags 1 and 2
001845e8: 00000000 nop                                              |
001845ec: 34424000 ori r2,r2,0x4000                                 |r2 = specials flags + Knockback flag
001845f0: a4620010 sh r2,0x0010(r3)                                 |Store TCA Special flags with knockback enabled
001845f4: 8fbf001c lw r31,0x001c(r29)       END
001845f8: 8fb20018  lw r18,0x0018(r29)      
001845fc: 8fb10014 lw r17,0x0014(r29)       
00184600: 8fb00010 lw r16,0x0010(r29)       
00184604: 27bd0020 addiu r29,r29,0x0020     
00184608: 03e00008 jr r31                   
0018460c: 00000000 nop

Notes

Routine is skipped if 
 - Current Ability Target Counter is not 0x01  ( 0x801938ec / 801938ec )
 - Target is immortal (Target 0x05 ENTD flags)
 - Target ENTD flags 0x01 and 0x02 ar enabled (Ramza avoids Knockback here)
 - Target = Attacker
 - Target is ridding (or being ridden)

Then Knockback direction is calculated
Destination Tile is checked : if not OK, Target will not be knocked back
  - reachable, targetable, lower than origin tile, not already occupied
  - Not lava, not too sloping, no depth, no lava, no obstacle 
  
If Target is knocked
 Current Ability Data
 - 0x801938ed : 0x80 in all cases ("Fall damage not calculated yet" flag)
                + 0x01 if unit is not flying/is a frog or a chicken
                + 0x02 if Unit is flying
 - 0x801938ca : Target Destination Tile X coordinate
 - 0x801938cb : Target Destination Tile Y coordinate
 - 0x801938cc : Target Destination Tile Elevation
 
 Target Current Action data
 - Special flags 2 updated with 0x40 (knockedback flag)

Return location

Battle.bin
00186558: Critical Hit Calculation
001869dc: Damage_and_Knockback_Routine_(Dash,_tackle,_throw_stone)