Difference between revisions of "AI Post Action Movement Decision Routine (0019693c)"

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
m (Dokurider moved page AI Ability CT Usage (0019693c) to AI Post Action Movement Decision Routine (0019693c): Better title to reflect what this routine really does)
Line 1: Line 1:
  r4 = {0x00ff, 0x7ffffff(Normal Value), 0x000X} (Distance (from target) to beat)
+
  '''BATTLE.BIN''' : - AI_Post_Action_Movement_Decision_Routine_(0019693c)
  r5 = Move to Target (True) or Move away from Enemy Team (False)
+
  This routine will try to find a Panel matching distance and Priority score conditions, If this tile is found the routine update coordinates at 8019f3c4 + 0xcc4 (with an offset based on 0xe2d value)
 
+
  ------------------------------------------------------------------------------------------
0019693c: 27bdffe8 addiu r29,r29,0xffe8
+
  Parameter : r4 = Maximum desired distance value
00196940: afb10014 sw r17,0x0014(r29)
+
  Parameter : r5 = 0x00 Priority prevails / 0x01 Distance Prevails
  00196944: 00a08821 addu r17,r5,r0 r17 = Running Away or Moving Towards
 
00196948: 3c0b7fff lui r11,0x7fff
 
0019694c: 356bffff ori r11,r11,0xffff r11 = Initialize Panel Priority + Total Distance
 
00196950: 3c0e7fff lui r14,0x7fff
 
00196954: 35ceffff ori r14,r14,0xffff r14 = Initialize Target Distance
 
00196958: 00006821 addu r13,r0,r0
 
0019695c: 00002821 addu r5,r0,r0
 
00196960: 0000c821 addu r25,r0,r0
 
00196964: 3c02801a lui r2,0x801a
 
00196968: 904201f1 lbu r2,0x01f1(r2) ??
 
0019696c: 3c0c801a lui r12,0x801a
 
00196970: 258cf3c4 addiu r12,r12,0xf3c4 r12 = AI data
 
00196974: afb00010 sw r16,0x0010(r29)
 
00196978: 00021080 sll r2,r2,0x02
 
0019697c: 24420cc4 addiu r2,r2,0x0cc4
 
00196980: 004c5021 addu r10,r2,r12 r10 = Movement Data
 
 
 
<Map Level Loop>
 
00196984: 91820e3b lbu r2,0x0e3b(r12) load map max Y
 
00196988: 00000000 nop
 
0019698c: 18400045 blez r2,0x00196aa4
 
00196990: 00004821 addu r9,r0,r0 Initialize Y
 
00196994: 03208021 addu r16,r25,r0 Initialize Targeting Matrix Position Pointer
 
00196998: 00a0c021 addu r24,r5,r0 r24 = Unit ID Pointer
 
 
 
<Y Loop>
 
0019699c: 91820e2d lbu r2,0x0e2d(r12) load unit ID
 
001969a0: 00000000 nop
 
001969a4: 000218c0 sll r3,r2,0x03 ID * 8
 
001969a8: 00621821 addu r3,r3,r2 ID * 9
 
001969ac: 000318c0 sll r3,r3,0x03 ID * 72 (0x48)
 
001969b0: 006c1821 addu r3,r3,r12 Get Unit AI Data Pointer
 
001969b4: 24630a74 addiu r3,r3,0x0a74 Get Movement Matrix
 
001969b8: 02031821 addu r3,r16,r3 Which map level?
 
001969bc: 00091040 sll r2,r9,0x01 Y * 2
 
001969c0: 00431021 addu r2,r2,r3 Current Row in Matrix
 
001969c4: 94430000 lhu r3,0x0000(r2) Load Movement Panels in Y Row
 
001969c8: 00000000 nop
 
001969cc: 10600030 beq r3,r0,0x00196a90 Next Y if no Movement Panels in Y Row
 
001969d0: 00000000 nop
 
001969d4: 91820e3a lbu r2,0x0e3a(r12) load map max X
 
001969d8: 00000000 nop
 
001969dc: 1840002c blez r2,0x00196a90 branch if invalid
 
001969e0: 00004021 addu r8,r0,r0 Initialize X
 
001969e4: 00607821 addu r15,r3,r0 r15 = Target positions in Row
 
001969e8: 010f1004 sllv r2,r15,r8 Is there an target on this X coordinate?
 
 
 
<X Loop> (Is panel in Move range?)
 
001969ec: 30428000 andi r2,r2,0x8000 0x8000 if true
 
