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

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
(Uploaded the correct routine)
(Updated Documentation)
Line 1: Line 1:
  r4 = {0x00ff, 0x7ffffff(Normal Value), 0x0003, 0x00002} (Ability CT to beat?)
+
  r4 = {0x00ff, 0x7ffffff(Normal Value), 0x000X} (Distance (from target) to beat)
 +
r5 = Move to Target (True) or Move away from Enemy Team (False)
  
 
  0019693c: 27bdffe8 addiu r29,r29,0xffe8
 
  0019693c: 27bdffe8 addiu r29,r29,0xffe8
 
  00196940: afb10014 sw r17,0x0014(r29)
 
  00196940: afb10014 sw r17,0x0014(r29)
  00196944: 00a08821 addu r17,r5,r0
+
  00196944: 00a08821 addu r17,r5,r0 r17 = Running Away or Moving Towards
 
  00196948: 3c0b7fff lui r11,0x7fff
 
  00196948: 3c0b7fff lui r11,0x7fff
  0019694c: 356bffff ori r11,r11,0xffff
+
  0019694c: 356bffff ori r11,r11,0xffff r11 = Initialize Panel Priority + Total Distance
 
  00196950: 3c0e7fff lui r14,0x7fff
 
  00196950: 3c0e7fff lui r14,0x7fff
  00196954: 35ceffff ori r14,r14,0xffff
+
  00196954: 35ceffff ori r14,r14,0xffff r14 = Initialize Target Distance
 
  00196958: 00006821 addu r13,r0,r0
 
  00196958: 00006821 addu r13,r0,r0
 
  0019695c: 00002821 addu r5,r0,r0
 
  0019695c: 00002821 addu r5,r0,r0
Line 14: Line 15:
 
  00196968: 904201f1 lbu r2,0x01f1(r2) ??
 
  00196968: 904201f1 lbu r2,0x01f1(r2) ??
 
  0019696c: 3c0c801a lui r12,0x801a
 
  0019696c: 3c0c801a lui r12,0x801a
  00196970: 258cf3c4 addiu r12,r12,0xf3c4 r12 = AI data
+
  00196970: 258cf3c4 addiu r12,r12,0xf3c4 r12 = AI data
 
  00196974: afb00010 sw r16,0x0010(r29)
 
  00196974: afb00010 sw r16,0x0010(r29)
 
  00196978: 00021080 sll r2,r2,0x02
 
  00196978: 00021080 sll r2,r2,0x02
 
  0019697c: 24420cc4 addiu r2,r2,0x0cc4
 
  0019697c: 24420cc4 addiu r2,r2,0x0cc4
  00196980: 004c5021 addu r10,r2,r12 Caster Targeting Matrix Pointer
+
  00196980: 004c5021 addu r10,r2,r12 r10 = Movement Data
  
 
  <Map Level Loop>
 
  <Map Level Loop>
Line 24: Line 25:
 
  00196988: 00000000 nop
 
  00196988: 00000000 nop
 
  0019698c: 18400045 blez r2,0x00196aa4
 
  0019698c: 18400045 blez r2,0x00196aa4
  00196990: 00004821 addu r9,r0,r0 Initialize Y
+
  00196990: 00004821 addu r9,r0,r0 Initialize Y
  00196994: 03208021 addu r16,r25,r0 Initialize Targeting Matrix Position Pointer
+
  00196994: 03208021 addu r16,r25,r0 Initialize Targeting Matrix Position Pointer
  00196998: 00a0c021 addu r24,r5,r0 r24 = Unit ID Pointer
+
  00196998: 00a0c021 addu r24,r5,r0 r24 = Unit ID Pointer
  
<Y Loop>
+
<Y Loop>
 
  0019699c: 91820e2d lbu r2,0x0e2d(r12) load unit ID
 
  0019699c: 91820e2d lbu r2,0x0e2d(r12) load unit ID
 
  001969a0: 00000000 nop
 
  001969a0: 00000000 nop
  001969a4: 000218c0 sll r3,r2,0x03 ID * 8
+
  001969a4: 000218c0 sll r3,r2,0x03 ID * 8
  001969a8: 00621821 addu r3,r3,r2 ID * 9
+
  001969a8: 00621821 addu r3,r3,r2 ID * 9
  001969ac: 000318c0 sll r3,r3,0x03 ID * 72 (0x48)
