Skip to content

Restore Rival Victory Speeches

kafujo edited this page Nov 13, 2023 · 3 revisions

Tutorial originally written by MechanicalPen on the iimarkus forums.

RIVAL has different "if rival wins" victory speeches coded into the game for each rival battle, but in the final version of the game only the very first one appears. This tutorial restores those speeches. Here is a video of the speeches: https://www.youtube.com/watch?v=RPODy8j27Dw

Go to: engine/battle/core.asm

; called when player is out of usable mons.
; prints appropriate lose message, sets carry flag if player blacked out (special case for initial rival fight)
HandlePlayerBlackOut:
	ld a, [wLinkState]
	cp LINK_STATE_BATTLING
	jr z, .notRival1Battle
-	ld a, [wCurOpponent] ; who's the current opponent?
-	cp OPP_RIVAL1 ; is it Rival1?
-	jr nz, .notRival1Battle ;if no, don't print our message.
+	ld a, [wIsInBattle] ; are we in a battle?
+	dec a ; is the battle a wild battle (without a trainer?)?
+	jr z, .notRival1Battle ;if yes, don't print our message.
	hlcoord 0, 0  ; rival 1 battle
	lb bc, 8, 21
	call ClearScreenArea
	call ScrollTrainerPicAfterBattle
	ld c, 40
	call DelayFrames
-	ld hl, Rival1WinText
-	call PrintText
+	call PrintEndBattleText
	ld a, [wCurMap]
	cp OAKS_LAB
	ret z            ; starter battle in oak's lab: don't black out
.notRival1Battle
	ld b, SET_PAL_BATTLE_BLACK
	call RunPaletteCommand
	ld hl, PlayerBlackedOutText2
	ld a, [wLinkState]
	cp LINK_STATE_BATTLING
	jr nz, .noLinkBattle
	ld hl, LinkBattleLostText
.noLinkBattle
	call PrintText
	ld a, [wd732]
	res 5, a
	ld [wd732], a
	call ClearScreen
	scf
	ret

Surprisingly, that's all you have to do to restore (most if not all) the Rival win quotes from that youtube video at the top! Yes, the game does actually load lose battle quotes for trainers by default! If we search for all instances of 'SaveEndBattleTextPointers' we can see that lose quotes ([wEndBattleLoseTextPointer]) are set in various scripts and in TalkToTrainer:: but they are usually set to the same thing as win quotes. In the case of TalkToTrainer, they are loaded from trainer headers but there is actually a bug which prevents them from loading correctly.

So, let's fix "ReadTrainerHeaderInfo::"!

Go to: home/trainers.asm

	jr z, .readPointer ; read end battle text
	cp $a
	jr nz, .done
+	pop de           ;BUGFIX: we pushed de onto the stack at the top, so we have to pop it off the stack to keep things symmetrical.
	ld a, [hli]        ; read end battle text (2) but override the result afterwards (XXX why, bug?)
	ld d, [hl]
	ld e, a
+	ret            ;BUGFIX: de contains the lose quote loaded from the trainer header. We are done here.  
-	jr .done
+	;jr .done    ;BUGFIX: this would replace de (the value we just loaded) with the value on the top of the stack. That's not the behavior we want.
.readPointer

That's everything! All that's left, if you want to make all trainers print lose quotes instead of just the rival, is to edit all the scripts and trainer headers to have lose quotes instead of two win quotes (due to limitations, the win and lose quote pointers have to be in the same place. But you can TX_FAR to the actual text that is located anywhere).

TX_FAR is a macro in pokered for the text command that looks up text in any bank. just search for it in the pokered codebase and you can see how it is used. But, here is an example:

ViridianGymBattleLoseText:
    TX_FAR _ViridianGymBattleLoseText
    db "@"

ViridianGymBattleWinText:
    TX_FAR _ViridianGymBattleWinText
    db "@"

For win / lose quotes, ViridianGymBattleLoseText and ViridianGymBattleWinText have to be in the same bank (and they are the pointers you reference in the trainer's header.) But _ViridianGymBattleLoseText and _ViridianGymBattleWinText can be anywhere they'll fit. The text engine can look them up (because you told it to with TX_FAR.)

Q) Which of the four pointer spots from the top would the "lose" text go, in relation to the "challenge" text, the "win" text, and the "post-battle" text?

A) These lines are the answer:

;    4 -> before battle text (into hl)
;    6 -> after battle text (into hl)
;    8 -> end battle text (into hl)

It appears to be in the order before, after, win, lose. But, try it and see!

Clone this wiki locally