# Introduce a new ability type-swap table. # Abilities in this table will change moves of one type to another # Example: Pixilate, Aerilate, Normalize, Galvanize # Adds this code, approximately, to the damage calculation step: # foreach entry in data.abilities.typeswaps: # if (gBattleMons[gBattlerAttacker].ability != entry.ability) continue; # if (gBattleMoves[gCurrentMove].type != entry.original) continue; # gBattleStruct->dynamicMoveType = entry.change | 0x40; # gDynamicBasePower *= entry.scale / 100; # create new table -> data.abilities.typeswaps @data.abilities.typeswaps(10) 42 00 0A 64 FF FF 00 00 @data.abilities.typeswaps ^data.abilities.typeswaps[ability.data.abilities.names original.data.pokemon.type.names change.data.pokemon.type.names scale.]!FFFF0000 # mark the divide method @!game(AXVE0) @1E0868 @!game(AXPE0) @1E07F8 @!game(AXVE1) @1E0880 @!game(AXPE1) @1E0810 @!game(BPRE0) @1E4018 @!game(BPGE0) @1E3FF4 @!game(BPRE1) @1E4088 @!game(BPGE1) @1E4064 @!game(BPEE0) @2E7540 @!game(All) ^thumb.divide # main routine (FR/LG/Emerald) @!game(BPRE0_BPGE0_BPRE1_BPGE1_BPEE0) @thumb.abilities.typeswaps(B0) .thumb @ from original script push {r4-r7, lr} # TODO in ruby, we push 6 registers, not just 4 sub sp, #16 @ r0 = current pokemon ability @ r1 = current pokemon move type @ r2 = typeswap ability table @ r3 = index @ loop until -1 @ compare pokemon ability (r0) vs first 2 bytes @ when match: @ compare pokemon type (r1) vs next byte @ when match: @ set dynamic type as 0x40 + target type (last byte) @ r0 = gBattleMons[gBattlerAttacker].ability ldr r0, [pc, ] ldr r1, [pc, ] ldrb r1, [r1, #0] mov r2, 0x58 @ sizeof(BattlePokemon) mul r1, r2 add r1, #0x20 @ BattlePokemon.ability ldrb r0, [r0, r1] @ r0 = gBattleMons[gBattlerAttacker].ability @ r1 = gBattleMoves[gCurrentMove].type ldr r1, = ldr r2, [pc, ] ldrh r2, [r2, #0] mov r3, #12 @ sizeof(BattleMove) mul r2, r3 add r2, #2 @ BattleMove.type (change to 3 if you've done move expansion) ldrb r1, [r1, r2] @ r1 = gBattleMoves[gCurrentMove].type @ r2 = pixilate ability table + index*4 (4 is the size of the table elements) ldr r2, = sub r2, #4 loop: add r2, #4 ldrh r3, [r2, #0] @ r3 = FFFF if we're at the end of the table ldr r4, =0xFFFF cmp r3, r4 @ ability == FFFF beq ldrb r3, [r2, #0] @ r3 = the ability from the table cmp r0, r3 @ ability == gBattleMons[gBattlerAttacker].ability bne ldrb r3, [r2, #1] @ r3 = the source type from the table cmp r1, r3 bne setDynamicMoveType: ldrb r3, [r2, #2] @ r3 = the target type mov r0, #0x40 orr r3, r0 ldr r0, [pc, ] ldr r0, [r0, #0] strb r3, [r0, #19] @ gBattleStruct->dynamicMoveType = data.abilities.typeswaps[i].change | 0x40 checkInitialDynamicBasePower: ldr r5, [pc, ] ldrh r0, [r5, #0] cmp r0, #0 bne setInitialDynamicBasePower: ldr r0, [pc, ] ldrh r0, [r0, #0] mov r1, #12 @ sizeof(BattleMove) mul r0, r1 add r0, #1 @ BattleMove.power (change to 2 if you've done move expansion) ldr r1, = ldrb r0, [r1, r0] @ r0 = gBattleMoves[gCurrentMove].power strh r0, [r5, #0] @ gDynamicBasePower = gBattleMoves[gCurrentMove].power scalePower: ldrb r3, [r2, #3] @ r3 = the target scale mul r0, r3 mov r1, #100 bl strh r0, [r5, #0] @ gDynamicBasePower = gDynamicBasePower * scale / 100 end: @ from original script ldr r4, [pc, ] ldr r5, [pc, ] @ return to original script ldr r0, = @ damagecalc bx r0 divide: ldr r2, = bx r2 gBattleMons: .word 0x02023BE4 gCurrentMove: .word 0x02023D4A gBattlerAttacker: .word 0x02023D6B gBattlerTarget: .word 0x02023D6C gSideStatuses: .word 0x02023DDE gDynamicBasePower: .word 0x02023F50 gBattleStruct: .word 0x02023FE8 .end @!game(BPEE0) @thumb.abilities.typeswaps+8C .thumb gBattleMons: .word 0x02024084 gCurrentMove: .word 0x020241EA gBattlerAttacker: .word 0x0202420B gBattlerTarget: .word 0x0202420C gSideStatuses: .word 0x0202428E gDynamicBasePower: .word 0x02024400 gBattleStruct: .word 0x0202449C .end # main routine (Ruby/Sapphire) (separate because R/S version uses more stack) @!game(AXVE0_AXPE0_AXVE1_AXPE1) @thumb.abilities.typeswaps(B0) .thumb @ from original script push {r4-r7, lr} mov r7, r9 mov r6, r8 push {r6-r7} @ r0 = current pokemon ability @ r1 = current pokemon move type @ r2 = typeswap ability table @ r3 = index @ loop until -1 @ compare pokemon ability (r0) vs first 2 bytes @ when match: @ compare pokemon type (r1) vs next byte @ when match: @ set dynamic type as 0x40 + target type (last byte) @ r0 = gBattleMons[gBattlerAttacker].ability ldr r0, [pc, ] ldr r1, [pc, ] ldrb r1, [r1, #0] mov r2, 0x58 @ sizeof(BattlePokemon) mul r1, r2 add r1, #0x20 @ BattlePokemon.ability ldrb r0, [r0, r1] @ r0 = gBattleMons[gBattlerAttacker].ability @ r1 = gBattleMoves[gCurrentMove].type ldr r1, = ldr r2, [pc, ] ldrh r2, [r2, #0] mov r3, #12 @ sizeof(BattleMove) mul r2, r3 add r2, #2 @ BattleMove.type (change to 3 if you've done move expansion) ldrb r1, [r1, r2] @ r1 = gBattleMoves[gCurrentMove].type @ r2 = pixilate ability table + index*4 (4 is the size of the table elements) ldr r2, = sub r2, #4 loop: add r2, #4 ldrh r3, [r2, #0] @ r3 = FFFF if we're at the end of the table ldr r4, =0xFFFF cmp r3, r4 @ ability == FFFF beq ldrb r3, [r2, #0] @ r3 = the ability from the table cmp r0, r3 @ ability == gBattleMons[gBattlerAttacker].ability bne ldrb r3, [r2, #1] @ r3 = the source type from the table cmp r1, r3 bne setDynamicMoveType: ldrb r3, [r2, #2] @ r3 = the target type mov r0, #0x40 orr r3, r0 ldr r0, [pc, ] strb r3, [r0, #0] @ gBattleStruct->dynamicMoveType = data.abilities.typeswaps[i].change | 0x40 checkInitialDynamicBasePower: ldr r5, [pc, ] ldrh r0, [r5, #0] cmp r0, #0 bne setInitialDynamicBasePower: ldr r0, [pc, ] ldrh r0, [r0, #0] mov r1, #12 @ sizeof(BattleMove) mul r0, r1 add r0, #1 @ BattleMove.power (change to 2 if you've done move expansion) ldr r1, = ldrb r0, [r1, r0] @ r0 = gBattleMoves[gCurrentMove].power strh r0, [r5, #0] @ gDynamicBasePower = gBattleMoves[gCurrentMove].power scalePower: ldrb r3, [r2, #3] @ r3 = the target scale mul r0, r3 mov r1, #100 bl strh r0, [r5, #0] @ gDynamicBasePower = gDynamicBasePower * scale / 100 end: @ return to original script ldr r0, = @ damagecalc bx r0 divide: ldr r2, = bx r2 gBattleMons: .word 0x02024A80 gCurrentMove: .word 0x02024BE6 gBattlerAttacker: .word 0x02024C07 gBattlerTarget: .word 0x02024C08 gSideStatuses: .word 0x02024C7A gDynamicBasePower: .word 0x02024DEC gBattleStructDynamicMoveType: .word 0x0201601C .end @!game(All) # hook atk05_damagecalc @scripts.commands.battle.battlescript/5/code/-1 .thumb ldr r0, =0 bx r0 .end @scripts.commands.battle.battlescript/5/code/+3 # goto the table so the user can edit it @data.abilities.typeswaps