Finish Post-Game Letter & Citrine Pass

This makes it so that once you clear the game, you will be able to get the Silph Letter from your mom, and the Citrine Pass by beating Professor Oak.

You'll now walk to your mother upon leaving your room post-clearing the game, and she'll hand you the letter. This'll basically explain your next quest to you.

The Professor Oak event kind of destroyed my sanity but that's fine. It works. Thanks to Martha for the idea.

Considerations for a full bag are done and they were annoying. I decided to show off and do some comedy to alleviate the lost sanity.
This commit is contained in:
Llinos Evans 2023-07-13 02:11:45 +01:00
parent c4afafb9ac
commit a13b1a0a47
6 changed files with 367 additions and 95 deletions

View file

@ -15,44 +15,47 @@ ChiefLetter1:
jr nz, .done
; with the way this is being done, coords will be unnecessary.
; this will trigger the minute you enter the house.
call UpdateSprites
call PlayerSeeMom
ld a, $ff
ld [wJoyIgnore], a
ld a, PLAYER_DIR_DOWN
ld [wPlayerMovingDirection], a
call UpdateSprites ; idk most movement scripts use this fsr
call PlayerSeeMom ; Show a cute little emotion bubble from the player.
jr MovePlayer ; Now kick the player upstairs. If you do this any other way, the game freaks out (eg. constant emotion bubbles, rsts)
.done
ret
MovePlayer:
ld a, $ff ; Firstly...
ld [wJoyIgnore], a ; No joypad inputs. No funny business. RLE is weird as fuck without it.
ld hl, wSimulatedJoypadStatesEnd
ld de, PlayerSeeMom_RLEMovement
call DecodeRLEList
dec a
ld [wSimulatedJoypadStatesIndex], a
call StartSimulatingJoypadStates
ld a, $2
ld [wRedsHouse1FCurScript], a
ld [wCurMapScript], a
.done
call StartSimulatingJoypadStates ; By this point, we're auto-moving.
ld a, $1 ; Now...
ld [wRedsHouse1FCurScript], a ; Get kicked up another flight to ChiefLetter2.
ld [wCurMapScript], a ; Safety.
ret
ChiefLetter2:
ld a, [wSimulatedJoypadStatesIndex]
ld a, [wSimulatedJoypadStatesIndex] ; This ties up the loose ends with the RLE.
and a
ret nz
call Delay3
ld a, $1
ldh [hSpriteIndex], a
call Delay3 ; Next...
ld a, SPRITE_FACING_LEFT
ldh [hSpriteFacingDirection], a
call SetSpriteFacingDirectionAndDelay
xor a ; Now...
ld [wJoyIgnore], a ; The player needs to be able to mash A.
ld a, $1 ; Load Mom's NPC ID
ldh [hSpriteIndex], a ; Slap it in the index
ld a, SPRITE_FACING_RIGHT ; Get this ready
ldh [hSpriteFacingDirection], a ; Now she'll face right, simulatiung talking to her.
call SetSpriteFacingDirectionAndDelay ; Get this all out.
call DisplayTextID ; Display her text ID, using the same thing from before.
; We did a little tomfoolery with her base text to make this work. Look below if you dare.
ld hl, MomGreeting
call PrintText
SetEvent EVENT_LETTER_RECEIVED
ld a, $1
ld a, $0 ; Anyway, kick the player back downstairs so the script can ret z for the rest of time.
ld [wRedsHouse1FCurScript], a
ld [wCurMapScript], a
ld [wCurMapScript], a ; aaand safety.
ret
PlayerSeeMom:
@ -75,10 +78,16 @@ PlayerSeeMom_RLEMovement:
RedsHouse1F_TextPointers:
dw RedsHouse1FMomText
dw RedsHouse1FTVText
dw MomGreeting
RedsHouse1FMomText:
text_asm
CheckEvent EVENT_POST_GAME_ATTAINED ; If the player hasn't got to the post game, we should never deal with this terribleness.
jr z, .normalProcessing ; So go to normal processing. Also if you go to debug without the post-game and letter events set up then this will loop infinitely. Please be reasonable.
CheckEvent EVENT_FUCK ; If some bozo triggers this I am going to be shocked.
jr nz, .bagWasFullButIsntNow ; No, seriously, you have to beat the Elite Four with a full bag. Ain't that a challenge?
CheckEvent EVENT_LETTER_RECEIVED ; Anyway, this was hell to debug. Let's go through the post-game together.
jr z, .letterSequence; This was all done so DisplayTextID could be used to get around a ton of bullshit.
.normalProcessing
ld a, [wd72e]
bit 3, a ; received a Pokémon from Oak?
jr nz, .heal
@ -87,6 +96,48 @@ RedsHouse1FMomText:
jr .done
.heal
call MomHealPokemon
jr .done
.letterSequence ; Look I know this code is cursed as fuck just bear with me
SetEvent EVENT_LETTER_RECEIVED ; Firstly, set the letter event
ld hl, MomYoureBack
call PrintText
lb bc, SILPHLETTER, 1 ; Alright, let's try to give the letter over.
call GiveItem ; Attempt is made.
jr nc, .bag_full ; If this triggers, you are a demented psychopath who needs to touch grass.
jr .LetterCanBeReceived ; If you're not weird, you can get it. Doing it this way saves a few instructions above.
.bag_full ; Psycho zone.
ld hl, MomBagFull
call PrintText
SetEvent EVENT_FUCK ; Set the funny event that I really wish I didn't need to have set up.
jr .done
.stillHavent ; Giga psycho zone. You get here if you still haven't sorted out your bag.
ld hl, MomBagStillFull
call PrintText
jr .done
.bagWasFullButIsntNow ; So now, if the weird kid has finally done their bag, we can progress.
ld hl, MomSavedIt
call PrintText
lb bc, SILPHLETTER, 1 ; We do this twice as otherwise it's a jr nightmare I don't want to debug
call GiveItem
jr nc, .stillHavent ; If they think they're smart, tough, it's a loop.
; Otherwise, fallthrough
.LetterCanBeReceived ; Jump here when getting the letter is possible.
ld hl, ReceivedChiefLetterText ; So now they get their letter.
call PrintText
ld a, [wSimulatedJoypadStatesEnd] ; ensuring that the text doesn't autoskip.
and a ; yep, here too.
call z, WaitForTextScrollButtonPress ; and here.
call EnableAutoTextBoxDrawing ; and here.
ld hl, ChiefLetterText
call PrintText
ld a, [wSimulatedJoypadStatesEnd] ; ensuring that the text doesn't autoskip. again. i tried making it a func but it got funky.
and a ; yep, here too.
call z, WaitForTextScrollButtonPress ; and here.
call EnableAutoTextBoxDrawing ; and here.
ld hl, MomAmazing
call PrintText
ResetEvent EVENT_FUCK ; Anyway, unset this and never deal with it again. This resets mom to her normal state.
; fallthrough
.done
jp TextScriptEnd
@ -145,24 +196,6 @@ TVWrongSideText:
; Post-Game stuff here.
MomGreeting:
text_asm
ld hl, MomYoureBack
call PrintText
lb bc, SILPHLETTER, 1
call GiveItem
ld hl, ReceivedChiefLetterText
call PrintText
ld a, [wSimulatedJoypadStatesEnd] ; ensuring that the text doesn't autoskip.
and a ; yep, here too.
call z, WaitForTextScrollButtonPress ; and here.
call EnableAutoTextBoxDrawing ; and here.
ld hl, ChiefLetterText
call PrintText
ld hl, MomAmazing
call PrintText
jp TextScriptEnd
ChiefLetterText:
text_far _ChiefLetterText
text_end
@ -173,8 +206,21 @@ MomYoureBack:
ReceivedChiefLetterText:
text_far _ReceivedChiefLetterText
sound_get_item_1
text_end
MomAmazing:
text_far _MomAmazing
text_end
MomBagFull:
text_far _MomBagFull
text_end
MomSavedIt:
text_far _MomSavedIt
text_end
MomBagStillFull:
text_far _MomBagStillFull
text_end

