Gym Leader Rematches!

This commit adds a large fundamental change to KEP, that being Gym Rematches.

This is achieved alongside a rework to the script that makes those post-game-gating NPCs shift around. If you add a new one, just add its constant to the lists you'll see in the Hall of Fame script.

It also fixes a few bugs:
- Fixed a bug where Cinnabar Gym loaded a fleet of Blaines. This occurred due to the way he is coded at base, and a misunderstanding I had when implementing his scaling. This is now fixed by standardising his gym script instead, while letting the gym trainers still use the old one.
- Fixed a bug where the Up-Grade NPC would not appear after beating Silph Co. 11F. However, Giovanni currently seems to have trouble with his text. This floor needs some re-coding anyway, given we need to add Jessie and James to it.

And some misc. changes:
- Changed the first Moon Stone in Mt. Moon to a Poison Stone for the Nidoking speedrunners
- Debug Mode now has a line of code to set up the post-game easily
- Changed Surge's initial battle text to Yellow's
- Added Sabrina's more accurate LGPE initial battle text, referring to the spoon she bent by accident
This commit is contained in:
Llinos Evans 2023-06-09 11:17:31 +01:00
parent 5f8250f0d1
commit 749abc67b7
24 changed files with 575 additions and 67 deletions

View file

@ -103,12 +103,37 @@ CeladonGymTrainerHeader6:
ErikaText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_ERIKA
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM21
jr nz, .afterBeat
call z, CeladonGymReceiveTM21
call DisableWaitingAfterTextDisplay
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and his trainer.
ld hl, ErikaRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, ErikaRematchDefeatedText
ld de, ErikaRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_ERIKA
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $4
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, ErikaPostBattleAdviceText
@ -303,3 +328,11 @@ CeladonGymEndBattleText8:
CeladonGymAfterBattleText8:
text_far _CeladonGymAfterBattleText8
text_end
ErikaRematchPreBattleText:
text_far _ErikaRematchPreBattleText
text_end
ErikaRematchDefeatedText:
text_far _ErikaRematchDefeatedText
text_end

View file

@ -89,12 +89,37 @@ CeruleanGymTrainerHeader1:
MistyText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_MISTY
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM11
jr nz, .afterBeat
call z, CeruleanGymReceiveTM11
call DisableWaitingAfterTextDisplay
jp .done
.rematchMode ; Rematch functionality. Just loads pre-battle text and her trainer.
ld hl, MistyRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, MistyRematchDefeatedText
ld de, MistyRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_MISTY
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $2
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, TM11ExplanationText
@ -222,3 +247,11 @@ CeruleanGymGuidePreBattleText:
CeruleanGymGuidePostBattleText:
text_far _CeruleanGymGuidePostBattleText
text_end
MistyRematchPreBattleText:
text_far _MistyRematchPreBattleText
text_end
MistyRematchDefeatedText:
text_far _MistyRematchDefeatedText
text_end

View file

@ -191,24 +191,7 @@ CinnabarGymScript_758b7:
ldh a, [hSpriteIndexOrTextID]
ld [wSpriteIndex], a
call EngageMapTrainer
; call InitBattleEnemyParameters ; put this back if you mess up
; gym scaling spaghetti code begins here - remove initial parameters as we're making our own
ld a, OPP_BLAINE
ld [wCurOpponent], a
ld hl, wObtainedBadges ; Picking the team based on badge count. Need +1 so it loads the right team: remember, you're fighting for the badge! Thanks to Chatot4444 for the help.
ld b, 1
call CountSetBits
ld a, [wNumSetBits]
inc a
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
;ends here
call InitBattleEnemyParameters
ld hl, wd72d
set 6, [hl]
set 7, [hl]
@ -224,15 +207,41 @@ CinnabarGymScript_758b7:
ld [wCurMapScript], a
jp TextScriptEnd
; Blaine's gym script has been standardised for gym scaling purposes.
BlaineText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_BLAINE
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM38
jr nz, .afterBeat
call z, CinnabarGymReceiveTM38
call DisableWaitingAfterTextDisplay
jp TextScriptEnd
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and his trainer.
ld hl, BlaineRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, BlaineRematchDefeatedText
ld de, BlaineRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_BLAINE
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $7
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, BlainePostBattleAdviceText
call PrintText
@ -243,9 +252,37 @@ BlaineText:
ld hl, ReceivedVolcanoBadgeText
ld de, ReceivedVolcanoBadgeText
call SaveEndBattleTextPointers
ld hl, wd72d
set 6, [hl]
set 7, [hl]
ld a, [wSpriteIndex]
call EngageMapTrainer
ld a, OPP_BLAINE
ld [wCurOpponent], a
ld hl, wObtainedBadges ; Picking the team based on badge count. Need +1 so it loads the right team: remember, you're fighting for the badge! Thanks to Chatot4444 for the help.
ld b, 1
call CountSetBits
ld a, [wNumSetBits]
inc a
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $7
ld [wGymLeaderNo], a
jp CinnabarGymScript_758b7
;ends here
ld a, $3
ld [wCinnabarGymCurScript], a
ld [wCurMapScript], a
jr .done
.done
jp TextScriptEnd
BlainePreBattleText:
text_far _BlainePreBattleText
@ -490,3 +527,11 @@ CinnabarGymGuidePreBattleText:
CinnabarGymGuidePostBattleText:
text_far _CinnabarGymGuidePostBattleText
text_end
BlaineRematchPreBattleText:
text_far _BlaineRematchPreBattleText
text_end
BlaineRematchDefeatedText:
text_far _BlaineRematchDefeatedText
text_end

