Knockback 2

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
Parameters : r4 = Knockback Direction ( South 0x00 / West 0x01 / North 0x02 / East 0x03)
             r5 = Destination X coordinates
             r6 = Destination Y coordinates

Returns : r2 =  Destination Tile Elevation is everything is OK
          r2 = -0x01 if Knockback is not possible

If Knockback is OK - Store : Knockback Height fall in 0x801938ee
                             Target ID from Current ability 0x801938c1 at 0x801938ef
-----------------------------------------------------------------------------------------
00184610: 27bdffd8 addiu r29,r29,-0x0028    |
00184614: afb20018 sw r18,0x0018(r29)       |
00184618: 00a09021 addu r18,r5,r0           |r18 = Destination X
0018461c: afb3001c sw r19,0x001c(r29)       |
00184620: 00c09821 addu r19,r6,r0           |r19 = Destination Y
00184624: afbf0020 sw r31,0x0020(r29)       |
00184628: afb10014 sw r17,0x0014(r29)       |
0018462c: 064000a1 bltz r18,0x001848b4      #If Destination X coordinates >= 0x00 /Else (out of Map) : branch to END (r2 will be set to -0x01)
00184630: afb00010 sw r16,0x0010(r29)           |
00184634: 066000a0 bltz r19,0x001848b8          #If Destination Y coordinates >= 0x00 /Else (out of Map) : branch to END (r2 = -0x01)
00184638: 2402ffff addiu r2,r0,-0x0001          |r2 = -0x01
0018463c: 3c02800e lui r2,0x800e                    |
00184640: 90424e9c lbu r2,0x4e9c(r2)                |r2 = Map Max X  0x800e4e9c 800e4e9c
00184644: 00000000 nop                              |
00184648: 0242102a slt r2,r18,r2                    |r2 = 0x01 if Destination X < Map max X
0018464c: 1040009a beq r2,r0,0x001848b8             #If Destination X is in the Map /Else (out of Map : branch to END (r2 = -0x01)
00184650: 2402ffff addiu r2,r0,-0x0001              |r2 = -0x01
00184654: 3c02800e lui r2,0x800e                        |
00184658: 90424ea0 lbu r2,0x4ea0(r2)                    |r2 = Map Max Y  0x800e4ea0 / 800e4ea0
0018465c: 00000000 nop                                  |
00184660: 0262102a slt r2,r19,r2                        |r2 = 0x01 if Destination Y < Map Max Y
00184664: 10400093 beq r2,r0,0x001848b4                 #If Destination Y is in the Map /Else (out of Map : branch to END (r2 will be set to  -0x01)
00184668: 34020001 ori r2,r0,0x0001                         |r2 = 0x01

CHECK AND SET KNOCKBACK DIRECTION 
0018466c: 10820012 beq r4,r2,0x001846b8                     #If Knockback direction is not West /Else Branch to West section
00184670: 28820002 slti r2,r4,0x0002                            |r2 = 0x01 if KnockBack direction <0x02
00184674: 10400005 beq r2,r0,0x0018468c                         #If Knockback direction is < 0x02
00184678: 00000000 nop                                              |
0018467c: 10800011 beq r4,r0,0x001846c4                             #If Knockback Direction is not South (0x00) /Else Branch to South
00184680: 00000000 nop                                                  |
00184684: 080611b3 j 0x001846cc                                         >>Trash Jump with nothing set  Should not happen
00184688: 00000000 nop                                                  |
                                                                    #Else (Knockback direction > 0x02)              
0018468c: 34020002 ori r2,r0,0x0002                                 |r2 = 0x02
00184690: 10820006 beq r4,r2,0x001846ac                             #If Knockback direction is not North /Else Branch to North Section
00184694: 34020003 ori r2,r0,0x0003                                     |r2=0x03
00184698: 1482000c bne r4,r2,0x001846cc                                 #If Knockback direction is East /Else Branch to Height checks with nothing set (should not happen)
0018469c: 00000000 nop                                                      |
                                            EAST
