Find Peril Most Unit (00198b04)
Jump to navigation
Jump to search
Description: Scores allied units based on their missing HP, status, distance, etc., then formulates a score for them. Status Scores do not accumulate. The routine only checks for one. The unit with the highest score gets returned to the routine. Status Priority goes as: Dead > Dead w/ Reraise = Critical > Blood Suck > Petrify > Confuse > Frog > Low HP > Critical HP It has two formulas, one for statused units and a "non-critical" formula. This routine hard caps AI Range, or target acquisition, to 7. This is why the game ignores downed units across the map, for better or worse. It also has a peril minimum, which is some explanation of why the AI seems averse to status curing at times. Also note the AI will not even give the unit with the most usable abilities a peril score unless it has a status. This is actually good for the most part because statuses include Critical and Low HP (>50% HP). This routine also accounts for Ramza (0x03 in the ENTD) and gives him a bonus score
Referenced In: Protect Allies - Auto Battle (001984ec) Save Fading Life - Auto Battle (00198df0)
Routines Used: Check for Status
00198b04: 3c03801a lui r3,0x801a 00198b08: 8c630bbc lw r3,0x0bbc(r3) Acting unit data 00198b0c: 3c02801a lui r2,0x801a 00198b10: 904201f2 lbu r2,0x01f2(r2) Acting unit id 00198b14: 27bdffc8 addiu r29,r29,0xffc8 00198b18: afb40020 sw r20,0x0020(r29) 00198b1c: 3c14801a lui r20,0x801a 00198b20: 2694f3c4 addiu r20,r20,0xf3c4 00198b24: afbe0030 sw r30,0x0030(r29) 00198b28: 0000f021 addu r30,r0,r0 00198b2c: afb20018 sw r18,0x0018(r29) 00198b30: 00009021 addu r18,r0,r0 00198b34: afb7002c sw r23,0x002c(r29) 00198b38: 0000b821 addu r23,r0,r0 00198b3c: afbf0034 sw r31,0x0034(r29) 00198b40: afb60028 sw r22,0x0028(r29) 00198b44: afb50024 sw r21,0x0024(r29) 00198b48: afb3001c sw r19,0x001c(r29) 00198b4c: afb10014 sw r17,0x0014(r29) 00198b50: afb00010 sw r16,0x0010(r29) 00198b54: a06201b9 sb r2,0x01b9(r3) Save Acting Unit ID 00198b58: 3c028019 lui r2,0x8019 00198b5c: 244208cc addiu r2,r2,0x08cc Unit Data 00198b60: 00121900 sll r3,r18,0x04 00198b64: 2463182c addiu r3,r3,0x182c 00198b68: 02838821 addu r17,r20,r3 00198b6c: 92230007 lbu r3,0x0007(r17) AI Target State 00198b70: 00000000 nop 00198b74: 30630010 andi r3,r3,0x0010 00198b78: 1460006a bne r3,r0,0x00198d24 <Unit++> if can't be targeted 00198b7c: 02e28021 addu r16,r23,r2 r16 = Current Unit Data Pointer
00198b80: 92220008 lbu r2,0x0008(r17) Load Enemy Flag 00198b84: 00000000 nop 00198b88: 14400066 bne r2,r0,0x00198d24 <Unit++> if enemy 00198b8c: 00000000 nop
00198b90: 8e8417f8 lw r4,0x17f8(r20) Acting unit data 00198b94: 0c0664db jal 0x0019936c Calculate Distance Between Units 00198b98: 02002821 addu r5,r16,r0 00198b9c: 96060028 lhu r6,0x0028(r16) r6 = Load Target Current HP 00198ba0: 9603002a lhu r3,0x002a(r16) r3 = Load Target Max HP 00198ba4: 000631c0 sll r6,r6,0x07 HP * 80 00198ba8: 00c3001a div r6,r3 (curHP * 80) / Max HP 00198bac: 00003012 mflo r6 r6 = "" 00198bb0: 02002021 addu r4,r16,r0 r4 = Current Unit Data Pointer 00198bb4: 34050002 ori r5,r0,0x0002 r5 = Dead Status 00198bb8: 340300ff ori r3,r0,0x00ff r3 = 0xff 00198bbc: 00629823 subu r19,r3,r2 r19 = ff - Distance between Target and Caster (Closer distance = Higher score) 00198bc0: 92030005 lbu r3,0x0005(r16) Load ENTD Flags 00198bc4: 34020080 ori r2,r0,0x0080 00198bc8: 30760003 andi r22,r3,0x0003 r22 = is unit Ramza?
<Dead?> 00198bcc: 0c066360 jal 0x00198d80 Check for Status 00198bd0: 0046a823 subu r21,r2,r6 r21 = 80 - curHP% 00198bd4: 10400006 beq r2,r0,0x00198bf0 <HP Recovery> if this unit is not dead 00198bd8: 00000000 nop
<Dead without reraise?> 00198bdc: 92220007 lbu r2,0x0007(r17) Load AI Target State 00198be0: 00000000 nop 00198be4: 30420020 andi r2,r2,0x0020 00198be8: 14400033 bne r2,r0,0x00198cb8 <Status Checks> if dead without reraise 00198bec: 34030078 ori r3,r0,0x0078 Dead = Highest Status Priority
<HP Recovery?> 00198bf0: 8e820e34 lw r2,0x0e34(r20) Acting unit decision data 00198bf4: 00000000 nop 00198bf8: 90420006 lbu r2,0x0006(r2) Load AI Targeting Flags 00198bfc: 00000000 nop 00198c00: 30420002 andi r2,r2,0x0002 00198c04: 1040000b beq r2,r0,0x00198c34 <Blood Suck> if doesn't have HP recovery ability (Skip ReraiseDead and Critical) 00198c08: 02002021 addu r4,r16,r0 r4 = Current Unit Data Pointer
<Dead w/ Reraise?> 00198c0c: 92220007 lbu r2,0x0007(r17) Load AI Target State 00198c10: 00000000 nop 00198c14: 30420040 andi r2,r2,0x0040 00198c18: 14400027 bne r2,r0,0x00198cb8 <Status Checks> if dead unit with reraise 00198c1c: 34030077 ori r3,r0,0x0077 Dead w/ reraise = 2nd highest?
<Critical?> 00198c20: 9202005a lbu r2,0x005a(r16) Load Current Status 3 00198c24: 00000000 nop 00198c28: 30420001 andi r2,r2,0x0001 00198c2c: 14400022 bne r2,r0,0x00198cb8 <Status Checks> if critical 00198c30: 00000000 nop Critical Unit = 2nd Highest
<Blood Suck?> 00198c34: 0c066360 jal 0x00198d80 Check for Status 00198c38: 3405000d ori r5,r0,0x000d Check for Blood Suck 00198c3c: 1440001e bne r2,r0,0x00198cb8 <Status Checks> if unit has Blood Suck 00198c40: 34030076 ori r3,r0,0x0076 Blood Suck = 3rd Highest
<Petrify?> 00198c44: 02002021 addu r4,r16,r0 00198c48: 0c066360 jal 0x00198d80 Check for Status 00198c4c: 34050008 ori r5,r0,0x0008 Check for Petrify 00198c50: 14400019 bne r2,r0,0x00198cb8 <Status Checks> if unit is Petrified 00198c54: 34030075 ori r3,r0,0x0075 Petrify = 4th Highest
<Confused?> 00198c58: 02002021 addu r4,r16,r0 00198c5c: 0c066360 jal 0x00198d80 Check for Status 00198c60: 3405000b ori r5,r0,0x000b Check for Confusion 00198c64: 14400014 bne r2,r0,0x00198cb8 <Status Checks> if unit is Confused 00198c68: 34030074 ori r3,r0,0x0074 Confusion = 5th Highest
<Frog?> 00198c6c: 02002021 addu r4,r16,r0 00198c70: 0c066360 jal 0x00198d80 Check for Status 00198c74: 34050016 ori r5,r0,0x0016 Check for Frog 00198c78: 10400003 beq r2,r0,0x00198c88 Branch if not Frog 00198c7c: 00000000 nop 00198c80: 0806632e j 0x00198cb8 <Status Checks> 00198c84: 34030073 ori r3,r0,0x0073 Frog = 6th Highest
<HP Recovery?> 00198c88: 8e820e34 lw r2,0x0e34(r20) Load Current AI Pointer 00198c8c: 00000000 nop 00198c90: 90420006 lbu r2,0x0006(r2) Load AI Target Flags 00198c94: 00000000 nop 00198c98: 30420002 andi r2,r2,0x0002 00198c9c: 10400006 beq r2,r0,0x00198cb8 <Status Checks> if doesn't have healing ability 00198ca0: 00001821 addu r3,r0,r0 No Priority if unit can heal itself (No low HP check)
<Low HP Unit?> 00198ca4: 92220007 lbu r2,0x0007(r17) Load AI Target State 00198ca8: 00000000 nop 00198cac: 30420001 andi r2,r2,0x0001 Get Low HP Flag 00198cb0: 00021023 subu r2,r0,r2 -1 if Low HP Flag, else 0 00198cb4: 30430072 andi r3,r2,0x0072 Low HP = 72 (7th Lowest)
<Status Checks> 00198cb8: 1460000f bne r3,r0,0x00198cf8 <Peril Score B> if low HP unit 00198cbc: 00031600 sll r2,r3,0x18 Status Score * 1000000
<Most usable abilities?> 00198cc0: 92220006 lbu r2,0x0006(r17) Load AI Target Flags 00198cc4: 00000000 nop 00198cc8: 30420004 andi r2,r2,0x0004 00198ccc: 14400015 bne r2,r0,0x00198d24 <Unit++> if unit has most usable abilities 00198cd0: 00000000 nop
<Acting Unit = Current Unit?> 00198cd4: 92820e2e lbu r2,0x0e2e(r20) Load Acting Unit ID 00198cd8: 00000000 nop 00198cdc: 14520002 bne r2,r18,0x00198ce8 <Peril Score A> if Acting Unit and Current Unit are the same unit 00198ce0: 00161a00 sll r3,r22,0x08` Ramza check * 100 = 300 (Ultimate Priority for AI) 00198ce4: 00009821 addu r19,r0,r0 Distance between targets is zero (same unit, duh)
<Peril Score A> (Non Statused Units) (Missing HP% * 10000) + (Ramza Check * 100) + Close Distance) 00198ce8: 00151400 sll r2,r21,0x10 Missing HP% (80 - curHP%) * 10000 00198cec: 00431021 addu r2,r2,r3 Missing HP% + Ramza Check * 100 00198cf0: 08066343 j 0x00198d0c 00198cf4: 00531821 addu r3,r2,r19 r3 = Missing HP% + Ramza Check + Distance
<Peril Score B> (Statused Unit) (Missing HP% * 100) + (State Check * 1000000) + (Close Distance * 10000) + Ramza) 00198cf8: 00131c00 sll r3,r19,0x10 Close Distance * 10000 00198cfc: 00431021 addu r2,r2,r3 Close Distance + State Check * 1000000 00198d00: 00151a00 sll r3,r21,0x08 Missing HP% * 100 00198d04: 00431021 addu r2,r2,r3 Close Distance + State Check + Missing HP% 00198d08: 00561821 addu r3,r2,r22 Close Distance + State Check + Missing HP% + Ramza Check
<Highest Peril Check> 00198d0c: 03c3102a slt r2,r30,r3 00198d10: 10400004 beq r2,r0,0x00198d24 <Unit++> if this unit is not the current most unit in peril 00198d14: 00000000 nop 00198d18: 8e8217f8 lw r2,0x17f8(r20) Load Acting Unit Data Pointer 00198d1c: 0060f021 addu r30,r3,r0 r30 = Highest Peril Score so far 00198d20: a05201b9 sb r18,0x01b9(r2) Current Unit that needs to be saved the most
<Unit++> 00198d24: 26520001 addiu r18,r18,0x0001 00198d28: 2a420015 slti r2,r18,0x0015 00198d2c: 1440ff8a bne r2,r0,0x00198b58 Do for all units 00198d30: 26f701c0 addiu r23,r23,0x01c0
<Peril Minimum> 00198d34: 8e840e34 lw r4,0x0e34(r20) Acting Unit's AI Decision Pointer 00198d38: 3c020200 lui r2,0x0200 00198d3c: 90830004 lbu r3,0x0004(r4) Load Range 00198d40: 005e102a slt r2,r2,r30 Set if Highest Peril Score > 0x02000000 00198d44: 306300f7 andi r3,r3,0x00f7 00198d48: a0830004 sb r3,0x0004(r4) Only look for units up to 7 range away
00198d4c: 8fbf0034 lw r31,0x0034(r29) 00198d50: 8fbe0030 lw r30,0x0030(r29) 00198d54: 8fb7002c lw r23,0x002c(r29) 00198d58: 8fb60028 lw r22,0x0028(r29) 00198d5c: 8fb50024 lw r21,0x0024(r29) 00198d60: 8fb40020 lw r20,0x0020(r29) 00198d64: 8fb3001c lw r19,0x001c(r29) 00198d68: 8fb20018 lw r18,0x0018(r29) 00198d6c: 8fb10014 lw r17,0x0014(r29) 00198d70: 8fb00010 lw r16,0x0010(r29) 00198d74: 27bd0038 addiu r29,r29,0x0038 00198d78: 03e00008 jr r31 00198d7c: 00000000 nop
Ideas to improve this routine: Rearrange the status priorities, removing Dead w/ Reraise. Remove the distance cap (Ideal)Make it aware of the death countdown timer and prioritizing based on that.