+
  001969ac: 000318c0 sll r3,r3,0x03 ID * 72 (0x48)
  001969b0: 006c1821 addu r3,r3,r12 Get Unit AI Data Pointer
+
  001969b0: 006c1821 addu r3,r3,r12 Get Unit AI Data Pointer
  001969b4: 24630a74 addiu r3,r3,0x0a74 Get Target Matrix
+
  001969b4: 24630a74 addiu r3,r3,0x0a74 Get Movement Matrix
  001969b8: 02031821 addu r3,r16,r3 Which map level?
+
  001969b8: 02031821 addu r3,r16,r3 Which map level?
  001969bc: 00091040 sll r2,r9,0x01 Y * 2
+
  001969bc: 00091040 sll r2,r9,0x01 Y * 2
  001969c0: 00431021 addu r2,r2,r3 Current Row in Matrix
+
  001969c0: 00431021 addu r2,r2,r3 Current Row in Matrix
  001969c4: 94430000 lhu r3,0x0000(r2) load Target positions in Y Row
+
  001969c4: 94430000 lhu r3,0x0000(r2) Load Movement Panels in Y Row
 
  001969c8: 00000000 nop
 
  001969c8: 00000000 nop
  001969cc: 10600030 beq r3,r0,0x00196a90 Next Row if no targets in Y Row
+
  001969cc: 10600030 beq r3,r0,0x00196a90 Next Y if no Movement Panels in Y Row
 
  001969d0: 00000000 nop
 
  001969d0: 00000000 nop
 
  001969d4: 91820e3a lbu r2,0x0e3a(r12) load map max X
 
  001969d4: 91820e3a lbu r2,0x0e3a(r12) load map max X
 
  001969d8: 00000000 nop
 
  001969d8: 00000000 nop
  001969dc: 1840002c blez r2,0x00196a90 branch if invalid?
+
  001969dc: 1840002c blez r2,0x00196a90 branch if invalid
  001969e0: 00004021 addu r8,r0,r0 Initialize X
+
  001969e0: 00004021 addu r8,r0,r0 Initialize X
  001969e4: 00607821 addu r15,r3,r0 r15 = Target positions in Row
+
  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?
+
  001969e8: 010f1004 sllv r2,r15,r8 Is there an target on this X coordinate?
  
<X Loop>
+
<X Loop> (Is panel in Move range?)
 
  001969ec: 30428000 andi r2,r2,0x8000 0x8000 if true
 
  001969ec: 30428000 andi r2,r2,0x8000 0x8000 if true
  001969f0: 10400022 beq r2,r0,0x00196a7c Next X if target is no target in this X coordinate
+
  001969f0: 10400022 beq r2,r0,0x00196a7c Next X if no Movement Panel on this X coordinate
001969f4: 00091100 sll r2,r9,0x04 Y * 10
 
  
  001969f8: 00481021 addu r2,r2,r8 + X
+
<Check Target Distance vs Preset/Record Value)
  001969fc: 03021821 addu r3,r24,r2 + Map Level Pointer
+
001969f4: 00091100 sll r2,r9,0x04 Y * 10
  00196a00: 006c3021 addu r6,r3,r12 Load Position in Targeting Matrix
+
  001969f8: 00481021 addu r2,r2,r8 + X
  00196a04: 90c703b4 lbu r7,0x03b4(r6) Load Ability Current CT?
+
  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
 
  00196a08: 00000000 nop
  00196a0c: 0087102a slt r2,r4,r7
+
  00196a0c: 0087102a slt r2,r4,r7 Find the smallest Target Distance
  00196a10: 1440001a bne r2,r0,0x00196a7c Next X if Ability Current CT is higher than the lowest Ability CT
+
  00196a10: 1440001a bne r2,r0,0x00196a7c Next X if Target Distance is larger than the Record/Preset
 
  00196a14: 00031040 sll r2,r3,0x01
 
  00196a14: 00031040 sll r2,r3,0x01
 
  00196a18: 004c1021 addu r2,r2,r12
 
  00196a18: 004c1021 addu r2,r2,r12
  00196a1c: 944305f4 lhu r3,0x05f4(r2) Load Unit Target Priority
+
  00196a1c: 944305f4 lhu r3,0x05f4(r2) Load Panel Priority (Panel Priority are all usually the same value)
  00196a20: 90c20174 lbu r2,0x0174(r6) Load Ability Priority? (19f538 + Unit Pointer)
+
  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
