Print text when you lose a trainer battle - pret/pokecrystal GitHub Wiki
Enemy trainers all have set text that gets printed when you win a battle with them. They also have space to set text for when you lose, but that only works for battles you can lose, and the only such battle is the first one with your rival in Cherrygrove City:
It turns out that all the other rival battles have unused loss text (documented on The Cutting Room Floor); and the battle with Red is also set to use the same "…" text whether you win or lose. Other trainers don't bother to set loss text, and just use 0 as a placeholder. For example, in maps/Route30.asm:
TrainerYoungsterJoey:
trainer YOUNGSTER, JOEY1, EVENT_BEAT_YOUNGSTER_JOEY, YoungsterJoey1SeenText, YoungsterJoey1BeatenText, 0, .Script
And in maps/VioletGym.asm:
VioletGymFalknerScript:
...
winlosstext FalknerWinLossText, 0
loadtrainer FALKNER, FALKNER1
startbattle
reloadmapafterbattle
Anyway, it's quite simple to enable this feature. Edit engine/battle/core.asm:
LostBattle:
ld a, 1
ld [wBattleEnded], a
ld a, [wInBattleTowerBattle]
bit 0, a
jr nz, .battle_tower
- ld a, [wBattleType]
- cp BATTLETYPE_CANLOSE
- jr nz, .not_canlose
+ ld a, [wBattleMode]
+ dec a ; wild?
+ jr z, .no_loss_text
+
+ ld hl, wLossTextPointer
+ ld a, [hli]
+ ld h, [hl]
+ or h
+ jr z, .no_loss_text
; Remove the enemy from the screen.
hlcoord 0, 0
lb bc, 8, 21
call ClearBox
call BattleWinSlideInEnemyTrainerFrontpic
ld c, 40
call DelayFrames
ld a, [wDebugFlags]
bit DEBUG_BATTLE_F, a
jr nz, .skip_win_loss_text
call PrintWinLossText
.skip_win_loss_text
ret
.battle_tower
; Remove the enemy from the screen.
hlcoord 0, 0
lb bc, 8, 21
call ClearBox
call BattleWinSlideInEnemyTrainerFrontpic
ld c, 40
call DelayFrames
call EmptyBattleTextbox
ld c, BATTLETOWERTEXT_WIN_TEXT
farcall BattleTowerText
call WaitPressAorB_BlinkCursor
call ClearTilemap
call ClearBGPalettes
ret
-.not_canlose
+.no_loss_text
ld a, [wLinkMode]
and a
jr nz, .LostLinkBattle
Now if you lose a trainer battle and [wLossTextPointer]
is nonzero, the text will be printed, regardless of what the battle type is.
There's one more thing to do. Edit maps/Route24.asm:
Route24RocketScript:
faceplayer
playmusic MUSIC_ROCKET_ENCOUNTER
opentext
writetext Route24RocketSeenText
waitbutton
closetext
- winlosstext Route24RocketBeatenText, -1
+ winlosstext Route24RocketBeatenText, 0
loadtrainer GRUNTM, GRUNTM_31
startbattle
dontrestartmapmusic
reloadmapafterbattle
...
If you lost against this Rocket Grunt, it would try printing text at [-1]
, which might glitch or crash the game. We just had to set it to the usual 0 for no loss text.
Now we're done!
You can optionally edit home/trainers.asm:
PrintWinLossText::
- ld a, [wBattleType]
- cp BATTLETYPE_CANLOSE
- jr .canlose ; ??????????
-
-; unused
- ld hl, wWinTextPointer
- jr .ok
-
-.canlose
ld a, [wBattleResult]
ld hl, wWinTextPointer
and $f ; WIN?
jr z, .ok
ld hl, wLossTextPointer
.ok
ld a, [hli]
ld h, [hl]
ld l, a
call GetMapScriptsBank
call FarPrintText
call WaitBGMap
call WaitPressAorB_BlinkCursor
ret
That removes some vestigial code which looks like Game Freak planned to check for BATTLETYPE_CANLOSE
here instead of in LostBattle
. (This would have worked if jr .canlose
had been jr z, .canlose
.) Removing this code doesn't affect gameplay, but it does save ROM space, which is especially useful in the home bank.