Get Unit Skillset Ability Data

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search
#   ROUTINE: Get Unit Skillset Ability Data
#       Returns ability data for a specified unit and skillset into a handful of output lists (parallel arrays) and returns the number of abilities.
#       Parameters:
#           r4              = (unitIndex)           In-battle unit index
#           r5              = (skillsetID)          Skillset ID
#           r6              = (abilityIDList)       Output list (Ability ID)
#           r7              = (abilityMPCostList)   Output list (Ability MP Cost)
#           *(sp + 0x10)    = (abilityCTList)       Output list (Ability CT)
#           *(sp + 0x14)    = (unusedOption)        Unused value (never referenced)  (Calling routines always pass 0 or 1)
#           *(sp + 0x18)    = (abilityFlags)        Output list (Ability Flags - Silence and persevere?)
#           *(sp + 0x1c)    = (abilityTurns)        Output list (Ability Turns - Number of turns until ability goes off)
#       Returns:
#           r2 = Number of abilities for unit in skillset

801817c0: 27bdfed0 addiu r29,r29,-0x0130
801817c4: afa400b0 sw r4,0x00b0(r29)                #   unitIndex
801817c8: 8fa400b0 lw r4,0x00b0(r29)
801817cc: afb40118 sw r20,0x0118(r29)
801817d0: 8fb40140 lw r20,0x0140(r29)               #   abilityCTList
801817d4: afb20110 sw r18,0x0110(r29)
801817d8: 8fb20148 lw r18,0x0148(r29)               #   abilityFlags
801817dc: afb1010c sw r17,0x010c(r29)
801817e0: 8fb1014c lw r17,0x014c(r29)               #   abilityTurns
801817e4: afbe0128 sw r30,0x0128(r29)
801817e8: 0000f021 addu r30,r0,r0                   #   abilityIndex = 0
801817ec: afbf012c sw r31,0x012c(r29)
801817f0: afb70124 sw r23,0x0124(r29)
801817f4: afb60120 sw r22,0x0120(r29)
801817f8: afb5011c sw r21,0x011c(r29)
801817fc: afb30114 sw r19,0x0114(r29)
80181800: afb00108 sw r16,0x0108(r29)
80181804: afa600c0 sw r6,0x00c0(r29)                #   &abilityIDList[0]
80181808: afa000e0 sw r0,0x00e0(r29)                #   hasMateriaBladeEquipped = false
8018180c: afa000e8 sw r0,0x00e8(r29)                #   hasSwordEquipped = false
80181810: afa000f0 sw r0,0x00f0(r29)                #   chargeValue = 0                 // 2 = Non-charge, 1 = Short Charge, 0 = neither
80181814: afa000f8 sw r0,0x00f8(r29)                #   isHalfMP = false
80181818: afa00100 sw r0,0x0100(r29)                #   isFrog = false
8018181c: afa700c8 sw r7,0x00c8(r29)                #   abilityMPCostList
80181820: 0c060435 jal 0x801810d4                   #   unit = Get Existent Battle Unit Pointer (unitIndex);
80181824: a3a500b8 sb r5,0x00b8(r29)                #   skillsetID
80181828: 00408021 addu r16,r2,r0                   #   unit
8018182c: 120000c3 beq r16,r0,0x80181b3c            #   if (unit == null) return 0;
80181830: 00001021 addu r2,r0,r0
80181834: 9202005a lbu r2,0x005a(r16)               #   unit.CurrentStatuses3
80181838: 00000000 nop
8018183c: 30420002 andi r2,r2,0x0002
80181840: 10400003 beq r2,r0,0x80181850             #   if (unit.CurrentStatuses3 & STATUS_FROG) {
80181844: 00000000 nop
80181848: 34090001 ori r9,r0,0x0001
8018184c: afa90100 sw r9,0x0100(r29)                #       isFrog = true
                                                    #   }
80181850: 92020090 lbu r2,0x0090(r16)               #   unit.Support2
80181854: 00000000 nop
80181858: 30420080 andi r2,r2,0x0080                
8018185c: 10400003 beq r2,r0,0x8018186c             #   if (unit.Support2 & SUPPORT_HALF_OF_MP) {
80181860: 00000000 nop
80181864: 34080001 ori r8,r0,0x0001
80181868: afa800f8 sw r8,0x00f8(r29)                #       isHalfMP = true
                                                    #   }
