Check if Linear Ability hits anything (0019c8ec)
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 8019f2f8
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)