001846a0: 00008021 addu r16,r0,r0           |r16 = 0x00 (Exit side is East)
001846a4: 080611b3 j 0x001846cc             >>Jump to Height checks
001846a8: 34110002 ori r17,r0,0x0002        |r17 = 0x02 (Entry Side is West)
                                            NORTH
001846ac: 34100006 ori r16,r0,0x0006        |r16 = 0x06 (Exit side is North)
001846b0: 080611b3 j 0x001846cc             >>Jump to Height checks
001846b4: 34110004 ori r17,r0,0x0004        |r17 = 0x04 (Entry side is south)
                                            WEST
001846b8: 34100002 ori r16,r0,0x0002        |r16 = 0x02 (Exit Side is West)
001846bc: 080611b3 j 0x001846cc             >>Jump to Height checks
001846c0: 00008821 addu r17,r0,r0           |r17 =0x00 (Entry Side is East)
                                            SOUTH
001846c4: 34100004 ori r16,r0,0x0004        |r16 = 0x04 (Exit Side is South)
001846c8: 34110006 ori r17,r0,0x0006        |r17 = 0x06 (Entry Side is North)

ORIGIN HEIGHT SETTING 
001846cc: 3c048019 lui r4,0x8019            |
001846d0: 8c842d98 lw r4,0x2d98(r4)         |r2 = Target Data pointer
001846d4: 0c060428 jal 0x001810a0           |-->Map Location Calculation returns r2 = Target Tile's ID
001846d8: 00000000 nop                      |
001846dc: 000210c0 sll r2,r2,0x03           |r2 = Target Tile's ID * 8
001846e0: 3c058019 lui r5,0x8019            |
001846e4: 24a5f8cc addiu r5,r5,-0x0734      |r5 = 0x8018f8cc  / 8018f8cc   (1st Tile data pointer)
001846e8: 00451021 addu r2,r2,r5            |r2 = Target's Tile data pointer
001846ec: 90440003 lbu r4,0x0003(r2)        |r4 = Target Tile's Height (halves) + Depth
001846f0: 90430004 lbu r3,0x0004(r2)        |r3 = Target Tile's Slope Type
001846f4: 3084001f andi r4,r4,0x001f        |r4 = Target Tile's Height (halves)
001846f8: 02031807 srav r3,r3,r16           |r3 = Target Tile's Slope Type shifted to Exit Side data
001846fc: 30630003 andi r3,r3,0x0003        |r3 = Target Tile's Exit border slope Mod (0,1 or 2)
00184700: 00830018 mult r4,r3               |Tile's Halves * Tile's Exit border slope data ( 0x00 if Lower part of tile, 0x01 if sloping border, 0x02 if Higher border)
00184704: 00002012 mflo r4                  |r4 = Target Tile's Exit Border Bonus Height (if Tile is sloping)
00184708: 3c03800e lui r3,0x800e            |
0018470c: 90634e9c lbu r3,0x4e9c(r3)        |r3 = Map Max X
00184710: 00000000 nop                      |
00184714: 02630018 mult r19,r3              |New Tile's Y * Max X
00184718: 90420002 lbu r2,0x0002(r2)        |r2 = Target Tile's Height
0018471c: 00000000 nop                      |
00184720: 00021040 sll r2,r2,0x01           |r2 = Target's Tile Height * 2
00184724: 00443021 addu r6,r2,r4            |r6 = Target's Tile Exit Border Total Heigth