8018186c: 92030092 lbu r3,0x0092(r16)               #   unit.Support4
80181870: 00000000 nop
80181874: 30620004 andi r2,r3,0x0004                
80181878: 10400003 beq r2,r0,0x80181888
8018187c: 34090002 ori r9,r0,0x0002
                                                    #   if (unit.Support4 & SUPPORT_NON_CHARGE) {
80181880: 08060626 j 0x80181898
80181884: afa900f0 sw r9,0x00f0(r29)                #       chargeValue = 2
                                                    #   }
80181888: 30620008 andi r2,r3,0x0008
8018188c: 10400002 beq r2,r0,0x80181898             #   else if (unit.Support4 & SUPPORT_SHORT_CHARGE) {
80181890: 34080001 ori r8,r0,0x0001
80181894: afa800f0 sw r8,0x00f0(r29)                #       chargeValue = 1
                                                    #   }
80181898: 27a40010 addiu r4,r29,0x0010
8018189c: 0c060dc3 jal 0x8018370c                   #   Calculate AT List (localATList, 0);
801818a0: 00002821 addu r5,r0,r0
801818a4: 92030184 lbu r3,0x0184(r16)               #   unit.EquippedFlags
801818a8: 00000000 nop
801818ac: 30620004 andi r2,r3,0x0004                
801818b0: 10400003 beq r2,r0,0x801818c0
801818b4: 30620008 andi r2,r3,0x0008
                                                    #   if (unit.EquippedFlags & EQUIPPED_MATERIA_BLADE) {
801818b8: 34090001 ori r9,r0,0x0001
801818bc: afa900e0 sw r9,0x00e0(r29)                #       hasMateriaBladeEquipped = true
                                                    #   }
801818c0: 10400003 beq r2,r0,0x801818d0             #   if (unit.EquippedFlags & EQUIPPED_SWORD) {
801818c4: 00000000 nop
801818c8: 34080001 ori r8,r0,0x0001
801818cc: afa800e8 sw r8,0x00e8(r29)                #       hasSwordEquipped = true
                                                    #   }
801818d0: 92020006 lbu r2,0x0006(r16)               #   unit.Flags
801818d4: 00000000 nop
801818d8: 30420020 andi r2,r2,0x0020                
801818dc: 14400016 bne r2,r0,0x80181938             #   if ((unit.Flags & FLAGS_MONSTER) == 0) {        // If human, not monster
801818e0: 00000000 nop
801818e4: 93a900b8 lbu r9,0x00b8(r29)               #       skillsetID
801818e8: 00000000 nop
801818ec: 2522fffb addiu r2,r9,-0x0005              #       skillsetID - 5
801818f0: 304200ff andi r2,r2,0x00ff
801818f4: 2c420013 sltiu r2,r2,0x0013
801818f8: 10400004 beq r2,r0,0x8018190c             #       if ((skillsetID - 5) < 0x13) {              // If skillset ID is between 0x05 and 0x17, inclusive (generic skillset, excluding Mime)
801818fc: 00000000 nop
80181900: 93a200b8 lbu r2,0x00b8(r29)               #           skillsetID
80181904: 0806064f j 0x8018193c
80181908: 2445fffb addiu r5,r2,-0x0005              #           unitSkillsetIndex = skillsetID - 5
                                                    #       } else {
8018190c: 92020012 lbu r2,0x0012(r16)               #           unit.PrimarySkillset
80181910: 93a300b8 lbu r3,0x00b8(r29)               #           skillsetID
80181914: 00000000 nop
80181918: 10620005 beq r3,r2,0x80181930
8018191c: 00002821 addu r5,r0,r0                    #           unitSkillsetIndex = 0
                                                    #           if (skillsetID != unit.PrimarySkillset) {
80181920: 92020162 lbu r2,0x0162(r16)               #               unit.SpecialSkillset
80181924: 00000000 nop
80181928: 14620003 bne r3,r2,0x80181938             #               if (skillsetID != unit.SpecialSkillset)
8018192c: 00000000 nop                              #                   unitSkillsetIndex = -1
                                                    #           }
80181930: 08060650 j 0x80181940
80181934: 2402ffff addiu r2,r0,-0x0001
                                                    #       }
                                                    #   } else {
80181938: 2405ffff addiu r5,r0,-0x0001              #       unitSkillsetIndex = -1
8018193c: 2402ffff addiu r2,r0,-0x0001
                                                    #   }
