summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/events/treemons.asm273
-rw-r--r--engine/menus/intro_menu.asm18
-rw-r--r--engine/pokegear/radio.asm1417
3 files changed, 1699 insertions, 9 deletions
diff --git a/engine/events/treemons.asm b/engine/events/treemons.asm
new file mode 100644
index 00000000..94782643
--- /dev/null
+++ b/engine/events/treemons.asm
@@ -0,0 +1,273 @@
+TreeMonEncounter:
+ xor a
+ ld [wTempWildMonSpecies], a
+ ld [wCurPartyLevel], a
+
+ ld hl, TreeMonMaps
+ call GetTreeMonSet
+ jr nc, .no_battle
+
+ call GetTreeMons
+ jr nc, .no_battle
+
+ call GetTreeMon
+ jr nc, .no_battle
+
+ ld a, BATTLETYPE_TREE
+ ld [wBattleType], a
+ ld a, 1
+ ld [wScriptVar], a
+ ret
+
+.no_battle
+ xor a
+ ld [wScriptVar], a
+ ret
+
+RockMonEncounter:
+ xor a
+ ld [wTempWildMonSpecies], a
+ ld [wCurPartyLevel], a
+
+ ld hl, RockMonMaps
+ call GetTreeMonSet
+ jr nc, .no_battle
+
+ call GetTreeMons
+ jr nc, .no_battle
+
+ ; 40% chance of an encounter
+ ld a, 10
+ call RandomRange
+ cp 4
+ jr nc, .no_battle
+
+ call SelectTreeMon
+ jr nc, .no_battle
+
+ ret
+
+.no_battle
+ xor a
+ ret
+
+db $05 ; ????
+
+GetTreeMonSet:
+; Return carry and treemon set in a
+; if the current map is in table hl.
+ ld a, [wMapNumber]
+ ld e, a
+ ld a, [wMapGroup]
+ ld d, a
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .not_in_table
+
+ cp d
+ jr nz, .skip2
+
+ ld a, [hli]
+ cp e
+ jr nz, .skip1
+
+ jr .in_table
+
+.skip2
+ inc hl
+.skip1
+ inc hl
+ jr .loop
+
+.not_in_table
+ xor a
+ ret
+
+.in_table
+ ld a, [hl]
+ scf
+ ret
+
+INCLUDE "data/wild/treemon_maps.asm"
+
+GetTreeMons:
+; Return the address of TreeMon table a in hl.
+; Return nc if table a doesn't exist.
+
+ cp NUM_TREEMON_SETS
+ jr nc, .quit
+
+ and a
+ jr z, .quit
+
+ ld e, a
+ ld d, 0
+ ld hl, TreeMons
+ add hl, de
+ add hl, de
+
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ scf
+ ret
+
+.quit
+ xor a
+ ret
+
+INCLUDE "data/wild/treemons.asm"
+
+GetTreeMon:
+ push hl
+ call GetTreeScore
+ pop hl
+ and a ; TREEMON_SCORE_BAD
+ jr z, .bad
+ cp TREEMON_SCORE_GOOD
+ jr z, .good
+ cp TREEMON_SCORE_RARE
+ jr z, .rare
+ ret
+
+.bad
+ ; 10% chance of an encounter
+ ld a, 10
+ call RandomRange
+ and a
+ jr nz, NoTreeMon
+ jr SelectTreeMon
+
+.good
+ ; 50% chance of an encounter
+ ld a, 10
+ call RandomRange
+ cp 5
+ jr nc, NoTreeMon
+ jr SelectTreeMon
+
+.rare
+ ; 80% chance of an encounter
+ ld a, 10
+ call RandomRange
+ cp 8
+ jr nc, NoTreeMon
+ jr .skip
+.skip
+ ld a, [hli]
+ cp -1
+ jr nz, .skip
+ call SelectTreeMon
+ ret
+
+SelectTreeMon:
+; Read a TreeMons table and pick one monster at random.
+
+ ld a, 100
+ call RandomRange
+.loop
+ sub [hl]
+ jr c, .ok
+ inc hl
+ inc hl
+ inc hl
+ jr .loop
+
+.ok
+ ld a, [hli]
+ cp -1
+ jr z, NoTreeMon
+
+ ld a, [hli]
+ ld [wTempWildMonSpecies], a
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ scf
+ ret
+
+NoTreeMon:
+ xor a
+ ld [wTempWildMonSpecies], a
+ ld [wCurPartyLevel], a
+ ret
+
+GetTreeScore:
+ call .CoordScore
+ ld [wBuffer1], a
+ call .OTIDScore
+ ld [wBuffer2], a
+ ld c, a
+ ld a, [wBuffer1]
+ sub c
+ jr z, .rare
+ jr nc, .ok
+ add 10
+.ok
+ cp 5
+ jr c, .good
+
+.bad
+ xor a ; TREEMON_SCORE_BAD
+ ret
+
+.good
+ ld a, TREEMON_SCORE_GOOD
+ ret
+
+.rare
+ ld a, TREEMON_SCORE_RARE
+ ret
+
+.CoordScore:
+ call GetFacingTileCoord
+ ld hl, 0
+ ld c, e
+ ld b, 0
+ ld a, d
+
+ and a
+ jr z, .next
+.loop
+ add hl, bc
+ dec a
+ jr nz, .loop
+.next
+
+ add hl, bc
+ ld c, d
+ add hl, bc
+
+ ld a, h
+ ldh [hDividend], a
+ ld a, l
+ ldh [hDividend + 1], a
+ ld a, 5
+ ldh [hDivisor], a
+ ld b, 2
+ call Divide
+
+ ldh a, [hQuotient + 2]
+ ldh [hDividend], a
+ ldh a, [hQuotient + 3]
+ ldh [hDividend + 1], a
+ ld a, 10
+ ldh [hDivisor], a
+ ld b, 2
+ call Divide
+
+ ldh a, [hRemainder]
+ ret
+
+.OTIDScore:
+ ld a, [wPlayerID]
+ ldh [hDividend], a
+ ld a, [wPlayerID + 1]
+ ldh [hDividend + 1], a
+ ld a, 10
+ ldh [hDivisor], a
+ ld b, 2
+ call Divide
+ ldh a, [hRemainder]
+ ret
diff --git a/engine/menus/intro_menu.asm b/engine/menus/intro_menu.asm
index 7c46ed93..e7534472 100644
--- a/engine/menus/intro_menu.asm
+++ b/engine/menus/intro_menu.asm
@@ -451,28 +451,28 @@ InitializeWorld: ; 5d97 (1:5d97)
ret
LoadOrRegenerateLuckyIDNumber: ; 5da7 (1:5da7)
- ld a, $0
+ ld a, 0
call OpenSRAM
ld a, [wCurDay]
inc a
ld b, a
- ld a, [s0_ac68]
+ ld a, [sLuckyNumberDay]
cp b
- ld a, [s0_ac6a]
+ ld a, [sLuckyIDNumber + 1]
ld c, a
- ld a, [s0_ac69]
+ ld a, [sLuckyIDNumber]
jr z, .asm_5dc9
ld a, b
- ld [s0_ac68], a
+ ld [sLuckyNumberDay], a
call Random
ld c, a
call Random
.asm_5dc9
- ld [wd9e9], a
- ld [s0_ac69], a
+ ld [wLuckyIDNumber], a
+ ld [sLuckyIDNumber], a
ld a, c
- ld [wd9ea], a
- ld [s0_ac6a], a
+ ld [wLuckyIDNumber + 1], a
+ ld [sLuckyIDNumber + 1], a
jp CloseSRAM
MainMenu_Continue:
diff --git a/engine/pokegear/radio.asm b/engine/pokegear/radio.asm
new file mode 100644
index 00000000..44babe34
--- /dev/null
+++ b/engine/pokegear/radio.asm
@@ -0,0 +1,1417 @@
+PlayRadioShow:
+; If we're already in the radio program proper, we don't need to be here.
+ ld a, [wCurRadioLine]
+ cp POKE_FLUTE_RADIO
+ jr nc, .ok
+; If Team Rocket is not occupying the radio tower, we don't need to be here.
+ ld a, [wStatusFlags2]
+ bit STATUSFLAGS2_ROCKETS_IN_RADIO_TOWER_F, a
+ jr z, .ok
+; If we're in Kanto, we don't need to be here.
+ call IsInJohto
+ and a
+ jr nz, .ok
+; Team Rocket broadcasts on all stations.
+ ld a, ROCKET_RADIO
+ ld [wCurRadioLine], a
+.ok
+; Jump to the currently loaded station. The index to which we need to jump is in wCurRadioLine.
+ ld a, [wCurRadioLine]
+ ld e, a
+ ld d, 0
+ ld hl, RadioJumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+RadioJumptable:
+; entries correspond to constants/radio_constants.asm
+ dw OaksPKMNTalk1 ; $00
+ dw PokedexShow1 ; $01
+ dw BenMonMusic1 ; $02
+ dw LuckyNumberShow1 ; $03
+ dw PeoplePlaces1 ; $04
+ dw FernMonMusic1 ; $05
+ dw RocketRadio1 ; $06
+ dw PokeFluteRadio ; $07
+ dw UnownRadio ; $08
+ dw EvolutionRadio ; $09
+; OaksPKMNTalk
+ dw OaksPKMNTalk2 ; $0a
+ dw OaksPKMNTalk3 ; $0b
+ dw OaksPKMNTalk4 ; $0c
+ dw OaksPKMNTalk5 ; $0d
+ dw OaksPKMNTalk6 ; $0e
+ dw OaksPKMNTalk7 ; $0f
+ dw OaksPKMNTalk8 ; $10
+ dw OaksPKMNTalk9 ; $11
+ dw PokedexShow2 ; $12
+ dw PokedexShow3 ; $13
+ dw PokedexShow4 ; $14
+ dw PokedexShow5 ; $15
+; Ben Music
+ dw BenMonMusic2 ; $16
+ dw BenMonMusic3 ; $17
+ dw BenFernMusic4 ; $18
+ dw BenFernMusic5 ; $19
+ dw BenFernMusic6 ; $1a
+ dw BenFernMusic7 ; $1b
+ dw FernMonMusic2 ; $1c
+; Lucky Number Show
+ dw LuckyNumberShow2 ; $1d
+ dw LuckyNumberShow3 ; $1e
+ dw LuckyNumberShow4 ; $1f
+ dw LuckyNumberShow5 ; $20
+ dw LuckyNumberShow6 ; $21
+ dw LuckyNumberShow7 ; $22
+ dw LuckyNumberShow8 ; $23
+ dw LuckyNumberShow9 ; $24
+ dw LuckyNumberShow10 ; $25
+ dw LuckyNumberShow11 ; $26
+ dw LuckyNumberShow12 ; $27
+ dw LuckyNumberShow13 ; $28
+ dw LuckyNumberShow14 ; $29
+ dw LuckyNumberShow15 ; $2a
+; People & Places
+ dw PeoplePlaces2 ; $2b
+ dw PeoplePlaces3 ; $2c
+ dw PeoplePlaces4 ; $2d
+ dw PeoplePlaces5 ; $2e
+ dw PeoplePlaces6 ; $2f
+ dw PeoplePlaces7 ; $30
+; Rocket Radio
+ dw RocketRadio2 ; $31
+ dw RocketRadio3 ; $32
+ dw RocketRadio4 ; $33
+ dw RocketRadio5 ; $34
+ dw RocketRadio6 ; $35
+ dw RocketRadio7 ; $36
+ dw RocketRadio8 ; $37
+ dw RocketRadio9 ; $38
+ dw RocketRadio10 ; $39
+; More Pokemon Channel stuff
+ dw OaksPKMNTalk10 ; $3a
+ dw OaksPKMNTalk11 ; $3b
+ dw OaksPKMNTalk12 ; $3c
+ dw OaksPKMNTalk13 ; $3d
+ dw OaksPKMNTalk14 ; $3e
+ dw RadioScroll ; $3f
+; More Pokemon Channel stuff
+ dw PokedexShow6 ; $40
+ dw PokedexShow7 ; $41
+ dw PokedexShow8 ; $42
+
+PrintRadioLine:
+ ld [wNextRadioLine], a
+ ld hl, wRadioText
+ ld a, [wNumRadioLinesPrinted]
+ cp 2
+ jr nc, .print
+ inc hl
+ ld [hl], TX_START
+ inc a
+ ld [wNumRadioLinesPrinted], a
+ cp 2
+ jr nz, .print
+ bccoord 1, 16
+ call PlaceHLTextAtBC
+ jr .skip
+.print
+ call PrintTextboxText
+.skip
+ ld a, RADIO_SCROLL
+ ld [wCurRadioLine], a
+ ld a, 100
+ ld [wRadioTextDelay], a
+ ret
+
+ReplacePeriodsWithSpaces:
+ push hl
+ ld b, SCREEN_WIDTH * 2
+.loop
+ ld a, [hl]
+ cp "."
+ jr nz, .next
+ ld [hl], " "
+
+.next
+ inc hl
+ dec b
+ jr nz, .loop
+ pop hl
+ ret
+
+RadioScroll:
+ ld hl, wRadioTextDelay
+ ld a, [hl]
+ and a
+ jr z, .proceed
+ dec [hl]
+ ret
+.proceed
+ ld a, [wNextRadioLine]
+ ld [wCurRadioLine], a
+ ld a, [wNumRadioLinesPrinted]
+ cp 1
+ call nz, CopyBottomLineToTopLine
+ jp ClearBottomLine
+
+OaksPKMNTalk1:
+ ld a, 5
+ ld [wOaksPKMNTalkSegmentCounter], a
+ call StartRadioStation
+ ld hl, OPT_IntroText1
+ ld a, OAKS_POKEMON_TALK_2
+ jp NextRadioLine
+
+OaksPKMNTalk2:
+ ld hl, OPT_IntroText2
+ ld a, OAKS_POKEMON_TALK_3
+ jp NextRadioLine
+
+OaksPKMNTalk3:
+ ld hl, OPT_IntroText3
+ ld a, OAKS_POKEMON_TALK_4
+ jp NextRadioLine
+
+OaksPKMNTalk4:
+; Choose a random route, and a random Pokemon from that route.
+.sample
+ call Random
+ and %11111
+ cp (OaksPKMNTalkRoutes.End - OaksPKMNTalkRoutes) / 2
+ jr nc, .sample
+ ; We now have a number between 0 and 14.
+ ld hl, OaksPKMNTalkRoutes
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ ; bc now contains the chosen map's group and number indices.
+ push bc
+
+ ; Search the JohtoGrassWildMons array for the chosen map.
+ ld hl, JohtoGrassWildMons
+.loop
+ ld a, BANK(JohtoGrassWildMons)
+ call GetFarByte
+ cp -1
+ jr z, .overflow
+ inc hl
+ cp b
+ jr nz, .next
+ ld a, BANK(JohtoGrassWildMons)
+ call GetFarByte
+ cp c
+ jr z, .done
+.next
+ dec hl
+ ld de, GRASS_WILDDATA_LENGTH
+ add hl, de
+ jr .loop
+
+.done
+ ; Point hl to the list of morning Pokémon., skipping percentages
+rept 4
+ inc hl
+endr
+ ; Generate a number, either 0, 1, or 2, to choose a time of day.
+.loop2
+ call Random
+ maskbits NUM_DAYTIMES
+ cp DARKNESS_F
+ jr z, .loop2
+
+ ld bc, 2 * NUM_GRASSMON
+ call AddNTimes
+.loop3
+ ; Choose one of the middle three Pokemon.
+ call Random
+ and NUM_GRASSMON
+ cp 2
+ jr c, .loop3
+ cp 5
+ jr nc, .loop3
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ inc hl ; skip level
+ ld a, BANK(JohtoGrassWildMons)
+ call GetFarByte
+ ld [wNamedObjectIndexBuffer], a
+ ld [wCurPartySpecies], a
+ call GetPokemonName
+ ld hl, wStringBuffer1
+ ld de, wMonOrItemNameBuffer
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+ ; Now that we've chosen our wild Pokemon,
+ ; let's recover the map index info and get its name.
+ pop bc
+ call GetWorldMapLocation
+ ld e, a
+ callfar GetLandmarkName
+ ld hl, OPT_OakText1
+ call CopyRadioTextToRAM
+ ld a, OAKS_POKEMON_TALK_5
+ jp PrintRadioLine
+
+.overflow
+ pop bc
+ ld a, OAKS_POKEMON_TALK
+ jp PrintRadioLine
+
+INCLUDE "data/radio/oaks_pkmn_talk_routes.asm"
+
+OaksPKMNTalk5:
+ ld hl, OPT_OakText2
+ ld a, OAKS_POKEMON_TALK_6
+ jp NextRadioLine
+
+OaksPKMNTalk6:
+ ld hl, OPT_OakText3
+ ld a, OAKS_POKEMON_TALK_7
+ jp NextRadioLine
+
+OPT_IntroText1:
+ text_far _OPT_IntroText1
+ text_end
+
+OPT_IntroText2:
+ text_far _OPT_IntroText2
+ text_end
+
+OPT_IntroText3:
+ text_far _OPT_IntroText3
+ text_end
+
+OPT_OakText1:
+ text_far _OPT_OakText1
+ text_end
+
+OPT_OakText2:
+ text_far _OPT_OakText2
+ text_end
+
+OPT_OakText3:
+ text_far _OPT_OakText3
+ text_end
+
+OaksPKMNTalk7:
+ ld a, [wCurPartySpecies]
+ ld [wNamedObjectIndexBuffer], a
+ call GetPokemonName
+ ld hl, OPT_MaryText1
+ ld a, OAKS_POKEMON_TALK_8
+ jp NextRadioLine
+
+OPT_MaryText1:
+ text_far _OPT_MaryText1
+ text_end
+
+OaksPKMNTalk8:
+ ; 0-15 are all valid indexes into .Adverbs,
+ ; so no need for a retry loop
+ call Random
+ maskbits NUM_OAKS_POKEMON_TALK_ADVERBS
+ ld e, a
+ ld d, 0
+ ld hl, .Adverbs
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, OAKS_POKEMON_TALK_9
+ jp NextRadioLine
+
+.Adverbs:
+; there are NUM_OAKS_POKEMON_TALK_ADVERBS entries
+ dw .OPT_SweetAdorablyText
+ dw .OPT_WigglySlicklyText
+ dw .OPT_AptlyNamedText
+ dw .OPT_UndeniablyKindOfText
+ dw .OPT_UnbearablyText
+ dw .OPT_WowImpressivelyText
+ dw .OPT_AlmostPoisonouslyText
+ dw .OPT_SensuallyText
+ dw .OPT_MischievouslyText
+ dw .OPT_TopicallyText
+ dw .OPT_AddictivelyText
+ dw .OPT_LooksInWaterText
+ dw .OPT_EvolutionMustBeText
+ dw .OPT_ProvocativelyText
+ dw .OPT_FlippedOutText
+ dw .OPT_HeartMeltinglyText
+
+.OPT_SweetAdorablyText:
+ text_far _OPT_SweetAdorablyText
+ text_end
+
+.OPT_WigglySlicklyText:
+ text_far _OPT_WigglySlicklyText
+ text_end
+
+.OPT_AptlyNamedText:
+ text_far _OPT_AptlyNamedText
+ text_end
+
+.OPT_UndeniablyKindOfText:
+ text_far _OPT_UndeniablyKindOfText
+ text_end
+
+.OPT_UnbearablyText:
+ text_far _OPT_UnbearablyText
+ text_end
+
+.OPT_WowImpressivelyText:
+ text_far _OPT_WowImpressivelyText
+ text_end
+
+.OPT_AlmostPoisonouslyText:
+ text_far _OPT_AlmostPoisonouslyText
+ text_end
+
+.OPT_SensuallyText:
+ text_far _OPT_SensuallyText
+ text_end
+
+.OPT_MischievouslyText:
+ text_far _OPT_MischievouslyText
+ text_end
+
+.OPT_TopicallyText:
+ text_far _OPT_TopicallyText
+ text_end
+
+.OPT_AddictivelyText:
+ text_far _OPT_AddictivelyText
+ text_end
+
+.OPT_LooksInWaterText:
+ text_far _OPT_LooksInWaterText
+ text_end
+
+.OPT_EvolutionMustBeText:
+ text_far _OPT_EvolutionMustBeText
+ text_end
+
+.OPT_ProvocativelyText:
+ text_far _OPT_ProvocativelyText
+ text_end
+
+.OPT_FlippedOutText:
+ text_far _OPT_FlippedOutText
+ text_end
+
+.OPT_HeartMeltinglyText:
+ text_far _OPT_HeartMeltinglyText
+ text_end
+
+OaksPKMNTalk9:
+ ; 0-15 are all valid indexes into .Adjectives,
+ ; so no need for a retry loop
+ call Random
+ maskbits NUM_OAKS_POKEMON_TALK_ADJECTIVES
+ ld e, a
+ ld d, 0
+ ld hl, .Adjectives
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wOaksPKMNTalkSegmentCounter]
+ dec a
+ ld [wOaksPKMNTalkSegmentCounter], a
+ ld a, OAKS_POKEMON_TALK_4
+ jr nz, .ok
+ ld a, 5
+ ld [wOaksPKMNTalkSegmentCounter], a
+ ld a, OAKS_POKEMON_TALK_10
+.ok
+ jp NextRadioLine
+
+.Adjectives:
+; there are NUM_OAKS_POKEMON_TALK_ADJECTIVES entries
+ dw .OPT_CuteText
+ dw .OPT_WeirdText
+ dw .OPT_PleasantText
+ dw .OPT_BoldSortOfText
+ dw .OPT_FrighteningText
+ dw .OPT_SuaveDebonairText
+ dw .OPT_PowerfulText
+ dw .OPT_ExcitingText
+ dw .OPT_GroovyText
+ dw .OPT_InspiringText
+ dw .OPT_FriendlyText
+ dw .OPT_HotHotHotText
+ dw .OPT_StimulatingText
+ dw .OPT_GuardedText
+ dw .OPT_LovelyText
+ dw .OPT_SpeedyText
+
+.OPT_CuteText:
+ text_far _OPT_CuteText
+ text_end
+
+.OPT_WeirdText:
+ text_far _OPT_WeirdText
+ text_end
+
+.OPT_PleasantText:
+ text_far _OPT_PleasantText
+ text_end
+
+.OPT_BoldSortOfText:
+ text_far _OPT_BoldSortOfText
+ text_end
+
+.OPT_FrighteningText:
+ text_far _OPT_FrighteningText
+ text_end
+
+.OPT_SuaveDebonairText:
+ text_far _OPT_SuaveDebonairText
+ text_end
+
+.OPT_PowerfulText:
+ text_far _OPT_PowerfulText
+ text_end
+
+.OPT_ExcitingText:
+ text_far _OPT_ExcitingText
+ text_end
+
+.OPT_GroovyText:
+ text_far _OPT_GroovyText
+ text_end
+
+.OPT_InspiringText:
+ text_far _OPT_InspiringText
+ text_end
+
+.OPT_FriendlyText:
+ text_far _OPT_FriendlyText
+ text_end
+
+.OPT_HotHotHotText:
+ text_far _OPT_HotHotHotText
+ text_end
+
+.OPT_StimulatingText:
+ text_far _OPT_StimulatingText
+ text_end
+
+.OPT_GuardedText:
+ text_far _OPT_GuardedText
+ text_end
+
+.OPT_LovelyText:
+ text_far _OPT_LovelyText
+ text_end
+
+.OPT_SpeedyText:
+ text_far _OPT_SpeedyText
+ text_end
+
+OaksPKMNTalk10:
+ farcall RadioMusicRestartPokemonChannel
+ ld hl, OPT_RestartText
+ call PrintText
+ call WaitBGMap
+ ld hl, OPT_PokemonChannelText
+ call PrintText
+ ld a, OAKS_POKEMON_TALK_11
+ ld [wCurRadioLine], a
+ ld a, 100
+ ld [wRadioTextDelay], a
+ ret
+
+OPT_PokemonChannelText:
+ text_far _OPT_PokemonChannelText
+ text_end
+
+OPT_RestartText:
+ text_end
+
+OaksPKMNTalk11:
+ ld hl, wRadioTextDelay
+ dec [hl]
+ ret nz
+ hlcoord 9, 14
+ ld de, .pokemon_string
+ ld a, OAKS_POKEMON_TALK_12
+ jp PlaceRadioString
+
+.pokemon_string
+ db "#MON@"
+
+OaksPKMNTalk12:
+ ld hl, wRadioTextDelay
+ dec [hl]
+ ret nz
+ hlcoord 1, 16
+ ld de, .pokemon_channel_string
+ ld a, OAKS_POKEMON_TALK_13
+ jp PlaceRadioString
+
+.pokemon_channel_string
+ db "#MON Channel@"
+
+OaksPKMNTalk13:
+ ld hl, wRadioTextDelay
+ dec [hl]
+ ret nz
+ hlcoord 12, 16
+ ld de, .terminator
+ ld a, OAKS_POKEMON_TALK_14
+ jp PlaceRadioString
+
+.terminator
+ db "@"
+
+OaksPKMNTalk14:
+ ld hl, wRadioTextDelay
+ dec [hl]
+ ret nz
+ ld de, MUSIC_POKEMON_TALK
+ callfar RadioMusicRestartDE
+ ld hl, .terminator
+ call PrintText
+ ld a, OAKS_POKEMON_TALK_4
+ ld [wNextRadioLine], a
+ xor a
+ ld [wNumRadioLinesPrinted], a
+ ld a, RADIO_SCROLL
+ ld [wCurRadioLine], a
+ ld a, 10
+ ld [wRadioTextDelay], a
+ ret
+
+.terminator
+ db "@"
+
+PlaceRadioString:
+ ld [wCurRadioLine], a
+ ld a, 100
+ ld [wRadioTextDelay], a
+ jp PlaceString
+
+CopyBottomLineToTopLine:
+ hlcoord 0, 15
+ decoord 0, 13
+ ld bc, SCREEN_WIDTH * 2
+ jp CopyBytes
+
+ClearBottomLine:
+ hlcoord 1, 15
+ ld bc, SCREEN_WIDTH - 2
+ ld a, " "
+ call ByteFill
+ hlcoord 1, 16
+ ld bc, SCREEN_WIDTH - 2
+ ld a, " "
+ jp ByteFill
+
+PokedexShow1:
+ call StartRadioStation
+.loop
+ call Random
+ cp NUM_POKEMON
+ jr nc, .loop
+ ld c, a
+ push bc
+ ld a, c
+ call CheckCaughtMon
+ pop bc
+ jr z, .loop
+ inc c
+ ld a, c
+ ld [wCurPartySpecies], a
+ ld [wNamedObjectIndexBuffer], a
+ call GetPokemonName
+ ld hl, PokedexShowText
+ ld a, POKEDEX_SHOW_2
+ jp NextRadioLine
+
+PokedexShow2:
+ ld a, [wCurPartySpecies]
+ dec a
+ ld hl, PokedexDataPointerTable
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ rlca
+ rlca
+ and 3
+ add $68
+ push af
+ ld a, BANK(PokedexDataPointerTable)
+ call GetFarHalfword
+ pop af
+ push af
+ push hl
+ call CopyDexEntryPart1
+ dec hl
+ ld [hl], "<DONE>"
+ ld hl, wPokedexShowPointerAddr
+ call CopyRadioTextToRAM
+ pop hl
+ pop af
+ call CopyDexEntryPart2
+rept 4
+ inc hl
+endr
+ ld a, l
+ ld [wPokedexShowPointerAddr], a
+ ld a, h
+ ld [wPokedexShowPointerAddr + 1], a
+ ld a, POKEDEX_SHOW_3
+ jp PrintRadioLine
+
+PokedexShow3:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW_4
+ jp PrintRadioLine
+
+PokedexShow4:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW_5
+ jp PrintRadioLine
+
+PokedexShow5:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW_6
+ jp PrintRadioLine
+
+PokedexShow6:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW_7
+ jp PrintRadioLine
+
+PokedexShow7:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW_8
+ jp PrintRadioLine
+
+PokedexShow8:
+ call CopyDexEntry
+ ld a, POKEDEX_SHOW
+ jp PrintRadioLine
+
+CopyDexEntry:
+ ld a, [wPokedexShowPointerAddr]
+ ld l, a
+ ld a, [wPokedexShowPointerAddr + 1]
+ ld h, a
+ ld a, [wPokedexShowPointerBank]
+ push af
+ push hl
+ call CopyDexEntryPart1
+ dec hl
+ ld [hl], "<DONE>"
+ ld hl, wPokedexShowPointerAddr
+ call CopyRadioTextToRAM
+ pop hl
+ pop af
+ call CopyDexEntryPart2
+ ret
+
+CopyDexEntryPart1:
+ ld de, wPokedexShowPointerBank
+ ld bc, SCREEN_WIDTH - 1
+ call FarCopyBytes
+ ld hl, wPokedexShowPointerAddr
+ ld [hl], TX_START
+ inc hl
+ ld [hl], "<LINE>"
+ inc hl
+.loop
+ ld a, [hli]
+ cp "@"
+ ret z
+ cp "<NEXT>"
+ ret z
+ cp "<DEXEND>"
+ ret z
+ jr .loop
+
+CopyDexEntryPart2:
+ ld d, a
+.loop
+ ld a, d
+ call GetFarByte
+ inc hl
+ cp "@"
+ jr z, .okay
+ cp "<NEXT>"
+ jr z, .okay
+ cp "<DEXEND>"
+ jr nz, .loop
+.okay
+ ld a, l
+ ld [wPokedexShowPointerAddr], a
+ ld a, h
+ ld [wPokedexShowPointerAddr + 1], a
+ ld a, d
+ ld [wPokedexShowPointerBank], a
+ ret
+
+PokedexShowText:
+ text_far _PokedexShowText
+ text_end
+
+BenMonMusic1:
+ call StartPokemonMusicChannel
+ ld hl, BenIntroText1
+ ld a, POKEMON_MUSIC_2
+ jp NextRadioLine
+
+BenMonMusic2:
+ ld hl, BenIntroText2
+ ld a, POKEMON_MUSIC_3
+ jp NextRadioLine
+
+BenMonMusic3:
+ ld hl, BenIntroText3
+ ld a, POKEMON_MUSIC_4
+ jp NextRadioLine
+
+FernMonMusic1:
+ call StartPokemonMusicChannel
+ ld hl, FernIntroText1
+ ld a, LETS_ALL_SING_2
+ jp NextRadioLine
+
+FernMonMusic2:
+ ld hl, FernIntroText2
+ ld a, POKEMON_MUSIC_4
+ jp NextRadioLine
+
+BenFernMusic4:
+ ld hl, BenFernText1
+ ld a, POKEMON_MUSIC_5
+ jp NextRadioLine
+
+BenFernMusic5:
+ call GetWeekday
+ and 1
+ ld hl, BenFernText2A
+ jr z, .SunTueThurSun
+ ld hl, BenFernText2B
+.SunTueThurSun:
+ ld a, POKEMON_MUSIC_6
+ jp NextRadioLine
+
+BenFernMusic6:
+ call GetWeekday
+ and 1
+ ld hl, BenFernText3A
+ jr z, .SunTueThurSun
+ ld hl, BenFernText3B
+.SunTueThurSun:
+ ld a, POKEMON_MUSIC_7
+ jp NextRadioLine
+
+BenFernMusic7:
+ ret
+
+StartPokemonMusicChannel:
+ call RadioTerminator
+ call PrintText
+ ld de, MUSIC_POKEMON_MARCH
+ call GetWeekday
+ and 1
+ jr z, .SunTueThurSun
+ ld de, MUSIC_POKEMON_LULLABY
+.SunTueThurSun:
+ callfar RadioMusicRestartDE
+ ret
+
+BenIntroText1:
+ text_far _BenIntroText1
+ text_end
+
+BenIntroText2:
+ text_far _BenIntroText2
+ text_end
+
+BenIntroText3:
+ text_far _BenIntroText3
+ text_end
+
+FernIntroText1:
+ text_far _FernIntroText1
+ text_end
+
+FernIntroText2:
+ text_far _FernIntroText2
+ text_end
+
+BenFernText1:
+ text_far _BenFernText1
+ text_end
+
+BenFernText2A:
+ text_far _BenFernText2A
+ text_end
+
+BenFernText2B:
+ text_far _BenFernText2B
+ text_end
+
+BenFernText3A:
+ text_far _BenFernText3A
+ text_end
+
+BenFernText3B:
+ text_far _BenFernText3B
+ text_end
+
+LuckyNumberShow1:
+ call StartRadioStation
+ callfar CheckLuckyNumberShowFlag
+ jr nc, .dontreset
+ callfar ResetLuckyNumberShowFlag
+.dontreset
+ ld hl, LC_Text1
+ ld a, LUCKY_NUMBER_SHOW_2
+ jp NextRadioLine
+
+LuckyNumberShow2:
+ ld hl, LC_Text2
+ ld a, LUCKY_NUMBER_SHOW_3
+ jp NextRadioLine
+
+LuckyNumberShow3:
+ ld hl, LC_Text3
+ ld a, LUCKY_NUMBER_SHOW_4
+ jp NextRadioLine
+
+LuckyNumberShow4:
+ ld hl, LC_Text4
+ ld a, LUCKY_NUMBER_SHOW_5
+ jp NextRadioLine
+
+LuckyNumberShow5:
+ ld hl, LC_Text5
+ ld a, LUCKY_NUMBER_SHOW_6
+ jp NextRadioLine
+
+LuckyNumberShow6:
+ ld hl, LC_Text6
+ ld a, LUCKY_NUMBER_SHOW_7
+ jp NextRadioLine
+
+LuckyNumberShow7:
+ ld hl, LC_Text7
+ ld a, LUCKY_NUMBER_SHOW_8
+ jp NextRadioLine
+
+LuckyNumberShow8:
+ ld hl, wStringBuffer1
+ ld de, wLuckyIDNumber
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+ call PrintNum
+ ld a, "@"
+ ld [wStringBuffer1 + 5], a
+ ld hl, LC_Text8
+ ld a, LUCKY_NUMBER_SHOW_9
+ jp NextRadioLine
+
+LuckyNumberShow9:
+ ld hl, LC_Text9
+ ld a, LUCKY_NUMBER_SHOW_10
+ jp NextRadioLine
+
+LuckyNumberShow10:
+ ld hl, LC_Text7
+ ld a, LUCKY_NUMBER_SHOW_11
+ jp NextRadioLine
+
+LuckyNumberShow11:
+ ld hl, LC_Text8
+ ld a, LUCKY_NUMBER_SHOW_12
+ jp NextRadioLine
+
+LuckyNumberShow12:
+ ld hl, LC_Text10
+ ld a, LUCKY_NUMBER_SHOW_13
+ jp NextRadioLine
+
+LuckyNumberShow13:
+ ld hl, LC_Text11
+ call Random
+ and a
+ ld a, LUCKY_CHANNEL
+ jr nz, .okay
+ ld a, LUCKY_NUMBER_SHOW_14
+.okay
+ jp NextRadioLine
+
+LuckyNumberShow14:
+ ld hl, LC_DragText1
+ ld a, LUCKY_NUMBER_SHOW_15
+ jp NextRadioLine
+
+LuckyNumberShow15:
+ ld hl, LC_DragText2
+ ld a, LUCKY_CHANNEL
+ jp NextRadioLine
+
+LC_Text1:
+ text_far _LC_Text1
+ text_end
+
+LC_Text2:
+ text_far _LC_Text2
+ text_end
+
+LC_Text3:
+ text_far _LC_Text3
+ text_end
+
+LC_Text4:
+ text_far _LC_Text4
+ text_end
+
+LC_Text5:
+ text_far _LC_Text5
+ text_end
+
+LC_Text6:
+ text_far _LC_Text6
+ text_end
+
+LC_Text7:
+ text_far _LC_Text7
+ text_end
+
+LC_Text8:
+ text_far _LC_Text8
+ text_end
+
+LC_Text9:
+ text_far _LC_Text9
+ text_end
+
+LC_Text10:
+ text_far _LC_Text10
+ text_end
+
+LC_Text11:
+ text_far _LC_Text11
+ text_end
+
+LC_DragText1:
+ text_far _LC_DragText1
+ text_end
+
+LC_DragText2:
+ text_far _LC_DragText2
+ text_end
+
+PeoplePlaces1:
+ call StartRadioStation
+ ld hl, PnP_Text1
+ ld a, PLACES_AND_PEOPLE_2
+ jp NextRadioLine
+
+PeoplePlaces2:
+ ld hl, PnP_Text2
+ ld a, PLACES_AND_PEOPLE_3
+ jp NextRadioLine
+
+PeoplePlaces3:
+ ld hl, PnP_Text3
+ call Random
+ cp 49 percent - 1
+ ld a, PLACES_AND_PEOPLE_4 ; People
+ jr c, .ok
+ ld a, PLACES_AND_PEOPLE_6 ; Places
+.ok
+ jp NextRadioLine
+
+PnP_Text1:
+ text_far _PnP_Text1
+ text_end
+
+PnP_Text2:
+ text_far _PnP_Text2
+ text_end
+
+PnP_Text3:
+ text_far _PnP_Text3
+ text_end
+
+PeoplePlaces4: ; People
+ call Random
+ maskbits NUM_TRAINER_CLASSES
+ inc a
+ cp NUM_TRAINER_CLASSES
+ jr nc, PeoplePlaces4
+ push af
+ ld hl, PnP_HiddenPeople
+ ld a, [wStatusFlags]
+ bit STATUSFLAGS_HALL_OF_FAME_F, a
+ jr z, .ok
+ ld hl, PnP_HiddenPeople_BeatE4
+ ld a, [wKantoBadges]
+ cp %11111111 ; all badges
+ jr nz, .ok
+ ld hl, PnP_HiddenPeople_BeatKanto
+.ok
+ pop af
+ ld c, a
+ ld de, 1
+ push bc
+ call IsInArray
+ pop bc
+ jr c, PeoplePlaces4
+ push bc
+ callfar GetTrainerClassName
+ ld de, wStringBuffer1
+ call CopyName1
+ pop bc
+ ld b, 1
+ callfar GetTrainerName
+ ld hl, PnP_Text4
+ ld a, PLACES_AND_PEOPLE_5
+ jp NextRadioLine
+
+INCLUDE "data/radio/pnp_hidden_people.asm"
+
+PnP_Text4:
+ text_far _PnP_Text4
+ text_end
+
+PeoplePlaces5:
+ ; 0-15 are all valid indexes into .Adjectives,
+ ; so no need for a retry loop
+ call Random
+ maskbits NUM_PNP_PEOPLE_ADJECTIVES
+ ld e, a
+ ld d, 0
+ ld hl, .Adjectives
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call Random
+ cp 4 percent
+ ld a, PLACES_AND_PEOPLE
+ jr c, .ok
+ call Random
+ cp 49 percent - 1
+ ld a, PLACES_AND_PEOPLE_4 ; People
+ jr c, .ok
+ ld a, PLACES_AND_PEOPLE_6 ; Places
+.ok
+ jp NextRadioLine
+
+.Adjectives:
+; there are NUM_PNP_PEOPLE_ADJECTIVES entries
+ dw PnP_CuteText
+ dw PnP_LazyText
+ dw PnP_HappyText
+ dw PnP_NoisyText
+ dw PnP_PrecociousText
+ dw PnP_BoldText
+ dw PnP_PickyText
+ dw PnP_SortOfOKText
+ dw PnP_SoSoText
+ dw PnP_GreatText
+ dw PnP_MyTypeText
+ dw PnP_CoolText
+ dw PnP_InspiringText
+ dw PnP_WeirdText
+ dw PnP_RightForMeText
+ dw PnP_OddText
+
+PnP_CuteText:
+ text_far _PnP_CuteText
+ text_end
+
+PnP_LazyText:
+ text_far _PnP_LazyText
+ text_end
+
+PnP_HappyText:
+ text_far _PnP_HappyText
+ text_end
+
+PnP_NoisyText:
+ text_far _PnP_NoisyText
+ text_end
+
+PnP_PrecociousText:
+ text_far _PnP_PrecociousText
+ text_end
+
+PnP_BoldText:
+ text_far _PnP_BoldText
+ text_end
+
+PnP_PickyText:
+ text_far _PnP_PickyText
+ text_end
+
+PnP_SortOfOKText:
+ text_far _PnP_SortOfOKText
+ text_end
+
+PnP_SoSoText:
+ text_far _PnP_SoSoText
+ text_end
+
+PnP_GreatText:
+ text_far _PnP_GreatText
+ text_end
+
+PnP_MyTypeText:
+ text_far _PnP_MyTypeText
+ text_end
+
+PnP_CoolText:
+ text_far _PnP_CoolText
+ text_end
+
+PnP_InspiringText:
+ text_far _PnP_InspiringText
+ text_end
+
+PnP_WeirdText:
+ text_far _PnP_WeirdText
+ text_end
+
+PnP_RightForMeText:
+ text_far _PnP_RightForMeText
+ text_end
+
+PnP_OddText:
+ text_far _PnP_OddText
+ text_end
+
+PeoplePlaces6: ; Places
+ call Random
+ cp (PnP_Places.End - PnP_Places) / 2
+ jr nc, PeoplePlaces6
+ ld hl, PnP_Places
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ call GetWorldMapLocation
+ ld e, a
+ callfar GetLandmarkName
+ ld hl, PnP_Text5
+ ld a, PLACES_AND_PEOPLE_7
+ jp NextRadioLine
+
+INCLUDE "data/radio/pnp_places.asm"
+
+PnP_Text5:
+ text_far _PnP_Text5
+ text_end
+
+PeoplePlaces7:
+ ; 0-15 are all valid indexes into .Adjectives,
+ ; so no need for a retry loop
+ call Random
+ maskbits NUM_PNP_PLACES_ADJECTIVES
+ ld e, a
+ ld d, 0
+ ld hl, .Adjectives
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CopyRadioTextToRAM
+ call Random
+ cp 4 percent
+ ld a, PLACES_AND_PEOPLE
+ jr c, .ok
+ call Random
+ cp 49 percent - 1
+ ld a, PLACES_AND_PEOPLE_4 ; People
+ jr c, .ok
+ ld a, PLACES_AND_PEOPLE_6 ; Places
+.ok
+ jp PrintRadioLine
+
+.Adjectives:
+; there are NUM_PNP_PLACES_ADJECTIVES entries
+ dw PnP_CuteText
+ dw PnP_LazyText
+ dw PnP_HappyText
+ dw PnP_NoisyText
+ dw PnP_PrecociousText
+ dw PnP_BoldText
+ dw PnP_PickyText
+ dw PnP_SortOfOKText
+ dw PnP_SoSoText
+ dw PnP_GreatText
+ dw PnP_MyTypeText
+ dw PnP_CoolText
+ dw PnP_InspiringText
+ dw PnP_WeirdText
+ dw PnP_RightForMeText
+ dw PnP_OddText
+
+RocketRadio1:
+ call StartRadioStation
+ ld hl, RocketRadioText1
+ ld a, ROCKET_RADIO_2
+ jp NextRadioLine
+
+RocketRadio2:
+ ld hl, RocketRadioText2
+ ld a, ROCKET_RADIO_3
+ jp NextRadioLine
+
+RocketRadio3:
+ ld hl, RocketRadioText3
+ ld a, ROCKET_RADIO_4
+ jp NextRadioLine
+
+RocketRadio4:
+ ld hl, RocketRadioText4
+ ld a, ROCKET_RADIO_5
+ jp NextRadioLine
+
+RocketRadio5:
+ ld hl, RocketRadioText5
+ ld a, ROCKET_RADIO_6
+ jp NextRadioLine
+
+RocketRadio6:
+ ld hl, RocketRadioText6
+ ld a, ROCKET_RADIO_7
+ jp NextRadioLine
+
+RocketRadio7:
+ ld hl, RocketRadioText7
+ ld a, ROCKET_RADIO_8
+ jp NextRadioLine
+
+RocketRadio8:
+ ld hl, RocketRadioText8
+ ld a, ROCKET_RADIO_9
+ jp NextRadioLine
+
+RocketRadio9:
+ ld hl, RocketRadioText9
+ ld a, ROCKET_RADIO_10
+ jp NextRadioLine
+
+RocketRadio10:
+ ld hl, RocketRadioText10
+ ld a, ROCKET_RADIO
+ jp NextRadioLine
+
+RocketRadioText1:
+ text_far _RocketRadioText1
+ text_end
+
+RocketRadioText2:
+ text_far _RocketRadioText2
+ text_end
+
+RocketRadioText3:
+ text_far _RocketRadioText3
+ text_end
+
+RocketRadioText4:
+ text_far _RocketRadioText4
+ text_end
+
+RocketRadioText5:
+ text_far _RocketRadioText5
+ text_end
+
+RocketRadioText6:
+ text_far _RocketRadioText6
+ text_end
+
+RocketRadioText7:
+ text_far _RocketRadioText7
+ text_end
+
+RocketRadioText8:
+ text_far _RocketRadioText8
+ text_end
+
+RocketRadioText9:
+ text_far _RocketRadioText9
+ text_end
+
+RocketRadioText10:
+ text_far _RocketRadioText10
+ text_end
+
+PokeFluteRadio:
+ call StartRadioStation
+ ld a, 1
+ ld [wNumRadioLinesPrinted], a
+ ret
+
+UnownRadio:
+ call StartRadioStation
+ ld a, 1
+ ld [wNumRadioLinesPrinted], a
+ ret
+
+EvolutionRadio:
+ call StartRadioStation
+ ld a, 1
+ ld [wNumRadioLinesPrinted], a
+ ret
+
+CopyRadioTextToRAM:
+ ld a, [hl]
+ cp TX_FAR
+ jp z, FarCopyRadioText
+ ld de, wRadioText
+ ld bc, SCREEN_WIDTH * 2
+ jp CopyBytes
+
+StartRadioStation:
+ ld a, [wNumRadioLinesPrinted]
+ and a
+ ret nz
+ call RadioTerminator
+ call PrintText
+ ld hl, RadioChannelSongs
+ ld a, [wCurRadioLine]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ callfar RadioMusicRestartDE
+ ret
+
+INCLUDE "data/radio/channel_music.asm"
+
+NextRadioLine:
+ push af
+ call CopyRadioTextToRAM
+ pop af
+ jp PrintRadioLine