Knockback 2
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