VermilionCity_Script: call EnableAutoTextBoxDrawing ld hl, wCurrentMapScriptFlags bit 6, [hl] res 6, [hl] push hl call nz, .initCityScript pop hl bit 5, [hl] res 5, [hl] call nz, .setFirstLockTrashCanIndex ld hl, VermilionCity_ScriptPointers ld a, [wVermilionCityCurScript] jp CallFunctionInTable .setFirstLockTrashCanIndex call Random ldh a, [hRandomSub] and $e ld [wFirstLockTrashCanIndex], a ret .initCityScript CheckEventHL EVENT_SS_ANNE_LEFT ret z CheckEventReuseHL EVENT_WALKED_PAST_GUARD_AFTER_SS_ANNE_LEFT SetEventReuseHL EVENT_WALKED_PAST_GUARD_AFTER_SS_ANNE_LEFT ret nz ld a, $2 ld [wVermilionCityCurScript], a ret VermilionCity_ScriptPointers: dw VermilionCityScript0 dw VermilionCityScript1 dw VermilionCityScript2 dw VermilionCityScript3 dw VermilionCityScript4 VermilionCityScript0: ld a, [wSpritePlayerStateData1FacingDirection] and a ; cp SPRITE_FACING_DOWN ret nz ld hl, SSAnneTicketCheckCoords call ArePlayerCoordsInArray ret nc xor a ldh [hJoyHeld], a ld [wcf0d], a ld a, $3 ldh [hSpriteIndexOrTextID], a call DisplayTextID ld a, [wObtainedBadges] ; ship returns after obtaining the marsh badge bit 5, a jr nz, .default CheckEvent EVENT_SS_ANNE_LEFT jr nz, .shipHasDeparted .default ld hl, OldSeaMapCheckCoords call ArePlayerCoordsInArray jp c, MovePlayerVermilion ld hl, CitrineCityCheckCoords call ArePlayerCoordsInArray jp c, MovePlayerVermilion ld b, S_S_TICKET predef GetQuantityOfItemInBag ld a, b and a ret nz .shipHasDeparted ld a, D_UP ld [wSimulatedJoypadStatesEnd], a ld a, $1 ld [wSimulatedJoypadStatesIndex], a call StartSimulatingJoypadStates ld a, $1 ld [wVermilionCityCurScript], a ret SSAnneTicketCheckCoords: ; Mother coords - use to universally trigger the same event dbmapcoord 18, 30 ; S. S. Anne dbmapcoord 10, 30 ; Faraway Island dbmapcoord 26, 30 ; Citrine City db -1 ; end ; I know it looks awful but I use the individual ones to launch off the new ticket script. ; We don't need an S.S. Anne one, as I'm using a process of elimination check system. OldSeaMapCheckCoords: dbmapcoord 10, 30 db -1 CitrineCityCheckCoords: dbmapcoord 26, 30 db -1 VermilionCityScript4: ld hl, SSAnneTicketCheckCoords call ArePlayerCoordsInArray ret c ld a, $0 ld [wVermilionCityCurScript], a ret VermilionCityScript2: ld a, $ff ld [wJoyIgnore], a ld a, D_UP ld [wSimulatedJoypadStatesEnd], a ld [wSimulatedJoypadStatesEnd + 1], a ld a, 2 ld [wSimulatedJoypadStatesIndex], a call StartSimulatingJoypadStates ld a, $3 ld [wVermilionCityCurScript], a ret VermilionCityScript3: ld a, [wSimulatedJoypadStatesIndex] and a ret nz xor a ld [wJoyIgnore], a ldh [hJoyHeld], a ld a, $0 ld [wVermilionCityCurScript], a ret VermilionCityScript1: ld a, [wSimulatedJoypadStatesIndex] and a ret nz ld c, 10 call DelayFrames ld a, $0 ld [wVermilionCityCurScript], a ret ; We call these four commands to stop text from autoskipping 4 times, may as well just make this. TheAutoskipStopinator: ld a, [wSimulatedJoypadStatesEnd] ; ensuring that the text doesn't autoskip. and a ; yep, here too. call z, WaitForTextScrollButtonPress ; and here. call EnableAutoTextBoxDrawing ; and here. ret ; So get this: If you check multiple tickets, there's a really janky crash. ; I can't be fucked fixing it, so let's force the player through the warp instead. ; Yes, I'm serious. MovePlayerVermilion: ld a, PLAYER_DIR_DOWN ld [wPlayerMovingDirection], a call UpdateSprites 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, WalkIntoWarp_RLEMovement call DecodeRLEList dec a ld [wSimulatedJoypadStatesIndex], a call StartSimulatingJoypadStates ; By this point, we're auto-moving. ld a, $0 ld [wVermilionCityCurScript], a ; safety ret WalkIntoWarp_RLEMovement: db D_DOWN, 2 db -1 ; end ; ================================================================ ; THIS IS NO LONGER USED, KEPT IN CASE A BETTER WARP SYSTEM COMES UP. ; Alright, so I'll explain the issue. ; For some reason, all the warp methods that exist do not seem to like this system. ; Faraway Island would load but have botched collision and break when you leave. ; Citrine City would outright crash. ; Bank movements and stuff were tried but nothing seemed to work as desired. ; Instead, we use a triple-harbour method, which makes the city look more lively anyway. ;VermillionCityScript_GetPassesInBag: ; Gets a list of Passes in the player's bag. ; Ripped and modified from the fossil guy ; xor a ; ld [wFilteredBagItemsCount], a ; ld de, wFilteredBagItems ; ld hl, PassList ;.loop ; ld a, [hli] ; and a ; jr z, .done ; push hl ; push de ; ld [wd11e], a ; ld b, a ; predef GetQuantityOfItemInBag ; pop de ; pop hl ; ld a, b ; and a ; jr z, .loop ; ; A Pass is in the bag ; ld a, [wd11e] ; ld [de], a ; inc de ; push hl ; ld hl, wFilteredBagItemsCount ; inc [hl] ; pop hl ; jr .loop ;.done ; ld a, $ff ; ld [de], a ; ret ;PassList: ; db S_S_TICKET ; db OLD_SEA_MAP ; db CITRINE_PASS ; ;db RAINBOW_PASS I planned this for a while, but the space wasn't there, and the scope was strange. ; db 0 ; end ;PrintPassesInBag: ; Prints each pass in the player's bag on a separate line in the menu. ; ld hl, wFilteredBagItems ; xor a ; ldh [hItemCounter], a ;.loop ; ld a, [hli] ; cp $ff ; ret z ; push hl ; ld [wd11e], a ; call GetItemName ; hlcoord 2, 2 ; ldh a, [hItemCounter] ; ld bc, SCREEN_WIDTH * 2 ; call AddNTimes ; ld de, wcd6d ; call PlaceString ; ld hl, hItemCounter ; inc [hl] ; pop hl ; jr .loop ;PassListings: ; ld hl, VermillionCityPassSelectionText ; call PrintText ; call VermillionCityScript_GetPassesInBag ; ld hl, wd730 ; set 6, [hl] ; xor a ; ld [wCurrentMenuItem], a ; ld a, A_BUTTON | B_BUTTON ; ld [wMenuWatchedKeys], a ; ld a, [wFilteredBagItemsCount] ; dec a ; ld [wMaxMenuItem], a ; ld a, 2 ; ld [wTopMenuItemY], a ; ld a, 1 ; ld [wTopMenuItemX], a ; ld a, [wFilteredBagItemsCount] ; dec a ; ld bc, 2 ; ld hl, 3 ; call AddNTimes ; dec l ; ld b, l ; ld c, $d ; hlcoord 0, 0 ; call TextBoxBorder ; call UpdateSprites ; call PrintPassesInBag ; ld hl, wd730 ; res 6, [hl] ; call HandleMenuInput ; bit BIT_B_BUTTON, a ; jr nz, .cancelledPass ; ld hl, wFilteredBagItems ; ld a, [wCurrentMenuItem] ; ld d, 0 ; ld e, a ; add hl, de ; ld a, [hl] ; ldh [hItemToRemoveID], a ; cp S_S_TICKET ; jp z, VermilionCityText3.playerHasTicket ; Saves time and less risk of bugs ; cp OLD_SEA_MAP ; jr z, .choseFaraway ; cp CITRINE_PASS ; jr z, .choseCitrine ; god bless the safari game and pokemon tower 7f for being the few times a forcewarp exists ; For some reason, these aren't working properly... ;.choseFaraway ; ld hl, EventVermillionCityOldSeaMap ; call PrintText ; ld a, FARAWAY_ISLAND_OUTSIDE ; ld [wDestinationMap], a ; ld hl, wd732 ; set 2, [hl] ; fly warp or dungeon warp ; call SpecialWarpIn ; jp SpecialEnterMap ;.choseCitrine ; ld hl, EventVermillionCityCitrinePass ; call PrintText ; ld a, CITRINE_CITY ; ldh [hWarpDestinationMap], a ; ld a, $6 ; ld [wDestinationWarpID], a ; call WarpFound2 ; jr .done ;.cancelledPass ; ld hl, PassRefuse ; call PrintText ;.done ; ret ; ; ================================================================ VermilionCity_TextPointers: dw VermilionCityText1 dw VermilionCityText2 dw VermilionCityText3 dw VermilionCityText4 dw VermilionCityText5 dw VermilionCityText6 dw OfficerJennySquirtle dw VermilionBeauty dw EventVermillionCityOldSeaMapGreeting dw EventVermillionCityCitrinePassGreeting dw VermilionCityText7 dw VermilionCityText8 dw MartSignText dw PokeCenterSignText dw VermilionCityText11 dw VermilionCityText12 dw VermilionCityText13 VermilionCityText1: text_far _VermilionCityText1 text_end VermilionCityText2: text_asm CheckEvent EVENT_SS_ANNE_LEFT jr nz, .shipHasDeparted ld hl, VermilionCityTextDidYouSee call PrintText jr .end .shipHasDeparted ld hl, VermilionCityTextSSAnneDeparted call PrintText .end jp TextScriptEnd VermilionCityTextDidYouSee: text_far _VermilionCityTextDidYouSee text_end VermilionCityTextSSAnneDeparted: text_far _VermilionCityTextSSAnneDeparted text_end VermilionCityText3: text_asm ; Checking the location that the script flagged earlier. ; Instead of using an item checker, this is more effective and easy on memory. ; Also, it doesn't get cross-threaded if you have multiples of the same thing. I had issues working around that one - I ain't a programmer by trade, unfortunately, I'm a TEFL student. ; Anyway, the code kicks you to different versions of the same script; I've had them isolated to call text in a way that's easier architecturally. Otherwise, we're checking the item found every time, and I'm 90% sure that nicks a WRAM entry. ; All in all: Yes, this is suboptimal, but I've been doing this for months. Sue me. ld hl, OldSeaMapCheckCoords call ArePlayerCoordsInArray jr c, HasOldSeaMap ld hl, CitrineCityCheckCoords call ArePlayerCoordsInArray jp c, HasCitrinePass ; If you have neither, this will continue as normal, see? ; This is why we needed the child coords. ; Before the coord system, we used this with the unused pass listing code. ; See where the issues arose? Possibly a neat exercise! ;ld b, OLD_SEA_MAP ;predef GetQuantityOfItemInBag ;ld a, b ;and a ;jp nz, PassListings ;ld b, CITRINE_PASS ;predef GetQuantityOfItemInBag ;ld a, b ;and a ;jp nz, PassListings CheckEvent EVENT_SS_ANNE_LEFT jr nz, .shipHasDeparted ld a, [wSpritePlayerStateData1FacingDirection] cp SPRITE_FACING_RIGHT jr z, .greetPlayer ld hl, .inFrontOfOrBehindGuardCoords call ArePlayerCoordsInArray jr nc, .greetPlayerAndCheckTicket .greetPlayer ld hl, SSAnneWelcomeText4 call PrintText jr .end .greetPlayerAndCheckTicket ld hl, SSAnneWelcomeText9 call PrintText call TheAutoskipStopinator ; this actually fixes a bug from vanilla... ld b, S_S_TICKET predef GetQuantityOfItemInBag ld a, b and a jr nz, .playerHasTicket ld hl, SSAnneNoTicketText call PrintText jr .end .playerHasTicket ld hl, SSAnneFlashedTicketText call PrintText ld a, $4 ld [wVermilionCityCurScript], a jr .end .shipHasDeparted ld hl, SSAnneNotHereText call PrintText .end jp TextScriptEnd .inFrontOfOrBehindGuardCoords ; This can be all at once don't worry. dbmapcoord 19, 29 ; in front of guard - S. S. Anne dbmapcoord 19, 31 ; behind guard - S. S. Anne dbmapcoord 11, 29 ; Faraway Island dbmapcoord 11, 31 ; Faraway Island dbmapcoord 27, 29 ; Citrine City dbmapcoord 27, 31 ; Citrine City db -1 ; end SSAnneWelcomeText4: text_far _SSAnneWelcomeText4 text_end SSAnneWelcomeText9: text_far _SSAnneWelcomeText9 text_end SSAnneFlashedTicketText: text_far _SSAnneFlashedTicketText text_end SSAnneNoTicketText: text_far _SSAnneNoTicketText text_end SSAnneNotHereText: text_far _SSAnneNotHereText text_end HasOldSeaMap: text_asm ld a, [wSpritePlayerStateData1FacingDirection] cp SPRITE_FACING_RIGHT jr z, .greetPlayer ld hl, VermilionCityText3.inFrontOfOrBehindGuardCoords call ArePlayerCoordsInArray jr nc, .greetPlayerAndCheckTicket .greetPlayer ld hl, EventVermillionCityOldSeaMapGreeting call PrintText jr .end .greetPlayerAndCheckTicket ld hl, EventVermillionCityOldSeaMapGreeting call PrintText call TheAutoskipStopinator ld b, OLD_SEA_MAP predef GetQuantityOfItemInBag ld a, b and a jr nz, .playerHasTicket ld hl, EventVermillionCityOldSeaMapGreetCheck call PrintText jr .end .playerHasTicket ld hl, EventVermillionCityOldSeaMap call PrintText ld a, $4 ld [wVermilionCityCurScript], a .end jp TextScriptEnd EventVermillionCityOldSeaMapGreeting: text "I am looking for" line "a certain map..." done text_end EventVermillionCityOldSeaMapGreetCheck: text "Do you have it?" done text_end HasCitrinePass: text_asm ld a, [wSpritePlayerStateData1FacingDirection] cp SPRITE_FACING_RIGHT jr z, .greetPlayer ld hl, VermilionCityText3.inFrontOfOrBehindGuardCoords call ArePlayerCoordsInArray jr nc, .greetPlayerAndCheckTicket .greetPlayer ld hl, EventVermillionCityCitrinePassGreeting call PrintText jr .end .greetPlayerAndCheckTicket ld hl, EventVermillionCityCitrinePassGreeting call PrintText call TheAutoskipStopinator ld b, CITRINE_PASS predef GetQuantityOfItemInBag ld a, b and a jr nz, .playerHasTicket ld hl, EventVermillionCityCitrinePassGreetCheck call PrintText jr .end .playerHasTicket ld hl, EventVermillionCityCitrinePass call PrintText ld a, $4 ld [wVermilionCityCurScript], a .end jp TextScriptEnd EventVermillionCityCitrinePassGreeting: text "Hah! I only serve" line "strong TRAINERs!" done text_end EventVermillionCityCitrinePassGreetCheck: text "Gonna need to see" line "proof, shrimp!" done text_end VermilionCityText4: text_far _VermilionCityText4 text_end VermilionCityText5: text_far _VermilionCityText5 text_asm ld a, MACHOP call PlayCry call WaitForSoundToFinish ld hl, VermilionCityText14 ret VermilionCityText14: text_far _VermilionCityText14 text_end VermilionCityText6: text_asm ld a, [wObtainedBadges] bit 5, a ; after obtaining the marsh badge the ship returns jr z, .default ld hl, VermilionCityText15 ret .default ld hl, VermilionCityText6get ret VermilionCityText6get: text_far _VermilionCityText6 text_end VermilionCityText15: text_far _VermilionCityText15 text_end VermilionCityText7: text_far _VermilionCityText7 text_end VermilionCityText8: text_far _VermilionCityText8 text_end VermilionCityText11: text_far _VermilionCityText11 text_end VermilionCityText12: text_far _VermilionCityText12 text_end VermilionCityText13: text_far _VermilionCityText13 text_end OfficerJennySquirtle: text_asm CheckEvent EVENT_GOT_SQUIRTLE jr nz, .howDoing CheckEvent EVENT_BEAT_LT_SURGE jr z, .noBadge ld hl, OfficerJennyHasBadge call PrintText call YesNoChoice ld a, [wCurrentMenuItem] and a jr nz, .refuse call SaveScreenTilesToBuffer1 ; prevents nickname screen corruption ld a, SQUIRTLE ld [wd11e], a ld [wcf91], a call GetMonName ld a, $1 ld [wDoNotWaitForButtonPressAfterDisplayingText], a lb bc, SQUIRTLE, 16 call GivePokemon ld a, [wAddedToParty] and a call z, WaitForTextScrollButtonPress ld a, $1 ld [wDoNotWaitForButtonPressAfterDisplayingText], a ld hl, OfficerJennyGive call PrintText SetEvent EVENT_GOT_SQUIRTLE jp TextScriptEnd .howDoing ld hl, OfficerJennyHowDoing jr .done .noBadge ld hl, OfficerJennyNoBadge jr .done .refuse ld hl, OfficerJennyRefuse ; fallthrough .done call PrintText jp TextScriptEnd OfficerJennyNoBadge: text_far _OfficerJennyText1 text_end OfficerJennyHasBadge: text_far _OfficerJennyText2 text_end OfficerJennyGive: text_far _OfficerJennyText3 text_waitbutton text_end OfficerJennyRefuse: text_far _OfficerJennyText4 text_end OfficerJennyHowDoing: text_far _OfficerJennyText5 text_end VermillionCityPassSelectionText: text_far _VermillionCityPassSelectionText text_end EventVermillionCityOldSeaMap: text_far _VermillionCityOldSeaMap text_end EventVermillionCityCitrinePass: text_far _VermillionCityCitrinePass text_end EventVermillionCitySSTicket: text_far _SSAnneFlashedTicketText text_end PassRefuse: text_far _VermillionCityHarborRefuse text_end ; LGPE Beauty who gives you a Persian or Arcanine depending on the game. ; Here, we make it a Cats vs Dogs question and change based on that. ; The way it works is it makes the player catch the opposite Pokemon, and then get the one they picked. ; Meowth = Arcanine ; Growlithe = Persian ; This code is nightmare fuel but it does the job. ; Basically, at some point, wBeautyChoice stops working for reasons scientists are still trying to figure out. VermilionBeauty: text_asm CheckEvent EVENT_VERMILION_BEAUTY_DONE ; First, check if the event is actually done. jp nz, .beautyDone ; Yes? Alright, no need for this. ld a, [wBeautyChoice] ; Next, we check if wBeautyChoice has been set. This saves an event constant. cp 0 ; It will never be 0 if the player has made their choice. jr z, .eventStart ; If it is, then the event needs to start. ; We need to do 2 skips here which triggers me but it works. ; You could put the finish check before the choice check, but then it gets a little weird. ; All it really achieves is weird architecture for like 3-4 less machine cycles. ld a, [wBeautyCounter] ; Alright, if you got here, then the event is in progress. cp 5 ; Do you have 5 of the scrunklies? jr z, .eventIsFinished ; Big if true. jr nz, .eventInProgress ; Small if false. ; Let us start the game. .eventStart ld hl, BeautyText1 ; Let's open the text. call PrintText call CatsDogsChoice ld a, [wCurrentMenuItem] ; Let's load what they picked. 0 is cats, 1 is dogs. and a jr nz, .getArcanine ; Skip storing Growlithe if dogs. ld a, GROWLITHE ; If they picked cats, then store Growlithe. jr .skip ; I know this looks bad, but if it isn't here, it'd store Growlithe and then go to Meowth anyway. .getArcanine ; If they get here, they picked dogs, so we store Meowth. ld a, MEOWTH .skip ; Now we land here. ld [wBeautyChoice], a ; Finally store the choice in wBeautyChoice. ld hl, BeautyText2 ; Now spit it out. call PrintText ; This is a jump point for if the event was already started. .eventInProgress ld a, [wBeautyChoice] ld [wd11e], a call GetMonName ld hl, BeautyChoice call PrintText jr .done ; no give pokemon. bad. ; Now if the event is finished, she needs to hand the Pokemon over. .eventIsFinished call SaveScreenTilesToBuffer1 ; saves us from some corruption disasters if nicknaming. ld hl, BeautyFinish1 ld a, [wBeautyChoice] cp GROWLITHE jr z, .skip2 ld hl, BeautyFinish2 .skip2 call PrintText call TheAutoskipStopinator lb bc, PERSIAN, 16 ; because we're elitists, let's see if they chose cats first. ld a, [wBeautyChoice] ; *sigh*, but if they're dog lovers, let's make sure they actually want Persian. cp GROWLITHE ; Do they? If yes, skip. jr z, .skip3 ; electric boogaloo lb bc, ARCANINE, 16 ; ok but skip2 means arc never gets loaded in. very good sequel. disney would NEVER. .skip3 call GivePokemon jr nc, .done call LoadScreenTilesFromBuffer1 ; saves us from some corruption disasters if nicknaming. SetEvent EVENT_VERMILION_BEAUTY_DONE ; and now we can finally rest. ld hl, wd72e set 0, [hl] jr .done ; Now if it's already been said and done, we go here. ; Due to man-made horrors beyond my comprehension, we need to split the text here. .beautyDone ld hl, BeautyExplain1 ld a, [wBeautyChoice] cp GROWLITHE jr z, .skip4 ld hl, BeautyExplain2 .skip4 call PrintText ld hl, BeautyExplainCont call PrintText ;fallthrough .done jp TextScriptEnd ; displays cats/dogs choice CatsDogsChoice: call SaveScreenTilesToBuffer1 call InitCatsDogsTextBoxParameters jr DisplayCatsDogsChoice InitCatsDogsTextBoxParameters: ld a, $2 ; loads the value for the unused SOUTH/EAST choice, which was changed to say CATS/DOGS ld [wTwoOptionMenuID], a hlcoord 12, 8 lb bc, 10, 13 ret DisplayCatsDogsChoice: ld a, $14 ld [wTextBoxID], a call DisplayTextBoxID jp LoadScreenTilesFromBuffer1 BeautyText1: text_far _BeautyText1 text_end BeautyText2: text_far _BeautyText2 text_end BeautyChoice: text_far _BeautyChoice text_end BeautyFinish1: text_far _BeautyFinish1 text_end BeautyFinish2: text_far _BeautyFinish2 text_end BeautyExplain1: text_far _BeautyExplain1 text_end BeautyExplain2: text_far _BeautyExplain2 text_end BeautyExplainCont: text_far _BeautyExplainCont text_end