001969f0: 10400022 beq r2,r0,0x00196a7c Next X if no Movement Panel on this X coordinate
 
 
 
<Check Target Distance vs Preset/Record Value)
 
  001969f4: 00091100 sll r2,r9,0x04 Y * 10
 
  001969f8: 00481021 addu r2,r2,r8 + X
 
001969fc: 03021821 addu r3,r24,r2 + Map Level Pointer
 
00196a00: 006c3021 addu r6,r3,r12 Load Position in Movement Matrix
 
00196a04: 90c703b4 lbu r7,0x03b4(r6) Load Distance from Target
 
00196a08: 00000000 nop
 
00196a0c: 0087102a slt r2,r4,r7 Find the smallest Target Distance
 
00196a10: 1440001a bne r2,r0,0x00196a7c Next X if Target Distance is larger than the Record/Preset
 
00196a14: 00031040 sll r2,r3,0x01
 
00196a18: 004c1021 addu r2,r2,r12
 
00196a1c: 944305f4 lhu r3,0x05f4(r2) Load Panel Priority (Panel Priority are all usually the same value)
 
  00196a20: 90c20174 lbu r2,0x0174(r6) Load Panel Enemy Distance (from all active enemies on team)
 
00196a24: 00031c00 sll r3,r3,0x10 Target Priority * 10000
 
00196a28: 12200007 beq r17,r0,0x00196a48 <Moving Away> if PV = Running Away (False)
 
00196a2c: 00621821 addu r3,r3,r2 Panel Priority + Enemy Distance
 
 
 
<Moving Towards> (PV = True)
 
00196a30: 14870003 bne r4,r7,0x00196a40 Save Panel Data if Current Target Distance is not equal to the Record (less than)
 
00196a34: 0163102a slt r2,r11,r3 Find Smallest Enemy Distance
 
00196a38: 14400010 bne r2,r0,0x00196a7c Next X if Current Enemy Distance is larger than the Record
 
00196a3c: 00000000 nop
 
00196a40: 08065a99 j 0x00196a64 Save Panel Data
 
00196a44: 00e02021 addu r4,r7,r0 r4 = New Record for Lowest Distance (from Target)
 
 
   
 
   
<Moving Away> (PV = False)
+
Return : r2 = 0x00 if no tiles found
  00196a48: 0163102a slt r2,r11,r3 Find Smallest Enemy Distance
+
          r2 = 0x01 if Tile found (Coordinates saved at AI 0xcc4 + word offset based on 0xe2d)
  00196a4c: 1440000b bne r2,r0,0x00196a7c Next X if Current Enemy Distance is larger than Record Enemy Distance
+
------------------------------------------------------------------------------------------
  00196a50: 00000000 nop
+
0019693c: 27bdffe8 addiu r29,r29,-0x0018    |
  00196a54: 146b0003 bne r3,r11,0x00196a64 Save Panel Data if Current Enemy Distance is not equal to the Record
+
00196940: afb10014 sw r17,0x0014(r29)        |
  00196a58: 01c7102a slt r2,r14,r7 Find Smallest Distance (from Target)
+
00196944: 00a08821 addu r17,r5,r0            |{{f/std|Preset Value 2 : Priority score prevails or Distance prevails}}
  00196a5c: 14400007 bne r2,r0,0x00196a7c Next X if Distance is larger than Record Distance
+
00196948: 3c0b7fff lui r11,0x7fff            |
  00196a60: 00000000 nop
+
0019694c: 356bffff ori r11,r11,0xffff        |{{f/std|Initialize record for Priority score.        Note : default score is 0x8001 and will be loaded as a signed value}}
 
+
00196950: 3c0e7fff lui r14,0x7fff            |
<Save Target>
+
00196954: 35ceffff ori r14,r14,0xffff        |{{f/std|Initialize record for target distance}}
  00196a64: 00605821 addu r11,r3,r0 r11 = Record Total Panel Priority + Enemy Distance
+
00196958: 00006821 addu r13,r0,r0            |
  00196a68: 00e07021 addu r14,r7,r0 r14 = Record Distance from Target
+
0019695c: 00002821 addu r5,r0,r0            |
  00196a6c: a1480000 sb r8,0x0000(r10) Target X
+
00196960: 0000c821 addu r25,r0,r0            |{{f/std|Elevation offset}}
  00196a70: a1490002 sb r9,0x0002(r10) Target Y
+
00196964: 3c02801a lui r2,0x801a            |
  00196a74: a14d0001 sb r13,0x0001(r10) Map Level