80181940: 14a20004 bne r5,r2,0x80181954             #   if (unitSkillsetIndex == -1) {       
80181944: 3c0800ff lui r8,0x00ff                    #       //  Either ((unit is a monster) 
80181948: 3508ffff ori r8,r8,0xffff                 #       //      or (skillsetID is not between 0x05 and 0x18 and not set as the primary or special skillset))...
8018194c: 08060658 j 0x80181960                     
80181950: afa800d0 sw r8,0x00d0(r29)                #       knownAbilityFlags = 0xffffff        // All abilities learned
                                                    #   } else {
80181954: 0c017880 jal 0x8005e200                  
80181958: 02002021 addu r4,r16,r0
8018195c: afa200d0 sw r2,0x00d0(r29)                #       knownAbilityFlags = Get Known Abilities (unit, unitSkillsetIndex);
                                                    #   }
80181960: 00009821 addu r19,r0,r0                   #   abilitySlotIndex = 0
80181964: 03d1b821 addu r23,r30,r17                 #   abilityTurns[abilitySlotIndex]
80181968: 03d2b021 addu r22,r30,r18                 #   abilityFlags[abilitySlotIndex]
8018196c: 8fa900c8 lw r9,0x00c8(r29)                #   abilityMPCostList
80181970: 03d4a821 addu r21,r30,r20                 #   abilityCTList[abilitySlotIndex]
80181974: 03c9a021 addu r20,r30,r9                  #   abilityMPCostList[abilitySlotIndex]
80181978: 3c020080 lui r2,0x0080
                                                    #   for (; abilitySlotIndex < 16; abilitySlotIndex++) {
8018197c: 8fa800d0 lw r8,0x00d0(r29)                #       knownAbilityFlags
80181980: 02621007 srav r2,r2,r19                   #       0x800000 >> abilitySlotIndex
80181984: 01021024 and r2,r8,r2                     
80181988: 10400064 beq r2,r0,0x80181b1c             #       if ((knownAbilityFlags & (0x800000 >> abilitySlotIndex)) == 0) continue;
8018198c: 00000000 nop
80181990: 93a400b8 lbu r4,0x00b8(r29)
80181994: 0c01695a jal 0x8005a568                   #       abilityID = Get Ability ID From Skillset (skillsetID, abilitySlotIndex);
80181998: 02602821 addu r5,r19,r0
8018199c: 8fa90100 lw r9,0x0100(r29)                #       isFrog
801819a0: 00402021 addu r4,r2,r0                    #       abilityID
801819a4: 11200006 beq r9,r0,0x801819c0
801819a8: a7a400d8 sh r4,0x00d8(r29)                #       abilityID
                                                    #       if (isFrog) {
801819ac: 00041400 sll r2,r4,0x10
801819b0: 00021403 sra r2,r2,0x10                   #           abilityID
801819b4: 3403001d ori r3,r0,0x001d
801819b8: 14430058 bne r2,r3,0x80181b1c             #           if (abilityID != 0x1d) continue;    // Frog
801819bc: 00000000 nop                              #       }
801819c0: 00041400 sll r2,r4,0x10
801819c4: 00021c03 sra r3,r2,0x10                   #       abilityID
801819c8: 10600054 beq r3,r0,0x80181b1c             #       if (abilityID == 0) continue;
801819cc: 2482ffff addiu r2,r4,-0x0001              #       abilityID - 1
801819d0: 3042ffff andi r2,r2,0xffff
801819d4: 2c42016f sltiu r2,r2,0x016f
801819d8: 10400036 beq r2,r0,0x80181ab4             #       if ((abilityID - 1) < 0x016f) {         // Ability ID is in range [1, 0x16f] - Normal ability, not Attack
801819dc: 000310c0 sll r2,r3,0x03
801819e0: 00431023 subu r2,r2,r3
801819e4: 00021040 sll r2,r2,0x01
801819e8: 3c038006 lui r3,0x8006
801819ec: 2463fbf0 addiu r3,r3,-0x0410
801819f0: 00432021 addu r4,r2,r3                    #           abilityData[abilityID]
801819f4: 90830006 lbu r3,0x0006(r4)                #           abilityData[abilityID].Flags4
801819f8: 00000000 nop
801819fc: 30620008 andi r2,r3,0x0008
80181a00: 10400005 beq r2,r0,0x80181a18             #           if (abilityData[abilityID].Flags4 & FLAGS_REQUIRES_SWORD) {
80181a04: 00000000 nop
80181a08: 8fa800e8 lw r8,0x00e8(r29)                #               hasSwordEquipped
80181a0c: 00000000 nop
80181a10: 11000042 beq r8,r0,0x80181b1c             #               if (!hasSwordEquipped) continue;
80181a14: 00000000 nop                              #           }
80181a18: 30620004 andi r2,r3,0x0004
80181a1c: 10400005 beq r2,r0,0x80181a34             #           if (abilityData[abilityID].Flags4 & FLAGS_REQUIRES_MATERIA_BLADE) {
80181a20: 00000000 nop
80181a24: 8fa900e0 lw r9,0x00e0(r29)                #               hasMateriaBladeEquipped
80181a28: 00000000 nop
80181a2c: 1120003b beq r9,r0,0x80181b1c             #               if (!hasMateriaBladeEquipped) continue;
80181a30: 00000000 nop                              #           }
80181a34: 8fa800f8 lw r8,0x00f8(r29)                #           isHalfMP
80181a38: 9091000d lbu r17,0x000d(r4)               #           MPCost = abilityData[abilityID].MPCost
80181a3c: 11000002 beq r8,r0,0x80181a48
80181a40: 26220001 addiu r2,r17,0x0001              #           abilityData[abilityID].MPCost + 1
                                                    #           if (isHalfMP) {
