HUBOL ‐ Trainer Sliding Messages & In‐Battle Music Changes - haven1433/HexManiacAdvance GitHub Wiki
Click here for HUBOL's main page. HUBOL is short for "Haven's Unofficial Build of Leon's dynamic Pokémon expansion."
Credits: Defa, DontJoelMe - OceanBlue, and Invis
First, add this anchor in free space:
data.cfru.trainerslides[trainerID:data.trainers.stats lastMonSong:songnames firstMonDown<""> lastSwitchIn<""> lastLowHp<"">]1
-
trainerID
: the Trainer fromdata.trainers.stats
-
lastMonSong
: the music played when the last Pokémon enters the battlefield -
firstMonDown
: message shown after the first Pokémon faints -
lastSwitchIn
: message shown when the last Pokémon enters the battlefield -
lastLowHp
: message shown when the last Pokémon has less than or equal to 25% HP
- You do not have to set the
lastSwitchIn
message if you set a music inlastMonSong
: they are not tied together. - If you set it to
mus_dummy
or to 65535, the background music will not change. - Ideally, you should choose songs with names that start with "mus_vs" or "mus_rs." ("rs" means music from Ruby/Sapphire)
Leave two FF bytes after the table to mark its end.
To add a message, click on the "Create new data" button on the left; if you do not see this button when having the fields set to <F7FFFFFF>
, then change them to <null>
.
You do not have to set all three messages for each Trainer, you can choose to show only one or two messages. To not show a message, type <null>
in the message field, or leave four FF bytes (shown as <F7FFFFFF>
in red).
If a Trainer has only one Pokémon in party, the messages lastLowHp and firstMonDown will be shown, while lastSwitchIn will not be shown.
When creating any new message, type \pn
at the end of the string: this makes the text stop during battle and wait for player input. If you do not add \pn
, the message will disappear immediately as soon as the game finishes printing the text string.
Add the following routine in free space, and note the offset.
Go to address 1490938
, and change 08 4B 1B 68 70 B5 04 00
to 00 4B 18 47 <offset+1>
. Also, go to 1490A81
, and change D0
to E0
.
ldr r3, =0x02022B4C @gBattleTypeFlags
ldr r3, [r3, #0]
push {r4-r6, lr}
lsl r5, r0, #0
lsl r6, r1, #0
lsl r4, r2, #0
lsl r3, r3, #28
bmi battletypetrainer
false:
mov r0, #0
b end
battletypetrainer:
ldr r3, =0x080751C5 @GetBattleSide
bl linker
cmp r0, #1
bne false
ldr r0, slidestable
ldr r1, tableend
looptrainerid:
ldrh r2, [r0] @.trainerID
cmp r2, r1
beq false
cmp r6, r2
beq switchcaseid
add r0, r0, #16 @next row
b looptrainerid
switchcaseid:
ldr r3, =0x02023FC4 @gBattleScripting
strb r5, [r3, #23] @.bank
ldr r2, empty
cmp r4, #1
beq slidelastlowhp
cmp r4, #0
beq slidelastswitchin
cmp r4, #2
bne false
ldr r3, freeram
mov r1, #0 @clear last switch-in flag
strb r1, [r3]
ldr r4, [r0, #4] @firstMonDown
cmp r4, #0
beq false
cmp r4, r2
beq false
mov r0, #1
ldr r3, GetEnemyMonCount
bl linker
lsl r5, r0, #0
mov r0, #0
ldr r3, GetEnemyMonCount
bl linker
sub r0, r0, #1
cmp r5, r0
bne false
ldr r3, gBattleStringLoader
str r4, [r3, #0]
b true
slidelastswitchin:
lsl r4, r0, #0
mov r0, #1
ldr r3, GetEnemyMonCount
bl linker
ldr r1, =0x02022B4C @gBattleTypeFlags
ldr r1, [r1]
mov r2, #1 @BATTLE_TYPE_DOUBLE
tst r1, r2
beq checksinglebattle
ldr r3, freeram
cmp r0, #2
bhi false @clearflagfordouble
ldrb r0, [r3]
cmp r0, #0
beq setflagfordouble
mov r0, #0
strb r0, [r3]
b false
setflagfordouble:
mov r0, #1
strb r0, [r3]
b setsong
checksinglebattle:
cmp r0, #1
bne false
setsong:
ldrh r0, [r4, #2] @lastMonSong
cmp r0, #0
beq checkmsg
ldr r1, tableend
cmp r0, r1
beq checkmsg
ldr r3, =0x08044091 @PlayMapChosenOrBattleBGM
bl linker
checkmsg:
ldr r0, [r4, #8] @lastSwitchIn
cmp r0, #0
beq false
ldr r2, empty
cmp r0, r2
beq false
ldr r3, gBattleStringLoader
str r0, [r3, #0]
mov r0, #1
end:
pop {r4-r6, pc}
linker: bx r3
slidelastlowhp:
ldr r6, [r0, #12] @lastLowHp
cmp r6, #0
beq false
cmp r6, r2
beq false
mov r0, #1
ldr r3, GetEnemyMonCount
bl linker
cmp r0, #1
bne false
mov r2, #88
mul r2, r5
ldr r3, =0x02023BE4 @gBattleMons
add r5, r3, r2
mov r2, #100
ldrh r3, [r5, #40] @current HP
cmp r3, #0
beq gotofalse
ldrh r1, [r5, #44] @max HP
lsl r0, r2, #0
mul r0, r3
ldr r3, =0x081E460D @udivsi3
bl linker
cmp r0, #24 @current HP <= 25% max HP
bls haslowhp
gotofalse:
b false @too far above for conditional branch
haslowhp:
ldr r3, =0x0203E038 @gNewBS
ldr r3, [r3, #0]
lsl r2, r3, #0
add r2, r2, #216
ldrb r2, [r2, #0]
cmp r2, #127
bhi gotofalse
mov r2, #128
add r3, r3, #213
ldrb r1, [r3, #3]
neg r2, r2
orr r2, r1
strb r2, [r3, #3]
ldr r3, gBattleStringLoader
str r6, [r3, #0]
true:
mov r0, #1
b end
tableend: .word 0x0000FFFF
empty: .word 0xFFFFFFFF
slidestable: .word <data.cfru.trainerslides>
freeram: .word 0x0203B7AB
gBattleStringLoader: .word 0x0203E020
GetEnemyMonCount: .word 0x0951EDBC +1