mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-10-27 08:49:58 -05:00
Improve ability_type_swaps
This now works for every game, and is included as an official script.
This commit is contained in:
@@ -40,6 +40,12 @@
|
||||
<None Include="Scripts\AddProfessorPokemonConstantsToRubySapphire.hma">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Scripts\type_items.hma">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="Scripts\ability_type_swaps.hma">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Crc32.NET" Version="1.2.0" />
|
||||
|
||||
@@ -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, <gDynamicBasePower>]
|
||||
ldrh r0, [r5, #0]
|
||||
cmp r0, #0
|
||||
bne <scalePower>
|
||||
@@ -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, <gSideStatuses>]
|
||||
ldr r5, [pc, <gBattlerTarget>]
|
||||
@ return to original script
|
||||
ldr r0, =<scripts.battle.thumb/5/code/>+8
|
||||
ldr r0, =<scripts.battle.thumb/5/code/+8> @ damagecalc
|
||||
bx r0
|
||||
gBattleMons: .word 0x02023BE4
|
||||
gBattlerAttacker: .word 0x02023D6B
|
||||
gCurrentMove: .word 0x02023D4A
|
||||
gBattleStruct: .word 0x02023FE8
|
||||
divide:
|
||||
ldr r2, =<1E4018>+1
|
||||
ldr r2, =<thumb.divide+1>
|
||||
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, <gBattleMons>]
|
||||
ldr r1, [pc, <gBattlerAttacker>]
|
||||
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, =<data.pokemon.moves.stats.battle>
|
||||
ldr r2, [pc, <gCurrentMove>]
|
||||
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, =<data.abilities.typeswaps>
|
||||
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 <end>
|
||||
ldrb r3, [r2, #0] @ r3 = the ability from the table
|
||||
cmp r0, r3 @ ability == gBattleMons[gBattlerAttacker].ability
|
||||
bne <loop>
|
||||
ldrb r3, [r2, #1] @ r3 = the source type from the table
|
||||
cmp r1, r3
|
||||
bne <loop>
|
||||
setDynamicMoveType:
|
||||
ldrb r3, [r2, #2] @ r3 = the target type
|
||||
mov r0, #0x40
|
||||
orr r3, r0
|
||||
ldr r0, [pc, <gBattleStructDynamicMoveType>]
|
||||
strb r3, [r0, #0] @ gBattleStruct->dynamicMoveType = data.abilities.typeswaps[i].change | 0x40
|
||||
checkInitialDynamicBasePower:
|
||||
ldr r5, [pc, <gDynamicBasePower>]
|
||||
ldrh r0, [r5, #0]
|
||||
cmp r0, #0
|
||||
bne <scalePower>
|
||||
setInitialDynamicBasePower:
|
||||
ldr r0, [pc, <gCurrentMove>]
|
||||
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, =<data.pokemon.moves.stats.battle>
|
||||
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 <divide>
|
||||
strh r0, [r5, #0] @ gDynamicBasePower = gDynamicBasePower * scale / 100
|
||||
end:
|
||||
@ return to original script
|
||||
ldr r0, =<scripts.battle.thumb/5/code/+8> @ damagecalc
|
||||
bx r0
|
||||
divide:
|
||||
ldr r2, =<thumb.divide+1>
|
||||
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 <thumb.abilities.typeswaps+1>
|
||||
@scripts.battle.thumb/5/code/+3 <thumb.abilities.typeswaps+1>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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, <gSpecialStatuses>]
|
||||
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, <intimidateBattler>]
|
||||
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, <gBattlerTarget>]
|
||||
strb r1, [r0, #0]
|
||||
@ gCurrentMove = data.abilities.entrance[i].move // 02023d4a
|
||||
ldr r0, =0x02023d4a
|
||||
ldr r0, [pc, <gCurrentMove>]
|
||||
ldrh r1, [r4, #2]
|
||||
strh r1, [r0, #0]
|
||||
@ gBattleScripting.battler = battler;
|
||||
ldr r0, =0x02023FC4 @ gBattleScripting
|
||||
ldr r0, [pc, <gBattleScripting>]
|
||||
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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user