View file

@ -1,9 +1,37 @@
Route1_Script:
jp EnableAutoTextBoxDrawing
;ld hl, Route1_ScriptPointers
call EnableAutoTextBoxDrawing
ld hl, Route1_ScriptPointers
ld a, [wRoute1CurScript]
jp CallFunctionInTable
Route1_ScriptPointers:
dw Route1Script0
dw OakVibeCheck
Route1Script0:
ret ; yeah it's just a switch-off. shush.
OakVibeCheck:
SetEvent EVENT_BEAT_OAK_ONCE ; This is set every time, but it doesn't matter, it sticks at 1 anyway.
CheckEvent EVENT_RECEIVED_CITRINE_PASS ; Before we do, has the player got the pass?
jr nz, .skip ; Yes? Now we go to auto-ret.
jr OakFirstWin ; Otherwise, move to the first win script to set that up.
.skip
ld a, $0
ld [wRoute1CurScript], a
ret
OakFirstWin:
CheckEvent EVENT_RECEIVED_CITRINE_PASS
jr nz, .skip
ld a, $3
ldh [hSpriteIndex], a
call DisplayTextID
.skip
ld a, $0
ld [wRoute1CurScript], a
ret
Route1_TextPointers:
dw Route1Text1
dw Route1Text2
@ -60,10 +88,19 @@ Route1Text3:
; text
Route1OakText:
text_asm
ld hl, OakBeforeBattleText
CheckEvent EVENT_BEAT_OAK_ONCE ; But if they've not beaten Oak, we need something else.
jr z, .skip ; So if they have, skip the next command.
CheckEvent EVENT_RECEIVED_CITRINE_PASS ; This is used for DisplayTextID. Is checked when Oak has been beaten once.
jp z, OakReceivePass
.skip
CheckEvent EVENT_BEAT_OAK_ONCE ; I am like, 99.9% sure there's another way to do this.
ld hl, OakFirstBattleText ; Load this only if the Citrine Pass hasn't been obtained yet.
jr z, .skip2
ld hl, OakBeforeBattleText ; If he's been beaten before, load the usual prebattle text
.skip2
call PrintText
call YesNoChoice
call YesNoChoice ; Do they want in?
ld a, [wCurrentMenuItem]
and a
jr nz, .refused
@ -86,40 +123,80 @@ Route1OakText:
cp STARTER2
jr nz, .NotSquirtle
ld a, $2 ; If Charmander, Venusaur
jr .done
jr .battleSetup
.NotSquirtle
cp STARTER3
jr nz, .Charmander
ld a, $3 ; If Bulbasaur, Totartle
jr .done
jr .battleSetup
.Charmander
cp STARTER1
jr nz, .Pikachu
ld a, $1 ; If Squirtle, Charizard
jr .done
jr .battleSetup
.Pikachu
cp STARTER4
jr nz, .Eevee
ld a, $4 ; If Pikachu, all 3
jr .done
jr .battleSetup
.Eevee
ld a, $5 ; If Eevee, also all 3
jr .done
jr .battleSetup
.refused
ld hl, OakNo
call PrintText
jp TextScriptEnd
.done
jr .done
.battleSetup
ld [wTrainerNo], a
ld a, 1
ld [wIsTrainerBattle], a
ld a, $2
ld [wRoute1CurScript], a
ld hl, OakDefeatedText
ld de, OakWonText
call SaveEndBattleTextPointers
ld a, $1
ld [wRoute1CurScript], a
.done
jp TextScriptEnd
OakReceivePass:
CheckEvent EVENT_FUCK ; This is for if the player is stupid
jp nz, .tryAgain
ld hl, OakFirstWinText
call PrintText
lb bc, CITRINE_PASS, 1
call GiveItem
jr nc, .bagFull
jr .getPass
.tryAgain
ld hl, OakTryAgain
call PrintText
lb bc, CITRINE_PASS, 1
call GiveItem
jr nc, .bagStillFull
jr .getPass
.bagFull
ld hl, OakBagFull
call PrintText
SetEvent EVENT_FUCK
jr .done
.bagStillFull
ld hl, OakBagStillFull
call PrintText
jr .done
.getPass
ld hl, ReceivedCitrinePassText
call PrintText
ld a, [wSimulatedJoypadStatesEnd] ; ensuring that the text doesn't autoskip.
and a ; yep, here too.
call z, WaitForTextScrollButtonPress ; and here.
call EnableAutoTextBoxDrawing ; and here.
ld hl, OakCitrineExplain
call PrintText
SetEvent EVENT_RECEIVED_CITRINE_PASS
; fallthrough
.done
jp TextScriptEnd
OakBeforeBattleText:
@ -140,4 +217,33 @@ OakYes:
OakNo:
text_far _OakNo
text_end
text_end
OakFirstBattleText:
text_far _OakFirstBattleText
text_end
OakFirstWinText:
text_far _OakFirstWin
text_end
ReceivedCitrinePassText:
text_far _ReceivedCitrinePassText
sound_get_item_2
text_end
OakCitrineExplain:
text_far _OakCitrineExplain
text_end
OakTryAgain:
text_far _OakTryAgain
text_end
OakBagFull:
text_far _OakBagFull
text_end
OakBagStillFull:
text_far _OakBagStillFull
text_end