Apply status (to action)

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search

Note that this is also formula 38 (100% status). It's both a subroutine called by other formulas, and a formula in the formula table.

No Parameters - Returns Nothing

Update (preserves previous data) TCA status infliction bytes (0x1b to 0x1f) or removal bytes (0x20 to 0x24) See Notes for more details
 - Add or remove status present in current ability status infliction data (0x80193907 to 0x9019390b)
 - Check if Status added can be inflicted (ENTD, Immunities etc) or removed (Innate etc..)
If Something is inflicted : Update Target Current Action 0x25 : Attack Type with 0x08 flag (Status change)
If Nothing is inflcited : Forces Attack miss (doesn't mean the attack will realy miss, depends of the calling location )
If Target is going to be invited : Update TCA special flags 1 with 0x10 (switch team)
------------------------------------------------------------------------------------------------------------------------
00187f24: 3c038019 lui r3,0x8019            |
00187f28: 90633906 lbu r3,0x3906(r3)        |r3 = Current Ability Status infliction Type  (From Weapon or Ability)  0x80193906 / 80193906
00187f2c: 27bdff38 addiu r29,r29,-0x00c8    |
00187f30: afbf00c0 sw r31,0x00c0(r29)       |
00187f34: afb300bc sw r19,0x00bc(r29)       |
00187f38: afb200b8 sw r18,0x00b8(r29)       |
00187f3c: afb100b4 sw r17,0x00b4(r29)       |
00187f40: 30620020 andi r2,r3,0x0020        |r2 <> 0x00 if Infliction Type is separate
00187f44: 1040000b beq r2,r0,0x00187f74     #If Current Ability Status infliction Type is Separate
00187f48: afb000b0 sw r16,0x00b0(r29)           |
00187f4c: 3c048019 lui r4,0x8019                |
00187f50: 8c842d90 lw r4,0x2d90(r4)             |r4 = Target Current action (TCA) data pointer
00187f54: 00000000 nop                          |
00187f58: 8482002a lh r2,0x002a(r4)             |r2 = TCA Hit%
00187f5c: 00000000 nop                          |
00187f60: 04410002 bgez r2,0x00187f6c           #If TCA hit% < 0x00 (never)
00187f64: 00000000 nop                              |
00187f68: 24420003 addiu r2,r2,0x0003               |r2 = 0x03 (Force Hit% at a minimal positive value)
00187f6c: 00021083 sra r2,r2,0x02               |r2 = TCA Hit% / 4
00187f70: a482002a sh r2,0x002a(r4)             |Store maximum status accuracy as 25% of base Accuracy
00187f74: 30620060 andi r2,r3,0x0060        |r2 <> 0x00 if Infliction Type is Separate or Random
00187f78: 10400008 beq r2,r0,0x00187f9c     #If Current Ability Status infliction Type is Separate or Random
00187f7c: 30620080 andi r2,r3,0x0080        |r2 = 0x80 If infliction type is All or nothing
00187f80: 3c028019 lui r2,0x8019                |
00187f84: 8c42f5fc lw r2,-0x0a04(r2)            |r2 = Action State ( 0x8018f5fc)
00187f88: 00000000 nop                          |
00187f8c: 10400003 beq r2,r0,0x00187f9c         #If Action is not being executed (Action state <> 0x00)
00187f90: 30620080 andi r2,r3,0x80              |r2 = 0x80 If infliction type is All or nothing
00187f94: 34030080 ori r3,r0,0x0080                 |Modify Ability Status infliction Type enabling All or Nothing (probably for display/AI purpose)
00187f98: 30620080 andi r2,r3,0x0080                |r2 = 0x80 

--- ALL or NOTHING Infliction Type  section ---
00187f9c: 10400010 beq r2,r0,0x00187fe0     #If Current Ability Status infliction Type is All or Nothing /Else branch to Random check
00187fa0: 00008021 addu r16,r0,r0               |r16 = 0x00 (loop counter)
00187fa4: 3c038019 lui r3,0x8019                @ LOOP Through each status set  (Add every Status from Current Ability data in TCA status infliction set)
00187fa8: 8c632d90 lw r3,0x2d90(r3)                 |r3 = TCA data pointer
00187fac: 3c018019 lui r1,0x8019                    |
00187fb0: 00300821 addu r1,r1,r16                   |r1 = 0x80190000 + This iteration Status set offset (= loop counter)
00187fb4: 90243907 lbu r4,0x3907(r1)                |r4 = This iteration Current Ability Inflicted status set  from 0x80193907 to 0x8019390b
00187fb8: 00701821 addu r3,r3,r16                   |r1 = 0x80190000 + This iteration Status set offset (= loop counter)
00187fbc: 9062001b lbu r2,0x001b(r3)                |r2 = This iteration TCA status infliction set  from TCA 0x1b to TCA 0x1f
00187fc0: 26100001 addiu r16,r16,0x0001             |r16 = Counter + 1
00187fc4: 00441025 or r2,r2,r4                      |r2 = Status from current ability data  + Status already set in TCA inflication byte
00187fc8: a062001b sb r2,0x001b(r3)                 |Store updated Status to inflict in this iteration set
00187fcc: 2a020005 slti r2,r16,0x0005               |r2 = 0x01 if Counter < 0x05
00187fd0: 1440fff4 bne r2,r0,0x00187fa4         Λ  Loop While r2 = 0x01 (5 times)
00187fd4: 00002021 addu r4,r0,r0                |r4 = 0x00 (clear r4 for status confirmation section)
00187fd8: 08062070 j 0x001881c0                 >>Jump to Confirm Status Part
00187fdc: 00000000 nop                          |

--- RANDOM Infliction Type section ---
00187fe0: 30620040 andi r2,r3,0x0040        |r2 <> 0x00 If  Status infliction type is Random
00187fe4: 10400030 beq r2,r0,0x001880a8     #If Current Ability Status infliction Type is Random /Else branch to separate check
00187fe8: 00008821 addu r17,r0,r0               |r17 = 0x00 (Will be used as Status counter,  +1 each time a status is stored)
00187fec: 00008021 addu r16,r0,r0               |r16 = 0x00 (Loop counter)
00187ff0: 34050080 ori r5,r0,0x0080             |r5 = 0x80 (used as base value for status bitmask)
00187ff4: 27a40010 addiu r4,r29,0x0010          |r4 = stack + 0x10 (Inner routine Stack pointer - Used to store status)
                                                @LOOP - Through each status (40 iterations)
00187ff8: 06010002 bgez r16,0x00188004              #If r16 < 0x00
00187ffc: 02001021 addu r2,r16,r0                   |r2 = status global rank (= loop counter)
00188000: 26020007 addiu r2,r16,0x0007                  |r2 = 0x0007 + r16 (is <0) (never checked ? r16 always >= 0x00)
00188004: 000210c3 sra r2,r2,0x03                   |r2 = This iteration Status set (global rank / 8)  will be = 0x00 until loop counter >= 0x08 then = 0x01 (9th iteration = 1st status of 2nd set)
00188008: 3c018019 lui r1,0x8019                    |
0018800c: 00220821 addu r1,r1,r2                    |r1 = 8019000X  (X = this iteration status set offset)
00188010: 90233907 lbu r3,0x3907(r1)                |r3 = This iteration current ability Status infliction set 1
00188014: 32020007 andi r2,r16,0x0007               |r2 = This iteration status rank in his set (r2 is the remainder of loop counter /8)
00188018: 00451007 srav r2,r5,r2                    |r2 = This iteration status bitmask in his set (if 1st status of is set, r2 = 0x00, bitmask = 0x80 / is last, r2 = 0x07, bitmask = 0x01)
0018801c: 00621824 and r3,r3,r2                     |r3 <> 0x00 if this iteration status is in Ability infliction list
00188020: 10600004 beq r3,r0,0x00188034             # If This iteration Status is in Current Ability infliction set
00188024: 00000000 nop                                  |
00188028: ac900000 sw r16,0x0000(r4)                    |Store loop counter (= Status global rank) at Stack 0x10 
0018802c: 24840004 addiu r4,r4,0x0004                   |r4 = Stack pointer + 0x04 (offset for each stored status)
00188030: 26310001 addiu r17,r17,0x0001                 |r17 =Number of statuses stored + 1
00188034: 26100001 addiu r16,r16,0x0001             |r16 = Loop counter +1
00188038: 2a020028 slti r2,r16,0x0028               |r2 = 0x01 if loop counter < 0x28 (40 iterations)
0018803c: 1440ffee bne r2,r0,0x00187ff8         Λ Loop while loop counter < 0x28
00188040: 00000000 nop                              |
00188044: 0c063ba8 jal 0x0018eea0               |-->Random Process, gives a number between 0-7fff Returns r2 = Number between 0x00 and 0x7fff 
00188048: 00000000 nop                          |
0018804c: 00510018 mult r2,r17                  |Number of Status * Random
00188050: 00001012 mflo r2                      |r2 = Number of status in ability  infliction list * Random number
00188054: 04410002 bgez r2,0x00188060           # If r2 < 0
00188058: 00000000 nop                              |
0018805c: 24427fff addiu r2,r2,0x7fff               |r2 = r2 positive value 
00188060: 000213c3 sra r2,r2,0x0f               |r2 = Random between 0 and Number of inflicted status - 1   Nb of statuses * Random / (Max possible random +1)
00188064: 00021080 sll r2,r2,0x02               |r2 = Drawed status rank in Stack list (Status number * 0x04)
00188068: 03a21021 add r2,r29,r2                |r2 = Stack pointer
0018806c: 8c450010 lw r5,0x0010(r2)             |r5 = Drawed Status global rank
00188070: 3c028019 lui r2,0x8019                |
00188074: 8c422d90 lw r2,0x2d90(r2)             |r2 = TCA data pointer
00188078: 04a10002 bgez r5,0x00188084           # if drawed status rank is < 0x00 (never true)
0018807c: 00a02021 addu r4,r5,r0                |r4 = drawed status global rank
00188080: 24a40007 addiu r4,r5,0x0007               |r4 = r5 + 0x07
00188084: 000420c3 sra r4,r4,0x03               |r4 = Drawed Status set  (global rank / 8)
00188088: 00442021 addu r4,r2,r4                |r4 = TCA data pointer + Drawed Status set offset
0018808c: 30a50007 andi r5,r5,0x0007            |r5 = Drawed Status rank in his set (kind of remainder of global rank/8)
00188090: 34020080 ori r2,r0,0x0080             |r2 = 0x80 (used as base value for bitmask)
00188094: 9083001b lbu r3,0x001b(r4)            |r3 = Drawed Status TCA infliction set byte
00188098: 00a21007 srav r2,r2,r5                |r2 = Drawed Status bitmask
0018809c: 00621825 or r3,r3,r2                  |r3 = TCA Drawed Status infliction set enhanced with drawed status
001880a0: 0806206f j 0x001881bc                 >>Jump to confirm status part
001880a4: a083001b sb r3,0x001b(r4)             |Store Inflicted Status Enhanced with Drawed Status

--- SEPARATE Infliction Type section ---
001880a8: 30620020 andi r2,r3,0x0020        |r2 <> 0x00 if infliction type is separate 
001880ac: 10400033 beq r2,r0,0x0018817c     #If Current Ability Status infliction Type is Separate
001880b0: 00008021 addu r16,r0,r0               |r16 = 0x00 (Loop counter)
001880b4: 34130080 ori r19,r0,0x0080            |r19 = 0x80 (base value for bitmask)
                                            
001880b8: 06010002 bgez r16,0x001880c4              #If Loop counter < 0x00  (never)
001880bc: 02001021 addu r2,r16,r0                   |r2 = Status global rank (= loop counter)
001880c0: 26020007 addiu r2,r16,0x0007                  |r2 = r16 + 0x07 (never checked ?)
001880c4: 000288c3 sra r17,r2,0x03                  |r17 = This iteration Status set (global rank / 8)
001880c8: 3c018019 lui r1,0x8019                    |
001880cc: 00310821 addu r1,r1,r17                   |r1 = 0x801900X (X = this iteration status set offset)
001880d0: 90233907 lbu r3,0x3907(r1)                |r3 = This iteration Current Ability Status infliction set byte
001880d4: 32020007 andi r2,r16,0x0007               |r2 = This iteration status rank in his set (kind of remainder of global rank / 8)
001880d8: 00539007 srav r18,r19,r2                  |r18 = This iteration status bitmask
001880dc: 00721824 and r3,r3,r18                    |r3 <> 0x00 if this iteration status is in infliction list
001880e0: 10600012 beq r3,r0,0x0018812c             #If This iteration Status is in Current Ability infliction list
001880e4: 34040064 ori r4,r0,0x0064                     |r4 = 0x64 (100)
001880e8: 0c017833 jal 0x0005e0cc                       |-->Check if Random is greater/equal to Chance Returns r2 = 0x00 if Random < 25% (Status will be inflicted)
001880ec: 34050018 ori r5,r0,0x0018                     |r5 = 0x18 (25) - Separate = innate 25%
001880f0: 14400006 bne r2,r0,0x0018810c                 #If This iteration Status is going to be inflicted  / Else branch avoiding deleting section
001880f4: 34020002 ori r2,r0,0x0002                         |r2 = 0x02
001880f8: 3c038019 lui r3,0x8019                            |
001880fc: 8c63f5fc lw r3,-0x0a04(r3)                        |r3 = Action State (0x8018f5fc)
00188100: 00000000 nop                                      |
00188104: 14620009 bne r3,r2,0x0018812c                     #If Action State is a Preview (= 0x02)  Useless (see 0x00187f8c : if separate and action stats <> 0x00 routine is drive to all or nothing section)
00188108: 00000000 nop                                          |
0018810c: 3c018019 lui r1,0x8019                        #E      |
00188110: 00310821 addu r1,r1,r17                               |r1 = 0x801900X (X = this iteration status set offset)
00188114: 90223907 lbu r2,0x3907(r1)                            |r2 = This iteration Current Ability Status infliction set byte
00188118: 00000000 nop                                          |
0018811c: 00521026 xor r2,r2,r18                                |r2 = This iteration infliction byte deprived of this iteration status
00188120: 3c018019 lui r1,0x8019                                |
00188124: 00310821 addu r1,r1,r17                               |r1 = 0x801900X (X = this iteration status set offset)
00188128: a0223907 sb r2,0x3907(r1)                             |Store deprived Ability infliction set of this iteration status
0018812c: 26100001 addiu r16,r16,0x0001             |r16 = loop counter + 1
00188130: 2a020028 slti r2,r16,0x0028               |r2 = 0x01 if counter < 0x28
00188134: 1440ffe0 bne r2,r0,0x001880b8         Λ Loop while counter < 40 
00188138: 00000000 nop                              |
0018813c: 00008021 addu r16,r0,r0               |r16 = 0x00 (next loop counter)
00188140: 3c038019 lui r3,0x8019                @LOOP - though all status set
00188144: 8c632d90 lw r3,0x2d90(r3)                 |r3 = TCA data pointer
00188148: 3c018019 lui r1,0x8019                    |
0018814c: 00300821 addu r1,r1,r16                   |r1 = 0x801900X (X = this iteration status set offset)
00188150: 90243907 lbu r4,0x3907(r1)                |r4 = This iteration Current Ability infliction Set
00188154: 00701821 addu r3,r3,r16                   |r3 = TCA data pointer + this iteration set offset
00188158: 9062001b lbu r2,0x001b(r3)                |r2 = This iteration TCA Status infliction set byte
0018815c: 26100001 addiu r16,r16,0x0001             |r16 = loop counter + 1
00188160: 00441025 or r2,r2,r4                      |r2 = TCA status infliction byte enhanced with this iteration Ability Status infliction byte
00188164: a062001b sb r2,0x001b(r3)                 |Store This iteration enhanced TCA status infliction set byte
00188168: 2a020005 slti r2,r16,0x0005               |r2 = 0x01 if loop counter <0x05
0018816c: 1440fff4 bne r2,r0,0x00188140         Λ Loop 5 times
00188170: 00002021 addu r4,r0,r0                |r4 = 0x00 (clear r4 for status confirmation section)
00188174: 08062070 j 0x001881c0                 >>Jump to confirm Status part
00188178: 00000000 nop                          |

--- CANCEL status section ---
0018817c: 30620010 andi r2,r3,0x0010        |r2 <> 0x00 if infliction type is cancel
00188180: 1040000f beq r2,r0,0x001881c0     #If Current Ability Status infliction Type is Cancel
00188184: 00002021 addu r4,r0,r0            |r4 = 0x00
00188188: 3c038019 lui r3,0x8019            @ LOOP though all status set
0018818c: 8c632d90 lw r3,0x2d90(r3)             |r3 = TCA data pointer
00188190: 3c018019 lui r1,0x8019                |
00188194: 00300821 addu r1,r1,r16               |r1 = 0x801900X (X = this iteration status set offset)
00188198: 90243907 lbu r4,0x3907(r1)            |r4 = This iteration Current Ability Status infliction set byte
0018819c: 00701821 addu r3,r3,r16               |r3 = TCA data pointer + this iteration set offset
001881a0: 90620020 lbu r2,0x0020(r3)            |r2 = This iteration TCA status removal byte
001881a4: 26100001 addiu r16,r16,0x0001         |r16 = loop counter +1
001881a8: 00441025 or r2,r2,r4                  |r2 = This iteration TCA removal byte enhanced with current ability status infliction
001881ac: a0620020 sb r2,0x0020(r3)             |Store This iteration TCA removal byte enhanced with this iteration Current ability status inlfiction set
001881b0: 2a020005 slti r2,r16,0x0005           |r2 = 0x01 if loop counter < 0x05
001881b4: 1440fff4 bne r2,r0,0x00188188     Λ Loop 5 times
001881b8: 00000000 nop                          |
001881bc: 00002021 addu r4,r0,r0            |r4 = 0x00 (clear r4 for status confirmation section)  landing site from random section

--- CONFIRM STATUS INFLICTION/REMOVAL ---
001881c0: 00008021 addu r16,r0,r0           |r16 = 0x00 (loop counter)
001881c4: 3c058019 lui r5,0x8019            |
001881c8: 8ca52d90 lw r5,0x2d90(r5)         |r5 = TCA data pointer
001881cc: 00000000 nop                      @ LOOP thought each set of status (TCA infliction and TCA removal)
001881d0: 00b01021 addu r2,r5,r16               |r2 = 0x80190000 + loop counter (used as Status set offset) | r2 = TCADP + offset
001881d4: 9043001b lbu r3,0x001b(r2)            |r3 = This iteration TCA Status infliction byte  from TCA 0x1b to TCA 0x1f
001881d8: 90420020 lbu r2,0x0020(r2)            |r2 = This iteration TCA status removal byte   from TCA 0x20 to TCA 0x24
001881dc: 26100001 addiu r16,r16,0x0001         |r16 = r16 +1 (offset)
001881e0: 00621825 or r3,r3,r2                  |r3 <> 0x00 if at least one status is inflicted / removed in this iteration
001881e4: 2a020005 slti r2,r16,0x0005           |r2 = 0x01 if loop counter < 0x05
001881e8: 1440fff8 bne r2,r0,0x001881cc     Λ Loop while r2 = 1 (5 loops for each set of status)
001881ec: 00832025 or r4,r4,r3                  |r4 <> 0x00 if at least one status is inflicted/removed in any set (preserved while looping)
001881f0: 308200ff andi r2,r4,0x00ff        |r2 <> 0x00 if there's at least one status in TCA infliction/removal bytes
001881f4: 10400005 beq r2,r0,0x0018820c     # If something is going to be inflicted/removed /Else branch to Force Attack miss and exits routine
001881f8: 00000000 nop                          |
001881fc: 0c0612c9 jal 0x00184b24               |-->Validate Status Changes      Checks is statuses can be inflicted/removed (Innate/immunity etc…), returns r2 = 0x00 if nothing is inflicted/removed
00188200: 00002021 addu r4,r0,r0                |r4 = 0x00 (Force above routine to check TCA infliction and removal sets)
00188204: 14400005 bne r2,r0,0x0018821c         # If There's nothing left to inflict/remove
00188208: 00000000 nop                              |
0018820c: 0c0610c3 jal 0x0018430c           #E      | -->Force_Attack_Miss   TCA hit flag = 0x00, Evade type = 0x07, Hit% = 0%
00188210: 00000000 nop                              |
00188214: 0806209a j 0x00188268                     >>Jump to END
00188218: 00000000 nop                              |
0018821c: 3c028019 lui r2,0x8019            #Else (Something is going to be inflicted)
00188220: 8c422d90 lw r2,0x2d90(r2)         |r2 = TCA data pointer
00188224: 00000000 nop                      |
00188228: 90430025 lbu r3,0x0025(r2)        |r3 = TCA Attack Type
0018822c: 00000000 nop                      |
00188230: 34630008 ori r3,r3,0x0008         |r3 = TCA Attack type enhanced with Status change
00188234: a0430025 sb r3,0x0025(r2)         |Store enhanced Attack type
00188238: 3c038019 lui r3,0x8019            |
0018823c: 8c632d90 lw r3,0x2d90(r3)         |r3 = TCA data pointer
00188240: 00000000 nop                      |
00188244: 9062001c lbu r2,0x001c(r3)        |r2 = TCA status infliction set 2
00188248: 00000000 nop                      |
0018824c: 30420040 andi r2,r2,0x0040        |r2 = 0x40 if invite is inflicted - Else 0x00
00188250: 10400005 beq r2,r0,0x00188268     # If target is invited 
00188254: 00000000 nop                          |
00188258: 94620010 lhu r2,0x0010(r3)            |r2 = TCA special flags 1 and 2
0018825c: 00000000 nop                          |
00188260: 34420040 ori r2,r2,0x0040             |r2 = TCA special flags enhanced with switch team
00188264: a4620010 sh r2,0x0010(r3)             |Store enhanced specials flags (+ switch team)
00188268: 8fbf00c0 lw r31,0x00c0(r29)       END
0018826c: 8fb300bc lw r19,0x00bc(r29)       
00188270: 8fb200b8 lw r18,0x00b8(r29)       
00188274: 8fb100b4 lw r17,0x00b4(r29)       
00188278: 8fb000b0 lw r16,0x00b0(r29)       
0018827c: 27bd00c8 addiu r29,r29,0x00c8     
00188280: 03e00008 jr r31                   
00188284: 00000000 nop                      

Notes

Inflict Statuses  from Current Ability status infliction (0x80193907 to 0x8019390b)
There's an action state check (0x8018f5fc), if <> 0x00 (not being executed), Infliction Type is forced to All or Nothing (for display purpose i guess)

Infliction depends of Current ability infliction type :
 - All or nothing : all statuses in the list will be inflicted
 - Random : One status of the list is drawed then inflicted
 - Separate : Each status has 25% chances of being inflicted (could end with no infliction)
              In facts : statuses not drawed are deleted from the infliction list
 - Cancel : all statuses from the list will be canceled
 

Once the Status infliction/removal sets are updated, check if the modifications are allowed (Status, ENTD flags, immunities)
Non-inflictable/removable statuses will be deleted from the TCA infliction/removal bytes. See Validate Status Changes

If Nothing is Inflicted/Removed Call Force_Attack_Miss 
Note that is this routine is called from a routine that is preserving TCA Hit flag and Hit%, the Action will not miss (only the status infliction will)

Return locations

Battle.bin
00186ac0: Song_abilities
00186bcc: Dance_abilities
00186cd8: Talk_Skill
00187ee4: Apply_status_(to_action)_-_(Preserve_hit_status,_evade_type,_hit_%)
00188ea8: 0A_Hit_F(MA+X)%
00188ee8: 0B_Hit_F(MA+X)%
0018966c: 22_Hit_(100%)_Status
00189994: 29_OppositeSex:_Hit_(MA+X)%
00189e84: 33_Hit_(PA+X)%
00189ffc: 3D_Hit_(MA+X)%
0018a078: 3F_Hit_(SP+X)%
0018a104: 40_Undead:_Hit_(SP+X)%
0018a16c: 41_Hit_(MA+X)%
0018a4d8: 50_Hit_(MA+X)%
0018a544: 51_Hit_(MA+X)%
0018a7fc: 57_+Lvl(1)_NS_100%_Add_Status_on_Caster
0018a9b4: 5A_Dragon:_Hit(100)%
0018b97c: Pre_Formula_Setup_(FDC) - Formula 38 return location (called with jalr)