DESTINATION HEIGHT SETTING 
00184728: 00001012 mflo r2                  |r2 = New Tile's Y * Max X
0018472c: 00521021 addu r2,r2,r18           |r2 = (New Tile's Y * Max X) + New Tile's X = New Tile's ID
00184730: 24430100 addiu r3,r2,0x0100       |r3 = New Tile's ID (for high elevation)
00184734: 000210c0 sll r2,r2,0x03           |r2 = Low Elevation New Tile Offset
00184738: 00454021 addu r8,r2,r5            |r8 = Low elevation New Tile data pointer
0018473c: 000318c0 sll r3,r3,0x03           |r3 = High Elevation New Tile Offset
Low elevation Tile height setting
00184740: 91020006 lbu r2,0x0006(r8)        |r2 = Low Elevation New Tile [0x06] byte
00184744: 00000000 nop                      |
00184748: 30420001 andi r2,r2,0x0001        |r2 = 0x01 if Low Tile is unselectable
0018474c: 10400003 beq r2,r0,0x0018475c     #If Low Tile is unselectable
00184750: 00653821 addu r7,r3,r5            |r7 = High elevation New Tile data pointer
00184754: 080611e2 j 0x00184788                 >>Jump avoiding Low Tile Section
00184758: 340400ff ori r4,r0,0x00ff             |r4 = 0x0ff (Max Height - will prevent this tile to be used later)
                                            #Else (Tile is selectable)
0018475c: 91030003 lbu r3,0x0003(r8)            |r3 = Low Elev. New Tile (Halves + depht)
00184760: 91020004 lbu r2,0x0004(r8)            |r2 = Low Elev. New Tile Slope Type
00184764: 3063001f andi r3,r3,0x001f            |r3 =  Low Elev. New Tile Halves
00184768: 02221007 srav r2,r2,r17               |r2 = New Tile Slope Type shifted to Entry side data
0018476c: 30420003 andi r2,r2,0x0003            |r2 = New Tile's Entry Side Slope Mod
00184770: 00620018 mult r3,r2                   |New Tile Height (halves) * Entry Side Slope Mod
00184774: 91020002 lbu r2,0x0002(r8)            |r2 = Low Elev. New Tile Height
00184778: 00000000 nop                          |
0018477c: 00021040 sll r2,r2,0x01               |r2 = Low Elev. New Tile Height * 2
00184780: 00001812 mflo r3                      |r3 =New Tile Entry Side Bonus Height (if tile is sloping)
00184784: 00432021 addu r4,r2,r3                |r4 = Low Elev. New Tile Entry Side Total Height
High elevation Tile height setting
00184788: 90e20006 lbu r2,0x0006(r7)        |r2 =  Higher Elevation New Tile's [0x06] Flags
0018478c: 00000000 nop                      |
00184790: 30420001 andi r2,r2,0x0001        |r2 = 0x01 if Higher Tile is unselectable
00184794: 1440000c bne r2,r0,0x001847c8     #If tile is selectable /Else Branch setting Height to 0xff, preventing this tile to be used)
00184798: 340300ff ori r3,r0,0x00ff         |r3 = 0x0ff (max Height)
0018479c: 90e30003 lbu r3,0x0003(r7)            |r3 = Higher ElevationNew Tile's  Height (halves) + Depth
001847a0: 90e20004 lbu r2,0x0004(r7)            |r2 =  Higher Elevation Tile's Slope Type
001847a4: 3063001f andi r3,r3,0x001f            |r3 = Higher ElevationNew Tile's  Height (halves) 
001847a8: 02221007 srav r2,r2,r17               |r2 = Slope Type shifted to Entry Side data
001847ac: 30420003 andi r2,r2,0x0003            |r2 = Higher Elev. New Tile's Entry Side Slope Mod
001847b0: 00620018 mult r3,r2                   |Height (halves) * Slope Mod?
001847b4: 90e20002 lbu r2,0x0002(r7)            |r2 = Higher Elev. New Tile's Height
001847b8: 00000000 nop                          |
001847bc: 00021040 sll r2,r2,0x01               |r2 = Higher Elev. New Tile's Height*2
001847c0: 00001812 mflo r3                      |r3 = Higher Elev. New Tile Entry Side Height bonus
001847c4: 00431821 addu r3,r2,r3                |r3 = Higher Elev. New Tile Entry Side Total Height

DESTINATION TILE SELECTION
001847c8: 00c4282a slt r5,r6,r4             |r5 = 0x01 if Exit Height < Low Tile Entry Height
001847cc: 10a00005 beq r5,r0,0x001847e4     #If Low Tile Entry Side Height > Target Exit Side Height
001847d0: 00c3102a slt r2,r6,r3             |r2 = 0x01 if Exit Height < Higher Tile Entry Height
001847d4: 10400012 beq r2,r0,0x00184820         #If Higher Tile Entry Side Height > Target Exit Side Height
001847d8: 00c4102a slt r2,r6,r4                     |
001847dc: 0806122e j 0x001848b8                     >>jump to  END r2 = -0x01 (both destination are too high)
001847e0: 2402ffff addiu r2,r0,-0x0001              |r2 = -0x01
001847e4: 1040000d beq r2,r0,0x0018481c     #If Higher Tile Entry Side Height > Target Exit Side Height
001847e8: 00000000 nop                          |

Only Low Tile is OK
001847ec: 14a0000e bne r5,r0,0x00184828         #If Target Exit Side Height > Low Tile Entry Side Height   useless ?
001847f0: 00000000 nop                              |
001847f4: 90e20005 lbu r2,0x0005(r7)                |r2  = Higher Elevation's Bridge Thickness / and targeting flags
001847f8: 00000000 nop                              |
001847fc: 3042001f andi r2,r2,0x001f                |r2  = Higher Elevation's Bridge Thickness
00184800: 00621823 subu r3,r3,r2                    |r3 = Higher Elev. New Tile Entry Side Total Height - Bridge Thickness (Start of ground above lower Tile)
00184804: 24c20004 addiu r2,r6,0x0004               |r2 = Exit Side Height + 0x04
00184808: 0062102a slt r2,r3,r2                     |r2 = 0x01 If Low Tile ceiling < Exit Tile + 0x04
0018480c: 1440002a bne r2,r0,0x001848b8             #If There's at least 0x04 between Exit ground and low tile ceilling /Else branch to  END r2 = -0x01
00184810: 2402ffff addiu r2,r0,-0x0001              |r2 = -0x01
00184814: 0806121a j 0x00184868                         >>jump to Fall Height setting
00184818: 00008821 addu r17,r0,r0                       |r17 = 0x00 (Destination Tile Elevation)
0018481c: 00c4102a slt r2,r6,r4             |r2 = 0x01 if Exit Height < Low Tile Entry Height
00184820: 1040000d beq r2,r0,0x00184858     #If Exit Height < Low Entry Height /Branch if both OK
00184824: 00c3102a slt r2,r6,r3                 |r2 = 0x01 if Exit Height < High Tile Entry Height

Only Higher Tile is OK
00184828: 1440000c bne r2,r0,0x0018485c         #If Exit Height > High Tile Entry Height  useless ?
0018482c: 0083102a slt r2,r4,r3                 |r2 = 0x01 if Low Tile Height < High Tile Height 
00184830: 91020005 lbu r2,0x0005(r8)                |r2 = Low Tile [0x05] 
00184834: 00000000 nop                              |
00184838: 3042001f andi r2,r2,0x001f                |r2 = Low Tile ? Thickness (If there's a ceiling on High Tile it is stored on low tile ?)
0018483c: 00822023 subu r4,r4,r2                    |r4 = Low Tile Height - ?
00184840: 24c20004 addiu r2,r6,0x0004               |r2 = Exit Height + 0x04
00184844: 0082102a slt r2,r4,r2                     |r2 = 0x01 if adjusted low tile Height <  Origin Height + 4  (what happens here means something only if it's High Tile ceiling)
00184848: 1440001b bne r2,r0,0x001848b8             #If  There's at least 0x04 between origin height and high tile ceilling /Else branch to  END r2 = -0x01
0018484c: 2402ffff addiu r2,r0,-0x0001              |r2 = -0x01
00184850: 0806121c j 0x00184870                         >>jump to resolution
00184854: 34110001 ori r17,r0,0x0001                    |r17 = 0x01 (Destination tile is higher elevation)

Both Tiles are OK
00184858: 0083102a slt r2,r4,r3             |r2 = 0x01 if Low Tile Height < High Tile Height
0018485c: 14400004 bne r2,r0,0x00184870     #If Low Tile Height > Higher Tile Height (???)
00184860: 34110001 ori r17,r0,0x0001        |r17 = 0x01 (Destination = High elevation Tile)
00184864: 00008821 addu r17,r0,r0               |r17 = 0x00 (Destination = Low Tile ???)

KNOCKBACK/FALL DATA SETTING
00184868: 0806121d j 0x00184874                 |
0018486c: 00c48023 subu r16,r6,r4               |r16 = KnockBack Height (Exit Height - Entry height)
00184870: 00c38023 subu r16,r6,r3               |
00184874: 0600000f bltz r16,0x001848b4          #If KnockBack Height >= 0x00 /Else branch to END (r2 will be set to -0x01)
00184878: 02402021 addu r4,r18,r0                   |r4 = New Tile X
0018487c: 02602821 addu r5,r19,r0                   |r5 = New Tile Y
00184880: 0c05f722 jal 0x0017dc88                   |-->Get_ID_of_Unit_if_Tile_is_Targetable Returns r2 = -0x01 if No units are on the Tile
00184884: 02203021 addu r6,r17,r0                   |r6 = New Tile Elevation
00184888: 2403ffff addiu r3,r0,-0x0001              |r3 = -0x01
0018488c: 1443000a bne r2,r3,0x001848b8             #If returned Value is -0x01 /Else branch to END (r2 = -0x01)
00184890: 2402ffff addiu r2,r0,-0x0001              |r2 = -0x01
00184894: 3c038019 lui r3,0x8019                        |
00184898: 906338c1 lbu r3,0x38c1(r3)                    |r3 = Current Ability Target ID
0018489c: 3c018019 lui r1,0x8019                        |
001848a0: a03038ee sb r16,0x38ee(r1)                    |Store Fall Height at 0x801938ee  801938ee
001848a4: 3c018019 lui r1,0x8019                        |
001848a8: a02338ef sb r3,0x38ef(r1)                     |Store Target ID at 0x801938ef  801938ef
001848ac: 0806122e j 0x001848b8                         >>Jump to END (r2 = Tile Elevation)
001848b0: 02201021 addu r2,r17,r0                       |r2 = Destination Tile elevation
001848b4: 2402ffff addiu r2,r0,-0x0001          |r2 = -0x01
001848b8: 8fbf0020 lw r31,0x0020(r29)           END
001848bc: 8fb3001c lw r19,0x001c(r29)           
001848c0: 8fb20018 lw r18,0x0018(r29)           
001848c4: 8fb10014 lw r17,0x0014(r29)           
001848c8: 8fb00010 lw r16,0x0010(r29)           
001848cc: 27bd0028 addiu r29,r29,0x0028         
001848d0: 03e00008 jr r31                       
001848d4: 00000000 nop

Notes

First checks if coordinates are valid

Then determines the knockback direction and calculates the origin and destination height. 
This is done in a complex way using the Slope Type (Tile data 0x04) to adjust the precise height of the exit edge of the origin and entry edge of the destination tile
See Slope Type


Choose the destination Tile (between the two elevations) by comparing their height to the origin (the destination must be lower than the origin).
This part also uses Tile data 0x05 (flags from 0x01 to 0x10) as a ceiling (this is an assumption). 
It looks like the 0x05 data in the low elevation tile is used as a ceiling for the high elevation tile.

Return location

 001844e8: Knockback_Calculation