Check if Linear Ability hits anything (0019c8ec)

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
BATTLE.BIN :  - Check_if_Linear_Ability_hits_anything_(0019c8ec)
This routine will flag Tiles in AI 0xb4c Table. The Whole Map if Range or AoE > 0x10, else Spread AoE (in a very strange logical way). If Ability has [linear], only keep a cross around the center.
------------------------------------------------------------------------------------------
Parameter : r4 = Mode (0 = Load Range, 1 = Load AoE, 2 = Load both Range and AoE,  3 = Use Preset Range)
            r5 = Forced Value if r4 = 0x03
Return : Nothing
------------------------------------------------------------------------------------------
0019c8ec: 27bdffd8 addiu r29,r29,-0x0028     |
0019c8f0: 00a04021 addu r8,r5,r0             |r8 = Preset Value 2
0019c8f4: 3c05801a lui r5,0x801a             |
0019c8f8: 24a5f3c4 addiu r5,r5,-0x0c3c       |AI ponter ( 0x8019f3c4)
0019c8fc: 34020001 ori r2,r0,0x0001          |
0019c900: 10820011 beq r4,r2,0x0019c948      #If Preset Value r4 = 0x01  branch to  dedicated section
0019c904: afbf0020 sw r31,0x0020(r29)        |
0019c908: 28820002 slti r2,r4,0x0002         |
0019c90c: 10400005 beq r2,r0,0x0019c924      #If Preset Value r4 < 0x02 
0019c910: 00000000 nop                           |
0019c914: 10800008 beq r4,r0,0x0019c938          #If Preset Value r4 = 0x00  branch to  dedicated section
0019c918: 29020010 slti r2,r8,0x0010             |Set if Range/AoE < 0x0010
0019c91c: 0806725d j 0x0019c974                  >>Jump and use r5
0019c920: 00000000 nop                           |
                                             Else : r4 > 0x01
0019c924: 34020002 ori r2,r0,0x0002              |
0019c928: 1082000b beq r4,r2,0x0019c958          #If Preset Value r4 = 0x02  branch to  dedicated section
0019c92c: 29020010 slti r2,r8,0x0010                 |0x1  if Preset was less than 0x000f
0019c930: 0806725d j 0x0019c974                      >>Jump and use r5
0019c934: 00000000 nop                               |
                  r4 = 0x00
0019c938: 3c08801a lui r8,0x801a                     |
0019c93c: 9108f3c8 lbu r8,-0x0c38(r8)                |Load Considered Ability Range  8019f3c4 + 0x04
0019c940: 0806725d j 0x0019c974                      >>Avoid other section
0019c944: 29020010 slti r2,r8,0x0010                 |Set if Range is less than 16
                  r4 = 0x01
0019c948: 3c08801a lui r8,0x801a                     |
0019c94c: 9108f3c9 lbu r8,-0x0c37(r8)                |Load Considered Ability AoE  8019f3c4 + 0x05
0019c950: 0806725d j 0x0019c974                      >>Avoid other section
0019c954: 29020010 slti r2,r8,0x0010                 |Set if AoE is less than 16
                  r4 = 0x02
0019c958: 3c03801a lui r3,0x801a                     |
0019c95c: 9063f3c8 lbu r3,-0x0c38(r3)                |Load Considered Ability Range  8019f3c4 + 0x04
0019c960: 3c02801a lui r2,0x801a                     |
0019c964: 9042f3c9 lbu r2,-0x0c37(r2)                |Load Considered Ability AoE  8019f3c4 + 0x05
0019c968: 00000000 nop                               |
0019c96c: 00624021 addu r8,r3,r2                     |Range + AoE
0019c970: 29020010 slti r2,r8,0x0010                 |
                  r4 = Else
0019c974: 1440000c bne r2,r0,0x0019c9a8              #If Considered Value > 0x0f - AoE will Cover the whole Map
0019c978: 34060011 ori r6,r0,0x0011                  |Prepare counter for alternate section

Flag the whole Map
                                                        @LOOP - Enable all Tiles flags
0019c97c: 00003021 addu r6,r0,r0                             |Initialize counter
0019c980: 3403ffff ori r3,r0,0xffff                          |
0019c984: 00a02021 addu r4,r5,r0                             |Dynamic AI data pointer ( 0x8019f3c4 + 1 halfword per iteration)
0019c988: a4830b4c sh r3,0x0b4c(r4)                          |Enable all tiles flags at AI 0x0b4c
0019c98c: a4830b70 sh r3,0x0b70(r4)                          |Enable all tiles flags at AI 0x0b70 (high elevation)
0019c990: 24c60001 addiu r6,r6,0x0001                        |counter + 1
0019c994: 28c20012 slti r2,r6,0x0012                         |
0019c998: 1440fffb bne r2,r0,0x0019c988                  #Loop for all panels
0019c99c: 24840002 addiu r4,r4,0x0002                        |Linear Panels Flags++
0019c9a0: 080672e1 j 0x0019cb84                          |Exit routine
0019c9a4: 00000000 nop                                       |