80181a44: 00028843 sra r17,r2,0x01                  #               MPCost = (abilityData[abilityID].MPCost + 1) / 2
                                                    #           }
80181a48: 9082000c lbu r2,0x000c(r4)                #           abilityData[abilityID].CT 
80181a4c: 90830005 lbu r3,0x0005(r4)                #           abilityData[abilityID].Flags3
80181a50: 3050007f andi r16,r2,0x007f               #           CT = abilityData[abilityID].CT & 0x7f
80181a54: 000321c2 srl r4,r3,0x07                   #           isReflectable = abilityData[abilityID].Flags3 >> 7      // (0x01 or 0x00)
80181a58: 30620020 andi r2,r3,0x0020                #           abilityData[abilityID].Flags3 & FLAGS_AFFECTED_BY_SILENCE
80181a5c: 00021102 srl r2,r2,0x04                   #           isAffectedBySilence = (abilityData[abilityID].Flags3 & FLAGS_AFFECTED_BY_SILENCE) >> 4  // (0x02 or 0x00)
80181a60: 30630004 andi r3,r3,0x0004                #           abilityData[abilityID].Flags3 & FLAGS_PERFORMING
80181a64: 1460000b bne r3,r0,0x80181a94
80181a68: 00829025 or r18,r4,r2                     #           flags = isReflectable | isAffectedBySilence
                                                    #           if ((abilityData[abilityID].Flags3 & FLAGS_PERFORMING) == 0) {
80181a6c: 8fa900f0 lw r9,0x00f0(r29)                #               chargeValue
80181a70: 34020001 ori r2,r0,0x0001
80181a74: 15220002 bne r9,r2,0x80181a80             #               if (chargeValue == 1) {     // Short Charge
80181a78: 26020001 addiu r2,r16,0x0001              #                   CT + 1
80181a7c: 00028043 sra r16,r2,0x01                  #                   CT = (CT + 1) / 2
                                                    #               }
80181a80: 8fa800f0 lw r8,0x00f0(r29)                #               chargeValue
80181a84: 34020002 ori r2,r0,0x0002
80181a88: 15020003 bne r8,r2,0x80181a98             
80181a8c: 02002821 addu r5,r16,r0
                                                    #               if (chargeValue == 2) {     // Non-charge
80181a90: 00008021 addu r16,r0,r0                   #                   CT = 0
                                                    #               }
                                                    #           }
80181a94: 02002821 addu r5,r16,r0
80181a98: 8fa400b0 lw r4,0x00b0(r29)
80181a9c: 0c0605c8 jal 0x80181720                   #           numTurns = Get Number of Turns to Resolve (unitIndex, CT, localATList);
80181aa0: 27a60010 addiu r6,r29,0x0010
80181aa4: a2910000 sb r17,0x0000(r20)               #           abilityMPCostList[abilityIndex] = MPCost
80181aa8: a2b00000 sb r16,0x0000(r21)               #           abilityCTList[abilityIndex] = CT
80181aac: 080606bc j 0x80181af0
80181ab0: a2d20000 sb r18,0x0000(r22)               #           abilityFlags[abilityIndex] = flags; abilityTurns[abilityIndex] = numTurns;
                                                    #       } else {