+
  00196a24: 00031c00 sll r3,r3,0x10 Target Priority * 10000
  00196a28: 12200007 beq r17,r0,0x00196a48 branch if PV = 0
+
  00196a28: 12200007 beq r17,r0,0x00196a48 <Moving Away> if PV = Running Away (False)
  00196a2c: 00621821 addu r3,r3,r2 Target Priority + Attack Priority
+
  00196a2c: 00621821 addu r3,r3,r2 Panel Priority + Enemy Distance
  
  00196a30: 14870003 bne r4,r7,0x00196a40 Save Target if Ability CT is lower than the lowest Ability CT
+
<Moving Towards> (PV = True)
  00196a34: 0163102a slt r2,r11,r3
+
  00196a30: 14870003 bne r4,r7,0x00196a40 Save Panel Data if Current Target Distance is not equal to the Record (less than)
  00196a38: 14400010 bne r2,r0,0x00196a7c Next X if Current Priority is higher than the lowest Priority so far
+
  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
 
  00196a3c: 00000000 nop
  00196a40: 08065a99 j 0x00196a64
+
  00196a40: 08065a99 j 0x00196a64 Save Panel Data
  00196a44: 00e02021 addu r4,r7,r0 r4 = Lowest Ability CT
+
  00196a44: 00e02021 addu r4,r7,r0 r4 = New Record for Lowest Distance (from Target)
  <If PV = 0> (Unit hasn't acted yet?)
+
   
  00196a48: 0163102a slt r2,r11,r3
+
<Moving Away> (PV = False)
  00196a4c: 1440000b bne r2,r0,0x00196a7c Branch if Current Priority is higher than the lowest Priority so far
+
  00196a48: 0163102a slt r2,r11,r3 Find Smallest Enemy Distance
 +
  00196a4c: 1440000b bne r2,r0,0x00196a7c Next X if Current Enemy Distance is larger than Record Enemy Distance
 
  00196a50: 00000000 nop
 
  00196a50: 00000000 nop
  00196a54: 146b0003 bne r3,r11,0x00196a64 Save Target if lower than the lowest Priority
+
  00196a54: 146b0003 bne r3,r11,0x00196a64 Save Panel Data if Current Enemy Distance is not equal to the Record
  00196a58: 01c7102a slt r2,r14,r7
+
  00196a58: 01c7102a slt r2,r14,r7 Find Smallest Distance (from Target)
  00196a5c: 14400007 bne r2,r0,0x00196a7c branch if Ability Current CT is lower than the lowest Ability CT
+
  00196a5c: 14400007 bne r2,r0,0x00196a7c Next X if Distance is larger than Record Distance
 
  00196a60: 00000000 nop
 
  00196a60: 00000000 nop
  
<Save Target>
+
<Save Target>
  00196a64: 00605821 addu r11,r3,r0 r11 = Best Total Priority
+
  00196a64: 00605821 addu r11,r3,r0 r11 = Record Total Panel Priority + Enemy Distance
  00196a68: 00e07021 addu r14,r7,r0 r14 = Lowest Current Ability CT
+
  00196a68: 00e07021 addu r14,r7,r0 r14 = Record Distance from Target
 
  00196a6c: a1480000 sb r8,0x0000(r10) Target X
 
  00196a6c: a1480000 sb r8,0x0000(r10) Target X
 
  00196a70: a1490002 sb r9,0x0002(r10) Target Y
 
  00196a70: a1490002 sb r9,0x0002(r10) Target Y
 
  00196a74: a14d0001 sb r13,0x0001(r10) Map Level
 
  00196a74: a14d0001 sb r13,0x0001(r10) Map Level
  00196a78: a1400003 sb r0,0x0003(r10) No longer deciding Target?
+
  00196a78: a1400003 sb r0,0x0003(r10) No longer deciding Panel?
  <X++>
+
   
 +
<X++>
 
  00196a7c: 91820e3a lbu r2,0x0e3a(r12) load map max X
 
  00196a7c: 91820e3a lbu r2,0x0e3a(r12) load map max X
 
  00196a80: 25080001 addiu r8,r8,0x0001 Current X++
 
  00196a80: 25080001 addiu r8,r8,0x0001 Current X++
 
  00196a84: 0102102a slt r2,r8,r2
 
  00196a84: 0102102a slt r2,r8,r2
  00196a88: 1440ffd8 bne r2,r0,0x001969ec Loop Max X times
+
  00196a88: 1440ffd8 bne r2,r0,0x001969ec Loop Max X times
 
  00196a8c: 010f1004 sllv r2,r15,r8
 
  00196a8c: 010f1004 sllv r2,r15,r8
</X Loop>
+
 
<Y++>
+
<Y++>
 
  00196a90: 91820e3b lbu r2,0x0e3b(r12) load map max Y
 
  00196a90: 91820e3b lbu r2,0x0e3b(r12) load map max Y
 
  00196a94: 25290001 addiu r9,r9,0x0001 Current Y++
 
  00196a94: 25290001 addiu r9,r9,0x0001 Current Y++
 
  00196a98: 0122102a slt r2,r9,r2
 
  00196a98: 0122102a slt r2,r9,r2
  00196a9c: 1440ffbf bne r2,r0,0x0019699c Loop Max Y times
+
  00196a9c: 1440ffbf bne r2,r0,0x0019699c Loop Max Y times
 
  00196aa0: 00000000 nop
 
  00196aa0: 00000000 nop
</Y Loop>
+
 
<Map Level++>
+
<Map Level++>
 
  00196aa4: 24a50120 addiu r5,r5,0x0120
 
  00196aa4: 24a50120 addiu r5,r5,0x0120
  00196aa8: 25ad0001 addiu r13,r13,0x0001 Map Level++
+
  00196aa8: 25ad0001 addiu r13,r13,0x0001 Map Level++
 
  00196aac: 29a20002 slti r2,r13,0x0002
 
  00196aac: 29a20002 slti r2,r13,0x0002
  00196ab0: 1440ffb4 bne r2,r0,0x00196984 Loop for both map levels
+
  00196ab0: 1440ffb4 bne r2,r0,0x00196984 Loop for both map levels
  00196ab4: 27390024 addiu r25,r25,0x0024 some counter++
+
  00196ab4: 27390024 addiu r25,r25,0x0024 some counter++
</Map Level Loop>
 
  
 +
<Evaluate Total Priority>
 
  00196ab8: 3c027fff lui r2,0x7fff
 
  00196ab8: 3c027fff lui r2,0x7fff
 
  00196abc: 3442ffff ori r2,r2,0xffff
 
  00196abc: 3442ffff ori r2,r2,0xffff
  00196ac0: 01621026 xor r2,r11,r2 Get Negative Total Priority
+
  00196ac0: 01621026 xor r2,r11,r2 Get Complement of Total Priority
  00196ac4: 0002102b sltu r2,r0,r2 r2 = True if Priority was Negative
+
  00196ac4: 0002102b sltu r2,r0,r2 r2 = True if Complement Priority was Negative (Original was Positive Priority)
 
+
 +
<Exit>
 
  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 124: Line 130:
 
  00196ad4: 03e00008 jr r31
 
  00196ad4: 03e00008 jr r31
 
  00196ad8: 00000000 nop
 
  00196ad8: 00000000 nop
 +
 +
Notes:
 +
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 22:29, 9 May 2017

r4 = {0x00ff, 0x7ffffff(Normal Value), 0x000X} (Distance (from target) to beat)
r5 = Move to Target (True) or Move away from Enemy Team (False)
0019693c: 27bdffe8 addiu r29,r29,0xffe8
00196940: afb10014 sw r17,0x0014(r29)
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)

00196a48: 0163102a slt r2,r11,r3				Find Smallest Enemy Distance
00196a4c: 1440000b bne r2,r0,0x00196a7c			Next X if Current Enemy Distance is larger than Record Enemy Distance
00196a50: 00000000 nop
00196a54: 146b0003 bne r3,r11,0x00196a64			Save Panel Data if Current Enemy Distance is not equal to the Record
00196a58: 01c7102a slt r2,r14,r7				Find Smallest Distance (from Target)
00196a5c: 14400007 bne r2,r0,0x00196a7c			Next X if Distance is larger than Record Distance
00196a60: 00000000 nop

<Save Target>

00196a64: 00605821 addu r11,r3,r0				r11 = Record Total Panel Priority + Enemy Distance
00196a68: 00e07021 addu r14,r7,r0				r14 = Record 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)				No longer deciding Panel?

<X++>

00196a7c: 91820e3a lbu r2,0x0e3a(r12)				load map max X
00196a80: 25080001 addiu r8,r8,0x0001				Current 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>

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

Notes:

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.