+
00196968: 904201f1 lbu r2,0x01f1(r2)        |{{f/load|AI 0xe2d}} {{f/std|Offset for considered data (0 is reachable tile, 1 is reachable and closer to Target) - might be more cases}}
  00196a78: a1400003 sb r0,0x0003(r10) No longer deciding Panel?
+
0019696c: 3c0c801a lui r12,0x801a            |
 +
00196970: 258cf3c4 addiu r12,r12,0xf3c4      |{{f/adr|8019f3c4}}
 +
00196974: afb00010 sw r16,0x0010(r29)        |
 +
00196978: 00021080 sll r2,r2,0x02            |{{f/std|Word Offset based on 0xe2d}}
 +
0019697c: 24420cc4 addiu r2,r2,0x0cc4        |
 +
00196980: 004c5021 addu r10,r2,r12          |{{f/adr|Pointer to 0x8019f3c4 + 0xcc4 + 0x2ed Offset}} {{f/std|<nowiki>Acting Unit coordinates when 0xe2d = 0x01</nowiki>}}
 +
                                            {{f/bloop|LOOP - Both Elevation}}
 +
00196984: 91820e3b lbu r2,0x0e3b(r12)            |{{f/load|Map Max Y}}
 +
00196988: 00000000 nop                          |
 +
0019698c: 18400045 blez r2,0x00196aa4            {{f/Cond|if Max Y is invalid branch to }} {{f/loc|Next Elevation}}
 +
00196990: 00004821 addu r9,r0,r0                |{{f/std|Initialize Y}}
 +
00196994: 03208021 addu r16,r25,r0              |{{f/std|Elevation Offset A (0 or 0x24)}}
 +
00196998: 00a0c021 addu r24,r5,r0                |{{f/std|Elevation Offset B (0 or 0x120)}}
 +
                                                {{f/bloop|LOOP - All Y rows}}
 +
0019699c: 91820e2d lbu r2,0x0e2d(r12)                |{{f/load|AI 0xe2d}}
 +
001969a0: 00000000 nop                              |
 +
001969a4: 000218c0 sll r3,r2,0x03                    |{{f/std|ID * 8}}
 +
001969a8: 00621821 addu r3,r3,r2                    |{{f/std|ID * 9}}
 +
001969ac: 000318c0 sll r3,r3,0x03                    |{{f/std|0xe2d offset for AI 0xa74 Table}}
 +
001969b0: 006c1821 addu r3,r3,r12                    |{{f/std|0x8019f3c4 + Offset}}
 +
001969b4: 24630a74 addiu r3,r3,0x0a74                |{{f/adr|Pointer to AI 0xa74 Table based on 0xe2d}} {{f/std|<nowiki>When 0xe2d = 1 : this a Map of all reachable tiles closest to Target</nowiki>}}
 +
001969b8: 02031821 addu r3,r16,r3                    |{{f/std|+Elevation offset}}
 +
001969bc: 00091040 sll r2,r9,0x01                    |{{f/std|Each Y row is an Halfword}}
 +
  001969c0: 00431021 addu r2,r2,r3                     |{{f/std|+Y offset}}
 +
  001969c4: 94430000 lhu r3,0x0000(r2)                |{{f/load|This Y row flags in AI 0xa74 Table}} {{f/std|Based on 0xe2d}}
 +
001969c8: 00000000 nop                              |
 +
001969cc: 10600030 beq r3,r0,0x00196a90              {{f/Cond|If there is no tiles of interest in this row}} {{f/loc|Next Y}}
 +
001969d0: 00000000 nop                                  |
 +
001969d4: 91820e3a lbu r2,0x0e3a(r12)                |{{f/load|Map Max X}}
 +
  001969d8: 00000000 nop                               |
 +
001969dc: 1840002c blez r2,0x00196a90                {{f/Cond|If Max X is invalid branch to }} {{f/loc|Next Y}}
 +
001969e0: 00004021 addu r8,r0,r0                    |{{f/std|Initialize X}}
 +
  001969e4: 00607821 addu r15,r3,r0                    |{{f/std|This Y row Flags}}
 +
001969e8: 010f1004 sllv r2,r15,r8                    |{{f/std|Shift to 1st Tile flag (by 0x00…)}}
 +
                                                    {{f/bloop|LOOP - All X tiles in Y row}}
 +
001969ec: 30428000 andi r2,r2,0x8000                    |{{f/std|Check This Tile flag}}
 +
001969f0: 10400022 beq r2,r0,0x00196a7c                  {{f/Cond|If This Tile flags is OFF branch to }} {{f/loc|Next X}}
 +