View file

@ -103,12 +103,37 @@ FuchsiaGymTrainerHeader5:
KogaText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_KOGA
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM06
jr nz, .afterBeat
call z, FuchsiaGymReceiveTM06
call DisableWaitingAfterTextDisplay
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and his trainer.
ld hl, KogaRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, KogaRematchDefeatedText
ld de, KogaRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_KOGA
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $5
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, KogaPostBattleAdviceText
@ -306,3 +331,12 @@ FuchsiaGymGuidePreBattleText:
FuchsiaGymGuidePostBattleText:
text_far _FuchsiaGymGuidePostBattleText
text_end
KogaRematchPreBattleText:
text_far _KogaRematchPreBattleText
text_end
KogaRematchDefeatedText:
text_far _KogaRematchDefeatedText
text_end

View file

@ -93,28 +93,10 @@ HallofFameRoomScript1:
ldh [hSpriteIndexOrTextID], a
call DisplayTextID
ld a, $ff
ld [wJoyIgnore], a ; TODO: Make this less awful. See: Giovanni in Silph
ld a, HS_CERULEAN_CAVE_GUY
ld [wMissableObjectIndex], a
predef HideObject
ld a, HS_MT_MOON_CRATER_GUARD
ld [wMissableObjectIndex], a
predef HideObject
ld a, HS_ROUTE_1_OAK
ld [wMissableObjectIndex], a
predef ShowObject
ld a, HS_BILLS_NIDORINO
ld [wMissableObjectIndex], a
predef HideObject
ld a, HS_MANSION_GUARD
ld [wMissableObjectIndex], a
predef HideObject
ld a, HS_YUJIROU
ld [wMissableObjectIndex], a
predef HideObject
ld a, HS_YUJIROU_REMATCH
ld [wMissableObjectIndex], a
predef ShowObject
ld [wJoyIgnore], a
call PostGameSetup
ld a, $2
ld [wHallOfFameCurScript], a
ret
@ -125,3 +107,43 @@ HallOfFame_TextPointers:
HallofFameRoomText1:
text_far _HallofFameRoomText1
text_end
; Post-Game Functionality
; This script is adapted from the Silph Co. 11F script that reforms Saffron City.
; It replaces the Cerulean Cave Guard bit, adapting him into the whole ordeal.
PostGameSetup:
SetEvent EVENT_POST_GAME_ATTAINED
ld hl, ObjectsToHide
.loop1
ld a, [hli]
cp $ff
jr z, .skip
push hl
ld [wMissableObjectIndex], a
predef HideObject
pop hl
jr .loop1
.skip
ld hl, ObjectsToShow
.loop2
ld a, [hli]
cp -1
ret z
push hl
ld [wMissableObjectIndex], a
predef ShowObject
pop hl
jr .loop2
ObjectsToShow:
db HS_ROUTE_1_OAK ; Oak post-game fight
db HS_YUJIROU_REMATCH ; Yujirou rematch
db -1 ; end
ObjectsToHide:
db HS_BILLS_NIDORINO ; Bill's Garden access
db HS_MANSION_GUARD ; Pokemon Mansion basement access
db HS_MT_MOON_CRATER_GUARD ; Mt. Moon Crater access
db HS_CERULEAN_CAVE_GUY ; Cerulean Cave access
db -1 ; end