Else Spread AoE
                                                     Else If Considered Value < 0x10 - Spread AoE
0019c9a8: 24a20022 addiu r2,r5,0x0022                    |8019f3c4 + 0x22
                                                        @LOOP - Initialize flags from 0xb4c to 0xb6e
0019c9ac: a4400b4c sh r0,0x0b4c(r2)                          |initialize flags at AI 0xb4c
0019c9b0: 24c6ffff addiu r6,r6,-0x0001                       |counter - 1 (start at 0x11)
0019c9b4: 04c1fffd bgez r6,0x0019c9ac                    #Reset all Panels
0019c9b8: 2442fffe addiu r2,r2,-0x0002                       |Dynamic pointer offset (- 0x2 each iteration)
0019c9bc: 90a90c76 lbu r9,0x0c76(r5)                     |Considered Unit Y coordinate 8019f3c4 + 0xc74 + 0x02
0019c9c0: 90a40c74 lbu r4,0x0c74(r5)                     |Considered Unit X coordinate 8019f3c4 + 0xc74 + 0x00
0019c9c4: 0500001d bltz r8,0x0019ca3c                    #If  Considered Ability [Range And/Or AoE] < 0  Skip AoE
0019c9c8: 00003021 addu r6,r0,r0                         |Initialize counter
0019c9cc: 288d0008 slti r13,r4,0x0008                    |0x1 if X < 0x8
0019c9d0: 3c0a801a lui r10,0x801a                        |
0019c9d4: 254af2f8 addiu r10,r10,-0x0d08                 |Pointer to AoE Binary Model  See Notes
0019c9d8: 34020007 ori r2,r0,0x0007                      |
0019c9dc: 00446023 subu r12,r2,r4                        |r12 = 7 - X (West)
0019c9e0: 248bfff9 addiu r11,r4,-0x0007                  |r11 = X - 7 (East)
0019c9e4: 01003821 addu r7,r8,r0                         |[Range And/Or AoE]
                                                    South Part of AoE
                                                        @LOOP - Spread AoE to the South(binary model)
0019c9e8: 01261023 subu r2,r9,r6                             |Unit Y - Counter (go away from coordinates of interest)
0019c9ec: 04400013 bltz r2,0x0019ca3c                        #If This Y iteration is North of the Unit Exit Loop
0019c9f0: 00000000 nop                                           |
0019c9f4: 11a00007 beq r13,r0,0x0019ca14                     #If unit X coordinates < 8 Spread AoE in Western part of map
0019c9f8: 00071840 sll r3,r7,0x01                            |Dynamic [Range And/Or AoE] Offset (-1 Halfword each iteration)
                                                            Center of AoE is in West 
0019c9fc: 00021040 sll r2,r2,0x01                                |Y distance offset (halfword)
0019ca00: 006a1821 addu r3,r3,r10                                |8019f2f8 + [Range And/Or AoE] offset
0019ca04: 94630000 lhu r3,0x0000(r3)                             |Load This iteration Y row of Flags (based on AoE)
0019ca08: 00451021 addu r2,r2,r5                                 |8019f3c4 + Y distance offset (Halfword)
0019ca0c: 0806728a j 0x0019ca28                                  >>Avoid East section
0019ca10: 01831804 sllv r3,r3,r12                                |center AoE flags to considered Tile
                                                            Center of AoE is in East
                                                             Else :  unit X coordinates > 7
0019ca14: 00021040 sll r2,r2,0x01                                |delta Y offset (halfword)
0019ca18: 006a1821 addu r3,r3,r10                                |8019f2f8 + [Range And/Or AoE] offset
0019ca1c: 94630000 lhu r3,0x0000(r3)                             |Load This iteration Y row of Flags (based on AoE)
0019ca20: 00451021 addu r2,r2,r5                                 |8019f3c4 + Y distance offset (Halfword)
0019ca24: 01631807 srav r3,r3,r11                                |center AoE flags to considered Tile
0019ca28: a4430b4c sh r3,0x0b4c(r2)                          |Save flags on This Y row
0019ca2c: 24c60001 addiu r6,r6,0x0001                        |Y row counter + 1
0019ca30: 0106102a slt r2,r8,r6                              |
0019ca34: 1040ffec beq r2,r0,0x0019c9e8                  Λ Loop Until AoE is extinguished
0019ca38: 24e7ffff addiu r7,r7,-0x0001                       |[Range And/Or AoE] - 1
0019ca3c: 1900001f blez r8,0x0019cabc                    #if [Range And/Or AoE] is < 1 :  Skip AoE spreading and jump to linear section
0019ca40: 34060001 ori r6,r0,0x0001                      |Set Y counter to 1 (Center Row is already done)
                                                    North part of AoE
