Learn Job Abilities
Jump to navigation
Jump to search
# ROUTINE: LEARN JOB ABILITIES # Learns abilities for the specified unit in the specified job. Either learns random abilities, or auto-learns all abiliies in the appropriate skillset. # Parameters: # r4 = (unit) Unit in-battle data pointer # r5 = (jobID) Job ID, where 0x4A (Squire) symbolizes base job, even if non-generic # r6 = (entdUnit) ENTD Unit pointer 8005ce74: 27bdffd0 addiu r29,r29,-0x0030 8005ce78: 00804021 addu r8,r4,r0 # unit 8005ce7c: 00a03821 addu r7,r5,r0 # jobID 8005ce80: afb60028 sw r22,0x0028(r29) 8005ce84: 0000b021 addu r22,r0,r0 # isAutoLearn = false 8005ce88: 24e9ffb6 addiu r9,r7,-0x004a # jobIndex = jobID - 0x4a 8005ce8c: 3402004a ori r2,r0,0x004a # 0x4a (Squire) 8005ce90: afbf002c sw r31,0x002c(r29) 8005ce94: afb50024 sw r21,0x0024(r29) 8005ce98: afb40020 sw r20,0x0020(r29) 8005ce9c: afb3001c sw r19,0x001c(r29) 8005cea0: afb20018 sw r18,0x0018(r29) 8005cea4: afb10014 sw r17,0x0014(r29) 8005cea8: 14e20011 bne r7,r2,0x8005cef0 # if (jobID == 0x4a) { // Base job 8005ceac: afb00010 sw r16,0x0010(r29) 8005ceb0: 91030000 lbu r3,0x0000(r8) # unit.baseClass 8005ceb4: 00000000 nop 8005ceb8: 2462ff80 addiu r2,r3,-0x0080 # unit.baseClass - 0x80 8005cebc: 304200ff andi r2,r2,0x00ff 8005cec0: 2c420002 sltiu r2,r2,0x0002 8005cec4: 14400016 bne r2,r0,0x8005cf20 # if ((unit.baseClass < 0x80) || (unit.baseClass > 0x81)) { // Not generic human 8005cec8: 306300ff andi r3,r3,0x00ff 8005cecc: 34020082 ori r2,r0,0x0082 8005ced0: 14620004 bne r3,r2,0x8005cee4 # if (unit.baseClass == 0x82) { // Generic monster 8005ced4: 00000000 nop 8005ced8: 91070003 lbu r7,0x0003(r8) # jobID = unit.jobID 8005cedc: 080173c8 j 0x8005cf20 # } else { // Special character 8005cee0: 00000000 nop 8005cee4: 91070000 lbu r7,0x0000(r8) # jobID = unit.baseClass 8005cee8: 080173c8 j 0x8005cf20 # } 8005ceec: 00000000 nop # } # } else { 8005cef0: 3c020080 lui r2,0x0080 # 0x800000 8005cef4: 01228007 srav r16,r2,r9 # jobUnlockedMask = 0x800000 >> jobIndex 8005cef8: 91020096 lbu r2,0x0096(r8) # unit.jobsUnlocked1 8005cefc: 91030097 lbu r3,0x0097(r8) # unit.jobsUnlocked2 8005cf00: 91040098 lbu r4,0x0098(r8) # unit.jobsUnlocked3 8005cf04: 00021400 sll r2,r2,0x10 # unit.jobsUnlocked1 << 16 8005cf08: 00031a00 sll r3,r3,0x08 # unit.jobsUnlocked2 << 8 8005cf0c: 00431021 addu r2,r2,r3 # (unit.jobsUnlocked1 << 16) + (unit.jobsUnlocked2 << 8) 8005cf10: 00442821 addu r5,r2,r4 # jobsUnlocked = (unit.jobsUnlocked1 << 16) + (unit.jobsUnlocked2 << 8) + unit.jobsUnlocked3 8005cf14: 00b01024 and r2,r5,r16 # isJobUnlocked = jobsUnlocked & jobUnlockedMask 8005cf18: 1040005d beq r2,r0,0x8005d090 # if (!isJobUnlocked) return; // Exit the routine if the job is not unlocked 8005cf1c: 00000000 nop # } 8005cf20: 91030006 lbu r3,0x0006(r8) # unit.Flags 8005cf24: 3402005b ori r2,r0,0x005b 8005cf28: 14e20004 bne r7,r2,0x8005cf3c # if ((jobID == 0x5b) // Bard 8005cf2c: 3402005c ori r2,r0,0x005c 8005cf30: 30620040 andi r2,r3,0x0040 # && (unit.Flags & UNIT_FLAG_FEMALE)) 8005cf34: 14400056 bne r2,r0,0x8005d090 # return; 8005cf38: 3402005c ori r2,r0,0x005c 8005cf3c: 14e20003 bne r7,r2,0x8005cf4c # if ((jobID == 0x5c) // Dancer 8005cf40: 30620080 andi r2,r3,0x0080 # && (unit.Flags & UNIT_FLAG_MALE)) 8005cf44: 14400052 bne r2,r0,0x8005d090 # return; 8005cf48: 00000000 nop 8005cf4c: 91020003 lbu r2,0x0003(r8) # unit.jobID 8005cf50: 00000000 nop 8005cf54: 14e20007 bne r7,r2,0x8005cf74 8005cf58: 00071040 sll r2,r7,0x01 # jobID * 2 # abilityIndex = 0 # if (unit.jobID == jobID) { 8005cf5c: 90c2001d lbu r2,0x001d(r6) # entdUnit.primarySkillset 8005cf60: 91150012 lbu r21,0x0012(r8) # skillset = unit.primarySkillset 8005cf64: 1440000a bne r2,r0,0x8005cf90 # if (entdUnit.primarySkillset == 0) { 8005cf68: 00008021 addu r16,r0,r0 8005cf6c: 080173e4 j 0x8005cf90 8005cf70: 34160001 ori r22,r0,0x0001 # isAutoLearn = true # } # } else { 8005cf74: 00471021 addu r2,r2,r7 # jobID * 3 8005cf78: 3c038006 lui r3,0x8006 8005cf7c: 8c636194 lw r3,0x6194(r3) # jobs 8005cf80: 00021100 sll r2,r2,0x04 # jobID * 48 8005cf84: 00431021 addu r2,r2,r3 # jobs[jobID] // sizeof(Job) == 48 8005cf88: 90550000 lbu r21,0x0000(r2) # skillset = jobs[jobID].skillset 8005cf8c: 00008021 addu r16,r0,r0 # } 8005cf90: 00091040 sll r2,r9,0x01 # jobIndex * 2 8005cf94: 00489821 addu r19,r2,r8 # (unit + (jobIndex * 2)) 8005cf98: 00491021 addu r2,r2,r9 # jobIndex * 3 8005cf9c: 00481021 addu r2,r2,r8 # (unit + (jobIndex * 3)) 8005cfa0: 24540099 addiu r20,r2,0x0099 # (unit + (jobIndex * 3)) + 0x99 8005cfa4: 00009021 addu r18,r0,r0 # isAbilityLearned = false # do { // Loop through abilities in skillset # isAbilityLearned = false 8005cfa8: 02a02021 addu r4,r21,r0 8005cfac: 0c01695a jal 0x8005a568 # abilityID = Get Ability ID From Skillset (skillset, abilityIndex); 8005cfb0: 02002821 addu r5,r16,r0 8005cfb4: 3042ffff andi r2,r2,0xffff 8005cfb8: 10400031 beq r2,r0,0x8005d080 # if (abilityID != 0) { 8005cfbc: 000218c0 sll r3,r2,0x03 # abilityID * 8 8005cfc0: 3c028006 lui r2,0x8006 8005cfc4: 2442ebf0 addiu r2,r2,-0x1410 # abilities 8005cfc8: 00628821 addu r17,r3,r2 # abilities[abilityIndex] 8005cfcc: 92250002 lbu r5,0x0002(r17) # abilities[abilityIndex].chanceToLearn 8005cfd0: 12c00003 beq r22,r0,0x8005cfe0 # if (isAutoLearn) { 8005cfd4: 00000000 nop 8005cfd8: 08017412 j 0x8005d048 8005cfdc: 34120001 ori r18,r0,0x0001 # isAbilityLearned = true # } else { 8005cfe0: 0c017833 jal 0x8005e0cc # isFail = Pass/Fail Roll (100, abilities[abilityIndex].chanceToLearn); 8005cfe4: 34040064 ori r4,r0,0x0064 8005cfe8: 14400017 bne r2,r0,0x8005d048 # if (!isFail) { // Roll succeeds 8005cfec: 00000000 nop 8005cff0: 96230000 lhu r3,0x0000(r17) # abilities[abilityIndex].jpCost 8005cff4: 966200dc lhu r2,0x00dc(r19) # jobJP = *(&unit.baseJobJP + (jobIndex * 2)) 8005cff8: 00000000 nop 8005cffc: 0043102b sltu r2,r2,r3 8005d000: 14400011 bne r2,r0,0x8005d048 8005d004: 02002021 addu r4,r16,r0 # abilityIndex # if (jobJP >= abilities[abilityIndex].jpCost) { 8005d008: 966200dc lhu r2,0x00dc(r19) # jobJP = *(&unit.baseJobJP + (jobIndex * 2)) 8005d00c: 00000000 nop 8005d010: 00431023 subu r2,r2,r3 # newJobJP = jobJP - abilities[abilityIndex].jpCost 8005d014: 06010002 bgez r16,0x8005d020 8005d018: a66200dc sh r2,0x00dc(r19) # *(&unit.baseJobJP + (jobIndex * 2)) = newJobJP // Save new job JP 8005d01c: 26040007 addiu r4,r16,0x0007 8005d020: 34120001 ori r18,r0,0x0001 # isAbilityLearned = true 8005d024: 000420c3 sra r4,r4,0x03 8005d028: 02842821 addu r5,r20,r4 # learnedAbilitiesPtr = (abilityIndex / 8) + ((unit + (jobIndex * 3)) + 0x99) 8005d02c: 000420c0 sll r4,r4,0x03 8005d030: 02042023 subu r4,r16,r4 # abilityIndex % 8 (modulo) 8005d034: 34020080 ori r2,r0,0x0080 8005d038: 90a30000 lbu r3,0x0000(r5) # learnedAbilityValue = *learnedAbilitiesPtr 8005d03c: 00821007 srav r2,r2,r4 # newLearnedAbilityFlag = 0x80 >> (abilityIndex % 8) 8005d040: 00621825 or r3,r3,r2 # learnedAbilityValue = learnedAbilityValue | newLearnedAbilityFlag 8005d044: a0a30000 sb r3,0x0000(r5) # *learnedAbilitiesPtr = learnedAbilityValue // Set ability as learned # } # } # } 8005d048: 1240000d beq r18,r0,0x8005d080 # if (isAbilityLearned) { 8005d04c: 00000000 nop 8005d050: 06010002 bgez r16,0x8005d05c 8005d054: 02002021 addu r4,r16,r0 # abilityIndex 8005d058: 26040007 addiu r4,r16,0x0007 8005d05c: 000420c3 sra r4,r4,0x03 # learnedAbilitiesPtr = (abilityIndex / 8) + ((unit + (jobIndex * 3)) + 0x99) 8005d060: 02842821 addu r5,r20,r4 8005d064: 000420c0 sll r4,r4,0x03 8005d068: 02042023 subu r4,r16,r4 # abilityIndex % 8 (modulo) 8005d06c: 34020080 ori r2,r0,0x0080 8005d070: 90a30000 lbu r3,0x0000(r5) # learnedAbilityValue = *learnedAbilitiesPtr 8005d074: 00821007 srav r2,r2,r4 # newLearnedAbilityFlag = 0x80 >> (abilityIndex % 8) 8005d078: 00621825 or r3,r3,r2 # learnedAbilityValue = learnedAbilityValue | newLearnedAbilityFlag 8005d07c: a0a30000 sb r3,0x0000(r5) # *learnedAbilitiesPtr = learnedAbilityValue // Set ability as learned # } # } 8005d080: 26100001 addiu r16,r16,0x0001 # abilityIndex = abilityIndex + 1 8005d084: 2a020018 slti r2,r16,0x0018 8005d088: 1440ffc7 bne r2,r0,0x8005cfa8 8005d08c: 00009021 addu r18,r0,r0 # isAbilityLearned = false # } while (abilityIndex < 24); 8005d090: 8fbf002c lw r31,0x002c(r29) 8005d094: 8fb60028 lw r22,0x0028(r29) 8005d098: 8fb50024 lw r21,0x0024(r29) 8005d09c: 8fb40020 lw r20,0x0020(r29) 8005d0a0: 8fb3001c lw r19,0x001c(r29) 8005d0a4: 8fb20018 lw r18,0x0018(r29) 8005d0a8: 8fb10014 lw r17,0x0014(r29) 8005d0ac: 8fb00010 lw r16,0x0010(r29) 8005d0b0: 27bd0030 addiu r29,r29,0x0030 8005d0b4: 03e00008 jr r31 8005d0b8: 00000000 nop