001969f4: 00091100 sll r2,r9,0x04                        |{{f/std|This Y row offset (0x10 byte per row)}}
 +
001969f8: 00481021 addu r2,r2,r8                        |{{f/std|This Tile offset (1 byte per Tile)}}
 +
  001969fc: 03021821 addu r3,r24,r2                       |{{f/std|+ Elevation offset (0 or 0x120)}}
 +
00196a00: 006c3021 addu r6,r3,r12                        |{{f/adr|Pointer to this Tile offset (1 byte per tile)}} {{f/std|For Table at 0x3b4 or 0x174}}
 +
00196a04: 90c703b4 lbu r7,0x03b4(r6)                    |{{f/load|Load this TIle Distance from Target}}
 +
00196a08: 00000000 nop                                  |
 +
00196a0c: 0087102a slt r2,r4,r7                          |{{f/std|0x1 if Distance > Preset Value}}
 +
  00196a10: 1440001a bne r2,r0,0x00196a7c                 {{f/Cond|If This Distance is above Best found value}} {{f/loc|Next X}} {{f/std|Start with preset Value 1}}
 +
00196a14: 00031040 sll r2,r3,0x01                        |{{f/std|General offset *2 (Halfword per tile)}}
 +
00196a18: 004c1021 addu r2,r2,r12                        |{{f/adr|Pointer to this Tile offset (for Table at 0x8019f3c4 + 0x5f4)}}
 +
00196a1c: 944305f4 lhu r3,0x05f4(r2)                    |{{f/load|Load This Panel Priority (Can change if Crystal or treasure)}}
 +
00196a20: 90c20174 lbu r2,0x0174(r6)                    |{{f/load|This Tile Foe Proximity score}} {{f/std| the closer the enemies, the higher the score}}
 +
00196a24: 00031c00 sll r3,r3,0x10                        |{{f/std|Pass priority in upper part}}
 +
                                                {{f/sec|Distance first}}
 +
  00196a28: 12200007 beq r17,r0,0x00196a48                {{f/Cond|If preset value 2 <> 0}}
 +
00196a2c: 00621821 addu r3,r3,r2                        |{{f/std|This Tile score}}
 +
00196a30: 14870003 bne r4,r7,0x00196a40                      {{f/Cond|<nowiki>If This distance = Preset Value 1</nowiki>}} {{f/std|Already branched if higher value}}
 +
  00196a34: 0163102a slt r2,r11,r3                                 |{{f/std|0x1 if This tile score > previous score}} {{f/std| Signed !! Default priority is 0x8001}}
 +
00196a38: 14400010 bne r2,r0,0x00196a7c                          {{f/Cond|If This tile prioriy is worse than saved one branch to }} {{f/loc|Next X}}
 +
00196a3c: 00000000 nop                                              |
 +
                                                            '''Else : Distance < Preset Value or Same distance but better priority'''
 +
  00196a40: 08065a99 j 0x00196a64                                  {{f/jump|jump to }} {{f/loc|Save new tile}}
 +
00196a44: 00e02021 addu r4,r7,r0                                 |{{f/std|<nowiki>r4 = New Record for Lowest Distance (from Target)</nowiki>}}
 +
                                                {{f/sec|Priority Score First}}
 +
                                                        '''<nowiki>Else : preset value 2 = 0x00</nowiki>'''
 +
  00196a48: 0163102a slt r2,r11,r3                            |{{f/std|0x1 if This tile score > previous score}} {{f/std| Signed !! Default priority is 0x8001}}
 +
  00196a4c: 1440000b bne r2,r0,0x00196a7c                      {{f/Cond|If This tile prioriy is worse than saved one branch to }} {{f/loc|Next X}}
 +
  00196a50: 00000000 nop                                          |
 +
  00196a54: 146b0003 bne r3,r11,0x00196a64                    {{f/Cond|if This Tile priority is Better than previous record previous record}} {{f/loc|Save new tile}}
 
   
 
   
<X++>
+
                                                            '''Else : Same Priority score'''
00196a7c: 91820e3a lbu r2,0x0e3a(r12) load map max X
+
  00196a58: 01c7102a slt r2,r14,r7                                |{{f/std|0x1 if Previous record distance < This Tile distance}}