0019ca44: 288c0008 slti r12,r4,0x0008                    |0x1 if Considered Tile is in the West part of the map  r4 is X coordinates
0019ca48: 3c07801a lui r7,0x801a                         |
0019ca4c: 24e7f2f8 addiu r7,r7,0xf2f8                    |Pointer to AoE Binary Model  See Notes
0019ca50: 34020007 ori r2,r0,0x0007                      |
0019ca54: 00445823 subu r11,r2,r4                        |r11 = 7 - X : distance from center of map (X axis West direction)
0019ca58: 248afff9 addiu r10,r4,-0x0007                  |r10 = X - 7 : distance from center of map (X axis East direction)
0019ca5c: 2504ffff addiu r4,r8,-0x0001                   |r4 = RangeAoe - 1 () I feel this is a bug… Why reduce AoE if you start 1 tile away from center
                                                        @LOOP - Spread AoE north of Center (start 1 tile away from center
0019ca60: 90a20e3b lbu r2,0x0e3b(r5)                         |Map Max Y
0019ca64: 01261821 addu r3,r9,r6                             |Y center + Y counter
0019ca68: 0062102a slt r2,r3,r2                              |
0019ca6c: 10400013 beq r2,r0,0x0019cabc                      #If AoE reached Map Limit Exit Loop
0019ca70: 00000000 nop                                       |
0019ca74: 11800007 beq r12,r0,0x0019ca94                     #If AoE center is in East part of Map : Avoid West section
0019ca78: 00031040 sll r2,r3,0x01                                |Y distance offset * 2
                                                            Center of AoE is in West 
0019ca7c: 00041840 sll r3,r4,0x01                                |Dynamic AoE offset
0019ca80: 00671821 addu r3,r3,r7                                 |8019f2f8 + [Range And/Or AoE] offset
0019ca84: 94630000 lhu r3,0x0000(r3)                             |Load This iteration Y row of Flags (based on AoE)
0019ca88: 00451021 addu r2,r2,r5                                 |8019f3c4 + Y distance offset (Halfword)
0019ca8c: 080672aa j 0x0019caa8                                  |Avoid East section
0019ca90: 01631804 sllv r3,r3,r11                                |center AoE flags to considered Tile
                                                            Center of AoE is in East
0019ca94: 00041840 sll r3,r4,0x01                                |RangeAoE * 2
0019ca98: 00671821 addu r3,r3,r7                                 |8019f2f8 + [Range And/Or AoE] offset
0019ca9c: 94630000 lhu r3,0x0000(r3)                             |Load This iteration Y row of Flags (based on AoE)
0019caa0: 00451021 addu r2,r2,r5                                 |8019f3c4 + Y distance offset (Halfword)
0019caa4: 01431807 srav r3,r3,r10                                |center AoE flags to considered Tile
0019caa8: a4430b4c sh r3,0x0b4c(r2)                              |Save flags on This Y row
0019caac: 24c60001 addiu r6,r6,0x0001                        |Y counter + 1
0019cab0: 0106102a slt r2,r8,r6                              |
0019cab4: 1040ffea beq r2,r0,0x0019ca60                  Λ Loop Until AoE is extinguished
0019cab8: 2484ffff addiu r4,r4,0xffff                        |AoE counter - 1
0019cabc: 8ca2000c lw r2,0x000c(r5)                      |Load AI Flags
0019cac0: 3c030020 lui r3,0x0020                         |
0019cac4: 00431024 and r2,r2,r3                          |

LINEAR ATTACK - Only keep a cross around Targeted Tile (should be acting unit)
0019cac8: 1040002a beq r2,r0,0x0019cb74              #If considered Ability has [Linear Attack]
0019cacc: 00000000 nop                                   |
0019cad0: 90a20e3b lbu r2,0x0e3b(r5)                     |Map Max Y
0019cad4: 00000000 nop                                   |
0019cad8: 18400026 blez r2,0x0019cb74                    #If Max Y is invalid Exit Loop
0019cadc: 00004821 addu r9,r0,r0                         |Initialize Y counter
0019cae0: 340a8000 ori r10,r0,0x8000                     |r10 = 0x8000 (prepare bitmask)
0019cae4: 00a04021 addu r8,r5,r0                         |Dynamic pointer to 0x8019f3c4 (+1 halfword each iteration)
                                                        @LOOP - All Y rows
0019cae8: 95060b4c lhu r6,0x0b4c(r8)                         |This Y row Flag in AI 0xb4c Table
0019caec: 00000000 nop                                       |
0019caf0: 10c0001b beq r6,r0,0x0019cb60                      #If All flags are OFF : go to  Next Y iteration
0019caf4: 00000000 nop                                           |
0019caf8: 90a20e3a lbu r2,0x0e3a(r5)                         |Map Max X
0019cafc: 00000000 nop                                       |
0019cb00: 18400017 blez r2,0x0019cb60                        #If Max X is invalid : go to  Next Y iteration
0019cb04: 00002021 addu r4,r0,r0                             |Initialize X counter
0019cb08: 01003821 addu r7,r8,r0                             |Dynamic pointer to 0x8019f3c4 (+1 halfword each Y iteration)
0019cb0c: 00861004 sllv r2,r6,r4                             |
                                                            @LOOP - All X tiles (in a Y row)
0019cb10: 30428000 andi r2,r2,0x8000                             |
0019cb14: 1040000d beq r2,r0,0x0019cb4c                          #If This iteration X flag is OFF : go to  Next X iteration
0019cb18: 00000000 nop                                               |
0019cb1c: 90a20c74 lbu r2,0x0c74(r5)                             |Center of AoE X
0019cb20: 00000000 nop                                           |
0019cb24: 10820009 beq r4,r2,0x0019cb4c                          #If X coordinates = Center of AoE X Next X iteration  keep flag ON
0019cb28: 00000000 nop                                               |
0019cb2c: 90a20c76 lbu r2,0x0c76(r5)                             |Center of AoE Y
0019cb30: 00000000 nop                                           |
0019cb34: 11220005 beq r9,r2,0x0019cb4c                          #If Y coordinates = Center of AoE Y Next X iteration  keep flag ON
0019cb38: 008a1807 srav r3,r10,r4                                |Bitmask for this X tile in Y row
0019cb3c: 94e20b4c lhu r2,0x0b4c(r7)                             |Load This Y row flags in AI 0xb4c
0019cb40: 00000000 nop                                           |
0019cb44: 00431026 xor r2,r2,r3                                  |Unflag all panels that are not in the Linear path
0019cb48: a4e20b4c sh r2,0x0b4c(r7)                              |Disable this Tile flag in AI 0xb4c
0019cb4c: 90a20e3a lbu r2,0x0e3a(r5)                             |Load Max X
0019cb50: 24840001 addiu r4,r4,0x0001                            |X counter +1
0019cb54: 0082102a slt r2,r4,r2                                  |
0019cb58: 1440ffed bne r2,r0,0x0019cb10                      #Loop until Max X
0019cb5c: 00861004 sllv r2,r6,r4                                 |Shift Y row flags to Next X iteration (considered flag in 0x8000 position)
0019cb60: 90a20e3b lbu r2,0x0e3b(r5)                         |Load Max Y
0019cb64: 25290001 addiu r9,r9,0x0001                        |Y counter +1
0019cb68: 0122102a slt r2,r9,r2                              |
0019cb6c: 1440ffde bne r2,r0,0x0019cae8                  #Loop until Max Y
0019cb70: 25080002 addiu r8,r8,0x0002                        |Halfword offset
0019cb74: 24a40b70 addiu r4,r5,0x0b70                        |
0019cb78: 24a50b4c addiu r5,r5,0x0b4c                        |
0019cb7c: 0c066ac2 jal 0x0019ab08                    |-->Transfer Halfword Values Copy low elevation tile's  bit to High elevation tiles (AT 0xb4c table)
0019cb80: 34060024 ori r6,r0,0x0024
0019cb84: 8fbf0020 lw r31,0x0020(r29)
0019cb88: 27bd0028 addiu r29,r29,0x0028
0019cb8c: 03e00008 jr r31
0019cb90: 00000000 nop

Notes

Table at 0x8019f2f8

0x8 Halfwords, used as bitmask to spread AoE (1 bit per Tile)

0x8019f2f8  | 0100 | 0000000100000000
0x8019f2fa  | 0380 | 0000001110000000
0x8019f2fc  | 07c0 | 0000011111000000
0x8019f2fe  | 0fe0 | 0000111111100000
0x8019f300  | 1ff0 | 0001111111110000
0x8019f302  | 3ff8 | 0011111111111000
0x8019f304  | 7ffc | 0111111111111100
0x8019f306  | fffe | 1111111111111110

Return locations

BATTLE.BIN
 0019b458: Check_if_any_units_are_in_range_(0019b30c)   r4 = 0x01 or 0x03 (r5 = 0x00)
 0019b8d8: AI_Targeting_Matrix_Analysis_(0019b7b8)      r4 = 0x01 or 0x03 (r5 = 0x00)
 0019c4a0: Evaluate_Linear_Ability_Behaviors            r4 = 0x02 or 0x00 - use 0x00 for Target specific Ability (AI 0x26 = 0x06)
 0019c744: Evaluate_Linear_Ability_Behaviors            r4 = 0x01 or 0x03 (r5 = 0x00)