View file

@ -95,12 +95,37 @@ PewterGymTrainerHeader0:
BrockText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_BROCK
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM34
jr nz, .afterBeat
call z, PewterGymScriptReceiveTM34
call DisableWaitingAfterTextDisplay
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and his trainer.
ld hl, BrockRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, BrockRematchDefeatedText
ld de, BrockRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_BROCK
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $1
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, BrockPostBattleAdviceText
@ -238,3 +263,11 @@ PewterGymText_5c524:
PewterGymGuidePostBattleText:
text_far _PewterGymGuidePostBattleText
text_end
BrockRematchPreBattleText:
text_far _BrockRematchPreBattleText
text_end
BrockRematchDefeatedText:
text_far _BrockRematchDefeatedText
text_end

View file

@ -104,12 +104,37 @@ SaffronGymTrainerHeader6:
SabrinaText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_SABRINA
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM46
jr nz, .afterBeat
call z, SaffronGymReceiveTM46
call DisableWaitingAfterTextDisplay
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and her trainer.
ld hl, SabrinaRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, SabrinaRematchDefeatedText
ld de, SabrinaRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_SABRINA
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $6
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, SabrinaPostBattleAdviceText
@ -326,3 +351,11 @@ SaffronGymEndBattleText7:
SaffronGymAfterBattleText7:
text_far _SaffronGymAfterBattleText7
text_end
SabrinaRematchPreBattleText:
text_far _SabrinaRematchPreBattleText
text_end
SabrinaRematchDefeatedText:
text_far _SabrinaRematchDefeatedText
text_end

View file

@ -186,6 +186,7 @@ MissableObjectIDs_62194:
db HS_SAFFRON_CITY_B
db HS_SAFFRON_CITY_C
db HS_SAFFRON_CITY_D
db HS_SAFFRON_CITY_UP_GRADE
db -1 ; end
MissableObjectIDs_6219b:
@ -198,7 +199,6 @@ MissableObjectIDs_6219b:
db HS_SAFFRON_CITY_7
db HS_SAFFRON_CITY_E
db HS_SAFFRON_CITY_F
db HS_SAFFRON_CITY_UP_GRADE
db HS_SILPH_CO_3F_1
db HS_SILPH_CO_3F_2
db HS_SILPH_CO_4F_1

View file

@ -111,12 +111,37 @@ VermilionGymTrainerHeader2:
LTSurgeText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; No need to view previous stuff, technically you can skip Bide this way but I think that's hilarious
jr nz, .rematchMode
CheckEvent EVENT_BEAT_LT_SURGE
jr z, .beforeBeat
CheckEventReuseA EVENT_GOT_TM24
jr nz, .afterBeat
call z, VermilionGymReceiveTM24
call DisableWaitingAfterTextDisplay
jp .done ; needed due to the rematch script length.
.rematchMode ; Rematch functionality. Just loads pre-battle text and his trainer.
ld hl, SurgeRematchPreBattleText
call PrintText
ld c, BANK(Music_MeetMaleTrainer)
ld a, MUSIC_MEET_MALE_TRAINER
call PlayMusic
set 6, [hl]
set 7, [hl]
ldh a, [hSpriteIndex]
ld [wSpriteIndex], a
ld hl, SurgeRematchDefeatedText
ld de, SurgeRematchDefeatedText
call SaveEndBattleTextPointers
call EngageMapTrainer
ld a, OPP_LT_SURGE
ld [wCurOpponent], a
ld a, 9
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $3
ld [wGymLeaderNo], a
jr .done
.afterBeat
ld hl, LTSurgePostBattleAdviceText
@ -263,3 +288,11 @@ VermilionGymGuidePreBattleText:
VermilionGymGuidePostBattleText:
text_far _VermilionGymGuidePostBattleText
text_end
SurgeRematchPreBattleText:
text_far _SurgeRematchPreBattleText
text_end
SurgeRematchDefeatedText:
text_far _SurgeRematchDefeatedText
text_end