00196a80: 25080001 addiu r8,r8,0x0001 Current X++
+
  00196a5c: 14400007 bne r2,r0,0x00196a7c                          {{f/Cond|If Previous record is closest don't save this tile }} {{f/loc|Next X}}
  00196a84: 0102102a slt r2,r8,r2
 
  00196a88: 1440ffd8 bne r2,r0,0x001969ec Loop Max X times
 
00196a8c: 010f1004 sllv r2,r15,r8
 
 
 
<Y++>
 
00196a90: 91820e3b lbu r2,0x0e3b(r12) load map max Y
 
00196a94: 25290001 addiu r9,r9,0x0001 Current Y++
 
00196a98: 0122102a slt r2,r9,r2
 
00196a9c: 1440ffbf bne r2,r0,0x0019699c Loop Max Y times
 
00196aa0: 00000000 nop
 
 
 
<Map Level++>
 
00196aa4: 24a50120 addiu r5,r5,0x0120
 
00196aa8: 25ad0001 addiu r13,r13,0x0001 Map Level++
 
00196aac: 29a20002 slti r2,r13,0x0002
 
00196ab0: 1440ffb4 bne r2,r0,0x00196984 Loop for both map levels
 
00196ab4: 27390024 addiu r25,r25,0x0024 some counter++
 
 
 
<Evaluate Total Priority>
 
00196ab8: 3c027fff lui r2,0x7fff
 
00196abc: 3442ffff ori r2,r2,0xffff
 
00196ac0: 01621026 xor r2,r11,r2 Get Complement of Total Priority
 
00196ac4: 0002102b sltu r2,r0,r2 r2 = True if Complement Priority was Negative (Original was Positive Priority)
 
 
   
 
   
<Exit>
+
                                                {{f/sec|Save this Tile (Closest to enemy (higher score if equality) or Better score (closest if equality)}}
 +
00196a64: 00605821 addu r11,r3,r0                        |{{f/std|<nowiki>r11 = Record Tile of interest score  ( Priority in upper part and Proximity score in lower)</nowiki>}}
 +
00196a68: 00e07021 addu r14,r7,r0                        |{{f/std|<nowiki>r14 = Record Tile of interest Distance from Target</nowiki>}}
 +
00196a6c: a1480000 sb r8,0x0000(r10)                    |{{f/store|Target X}}
 +
00196a70: a1490002 sb r9,0x0002(r10)                    |{{f/store|Target Y}}
 +
00196a74: a14d0001 sb r13,0x0001(r10)                    |{{f/store|Map Level}}
 +
00196a78: a1400003 sb r0,0x0003(r10)                    |{{f/store|Reset AI 0xcc4 byte 0x03}} {{f/std| (based on 0xe2d)}}
 +
00196a7c: 91820e3a lbu r2,0x0e3a(r12)                    |{{f/load|load map max X}}
 +
00196a80: 25080001 addiu r8,r8,0x0001                    |{{f/std|X Counter + 1}}
 +
00196a84: 0102102a slt r2,r8,r2                          |
 +
00196a88: 1440ffd8 bne r2,r0,0x001969ec              {{f/Cond|Loop Max X times}}
 +
00196a8c: 010f1004 sllv r2,r15,r8                        |{{f/std|Shift flags for next iteration (flag of interest is becomes 0x8000)}}
 +
00196a90: 91820e3b lbu r2,0x0e3b(r12)                |{{f/load|Map Max Y}}
 +
00196a94: 25290001 addiu r9,r9,0x0001                |{{f/std|Y counter + 1}}
 +
00196a98: 0122102a slt r2,r9,r2                      |
 +
00196a9c: 1440ffbf bne r2,r0,0x0019699c          {{f/Cond|<nowiki>Loop until Y = max Y</nowiki>}}
 +
00196aa0: 00000000 nop                              |
 +
00196aa4: 24a50120 addiu r5,r5,0x0120            |{{f/std|Elevation offset for Table AI 0x5f4}}
 +
00196aa8: 25ad0001 addiu r13,r13,0x0001          |{{f/std|Elevation counter + 1}}
 +
00196aac: 29a20002 slti r2,r13,0x0002            |
 +
00196ab0: 1440ffb4 bne r2,r0,0x00196984      {{f/Cond|Loop for both map levels}}
 +
00196ab4: 27390024 addiu r25,r25,0x0024          |{{f/std|Elevation offset for Table AI 0x174 and Table AI 0x3b4}}
 +
00196ab8: 3c027fff lui r2,0x7fff                |
 +
00196abc: 3442ffff ori r2,r2,0xffff          |{{f/std|0x7fffffff}}
 +
00196ac0: 01621026 xor r2,r11,r2            |{{f/std|0 if r11 is unchanged}}
 +
00196ac4: 0002102b sltu r2,r0,r2            |{{f/std|<nowiki>r2 = 0 if nothing found, 1 if something found</nowiki>}} {{f/std|unsigned}}
 
  00196ac8: 8fb10014 lw r17,0x0014(r29)
 
  00196ac8: 8fb10014 lw r17,0x0014(r29)
 
  00196acc: 8fb00010 lw r16,0x0010(r29)
 
  00196acc: 8fb00010 lw r16,0x0010(r29)
Line 130: Line 122:
 
  00196ad4: 03e00008 jr r31
 
  00196ad4: 03e00008 jr r31
 
  00196ad8: 00000000 nop
 
  00196ad8: 00000000 nop
 +
===Return locations===
 +
'''BATTLE.BIN'''
 +
  001966d4: [[Map_movement_decision/data_setting]]
 +
  00196918: [[Get_Positive_Priority_(00196908)]]  r5 = 0x00 / r4 = Acting  Unit Shortest Ability range (loaded  from 8019f3c6)
 +
  0019692c: [[Get_Positive_Priority_(00196908)]]  r5 = 0x01 / r4 = 0x7fffffff
 +
  00197258: [[Set_chosen_ability/target_for_AI_status]]
 +
  00197314: [[Set_chosen_ability/target_for_AI_status]]
 +
  001983f8: [[001982d8_-_001984e8]]
 +
  001990e4: [[0019905c_-_00199120]]
  
Notes:
+
Notes (By Dokurider) :
 
  Because this routine doesn't exclude ALL equal result cases, it ends up frequently saving the Last Panel Processed as the final result. This is different from how the other movement routines work and ends up causing some discrepancies and contributes to the AI's erratic movement.
 
  Because this routine doesn't exclude ALL equal result cases, it ends up frequently saving the Last Panel Processed as the final result. This is different from how the other movement routines work and ends up causing some discrepancies and contributes to the AI's erratic movement.

Revision as of 09:58, 20 April 2024

BATTLE.BIN :  - AI_Post_Action_Movement_Decision_Routine_(0019693c)
This routine will try to find a Panel matching distance and Priority score conditions, If this tile is found the routine update coordinates at 8019f3c4 + 0xcc4 (with an offset based on 0xe2d value)
------------------------------------------------------------------------------------------
Parameter : r4 = Maximum desired distance value
Parameter : r5 = 0x00 Priority prevails / 0x01 Distance Prevails

Return : r2 = 0x00 if no tiles found
         r2 = 0x01 if Tile found (Coordinates saved at AI 0xcc4 + word offset based on 0xe2d)
------------------------------------------------------------------------------------------
0019693c: 27bdffe8 addiu r29,r29,-0x0018     |
00196940: afb10014 sw r17,0x0014(r29)        |
00196944: 00a08821 addu r17,r5,r0            |Preset Value 2 : Priority score prevails or Distance prevails
00196948: 3c0b7fff lui r11,0x7fff            |
0019694c: 356bffff ori r11,r11,0xffff        |Initialize record for Priority score.        Note : default score is 0x8001 and will be loaded as a signed value
00196950: 3c0e7fff lui r14,0x7fff            |
00196954: 35ceffff ori r14,r14,0xffff        |Initialize record for target distance
00196958: 00006821 addu r13,r0,r0            |
0019695c: 00002821 addu r5,r0,r0             |
00196960: 0000c821 addu r25,r0,r0            |Elevation offset
00196964: 3c02801a lui r2,0x801a             |
00196968: 904201f1 lbu r2,0x01f1(r2)         |AI 0xe2d Offset for considered data (0 is reachable tile, 1 is reachable and closer to Target) - might be more cases
0019696c: 3c0c801a lui r12,0x801a            |
00196970: 258cf3c4 addiu r12,r12,0xf3c4      |8019f3c4
00196974: afb00010 sw r16,0x0010(r29)        |
00196978: 00021080 sll r2,r2,0x02            |Word Offset based on 0xe2d
0019697c: 24420cc4 addiu r2,r2,0x0cc4        |
00196980: 004c5021 addu r10,r2,r12           |Pointer to 0x8019f3c4 + 0xcc4 + 0x2ed Offset Acting Unit coordinates when 0xe2d = 0x01
                                            @LOOP - Both Elevation
00196984: 91820e3b lbu r2,0x0e3b(r12)            |Map Max Y
00196988: 00000000 nop                           |
0019698c: 18400045 blez r2,0x00196aa4            #if Max Y is invalid branch to  Next Elevation
00196990: 00004821 addu r9,r0,r0                 |Initialize Y
00196994: 03208021 addu r16,r25,r0               |Elevation Offset A (0 or 0x24)
00196998: 00a0c021 addu r24,r5,r0                |Elevation Offset B (0 or 0x120)
                                                @LOOP - All Y rows
0019699c: 91820e2d lbu r2,0x0e2d(r12)                |AI 0xe2d
001969a0: 00000000 nop                               |
001969a4: 000218c0 sll r3,r2,0x03                    |ID * 8
001969a8: 00621821 addu r3,r3,r2                     |ID * 9
001969ac: 000318c0 sll r3,r3,0x03                    |0xe2d offset for AI 0xa74 Table
001969b0: 006c1821 addu r3,r3,r12                    |0x8019f3c4 + Offset
001969b4: 24630a74 addiu r3,r3,0x0a74                |Pointer to AI 0xa74 Table based on 0xe2d When 0xe2d = 1 : this a Map of all reachable tiles closest to Target
001969b8: 02031821 addu r3,r16,r3                    |+Elevation offset
001969bc: 00091040 sll r2,r9,0x01                    |Each Y row is an Halfword
001969c0: 00431021 addu r2,r2,r3                     |+Y offset
001969c4: 94430000 lhu r3,0x0000(r2)                 |This Y row flags in AI 0xa74 Table Based on 0xe2d
001969c8: 00000000 nop                               |
001969cc: 10600030 beq r3,r0,0x00196a90              #If there is no tiles of interest in this row Next Y
001969d0: 00000000 nop                                   |
001969d4: 91820e3a lbu r2,0x0e3a(r12)                |Map Max X
001969d8: 00000000 nop                               |
001969dc: 1840002c blez r2,0x00196a90                #If Max X is invalid branch to  Next Y
001969e0: 00004021 addu r8,r0,r0                     |Initialize X
001969e4: 00607821 addu r15,r3,r0                    |This Y row Flags
001969e8: 010f1004 sllv r2,r15,r8                    |Shift to 1st Tile flag (by 0x00…)
                                                    @LOOP - All X tiles in Y row
001969ec: 30428000 andi r2,r2,0x8000                     |Check This Tile flag
001969f0: 10400022 beq r2,r0,0x00196a7c                  #If This Tile flags is OFF branch to  Next X
001969f4: 00091100 sll r2,r9,0x04                        |This Y row offset (0x10 byte per row)
001969f8: 00481021 addu r2,r2,r8                         |This Tile offset (1 byte per Tile)
001969fc: 03021821 addu r3,r24,r2                        |+ Elevation offset (0 or 0x120)
00196a00: 006c3021 addu r6,r3,r12                        |Pointer to this Tile offset (1 byte per tile) For Table at 0x3b4 or 0x174
00196a04: 90c703b4 lbu r7,0x03b4(r6)                     |Load this TIle Distance from Target
00196a08: 00000000 nop                                   |
00196a0c: 0087102a slt r2,r4,r7                          |0x1 if Distance > Preset Value
00196a10: 1440001a bne r2,r0,0x00196a7c                  #If This Distance is above Best found value Next X Start with preset Value 1
00196a14: 00031040 sll r2,r3,0x01                        |General offset *2 (Halfword per tile)
00196a18: 004c1021 addu r2,r2,r12                        |Pointer to this Tile offset (for Table at 0x8019f3c4 + 0x5f4)
00196a1c: 944305f4 lhu r3,0x05f4(r2)                     |Load This Panel Priority (Can change if Crystal or treasure)
00196a20: 90c20174 lbu r2,0x0174(r6)                     |This Tile Foe Proximity score  the closer the enemies, the higher the score
00196a24: 00031c00 sll r3,r3,0x10                        |Pass priority in upper part
                                                Distance first
00196a28: 12200007 beq r17,r0,0x00196a48                 #If preset value 2 <> 0
00196a2c: 00621821 addu r3,r3,r2                         |This Tile score
00196a30: 14870003 bne r4,r7,0x00196a40                      #If This distance = Preset Value 1 Already branched if higher value
00196a34: 0163102a slt r2,r11,r3                                 |0x1 if This tile score > previous score  Signed !! Default priority is 0x8001
00196a38: 14400010 bne r2,r0,0x00196a7c                          #If This tile prioriy is worse than saved one branch to  Next X
00196a3c: 00000000 nop                                               |
                                                            Else : Distance < Preset Value or Same distance but better priority
00196a40: 08065a99 j 0x00196a64                                  >>jump to  Save new tile
00196a44: 00e02021 addu r4,r7,r0                                 |r4 = New Record for Lowest Distance (from Target)
                                                Priority Score First
                                                        Else : preset value 2 = 0x00
00196a48: 0163102a slt r2,r11,r3                             |0x1 if This tile score > previous score  Signed !! Default priority is 0x8001
00196a4c: 1440000b bne r2,r0,0x00196a7c                      #If This tile prioriy is worse than saved one branch to  Next X
00196a50: 00000000 nop                                           |
00196a54: 146b0003 bne r3,r11,0x00196a64                     #if This Tile priority is Better than previous record previous record Save new tile

                                                            Else : Same Priority score
00196a58: 01c7102a slt r2,r14,r7                                 |0x1 if Previous record distance < This Tile distance
00196a5c: 14400007 bne r2,r0,0x00196a7c                          #If Previous record is closest don't save this tile  Next X

                                                Save this Tile (Closest to enemy (higher score if equality) or Better score (closest if equality)
00196a64: 00605821 addu r11,r3,r0                        |r11 = Record Tile of interest score  ( Priority in upper part and Proximity score in lower)
00196a68: 00e07021 addu r14,r7,r0                        |r14 = Record Tile of interest Distance from Target
00196a6c: a1480000 sb r8,0x0000(r10)                     |Target X
00196a70: a1490002 sb r9,0x0002(r10)                     |Target Y
00196a74: a14d0001 sb r13,0x0001(r10)                    |Map Level
00196a78: a1400003 sb r0,0x0003(r10)                     |Reset AI 0xcc4 byte 0x03  (based on 0xe2d)
00196a7c: 91820e3a lbu r2,0x0e3a(r12)                    |load map max X
00196a80: 25080001 addiu r8,r8,0x0001                    |X Counter + 1
00196a84: 0102102a slt r2,r8,r2                          |
00196a88: 1440ffd8 bne r2,r0,0x001969ec              #Loop Max X times
00196a8c: 010f1004 sllv r2,r15,r8                        |Shift flags for next iteration (flag of interest is becomes 0x8000)
00196a90: 91820e3b lbu r2,0x0e3b(r12)                |Map Max Y
00196a94: 25290001 addiu r9,r9,0x0001                |Y counter + 1
00196a98: 0122102a slt r2,r9,r2                      |
00196a9c: 1440ffbf bne r2,r0,0x0019699c          #Loop until Y = max Y
00196aa0: 00000000 nop                               |
00196aa4: 24a50120 addiu r5,r5,0x0120            |Elevation offset for Table AI 0x5f4
00196aa8: 25ad0001 addiu r13,r13,0x0001          |Elevation counter + 1
00196aac: 29a20002 slti r2,r13,0x0002            |
00196ab0: 1440ffb4 bne r2,r0,0x00196984      #Loop for both map levels
00196ab4: 27390024 addiu r25,r25,0x0024          |Elevation offset for Table AI 0x174 and Table AI 0x3b4
00196ab8: 3c027fff lui r2,0x7fff                 |
00196abc: 3442ffff ori r2,r2,0xffff          |0x7fffffff
00196ac0: 01621026 xor r2,r11,r2             |0 if r11 is unchanged
00196ac4: 0002102b sltu r2,r0,r2             |r2 = 0 if nothing found, 1 if something found unsigned
00196ac8: 8fb10014 lw r17,0x0014(r29)
00196acc: 8fb00010 lw r16,0x0010(r29)
00196ad0: 27bd0018 addiu r29,r29,0x0018
00196ad4: 03e00008 jr r31
00196ad8: 00000000 nop

Return locations

BATTLE.BIN
 001966d4: Map_movement_decision/data_setting
 00196918: Get_Positive_Priority_(00196908)   r5 = 0x00 / r4 = Acting  Unit Shortest Ability range (loaded  from 8019f3c6)
 0019692c: Get_Positive_Priority_(00196908)   r5 = 0x01 / r4 = 0x7fffffff
 00197258: Set_chosen_ability/target_for_AI_status
 00197314: Set_chosen_ability/target_for_AI_status
 001983f8: 001982d8_-_001984e8
 001990e4: 0019905c_-_00199120

Notes (By Dokurider) :

Because this routine doesn't exclude ALL equal result cases, it ends up frequently saving the Last Panel Processed as the final result. This is different from how the other movement routines work and ends up causing some discrepancies and contributes to the AI's erratic movement.