diff --git a/src/HexManiac.WPF/HexManiac.WPF.csproj b/src/HexManiac.WPF/HexManiac.WPF.csproj index aee0044f..4f6d9fe8 100644 --- a/src/HexManiac.WPF/HexManiac.WPF.csproj +++ b/src/HexManiac.WPF/HexManiac.WPF.csproj @@ -40,6 +40,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + diff --git a/src/HexManiac.WPF/Scripts/ability_type_swaps.hma b/src/HexManiac.WPF/Scripts/ability_type_swaps.hma index 08fb6a60..e741a810 100644 --- a/src/HexManiac.WPF/Scripts/ability_type_swaps.hma +++ b/src/HexManiac.WPF/Scripts/ability_type_swaps.hma @@ -1,5 +1,4 @@ # Introduce a new ability type-swap table. -# FireRed Only # Abilities in this table will change moves of one type to another # Example: Pixilate @@ -20,10 +19,21 @@ -# main routine +# 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} + push {r4-r7, lr} # TODO in ruby, we push 6 registers, not just 4 sub sp, #16 @ r0 = current pokemon ability @@ -79,7 +89,7 @@ ldr r0, [r0, #0] strb r3, [r0, #19] @ gBattleStruct->dynamicMoveType = data.abilities.typeswaps[i].change | 0x40 checkInitialDynamicBasePower: - ldr r5, =0x02023F50 @ gDynamicBasePower + ldr r5, [pc, ] ldrh r0, [r5, #0] cmp r0, #0 bne @@ -100,28 +110,141 @@ strh r0, [r5, #0] @ gDynamicBasePower = gDynamicBasePower * scale / 100 end: @ from original script - ldr r4, =0x02023DDE - ldr r5, =0x02023D6C + ldr r4, [pc, ] + ldr r5, [pc, ] @ return to original script - ldr r0, =+8 + ldr r0, = @ damagecalc bx r0 - gBattleMons: .word 0x02023BE4 - gBattlerAttacker: .word 0x02023D6B - gCurrentMove: .word 0x02023D4A - gBattleStruct: .word 0x02023FE8 divide: - ldr r2, =<1E4018>+1 + 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 -@01E59C .thumb +@scripts.battle.thumb/5/code/-1 .thumb ldr r0, =0 bx r0 .end -@01E59C+4 +@scripts.battle.thumb/5/code/+3 diff --git a/src/HexManiac.WPF/Scripts/entrance_abilities.hma b/src/HexManiac.WPF/Scripts/entrance_abilities.hma index 2d31c5f9..840790f7 100644 --- a/src/HexManiac.WPF/Scripts/entrance_abilities.hma +++ b/src/HexManiac.WPF/Scripts/entrance_abilities.hma @@ -15,6 +15,8 @@ # gBattleScripting.battler = battler; # ++effect; + + # setup anchors @1D927F ^scripts.abilities.entrance.drizzle`bse` @1D92BF ^scripts.abilities.entrance.sandstream`bse` @@ -35,6 +37,8 @@ # End Table # 00 00 FF FF FF FF FF FF @data.abilities.entrance ^data.abilities.entrance[ability:data.abilities.names animation:data.pokemon.moves.names script<`bse`>]!0000 + + # main routine @thumb.abilities.entrance(90) .thumb push {r0-r7} @@ -54,7 +58,7 @@ mov r1, r10 @ battler mov r2, #20 mul r1, r2 - ldr r2, =0x02023ECC @ gSpecialStatuses + ldr r2, [pc, ] add r1, r2 ldrb r3, [r1, #1] @ gSpecialStatuses[battler].0 (entrance is bit 9, previously unused) lsl r3, r3, #31 @ put bit 9 in the negative bit slot @@ -66,7 +70,7 @@ orr r3, r5 strb r3, [r1, #1] @ gBattleStruct->intimidateBattler = battler; - ldr r0, =0x02023FE8 + ldr r0, [pc, ] ldr r0, [r0, #0] add r0, #216 mov r1, r10 @ battler @@ -79,14 +83,14 @@ mov r0, r10 mov r1, #1 eor r1, r0 - ldr r0, =0x02023d6c @ gBattlerTarget + ldr r0, [pc, ] strb r1, [r0, #0] @ gCurrentMove = data.abilities.entrance[i].move // 02023d4a - ldr r0, =0x02023d4a + ldr r0, [pc, ] ldrh r1, [r4, #2] strh r1, [r0, #0] @ gBattleScripting.battler = battler; - ldr r0, =0x02023FC4 @ gBattleScripting + ldr r0, [pc, ] mov r1, r10 strb r1, [r0, #23] @ .battler @ ++effect; @@ -104,6 +108,11 @@ long_branch: ldr r1, =<01BC25> bx r1 + gCurrentMove: .word 0x02023D4A + gBattlerTarget: .word 0x02023D6C + gSpecialStatuses: .word 0x02023ECC + gBattleScripting: .word 0x02023FC4 + intimidateBattler: .word 0x02023FE8 .end