80181ab4: 2482fe6a addiu r2,r4,-0x0196
80181ab8: 3042ffff andi r2,r2,0xffff
80181abc: 2c420008 sltiu r2,r2,0x0008
80181ac0: 1040000c beq r2,r0,0x80181af4             #           if ((abilityID - 0x0196) < 8) {     // 0x0x196 to 0x019D - Charge abilities
80181ac4: 00031040 sll r2,r3,0x01
80181ac8: 27a60010 addiu r6,r29,0x0010
80181acc: 3c018006 lui r1,0x8006
80181ad0: 00220821 addu r1,r1,r2
80181ad4: 90300d18 lbu r16,0x0d18(r1)               #               CT = chargeAbilityData[abilityID - 0x0196].CT
80181ad8: 8fa400b0 lw r4,0x00b0(r29)
80181adc: 0c0605c8 jal 0x80181720                   #               numTurns = Get Number of Turns to Resolve (unitIndex, CT, localATList);
80181ae0: 02002821 addu r5,r16,r0
80181ae4: a2800000 sb r0,0x0000(r20)                #               abilityMPCostList[abilityIndex] = 0
80181ae8: a2b00000 sb r16,0x0000(r21)               #               abilityCTList[abilityIndex] = CT
80181aec: a2c00000 sb r0,0x0000(r22)                #               abilityFlags[abilityIndex] = 0
80181af0: a2e20000 sb r2,0x0000(r23)                #               abilityTurns[abilityIndex] = numTurns
                                                    #           }
                                                    #       }
80181af4: 26f70001 addiu r23,r23,0x0001             #       (abilityTurns[abilityIndex])
80181af8: 26d60001 addiu r22,r22,0x0001             #       (abilityFlags[abilityIndex])
80181afc: 26b50001 addiu r21,r21,0x0001             #       (abilityCTList[abilityIndex])
80181b00: 26940001 addiu r20,r20,0x0001             #       (abilityMPCostList[abilityIndex])
80181b04: 97a800d8 lhu r8,0x00d8(r29)               #       abilityID
80181b08: 8fa900c0 lw r9,0x00c0(r29)                #       storeAbilityPtr = &abilityIDList[abilityIndex]
80181b0c: 27de0001 addiu r30,r30,0x0001             #       abilityIndex = abilityIndex + 1
80181b10: a5280000 sh r8,0x0000(r9)                 #       *storeAbilityPtr = abilityID
80181b14: 25290002 addiu r9,r9,0x0002
80181b18: afa900c0 sw r9,0x00c0(r29)                #       &abilityIDList[abilityIndex]
80181b1c: 26730001 addiu r19,r19,0x0001             #       // (abilitySlotIndex = abilitySlotIndex + 1)
80181b20: 2a620010 slti r2,r19,0x0010
80181b24: 1440ff95 bne r2,r0,0x8018197c
80181b28: 3c020080 lui r2,0x0080
                                                    #   }
80181b2c: 8fa900c0 lw r9,0x00c0(r29)                #   &abilityIDList[abilityIndex]
80181b30: 2402ffff addiu r2,r0,-0x0001
80181b34: a5220000 sh r2,0x0000(r9)                 #   abilityIDList[abilityIndex] = -1
80181b38: 03c01021 addu r2,r30,r0                   #   return abilityIndex;
80181b3c: 8fbf012c lw r31,0x012c(r29)
80181b40: 8fbe0128 lw r30,0x0128(r29)
80181b44: 8fb70124 lw r23,0x0124(r29)
80181b48: 8fb60120 lw r22,0x0120(r29)
80181b4c: 8fb5011c lw r21,0x011c(r29)
80181b50: 8fb40118 lw r20,0x0118(r29)
80181b54: 8fb30114 lw r19,0x0114(r29)
80181b58: 8fb20110 lw r18,0x0110(r29)
80181b5c: 8fb1010c lw r17,0x010c(r29)
80181b60: 8fb00108 lw r16,0x0108(r29)
80181b64: 27bd0130 addiu r29,r29,0x0130
80181b68: 03e00008 jr r31
80181b6c: 00000000 nop