shithub: pokered

Download patch

ref: e882708b85e19cf30e05fcf31ccedc5f03367702
parent: 6bd86e10c32cd7b464425adfc01621f3ff6726aa
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Fri Jul 3 09:23:51 EDT 2020

Split up engine/events/hidden_object_functions

diff: cannot open b/engine/events/hidden_objects//null: file does not exist: 'b/engine/events/hidden_objects//null'
--- a/engine/events/hidden_object_functions14.asm
+++ /dev/null
@@ -1,100 +1,0 @@
-PrintNotebookText:
-	call EnableAutoTextBoxDrawing
-	ld a, $1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	ld a, [wHiddenObjectFunctionArgument]
-	jp PrintPredefTextID
-
-TMNotebook::
-	TX_FAR TMNotebookText
-	TX_WAIT
-	db "@"
-
-ViridianSchoolNotebook::
-	TX_ASM
-	ld hl, ViridianSchoolNotebookText1
-	call PrintText
-	call TurnPageSchoolNotebook
-	jr nz, .doneReading
-	ld hl, ViridianSchoolNotebookText2
-	call PrintText
-	call TurnPageSchoolNotebook
-	jr nz, .doneReading
-	ld hl, ViridianSchoolNotebookText3
-	call PrintText
-	call TurnPageSchoolNotebook
-	jr nz, .doneReading
-	ld hl, ViridianSchoolNotebookText4
-	call PrintText
-	ld hl, ViridianSchoolNotebookText5
-	call PrintText
-.doneReading
-	jp TextScriptEnd
-
-TurnPageSchoolNotebook:
-	ld hl, TurnPageText
-	call PrintText
-	call YesNoChoice
-	ld a, [wCurrentMenuItem]
-	and a
-	ret
-
-TurnPageText:
-	TX_FAR _TurnPageText
-	db "@"
-
-ViridianSchoolNotebookText5:
-	TX_FAR _ViridianSchoolNotebookText5
-	TX_WAIT
-	db "@"
-
-ViridianSchoolNotebookText1:
-	TX_FAR _ViridianSchoolNotebookText1
-	db "@"
-
-ViridianSchoolNotebookText2:
-	TX_FAR _ViridianSchoolNotebookText2
-	db "@"
-
-ViridianSchoolNotebookText3:
-	TX_FAR _ViridianSchoolNotebookText3
-	db "@"
-
-ViridianSchoolNotebookText4:
-	TX_FAR _ViridianSchoolNotebookText4
-	db "@"
-
-PrintFightingDojoText2:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump EnemiesOnEverySideText
-
-EnemiesOnEverySideText::
-	TX_FAR _EnemiesOnEverySideText
-	db "@"
-
-PrintFightingDojoText3:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump WhatGoesAroundComesAroundText
-
-WhatGoesAroundComesAroundText::
-	TX_FAR _WhatGoesAroundComesAroundText
-	db "@"
-
-PrintFightingDojoText:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump FightingDojoText
-
-FightingDojoText::
-	TX_FAR _FightingDojoText
-	db "@"
-
-PrintIndigoPlateauHQText:
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump IndigoPlateauHQText
-
-IndigoPlateauHQText::
-	TX_FAR _IndigoPlateauHQText
-	db "@"
--- a/engine/events/hidden_object_functions17.asm
+++ /dev/null
@@ -1,475 +1,0 @@
-PrintRedSNESText:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump RedBedroomSNESText
-
-RedBedroomSNESText::
-	TX_FAR _RedBedroomSNESText
-	db "@"
-
-OpenRedsPC:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump RedBedroomPCText
-
-RedBedroomPCText::
-	TX_PLAYERS_PC
-
-Route15GateLeftBinoculars:
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	call EnableAutoTextBoxDrawing
-	tx_pre Route15UpstairsBinocularsText
-	ld a, ARTICUNO
-	ld [wcf91], a
-	call PlayCry
-	jp DisplayMonFrontSpriteInBox
-
-Route15UpstairsBinocularsText::
-	TX_FAR _Route15UpstairsBinocularsText
-	db "@"
-
-AerodactylFossil:
-	ld a, FOSSIL_AERODACTYL
-	ld [wcf91], a
-	call DisplayMonFrontSpriteInBox
-	call EnableAutoTextBoxDrawing
-	tx_pre AerodactylFossilText
-	ret
-
-AerodactylFossilText::
-	TX_FAR _AerodactylFossilText
-	db "@"
-
-KabutopsFossil:
-	ld a, FOSSIL_KABUTOPS
-	ld [wcf91], a
-	call DisplayMonFrontSpriteInBox
-	call EnableAutoTextBoxDrawing
-	tx_pre KabutopsFossilText
-	ret
-
-KabutopsFossilText::
-	TX_FAR _KabutopsFossilText
-	db "@"
-
-DisplayMonFrontSpriteInBox:
-; Displays a pokemon's front sprite in a pop-up window.
-; [wcf91] = pokemon internal id number
-	ld a, 1
-	ld [H_AUTOBGTRANSFERENABLED], a
-	call Delay3
-	xor a
-	ld [hWY], a
-	call SaveScreenTilesToBuffer1
-	ld a, MON_SPRITE_POPUP
-	ld [wTextBoxID], a
-	call DisplayTextBoxID
-	call UpdateSprites
-	ld a, [wcf91]
-	ld [wd0b5], a
-	call GetMonHeader
-	ld de, vChars1 + $310
-	call LoadMonFrontSprite
-	ld a, $80
-	ld [hStartTileID], a
-	coord hl, 10, 11
-	predef AnimateSendingOutMon
-	call WaitForTextScrollButtonPress
-	call LoadScreenTilesFromBuffer1
-	call Delay3
-	ld a, $90
-	ld [hWY], a
-	ret
-
-PrintBlackboardLinkCableText:
-	call EnableAutoTextBoxDrawing
-	ld a, $1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	ld a, [wHiddenObjectFunctionArgument]
-	call PrintPredefTextID
-	ret
-
-LinkCableHelp::
-	TX_ASM
-	call SaveScreenTilesToBuffer1
-	ld hl, LinkCableHelpText1
-	call PrintText
-	xor a
-	ld [wMenuItemOffset], a ; not used
-	ld [wCurrentMenuItem], a
-	ld [wLastMenuItem], a
-	ld a, A_BUTTON | B_BUTTON
-	ld [wMenuWatchedKeys], a
-	ld a, 3
-	ld [wMaxMenuItem], a
-	ld a, 2
-	ld [wTopMenuItemY], a
-	ld a, 1
-	ld [wTopMenuItemX], a
-.linkHelpLoop
-	ld hl, wd730
-	set 6, [hl]
-	coord hl, 0, 0
-	ld b, 8
-	ld c, 13
-	call TextBoxBorder
-	coord hl, 2, 2
-	ld de, HowToLinkText
-	call PlaceString
-	ld hl, LinkCableHelpText2
-	call PrintText
-	call HandleMenuInput
-	bit 1, a ; pressed b
-	jr nz, .exit
-	ld a, [wCurrentMenuItem]
-	cp 3 ; pressed a on "STOP READING"
-	jr z, .exit
-	ld hl, wd730
-	res 6, [hl]
-	ld hl, LinkCableInfoTexts
-	add a
-	ld d, 0
-	ld e, a
-	add hl, de
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	call PrintText
-	jp .linkHelpLoop
-.exit
-	ld hl, wd730
-	res 6, [hl]
-	call LoadScreenTilesFromBuffer1
-	jp TextScriptEnd
-
-LinkCableHelpText1:
-	TX_FAR _LinkCableHelpText1
-	db "@"
-
-LinkCableHelpText2:
-	TX_FAR _LinkCableHelpText2
-	db "@"
-
-HowToLinkText:
-	db   "HOW TO LINK"
-	next "COLOSSEUM"
-	next "TRADE CENTER"
-	next "STOP READING@"
-
-LinkCableInfoTexts:
-	dw LinkCableInfoText1
-	dw LinkCableInfoText2
-	dw LinkCableInfoText3
-
-LinkCableInfoText1:
-	TX_FAR _LinkCableInfoText1
-	db "@"
-
-LinkCableInfoText2:
-	TX_FAR _LinkCableInfoText2
-	db "@"
-
-LinkCableInfoText3:
-	TX_FAR _LinkCableInfoText3
-	db "@"
-
-ViridianSchoolBlackboard::
-	TX_ASM
-	call SaveScreenTilesToBuffer1
-	ld hl, ViridianSchoolBlackboardText1
-	call PrintText
-	xor a
-	ld [wMenuItemOffset], a
-	ld [wCurrentMenuItem], a
-	ld [wLastMenuItem], a
-	ld a, D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON
-	ld [wMenuWatchedKeys], a
-	ld a, 2
-	ld [wMaxMenuItem], a
-	ld a, 2
-	ld [wTopMenuItemY], a
-	ld a, 1
-	ld [wTopMenuItemX], a
-.blackboardLoop
-	ld hl, wd730
-	set 6, [hl]
-	coord hl, 0, 0
-	lb bc, 6, 10
-	call TextBoxBorder
-	coord hl, 1, 2
-	ld de, StatusAilmentText1
-	call PlaceString
-	coord hl, 6, 2
-	ld de, StatusAilmentText2
-	call PlaceString
-	ld hl, ViridianSchoolBlackboardText2
-	call PrintText
-	call HandleMenuInput ; pressing up and down is handled in here
-	bit 1, a ; pressed b
-	jr nz, .exitBlackboard
-	bit 4, a ; pressed right
-	jr z, .didNotPressRight
-	; move cursor to right column
-	ld a, 2
-	ld [wMaxMenuItem], a
-	ld a, 2
-	ld [wTopMenuItemY], a
-	ld a, 6
-	ld [wTopMenuItemX], a
-	ld a, 3 ; in the the right column, use an offset to prevent overlap
-	ld [wMenuItemOffset], a
-	jr .blackboardLoop
-.didNotPressRight
-	bit 5, a ; pressed left
-	jr z, .didNotPressLeftOrRight
-	; move cursor to left column
-	ld a, 2
-	ld [wMaxMenuItem], a
-	ld a, 2
-	ld [wTopMenuItemY], a
-	ld a, 1
-	ld [wTopMenuItemX], a
-	xor a
-	ld [wMenuItemOffset], a
-	jr .blackboardLoop
-.didNotPressLeftOrRight
-	ld a, [wCurrentMenuItem]
-	ld b, a
-	ld a, [wMenuItemOffset]
-	add b
-	cp 5 ; cursor is pointing to "QUIT"
-	jr z, .exitBlackboard
-	; we must have pressed a on a status condition
-	; so print the text
-	ld hl, wd730
-	res 6, [hl]
-	ld hl, ViridianBlackboardStatusPointers
-	add a
-	ld d, 0
-	ld e, a
-	add hl, de
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	call PrintText
-	jp .blackboardLoop
-.exitBlackboard
-	ld hl, wd730
-	res 6, [hl]
-	call LoadScreenTilesFromBuffer1
-	jp TextScriptEnd
-
-ViridianSchoolBlackboardText1:
-	TX_FAR _ViridianSchoolBlackboardText1
-	db "@"
-
-ViridianSchoolBlackboardText2:
-	TX_FAR _ViridianSchoolBlackboardText2
-	db "@"
-
-StatusAilmentText1:
-	db   " SLP"
-	next " PSN"
-	next " PAR@"
-
-StatusAilmentText2:
-	db   " BRN"
-	next " FRZ"
-	next " QUIT@@"
-
-ViridianBlackboardStatusPointers:
-	dw ViridianBlackboardSleepText
-	dw ViridianBlackboardPoisonText
-	dw ViridianBlackboardPrlzText
-	dw ViridianBlackboardBurnText
-	dw ViridianBlackboardFrozenText
-
-ViridianBlackboardSleepText:
-	TX_FAR _ViridianBlackboardSleepText
-	db "@"
-
-ViridianBlackboardPoisonText:
-	TX_FAR _ViridianBlackboardPoisonText
-	db "@"
-
-ViridianBlackboardPrlzText:
-	TX_FAR _ViridianBlackboardPrlzText
-	db "@"
-
-ViridianBlackboardBurnText:
-	TX_FAR _ViridianBlackboardBurnText
-	db "@"
-
-ViridianBlackboardFrozenText:
-	TX_FAR _ViridianBlackboardFrozenText
-	db "@"
-
-PrintTrashText:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump VermilionGymTrashText
-
-VermilionGymTrashText::
-	TX_FAR _VermilionGymTrashText
-	db "@"
-
-GymTrashScript:
-	call EnableAutoTextBoxDrawing
-	ld a, [wHiddenObjectFunctionArgument]
-	ld [wGymTrashCanIndex], a
-
-; Don't do the trash can puzzle if it's already been done.
-	CheckEvent EVENT_2ND_LOCK_OPENED
-	jr z, .ok
-
-	tx_pre_jump VermilionGymTrashText
-
-.ok
-	CheckEventReuseA EVENT_1ST_LOCK_OPENED
-	jr nz, .trySecondLock
-
-	ld a, [wFirstLockTrashCanIndex]
-	ld b, a
-	ld a, [wGymTrashCanIndex]
-	cp b
-	jr z, .openFirstLock
-
-	tx_pre_id VermilionGymTrashText
-	jr .done
-
-.openFirstLock
-; Next can is trying for the second switch.
-	SetEvent EVENT_1ST_LOCK_OPENED
-
-	ld hl, GymTrashCans
-	ld a, [wGymTrashCanIndex]
-	; * 5
-	ld b, a
-	add a
-	add a
-	add b
-
-	ld d, 0
-	ld e, a
-	add hl, de
-	ld a, [hli]
-
-; There is a bug in this code. It should calculate a value in the range [0, 3]
-; but if the mask and random number don't have any 1 bits in common, then
-; the result of the AND will be 0. When 1 is subtracted from that, the value
-; will become $ff. This will result in 255 being added to hl, which will cause
-; hl to point to one of the zero bytes that pad the end of the ROM bank.
-; Trash can 0 was intended to be able to have the second lock only when the
-; first lock was in trash can 1 or 3. However, due to this bug, trash can 0 can
-; have the second lock regardless of which trash can had the first lock.
-
-	ld [hGymTrashCanRandNumMask], a
-	push hl
-	call Random
-	swap a
-	ld b, a
-	ld a, [hGymTrashCanRandNumMask]
-	and b
-	dec a
-	pop hl
-
-	ld d, 0
-	ld e, a
-	add hl, de
-	ld a, [hl]
-	and $f
-	ld [wSecondLockTrashCanIndex], a
-
-	tx_pre_id VermilionGymTrashSuccessText1
-	jr .done
-
-.trySecondLock
-	ld a, [wSecondLockTrashCanIndex]
-	ld b, a
-	ld a, [wGymTrashCanIndex]
-	cp b
-	jr z, .openSecondLock
-
-; Reset the cans.
-	ResetEvent EVENT_1ST_LOCK_OPENED
-	call Random
-
-	and $e
-	ld [wFirstLockTrashCanIndex], a
-
-	tx_pre_id VermilionGymTrashFailText
-	jr .done
-
-.openSecondLock
-; Completed the trash can puzzle.
-	SetEvent EVENT_2ND_LOCK_OPENED
-	ld hl, wCurrentMapScriptFlags
-	set 6, [hl]
-
-	tx_pre_id VermilionGymTrashSuccessText3
-
-.done
-	jp PrintPredefTextID
-
-GymTrashCans:
-; byte 0: mask for random number
-; bytes 1-4: indices of the trash cans that can have the second lock
-;            (but see the comment above explaining a bug regarding this)
-; Note that the mask is simply the number of valid trash can indices that
-; follow. The remaining bytes are filled with 0 to pad the length of each entry
-; to 5 bytes.
-	db 2,  1,  3,  0,  0 ; 0
-	db 3,  0,  2,  4,  0 ; 1
-	db 2,  1,  5,  0,  0 ; 2
-	db 3,  0,  4,  6,  0 ; 3
-	db 4,  1,  3,  5,  7 ; 4
-	db 3,  2,  4,  8,  0 ; 5
-	db 3,  3,  7,  9,  0 ; 6
-	db 4,  4,  6,  8, 10 ; 7
-	db 3,  5,  7, 11,  0 ; 8
-	db 3,  6, 10, 12,  0 ; 9
-	db 4,  7,  9, 11, 13 ; 10
-	db 3,  8, 10, 14,  0 ; 11
-	db 2,  9, 13,  0,  0 ; 12
-	db 3, 10, 12, 14,  0 ; 13
-	db 2, 11, 13,  0,  0 ; 14
-
-VermilionGymTrashSuccessText1::
-	TX_FAR _VermilionGymTrashSuccessText1
-	TX_ASM
-	call WaitForSoundToFinish
-	ld a, SFX_SWITCH
-	call PlaySound
-	call WaitForSoundToFinish
-	jp TextScriptEnd
-
-; unused
-VermilionGymTrashSuccessText2::
-	TX_FAR _VermilionGymTrashSuccessText2
-	db "@"
-
-; unused
-VermilionGymTrashSuccesPlaySfx:
-	TX_ASM
-	call WaitForSoundToFinish
-	ld a, SFX_SWITCH
-	call PlaySound
-	call WaitForSoundToFinish
-	jp TextScriptEnd
-
-VermilionGymTrashSuccessText3::
-	TX_FAR _VermilionGymTrashSuccessText3
-	TX_ASM
-	call WaitForSoundToFinish
-	ld a, SFX_GO_INSIDE
-	call PlaySound
-	call WaitForSoundToFinish
-	jp TextScriptEnd
-
-VermilionGymTrashFailText::
-	TX_FAR _VermilionGymTrashFailText
-	TX_ASM
-	call WaitForSoundToFinish
-	ld a, SFX_DENIED
-	call PlaySound
-	call WaitForSoundToFinish
-	jp TextScriptEnd
--- a/engine/events/hidden_object_functions18.asm
+++ /dev/null
@@ -1,198 +1,0 @@
-GymStatues:
-; if in a gym and have the corresponding badge, a = GymStatueText2_id and jp PrintPredefTextID
-; if in a gym and don’t have the corresponding badge, a = GymStatueText1_id and jp PrintPredefTextID
-; else ret
-	call EnableAutoTextBoxDrawing
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	ld hl, .BadgeFlags
-	ld a, [wCurMap]
-	ld b, a
-.loop
-	ld a, [hli]
-	cp $ff
-	ret z
-	cp b
-	jr z, .match
-	inc hl
-	jr .loop
-.match
-	ld b, [hl]
-	ld a, [wBeatGymFlags]
-	and b
-	cp b
-	tx_pre_id GymStatueText2
-	jr z, .haveBadge
-	tx_pre_id GymStatueText1
-.haveBadge
-	jp PrintPredefTextID
-
-.BadgeFlags:
-	db PEWTER_GYM,   %00000001
-	db CERULEAN_GYM, %00000010
-	db VERMILION_GYM,%00000100
-	db CELADON_GYM,  %00001000
-	db FUCHSIA_GYM,  %00010000
-	db SAFFRON_GYM,  %00100000
-	db CINNABAR_GYM, %01000000
-	db VIRIDIAN_GYM, %10000000
-	db $ff
-
-GymStatueText1::
-	TX_FAR _GymStatueText1
-	db "@"
-
-GymStatueText2::
-	TX_FAR _GymStatueText2
-	db "@"
-
-PrintBenchGuyText:
-	call EnableAutoTextBoxDrawing
-	ld hl, BenchGuyTextPointers
-	ld a, [wCurMap]
-	ld b, a
-.loop
-	ld a, [hli]
-	cp $ff
-	ret z
-	cp b
-	jr z, .match
-	inc hl
-	inc hl
-	jr .loop
-.match
-	ld a, [hli]
-	ld b, a
-	ld a, [wSpriteStateData1 + 9]
-	cp b
-	jr nz, .loop ; player isn't facing left at the bench guy
-	ld a, [hl]
-	jp PrintPredefTextID
-
-; format: db map id, player sprite facing direction, text id of PredefTextIDPointerTable
-BenchGuyTextPointers:
-	db VIRIDIAN_POKECENTER,   SPRITE_FACING_LEFT
-	db_tx_pre ViridianCityPokecenterBenchGuyText
-	db PEWTER_POKECENTER,     SPRITE_FACING_LEFT
-	db_tx_pre PewterCityPokecenterBenchGuyText
-	db CERULEAN_POKECENTER,   SPRITE_FACING_LEFT
-	db_tx_pre CeruleanCityPokecenterBenchGuyText
-	db LAVENDER_POKECENTER,   SPRITE_FACING_LEFT
-	db_tx_pre LavenderCityPokecenterBenchGuyText
-	db VERMILION_POKECENTER,  SPRITE_FACING_LEFT
-	db_tx_pre VermilionCityPokecenterBenchGuyText
-	db CELADON_POKECENTER,    SPRITE_FACING_LEFT
-	db_tx_pre CeladonCityPokecenterBenchGuyText
-	db CELADON_HOTEL,         SPRITE_FACING_LEFT
-	db_tx_pre CeladonCityHotelText
-	db FUCHSIA_POKECENTER,    SPRITE_FACING_LEFT
-	db_tx_pre FuchsiaCityPokecenterBenchGuyText
-	db CINNABAR_POKECENTER,   SPRITE_FACING_LEFT
-	db_tx_pre CinnabarIslandPokecenterBenchGuyText
-	db SAFFRON_POKECENTER,    SPRITE_FACING_LEFT
-	db_tx_pre SaffronCityPokecenterBenchGuyText
-	db MT_MOON_POKECENTER,    SPRITE_FACING_LEFT
-	db_tx_pre MtMoonPokecenterBenchGuyText
-	db ROCK_TUNNEL_POKECENTER,SPRITE_FACING_LEFT
-	db_tx_pre RockTunnelPokecenterBenchGuyText
-	db $FF
-
-ViridianCityPokecenterBenchGuyText::
-	TX_FAR _ViridianCityPokecenterGuyText
-	db "@"
-
-PewterCityPokecenterBenchGuyText::
-	TX_FAR _PewterCityPokecenterGuyText
-	db "@"
-
-CeruleanCityPokecenterBenchGuyText::
-	TX_FAR _CeruleanPokecenterGuyText
-	db "@"
-
-LavenderCityPokecenterBenchGuyText::
-	TX_FAR _LavenderPokecenterGuyText
-	db "@"
-
-MtMoonPokecenterBenchGuyText::
-	TX_FAR _MtMoonPokecenterBenchGuyText
-	db "@"
-
-RockTunnelPokecenterBenchGuyText::
-	TX_FAR _RockTunnelPokecenterGuyText
-	db "@"
-
-UnusedBenchGuyText1::
-	TX_FAR _UnusedBenchGuyText1
-	db "@"
-
-UnusedBenchGuyText2::
-	TX_FAR _UnusedBenchGuyText2
-	db "@"
-
-UnusedBenchGuyText3::
-	TX_FAR _UnusedBenchGuyText3
-	db "@"
-
-VermilionCityPokecenterBenchGuyText::
-	TX_FAR _VermilionPokecenterGuyText
-	db "@"
-
-CeladonCityPokecenterBenchGuyText::
-	TX_FAR _CeladonCityPokecenterGuyText
-	db "@"
-
-FuchsiaCityPokecenterBenchGuyText::
-	TX_FAR _FuchsiaCityPokecenterGuyText
-	db "@"
-
-CinnabarIslandPokecenterBenchGuyText::
-	TX_FAR _CinnabarPokecenterGuyText
-	db "@"
-
-SaffronCityPokecenterBenchGuyText::
-	TX_ASM
-	CheckEvent EVENT_BEAT_SILPH_CO_GIOVANNI
-	ld hl, SaffronCityPokecenterBenchGuyText2
-	jr nz, .asm_624f2
-	ld hl, SaffronCityPokecenterBenchGuyText1
-.asm_624f2
-	call PrintText
-	jp TextScriptEnd
-
-SaffronCityPokecenterBenchGuyText1:
-	TX_FAR _SaffronCityPokecenterGuyText1
-	db "@"
-
-SaffronCityPokecenterBenchGuyText2:
-	TX_FAR _SaffronCityPokecenterGuyText2
-	db "@"
-
-CeladonCityHotelText::
-	TX_FAR _CeladonCityHotelText
-	db "@"
-
-	ret
-
-UnusedPredefText::
-	db "@"
-
-PrintBookcaseText:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump BookcaseText
-
-BookcaseText::
-	TX_FAR _BookcaseText
-	db "@"
-
-OpenPokemonCenterPC:
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP ; check to see if player is facing up
-	ret nz
-	call EnableAutoTextBoxDrawing
-	ld a, $1
-	ld [wAutoTextBoxDrawingControl], a
-	tx_pre_jump PokemonCenterPCText
-
-PokemonCenterPCText::
-	TX_POKECENTER_PC
--- a/engine/events/hidden_object_functions3.asm
+++ /dev/null
@@ -1,117 +1,0 @@
-; prints text for bookshelves in buildings without sign events
-PrintBookshelfText::
-	ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
-	cp SPRITE_FACING_UP
-	jr nz, .noMatch
-; facing up
-	ld a, [wCurMapTileset]
-	ld b, a
-	aCoord 8, 7
-	ld c, a
-	ld hl, BookshelfTileIDs
-.loop
-	ld a, [hli]
-	cp $ff
-	jr z, .noMatch
-	cp b
-	jr nz, .nextBookshelfEntry1
-	ld a, [hli]
-	cp c
-	jr nz, .nextBookshelfEntry2
-	ld a, [hl]
-	push af
-	call EnableAutoTextBoxDrawing
-	pop af
-	call PrintPredefTextID
-	xor a
-	ld [$ffdb], a
-	ret
-.nextBookshelfEntry1
-	inc hl
-.nextBookshelfEntry2
-	inc hl
-	jr .loop
-.noMatch
-	ld a, $ff
-	ld [$ffdb], a
-	jpba PrintCardKeyText
-
-INCLUDE "data/tilesets/bookshelf_tile_ids.asm"
-
-IndigoPlateauStatues::
-	TX_ASM
-	ld hl, IndigoPlateauStatuesText1
-	call PrintText
-	ld a, [wXCoord]
-	bit 0, a
-	ld hl, IndigoPlateauStatuesText2
-	jr nz, .ok
-	ld hl, IndigoPlateauStatuesText3
-.ok
-	call PrintText
-	jp TextScriptEnd
-
-IndigoPlateauStatuesText1:
-	TX_FAR _IndigoPlateauStatuesText1
-	db "@"
-
-IndigoPlateauStatuesText2:
-	TX_FAR _IndigoPlateauStatuesText2
-	db "@"
-
-IndigoPlateauStatuesText3:
-	TX_FAR _IndigoPlateauStatuesText3
-	db "@"
-
-BookOrSculptureText::
-	TX_ASM
-	ld hl, PokemonBooksText
-	ld a, [wCurMapTileset]
-	cp MANSION ; Celadon Mansion tileset
-	jr nz, .ok
-	aCoord 8, 6
-	cp $38
-	jr nz, .ok
-	ld hl, DiglettSculptureText
-.ok
-	call PrintText
-	jp TextScriptEnd
-
-PokemonBooksText:
-	TX_FAR _PokemonBooksText
-	db "@"
-
-DiglettSculptureText:
-	TX_FAR _DiglettSculptureText
-	db "@"
-
-ElevatorText::
-	TX_FAR _ElevatorText
-	db "@"
-
-TownMapText::
-	TX_FAR _TownMapText
-	TX_BLINK
-	TX_ASM
-	ld a, $1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	ld hl, wd730
-	set 6, [hl]
-	call GBPalWhiteOutWithDelay3
-	xor a
-	ld [hWY], a
-	inc a
-	ld [H_AUTOBGTRANSFERENABLED], a
-	call LoadFontTilePatterns
-	callba DisplayTownMap
-	ld hl, wd730
-	res 6, [hl]
-	ld de, TextScriptEnd
-	push de
-	ld a, [H_LOADEDROMBANK]
-	push af
-	jp CloseTextDisplay
-
-PokemonStuffText::
-	TX_FAR _PokemonStuffText
-	db "@"
--- a/engine/events/hidden_object_functions7.asm
+++ /dev/null
@@ -1,467 +1,0 @@
-PrintNewBikeText:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump NewBicycleText
-
-NewBicycleText::
-	TX_FAR _NewBicycleText
-	db "@"
-
-DisplayOakLabLeftPoster:
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump PushStartText
-
-PushStartText::
-	TX_FAR _PushStartText
-	db "@"
-
-DisplayOakLabRightPoster:
-	call EnableAutoTextBoxDrawing
-	ld hl, wPokedexOwned
-	ld b, wPokedexOwnedEnd - wPokedexOwned
-	call CountSetBits
-	ld a, [wNumSetBits]
-	cp 2
-	tx_pre_id SaveOptionText
-	jr c, .ownLessThanTwo
-	; own two or more mon
-	tx_pre_id StrengthsAndWeaknessesText
-.ownLessThanTwo
-	jp PrintPredefTextID
-
-SaveOptionText::
-	TX_FAR _SaveOptionText
-	db "@"
-
-StrengthsAndWeaknessesText::
-	TX_FAR _StrengthsAndWeaknessesText
-	db "@"
-
-SafariZoneCheck::
-	CheckEventHL EVENT_IN_SAFARI_ZONE ; if we are not in the Safari Zone,
-	jr z, SafariZoneGameStillGoing ; don't bother printing game over text
-	ld a, [wNumSafariBalls]
-	and a
-	jr z, SafariZoneGameOver
-	jr SafariZoneGameStillGoing
-
-SafariZoneCheckSteps::
-	ld a, [wSafariSteps]
-	ld b, a
-	ld a, [wSafariSteps + 1]
-	ld c, a
-	or b
-	jr z, SafariZoneGameOver
-	dec bc
-	ld a, b
-	ld [wSafariSteps], a
-	ld a, c
-	ld [wSafariSteps + 1], a
-SafariZoneGameStillGoing:
-	xor a
-	ld [wSafariZoneGameOver], a
-	ret
-
-SafariZoneGameOver:
-	call EnableAutoTextBoxDrawing
-	xor a
-	ld [wAudioFadeOutControl], a
-	dec a
-	call PlaySound
-	ld c, BANK(SFX_Safari_Zone_PA)
-	ld a, SFX_SAFARI_ZONE_PA
-	call PlayMusic
-.waitForMusicToPlay
-	ld a, [wChannelSoundIDs + Ch5]
-	cp SFX_SAFARI_ZONE_PA
-	jr nz, .waitForMusicToPlay
-	ld a, TEXT_SAFARI_GAME_OVER
-	ld [hSpriteIndexOrTextID], a
-	call DisplayTextID
-	xor a
-	ld [wPlayerMovingDirection], a
-	ld a, SAFARI_ZONE_GATE
-	ld [hWarpDestinationMap], a
-	ld a, $3
-	ld [wDestinationWarpID], a
-	ld a, $5
-	ld [wSafariZoneGateCurScript], a
-	SetEvent EVENT_SAFARI_GAME_OVER
-	ld a, 1
-	ld [wSafariZoneGameOver], a
-	ret
-
-PrintSafariGameOverText::
-	xor a
-	ld [wJoyIgnore], a
-	ld hl, SafariGameOverText
-	jp PrintText
-
-SafariGameOverText:
-	TX_ASM
-	ld a, [wNumSafariBalls]
-	and a
-	jr z, .noMoreSafariBalls
-	ld hl, TimesUpText
-	call PrintText
-.noMoreSafariBalls
-	ld hl, GameOverText
-	call PrintText
-	jp TextScriptEnd
-
-TimesUpText:
-	TX_FAR _TimesUpText
-	db "@"
-
-GameOverText:
-	TX_FAR _GameOverText
-	db "@"
-
-PrintCinnabarQuiz:
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump CinnabarGymQuiz
-
-CinnabarGymQuiz::
-	TX_ASM
-	xor a
-	ld [wOpponentAfterWrongAnswer], a
-	ld a, [wHiddenObjectFunctionArgument]
-	push af
-	and $f
-	ld [hGymGateIndex], a
-	pop af
-	and $f0
-	swap a
-	ld [$ffdc], a
-	ld hl, CinnabarGymQuizIntroText
-	call PrintText
-	ld a, [hGymGateIndex]
-	dec a
-	add a
-	ld d, 0
-	ld e, a
-	ld hl, CinnabarQuizQuestions
-	add hl, de
-	ld a, [hli]
-	ld h, [hl]
-	ld l, a
-	call PrintText
-	ld a, 1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	call CinnabarGymQuiz_1ea92
-	jp TextScriptEnd
-
-CinnabarGymQuizIntroText:
-	TX_FAR _CinnabarGymQuizIntroText
-	db "@"
-
-CinnabarQuizQuestions:
-	dw CinnabarQuizQuestionsText1
-	dw CinnabarQuizQuestionsText2
-	dw CinnabarQuizQuestionsText3
-	dw CinnabarQuizQuestionsText4
-	dw CinnabarQuizQuestionsText5
-	dw CinnabarQuizQuestionsText6
-
-CinnabarQuizQuestionsText1:
-	TX_FAR _CinnabarQuizQuestionsText1
-	db "@"
-
-CinnabarQuizQuestionsText2:
-	TX_FAR _CinnabarQuizQuestionsText2
-	db "@"
-
-CinnabarQuizQuestionsText3:
-	TX_FAR _CinnabarQuizQuestionsText3
-	db "@"
-
-CinnabarQuizQuestionsText4:
-	TX_FAR _CinnabarQuizQuestionsText4
-	db "@"
-
-CinnabarQuizQuestionsText5:
-	TX_FAR _CinnabarQuizQuestionsText5
-	db "@"
-
-CinnabarQuizQuestionsText6:
-	TX_FAR _CinnabarQuizQuestionsText6
-	db "@"
-
-CinnabarGymGateFlagAction:
-	EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED
-	predef_jump FlagActionPredef
-
-CinnabarGymQuiz_1ea92:
-	call YesNoChoice
-	ld a, [$ffdc]
-	ld c, a
-	ld a, [wCurrentMenuItem]
-	cp c
-	jr nz, .wrongAnswer
-	ld hl, wCurrentMapScriptFlags
-	set 5, [hl]
-	ld a, [hGymGateIndex]
-	ld [$ffe0], a
-	ld hl, CinnabarGymQuizCorrectText
-	call PrintText
-	ld a, [$ffe0]
-	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
-	ld c, a
-	ld b, FLAG_SET
-	call CinnabarGymGateFlagAction
-	jp UpdateCinnabarGymGateTileBlocks_
-.wrongAnswer
-	call WaitForSoundToFinish
-	ld a, SFX_DENIED
-	call PlaySound
-	call WaitForSoundToFinish
-	ld hl, CinnabarGymQuizIncorrectText
-	call PrintText
-	ld a, [hGymGateIndex]
-	add $2
-	AdjustEventBit EVENT_BEAT_CINNABAR_GYM_TRAINER_0, 2
-	ld c, a
-	ld b, FLAG_TEST
-	EventFlagAddress hl, EVENT_BEAT_CINNABAR_GYM_TRAINER_0
-	predef FlagActionPredef
-	ld a, c
-	and a
-	ret nz
-	ld a, [hGymGateIndex]
-	add $2
-	ld [wOpponentAfterWrongAnswer], a
-	ret
-
-CinnabarGymQuizCorrectText:
-	TX_SFX_ITEM_1
-	TX_FAR _CinnabarGymQuizCorrectText
-	TX_BLINK
-	TX_ASM
-
-	ld a, [$ffe0]
-	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
-	ld c, a
-	ld b, FLAG_TEST
-	call CinnabarGymGateFlagAction
-	ld a, c
-	and a
-	jp nz, TextScriptEnd
-	call WaitForSoundToFinish
-	ld a, SFX_GO_INSIDE
-	call PlaySound
-	call WaitForSoundToFinish
-	jp TextScriptEnd
-
-CinnabarGymQuizIncorrectText:
-	TX_FAR _CinnabarGymQuizIncorrectText
-	db "@"
-
-UpdateCinnabarGymGateTileBlocks_::
-; Update the overworld map with open floor blocks or locked gate blocks
-; depending on event flags.
-	ld a, 6
-	ld [hGymGateIndex], a
-.loop
-	ld a, [hGymGateIndex]
-	dec a
-	add a
-	add a
-	ld d, 0
-	ld e, a
-	ld hl, CinnabarGymGateCoords
-	add hl, de
-	ld a, [hli]
-	ld b, [hl]
-	ld c, a
-	inc hl
-	ld a, [hl]
-	ld [wGymGateTileBlock], a
-	push bc
-	ld a, [hGymGateIndex]
-	ld [$ffe0], a
-	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
-	ld c, a
-	ld b, FLAG_TEST
-	call CinnabarGymGateFlagAction
-	ld a, c
-	and a
-	jr nz, .unlocked
-	ld a, [wGymGateTileBlock]
-	jr .next
-.unlocked
-	ld a, $e
-.next
-	pop bc
-	ld [wNewTileBlockID], a
-	predef ReplaceTileBlock
-	ld hl, hGymGateIndex
-	dec [hl]
-	jr nz, .loop
-	ret
-
-CinnabarGymGateCoords:
-	; format: x-coord, y-coord, direction, padding
-	; direction: $54 = horizontal gate, $5f = vertical gate
-	db $09,$03,$54,$00
-	db $06,$03,$54,$00
-	db $06,$06,$54,$00
-	db $03,$08,$5f,$00
-	db $02,$06,$54,$00
-	db $02,$03,$54,$00
-
-PrintMagazinesText:
-	call EnableAutoTextBoxDrawing
-	tx_pre MagazinesText
-	ret
-
-MagazinesText::
-	TX_FAR _MagazinesText
-	db "@"
-
-BillsHousePC:
-	call EnableAutoTextBoxDrawing
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	CheckEvent EVENT_LEFT_BILLS_HOUSE_AFTER_HELPING
-	jr nz, .displayBillsHousePokemonList
-	CheckEventReuseA EVENT_USED_CELL_SEPARATOR_ON_BILL
-	jr nz, .displayBillsHouseMonitorText
-	CheckEventReuseA EVENT_BILL_SAID_USE_CELL_SEPARATOR
-	jr nz, .doCellSeparator
-.displayBillsHouseMonitorText
-	tx_pre_jump BillsHouseMonitorText
-.doCellSeparator
-	ld a, $1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	tx_pre BillsHouseInitiatedText
-	ld c, 32
-	call DelayFrames
-	ld a, SFX_TINK
-	call PlaySound
-	call WaitForSoundToFinish
-	ld c, 80
-	call DelayFrames
-	ld a, SFX_SHRINK
-	call PlaySound
-	call WaitForSoundToFinish
-	ld c, 48
-	call DelayFrames
-	ld a, SFX_TINK
-	call PlaySound
-	call WaitForSoundToFinish
-	ld c, 32
-	call DelayFrames
-	ld a, SFX_GET_ITEM_1
-	call PlaySound
-	call WaitForSoundToFinish
-	call PlayDefaultMusic
-	SetEvent EVENT_USED_CELL_SEPARATOR_ON_BILL
-	ret
-.displayBillsHousePokemonList
-	ld a, $1
-	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
-	tx_pre BillsHousePokemonList
-	ret
-
-BillsHouseMonitorText::
-	TX_FAR _BillsHouseMonitorText
-	db "@"
-
-BillsHouseInitiatedText::
-	TX_FAR _BillsHouseInitiatedText
-	TX_BLINK
-	TX_ASM
-	ld a, $ff
-	ld [wNewSoundID], a
-	call PlaySound
-	ld c, 16
-	call DelayFrames
-	ld a, SFX_SWITCH
-	call PlaySound
-	call WaitForSoundToFinish
-	ld c, 60
-	call DelayFrames
-	jp TextScriptEnd
-
-BillsHousePokemonList::
-	TX_ASM
-	call SaveScreenTilesToBuffer1
-	ld hl, BillsHousePokemonListText1
-	call PrintText
-	xor a
-	ld [wMenuItemOffset], a ; not used
-	ld [wCurrentMenuItem], a
-	ld [wLastMenuItem], a
-	ld a, A_BUTTON | B_BUTTON
-	ld [wMenuWatchedKeys], a
-	ld a, 4
-	ld [wMaxMenuItem], a
-	ld a, 2
-	ld [wTopMenuItemY], a
-	ld a, 1
-	ld [wTopMenuItemX], a
-.billsPokemonLoop
-	ld hl, wd730
-	set 6, [hl]
-	coord hl, 0, 0
-	ld b, 10
-	ld c, 9
-	call TextBoxBorder
-	coord hl, 2, 2
-	ld de, BillsMonListText
-	call PlaceString
-	ld hl, BillsHousePokemonListText2
-	call PrintText
-	call SaveScreenTilesToBuffer2
-	call HandleMenuInput
-	bit 1, a ; pressed b
-	jr nz, .cancel
-	ld a, [wCurrentMenuItem]
-	add EEVEE
-	cp EEVEE
-	jr z, .displayPokedex
-	cp FLAREON
-	jr z, .displayPokedex
-	cp JOLTEON
-	jr z, .displayPokedex
-	cp VAPOREON
-	jr z, .displayPokedex
-	jr .cancel
-.displayPokedex
-	call DisplayPokedex
-	call LoadScreenTilesFromBuffer2
-	jr .billsPokemonLoop
-.cancel
-	ld hl, wd730
-	res 6, [hl]
-	call LoadScreenTilesFromBuffer2
-	jp TextScriptEnd
-
-BillsHousePokemonListText1:
-	TX_FAR _BillsHousePokemonListText1
-	db "@"
-
-BillsMonListText:
-	db   "EEVEE"
-	next "FLAREON"
-	next "JOLTEON"
-	next "VAPOREON"
-	next "CANCEL@"
-
-BillsHousePokemonListText2:
-	TX_FAR _BillsHousePokemonListText2
-	db "@"
-
-DisplayOakLabEmailText:
-	ld a, [wSpriteStateData1 + 9]
-	cp SPRITE_FACING_UP
-	ret nz
-	call EnableAutoTextBoxDrawing
-	tx_pre_jump OakLabEmailText
-
-OakLabEmailText::
-	TX_FAR _OakLabEmailText
-	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/bench_guys.asm
@@ -1,0 +1,124 @@
+PrintBenchGuyText:
+	call EnableAutoTextBoxDrawing
+	ld hl, BenchGuyTextPointers
+	ld a, [wCurMap]
+	ld b, a
+.loop
+	ld a, [hli]
+	cp $ff
+	ret z
+	cp b
+	jr z, .match
+	inc hl
+	inc hl
+	jr .loop
+.match
+	ld a, [hli]
+	ld b, a
+	ld a, [wSpriteStateData1 + 9]
+	cp b
+	jr nz, .loop ; player isn't facing left at the bench guy
+	ld a, [hl]
+	jp PrintPredefTextID
+
+; format: db map id, player sprite facing direction, text id of PredefTextIDPointerTable
+BenchGuyTextPointers:
+	db VIRIDIAN_POKECENTER,   SPRITE_FACING_LEFT
+	db_tx_pre ViridianCityPokecenterBenchGuyText
+	db PEWTER_POKECENTER,     SPRITE_FACING_LEFT
+	db_tx_pre PewterCityPokecenterBenchGuyText
+	db CERULEAN_POKECENTER,   SPRITE_FACING_LEFT
+	db_tx_pre CeruleanCityPokecenterBenchGuyText
+	db LAVENDER_POKECENTER,   SPRITE_FACING_LEFT
+	db_tx_pre LavenderCityPokecenterBenchGuyText
+	db VERMILION_POKECENTER,  SPRITE_FACING_LEFT
+	db_tx_pre VermilionCityPokecenterBenchGuyText
+	db CELADON_POKECENTER,    SPRITE_FACING_LEFT
+	db_tx_pre CeladonCityPokecenterBenchGuyText
+	db CELADON_HOTEL,         SPRITE_FACING_LEFT
+	db_tx_pre CeladonCityHotelText
+	db FUCHSIA_POKECENTER,    SPRITE_FACING_LEFT
+	db_tx_pre FuchsiaCityPokecenterBenchGuyText
+	db CINNABAR_POKECENTER,   SPRITE_FACING_LEFT
+	db_tx_pre CinnabarIslandPokecenterBenchGuyText
+	db SAFFRON_POKECENTER,    SPRITE_FACING_LEFT
+	db_tx_pre SaffronCityPokecenterBenchGuyText
+	db MT_MOON_POKECENTER,    SPRITE_FACING_LEFT
+	db_tx_pre MtMoonPokecenterBenchGuyText
+	db ROCK_TUNNEL_POKECENTER,SPRITE_FACING_LEFT
+	db_tx_pre RockTunnelPokecenterBenchGuyText
+	db $FF
+
+ViridianCityPokecenterBenchGuyText::
+	TX_FAR _ViridianCityPokecenterGuyText
+	db "@"
+
+PewterCityPokecenterBenchGuyText::
+	TX_FAR _PewterCityPokecenterGuyText
+	db "@"
+
+CeruleanCityPokecenterBenchGuyText::
+	TX_FAR _CeruleanPokecenterGuyText
+	db "@"
+
+LavenderCityPokecenterBenchGuyText::
+	TX_FAR _LavenderPokecenterGuyText
+	db "@"
+
+MtMoonPokecenterBenchGuyText::
+	TX_FAR _MtMoonPokecenterBenchGuyText
+	db "@"
+
+RockTunnelPokecenterBenchGuyText::
+	TX_FAR _RockTunnelPokecenterGuyText
+	db "@"
+
+UnusedBenchGuyText1::
+	TX_FAR _UnusedBenchGuyText1
+	db "@"
+
+UnusedBenchGuyText2::
+	TX_FAR _UnusedBenchGuyText2
+	db "@"
+
+UnusedBenchGuyText3::
+	TX_FAR _UnusedBenchGuyText3
+	db "@"
+
+VermilionCityPokecenterBenchGuyText::
+	TX_FAR _VermilionPokecenterGuyText
+	db "@"
+
+CeladonCityPokecenterBenchGuyText::
+	TX_FAR _CeladonCityPokecenterGuyText
+	db "@"
+
+FuchsiaCityPokecenterBenchGuyText::
+	TX_FAR _FuchsiaCityPokecenterGuyText
+	db "@"
+
+CinnabarIslandPokecenterBenchGuyText::
+	TX_FAR _CinnabarPokecenterGuyText
+	db "@"
+
+SaffronCityPokecenterBenchGuyText::
+	TX_ASM
+	CheckEvent EVENT_BEAT_SILPH_CO_GIOVANNI
+	ld hl, SaffronCityPokecenterBenchGuyText2
+	jr nz, .asm_624f2
+	ld hl, SaffronCityPokecenterBenchGuyText1
+.asm_624f2
+	call PrintText
+	jp TextScriptEnd
+
+SaffronCityPokecenterBenchGuyText1:
+	TX_FAR _SaffronCityPokecenterGuyText1
+	db "@"
+
+SaffronCityPokecenterBenchGuyText2:
+	TX_FAR _SaffronCityPokecenterGuyText2
+	db "@"
+
+CeladonCityHotelText::
+	TX_FAR _CeladonCityHotelText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/bills_house_pc.asm
@@ -1,0 +1,134 @@
+BillsHousePC:
+	call EnableAutoTextBoxDrawing
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	CheckEvent EVENT_LEFT_BILLS_HOUSE_AFTER_HELPING
+	jr nz, .displayBillsHousePokemonList
+	CheckEventReuseA EVENT_USED_CELL_SEPARATOR_ON_BILL
+	jr nz, .displayBillsHouseMonitorText
+	CheckEventReuseA EVENT_BILL_SAID_USE_CELL_SEPARATOR
+	jr nz, .doCellSeparator
+.displayBillsHouseMonitorText
+	tx_pre_jump BillsHouseMonitorText
+.doCellSeparator
+	ld a, $1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	tx_pre BillsHouseInitiatedText
+	ld c, 32
+	call DelayFrames
+	ld a, SFX_TINK
+	call PlaySound
+	call WaitForSoundToFinish
+	ld c, 80
+	call DelayFrames
+	ld a, SFX_SHRINK
+	call PlaySound
+	call WaitForSoundToFinish
+	ld c, 48
+	call DelayFrames
+	ld a, SFX_TINK
+	call PlaySound
+	call WaitForSoundToFinish
+	ld c, 32
+	call DelayFrames
+	ld a, SFX_GET_ITEM_1
+	call PlaySound
+	call WaitForSoundToFinish
+	call PlayDefaultMusic
+	SetEvent EVENT_USED_CELL_SEPARATOR_ON_BILL
+	ret
+.displayBillsHousePokemonList
+	ld a, $1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	tx_pre BillsHousePokemonList
+	ret
+
+BillsHouseMonitorText::
+	TX_FAR _BillsHouseMonitorText
+	db "@"
+
+BillsHouseInitiatedText::
+	TX_FAR _BillsHouseInitiatedText
+	TX_BLINK
+	TX_ASM
+	ld a, $ff
+	ld [wNewSoundID], a
+	call PlaySound
+	ld c, 16
+	call DelayFrames
+	ld a, SFX_SWITCH
+	call PlaySound
+	call WaitForSoundToFinish
+	ld c, 60
+	call DelayFrames
+	jp TextScriptEnd
+
+BillsHousePokemonList::
+	TX_ASM
+	call SaveScreenTilesToBuffer1
+	ld hl, BillsHousePokemonListText1
+	call PrintText
+	xor a
+	ld [wMenuItemOffset], a ; not used
+	ld [wCurrentMenuItem], a
+	ld [wLastMenuItem], a
+	ld a, A_BUTTON | B_BUTTON
+	ld [wMenuWatchedKeys], a
+	ld a, 4
+	ld [wMaxMenuItem], a
+	ld a, 2
+	ld [wTopMenuItemY], a
+	ld a, 1
+	ld [wTopMenuItemX], a
+.billsPokemonLoop
+	ld hl, wd730
+	set 6, [hl]
+	coord hl, 0, 0
+	ld b, 10
+	ld c, 9
+	call TextBoxBorder
+	coord hl, 2, 2
+	ld de, BillsMonListText
+	call PlaceString
+	ld hl, BillsHousePokemonListText2
+	call PrintText
+	call SaveScreenTilesToBuffer2
+	call HandleMenuInput
+	bit 1, a ; pressed b
+	jr nz, .cancel
+	ld a, [wCurrentMenuItem]
+	add EEVEE
+	cp EEVEE
+	jr z, .displayPokedex
+	cp FLAREON
+	jr z, .displayPokedex
+	cp JOLTEON
+	jr z, .displayPokedex
+	cp VAPOREON
+	jr z, .displayPokedex
+	jr .cancel
+.displayPokedex
+	call DisplayPokedex
+	call LoadScreenTilesFromBuffer2
+	jr .billsPokemonLoop
+.cancel
+	ld hl, wd730
+	res 6, [hl]
+	call LoadScreenTilesFromBuffer2
+	jp TextScriptEnd
+
+BillsHousePokemonListText1:
+	TX_FAR _BillsHousePokemonListText1
+	db "@"
+
+BillsMonListText:
+	db   "EEVEE"
+	next "FLAREON"
+	next "JOLTEON"
+	next "VAPOREON"
+	next "CANCEL@"
+
+BillsHousePokemonListText2:
+	TX_FAR _BillsHousePokemonListText2
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/blues_room.asm
@@ -1,0 +1,13 @@
+
+	ret ; unused
+
+UnusedPredefText::
+	db "@"
+
+PrintBookcaseText:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump BookcaseText
+
+BookcaseText::
+	TX_FAR _BookcaseText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/bookshelves.asm
@@ -1,0 +1,39 @@
+; prints text for bookshelves in buildings without sign events
+PrintBookshelfText::
+	ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+	cp SPRITE_FACING_UP
+	jr nz, .noMatch
+; facing up
+	ld a, [wCurMapTileset]
+	ld b, a
+	aCoord 8, 7
+	ld c, a
+	ld hl, BookshelfTileIDs
+.loop
+	ld a, [hli]
+	cp $ff
+	jr z, .noMatch
+	cp b
+	jr nz, .nextBookshelfEntry1
+	ld a, [hli]
+	cp c
+	jr nz, .nextBookshelfEntry2
+	ld a, [hl]
+	push af
+	call EnableAutoTextBoxDrawing
+	pop af
+	call PrintPredefTextID
+	xor a
+	ld [$ffdb], a
+	ret
+.nextBookshelfEntry1
+	inc hl
+.nextBookshelfEntry2
+	inc hl
+	jr .loop
+.noMatch
+	ld a, $ff
+	ld [$ffdb], a
+	jpba PrintCardKeyText
+
+INCLUDE "data/tilesets/bookshelf_tile_ids.asm"
--- /dev/null
+++ b/engine/events/hidden_objects/cinnabar_gym_quiz.asm
@@ -1,0 +1,194 @@
+PrintCinnabarQuiz:
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump CinnabarGymQuiz
+
+CinnabarGymQuiz::
+	TX_ASM
+	xor a
+	ld [wOpponentAfterWrongAnswer], a
+	ld a, [wHiddenObjectFunctionArgument]
+	push af
+	and $f
+	ld [hGymGateIndex], a
+	pop af
+	and $f0
+	swap a
+	ld [$ffdc], a
+	ld hl, CinnabarGymQuizIntroText
+	call PrintText
+	ld a, [hGymGateIndex]
+	dec a
+	add a
+	ld d, 0
+	ld e, a
+	ld hl, CinnabarQuizQuestions
+	add hl, de
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	call PrintText
+	ld a, 1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	call CinnabarGymQuiz_1ea92
+	jp TextScriptEnd
+
+CinnabarGymQuizIntroText:
+	TX_FAR _CinnabarGymQuizIntroText
+	db "@"
+
+CinnabarQuizQuestions:
+	dw CinnabarQuizQuestionsText1
+	dw CinnabarQuizQuestionsText2
+	dw CinnabarQuizQuestionsText3
+	dw CinnabarQuizQuestionsText4
+	dw CinnabarQuizQuestionsText5
+	dw CinnabarQuizQuestionsText6
+
+CinnabarQuizQuestionsText1:
+	TX_FAR _CinnabarQuizQuestionsText1
+	db "@"
+
+CinnabarQuizQuestionsText2:
+	TX_FAR _CinnabarQuizQuestionsText2
+	db "@"
+
+CinnabarQuizQuestionsText3:
+	TX_FAR _CinnabarQuizQuestionsText3
+	db "@"
+
+CinnabarQuizQuestionsText4:
+	TX_FAR _CinnabarQuizQuestionsText4
+	db "@"
+
+CinnabarQuizQuestionsText5:
+	TX_FAR _CinnabarQuizQuestionsText5
+	db "@"
+
+CinnabarQuizQuestionsText6:
+	TX_FAR _CinnabarQuizQuestionsText6
+	db "@"
+
+CinnabarGymGateFlagAction:
+	EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED
+	predef_jump FlagActionPredef
+
+CinnabarGymQuiz_1ea92:
+	call YesNoChoice
+	ld a, [$ffdc]
+	ld c, a
+	ld a, [wCurrentMenuItem]
+	cp c
+	jr nz, .wrongAnswer
+	ld hl, wCurrentMapScriptFlags
+	set 5, [hl]
+	ld a, [hGymGateIndex]
+	ld [$ffe0], a
+	ld hl, CinnabarGymQuizCorrectText
+	call PrintText
+	ld a, [$ffe0]
+	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
+	ld c, a
+	ld b, FLAG_SET
+	call CinnabarGymGateFlagAction
+	jp UpdateCinnabarGymGateTileBlocks_
+.wrongAnswer
+	call WaitForSoundToFinish
+	ld a, SFX_DENIED
+	call PlaySound
+	call WaitForSoundToFinish
+	ld hl, CinnabarGymQuizIncorrectText
+	call PrintText
+	ld a, [hGymGateIndex]
+	add $2
+	AdjustEventBit EVENT_BEAT_CINNABAR_GYM_TRAINER_0, 2
+	ld c, a
+	ld b, FLAG_TEST
+	EventFlagAddress hl, EVENT_BEAT_CINNABAR_GYM_TRAINER_0
+	predef FlagActionPredef
+	ld a, c
+	and a
+	ret nz
+	ld a, [hGymGateIndex]
+	add $2
+	ld [wOpponentAfterWrongAnswer], a
+	ret
+
+CinnabarGymQuizCorrectText:
+	TX_SFX_ITEM_1
+	TX_FAR _CinnabarGymQuizCorrectText
+	TX_BLINK
+	TX_ASM
+
+	ld a, [$ffe0]
+	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
+	ld c, a
+	ld b, FLAG_TEST
+	call CinnabarGymGateFlagAction
+	ld a, c
+	and a
+	jp nz, TextScriptEnd
+	call WaitForSoundToFinish
+	ld a, SFX_GO_INSIDE
+	call PlaySound
+	call WaitForSoundToFinish
+	jp TextScriptEnd
+
+CinnabarGymQuizIncorrectText:
+	TX_FAR _CinnabarGymQuizIncorrectText
+	db "@"
+
+UpdateCinnabarGymGateTileBlocks_::
+; Update the overworld map with open floor blocks or locked gate blocks
+; depending on event flags.
+	ld a, 6
+	ld [hGymGateIndex], a
+.loop
+	ld a, [hGymGateIndex]
+	dec a
+	add a
+	add a
+	ld d, 0
+	ld e, a
+	ld hl, CinnabarGymGateCoords
+	add hl, de
+	ld a, [hli]
+	ld b, [hl]
+	ld c, a
+	inc hl
+	ld a, [hl]
+	ld [wGymGateTileBlock], a
+	push bc
+	ld a, [hGymGateIndex]
+	ld [$ffe0], a
+	AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
+	ld c, a
+	ld b, FLAG_TEST
+	call CinnabarGymGateFlagAction
+	ld a, c
+	and a
+	jr nz, .unlocked
+	ld a, [wGymGateTileBlock]
+	jr .next
+.unlocked
+	ld a, $e
+.next
+	pop bc
+	ld [wNewTileBlockID], a
+	predef ReplaceTileBlock
+	ld hl, hGymGateIndex
+	dec [hl]
+	jr nz, .loop
+	ret
+
+CinnabarGymGateCoords:
+	; format: x-coord, y-coord, direction, padding
+	; direction: $54 = horizontal gate, $5f = vertical gate
+	db $09,$03,$54,$00
+	db $06,$03,$54,$00
+	db $06,$06,$54,$00
+	db $03,$08,$5f,$00
+	db $02,$06,$54,$00
+	db $02,$03,$54,$00
--- /dev/null
+++ b/engine/events/hidden_objects/diglett_sculpture.asm
@@ -1,0 +1,21 @@
+BookOrSculptureText::
+	TX_ASM
+	ld hl, PokemonBooksText
+	ld a, [wCurMapTileset]
+	cp MANSION ; Celadon Mansion tileset
+	jr nz, .ok
+	aCoord 8, 6
+	cp $38
+	jr nz, .ok
+	ld hl, DiglettSculptureText
+.ok
+	call PrintText
+	jp TextScriptEnd
+
+PokemonBooksText:
+	TX_FAR _PokemonBooksText
+	db "@"
+
+DiglettSculptureText:
+	TX_FAR _DiglettSculptureText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/elevator.asm
@@ -1,0 +1,3 @@
+ElevatorText::
+	TX_FAR _ElevatorText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/fighting_dojo.asm
@@ -1,0 +1,23 @@
+PrintFightingDojoText2:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump EnemiesOnEverySideText
+
+EnemiesOnEverySideText::
+	TX_FAR _EnemiesOnEverySideText
+	db "@"
+
+PrintFightingDojoText3:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump WhatGoesAroundComesAroundText
+
+WhatGoesAroundComesAroundText::
+	TX_FAR _WhatGoesAroundComesAroundText
+	db "@"
+
+PrintFightingDojoText:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump FightingDojoText
+
+FightingDojoText::
+	TX_FAR _FightingDojoText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/gym_statues.asm
@@ -1,0 +1,48 @@
+GymStatues:
+; if in a gym and have the corresponding badge, a = GymStatueText2_id and jp PrintPredefTextID
+; if in a gym and don’t have the corresponding badge, a = GymStatueText1_id and jp PrintPredefTextID
+; else ret
+	call EnableAutoTextBoxDrawing
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	ld hl, .BadgeFlags
+	ld a, [wCurMap]
+	ld b, a
+.loop
+	ld a, [hli]
+	cp $ff
+	ret z
+	cp b
+	jr z, .match
+	inc hl
+	jr .loop
+.match
+	ld b, [hl]
+	ld a, [wBeatGymFlags]
+	and b
+	cp b
+	tx_pre_id GymStatueText2
+	jr z, .haveBadge
+	tx_pre_id GymStatueText1
+.haveBadge
+	jp PrintPredefTextID
+
+.BadgeFlags:
+	db PEWTER_GYM,   %00000001
+	db CERULEAN_GYM, %00000010
+	db VERMILION_GYM,%00000100
+	db CELADON_GYM,  %00001000
+	db FUCHSIA_GYM,  %00010000
+	db SAFFRON_GYM,  %00100000
+	db CINNABAR_GYM, %01000000
+	db VIRIDIAN_GYM, %10000000
+	db $ff
+
+GymStatueText1::
+	TX_FAR _GymStatueText1
+	db "@"
+
+GymStatueText2::
+	TX_FAR _GymStatueText2
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/indigo_plateau_hq.asm
@@ -1,0 +1,10 @@
+PrintIndigoPlateauHQText:
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump IndigoPlateauHQText
+
+IndigoPlateauHQText::
+	TX_FAR _IndigoPlateauHQText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/indigo_plateau_statues.asm
@@ -1,0 +1,24 @@
+IndigoPlateauStatues::
+	TX_ASM
+	ld hl, IndigoPlateauStatuesText1
+	call PrintText
+	ld a, [wXCoord]
+	bit 0, a
+	ld hl, IndigoPlateauStatuesText2
+	jr nz, .ok
+	ld hl, IndigoPlateauStatuesText3
+.ok
+	call PrintText
+	jp TextScriptEnd
+
+IndigoPlateauStatuesText1:
+	TX_FAR _IndigoPlateauStatuesText1
+	db "@"
+
+IndigoPlateauStatuesText2:
+	TX_FAR _IndigoPlateauStatuesText2
+	db "@"
+
+IndigoPlateauStatuesText3:
+	TX_FAR _IndigoPlateauStatuesText3
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/magazines.asm
@@ -1,0 +1,8 @@
+PrintMagazinesText:
+	call EnableAutoTextBoxDrawing
+	tx_pre MagazinesText
+	ret
+
+MagazinesText::
+	TX_FAR _MagazinesText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/museum_fossils.asm
@@ -1,0 +1,52 @@
+AerodactylFossil:
+	ld a, FOSSIL_AERODACTYL
+	ld [wcf91], a
+	call DisplayMonFrontSpriteInBox
+	call EnableAutoTextBoxDrawing
+	tx_pre AerodactylFossilText
+	ret
+
+AerodactylFossilText::
+	TX_FAR _AerodactylFossilText
+	db "@"
+
+KabutopsFossil:
+	ld a, FOSSIL_KABUTOPS
+	ld [wcf91], a
+	call DisplayMonFrontSpriteInBox
+	call EnableAutoTextBoxDrawing
+	tx_pre KabutopsFossilText
+	ret
+
+KabutopsFossilText::
+	TX_FAR _KabutopsFossilText
+	db "@"
+
+DisplayMonFrontSpriteInBox:
+; Displays a pokemon's front sprite in a pop-up window.
+; [wcf91] = pokemon internal id number
+	ld a, 1
+	ld [H_AUTOBGTRANSFERENABLED], a
+	call Delay3
+	xor a
+	ld [hWY], a
+	call SaveScreenTilesToBuffer1
+	ld a, MON_SPRITE_POPUP
+	ld [wTextBoxID], a
+	call DisplayTextBoxID
+	call UpdateSprites
+	ld a, [wcf91]
+	ld [wd0b5], a
+	call GetMonHeader
+	ld de, vChars1 + $310
+	call LoadMonFrontSprite
+	ld a, $80
+	ld [hStartTileID], a
+	coord hl, 10, 11
+	predef AnimateSendingOutMon
+	call WaitForTextScrollButtonPress
+	call LoadScreenTilesFromBuffer1
+	call Delay3
+	ld a, $90
+	ld [hWY], a
+	ret
--- /dev/null
+++ b/engine/events/hidden_objects/new_bike.asm
@@ -1,0 +1,7 @@
+PrintNewBikeText:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump NewBicycleText
+
+NewBicycleText::
+	TX_FAR _NewBicycleText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/oaks_lab_email.asm
@@ -1,0 +1,10 @@
+DisplayOakLabEmailText:
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump OakLabEmailText
+
+OakLabEmailText::
+	TX_FAR _OakLabEmailText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/oaks_lab_posters.asm
@@ -1,0 +1,29 @@
+DisplayOakLabLeftPoster:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump PushStartText
+
+PushStartText::
+	TX_FAR _PushStartText
+	db "@"
+
+DisplayOakLabRightPoster:
+	call EnableAutoTextBoxDrawing
+	ld hl, wPokedexOwned
+	ld b, wPokedexOwnedEnd - wPokedexOwned
+	call CountSetBits
+	ld a, [wNumSetBits]
+	cp 2
+	tx_pre_id SaveOptionText
+	jr c, .ownLessThanTwo
+	; own two or more mon
+	tx_pre_id StrengthsAndWeaknessesText
+.ownLessThanTwo
+	jp PrintPredefTextID
+
+SaveOptionText::
+	TX_FAR _SaveOptionText
+	db "@"
+
+StrengthsAndWeaknessesText::
+	TX_FAR _StrengthsAndWeaknessesText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/pokecenter_pc.asm
@@ -1,0 +1,11 @@
+OpenPokemonCenterPC:
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP ; check to see if player is facing up
+	ret nz
+	call EnableAutoTextBoxDrawing
+	ld a, $1
+	ld [wAutoTextBoxDrawingControl], a
+	tx_pre_jump PokemonCenterPCText
+
+PokemonCenterPCText::
+	TX_POKECENTER_PC
--- /dev/null
+++ b/engine/events/hidden_objects/pokemon_stuff.asm
@@ -1,0 +1,3 @@
+PokemonStuffText::
+	TX_FAR _PokemonStuffText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/reds_room.asm
@@ -1,0 +1,14 @@
+PrintRedSNESText:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump RedBedroomSNESText
+
+RedBedroomSNESText::
+	TX_FAR _RedBedroomSNESText
+	db "@"
+
+OpenRedsPC:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump RedBedroomPCText
+
+RedBedroomPCText::
+	TX_PLAYERS_PC
--- /dev/null
+++ b/engine/events/hidden_objects/route_15_binoculars.asm
@@ -1,0 +1,14 @@
+Route15GateLeftBinoculars:
+	ld a, [wSpriteStateData1 + 9]
+	cp SPRITE_FACING_UP
+	ret nz
+	call EnableAutoTextBoxDrawing
+	tx_pre Route15UpstairsBinocularsText
+	ld a, ARTICUNO
+	ld [wcf91], a
+	call PlayCry
+	jp DisplayMonFrontSpriteInBox
+
+Route15UpstairsBinocularsText::
+	TX_FAR _Route15UpstairsBinocularsText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/safari_game.asm
@@ -1,0 +1,79 @@
+SafariZoneCheck::
+	CheckEventHL EVENT_IN_SAFARI_ZONE ; if we are not in the Safari Zone,
+	jr z, SafariZoneGameStillGoing ; don't bother printing game over text
+	ld a, [wNumSafariBalls]
+	and a
+	jr z, SafariZoneGameOver
+	jr SafariZoneGameStillGoing
+
+SafariZoneCheckSteps::
+	ld a, [wSafariSteps]
+	ld b, a
+	ld a, [wSafariSteps + 1]
+	ld c, a
+	or b
+	jr z, SafariZoneGameOver
+	dec bc
+	ld a, b
+	ld [wSafariSteps], a
+	ld a, c
+	ld [wSafariSteps + 1], a
+SafariZoneGameStillGoing:
+	xor a
+	ld [wSafariZoneGameOver], a
+	ret
+
+SafariZoneGameOver:
+	call EnableAutoTextBoxDrawing
+	xor a
+	ld [wAudioFadeOutControl], a
+	dec a
+	call PlaySound
+	ld c, BANK(SFX_Safari_Zone_PA)
+	ld a, SFX_SAFARI_ZONE_PA
+	call PlayMusic
+.waitForMusicToPlay
+	ld a, [wChannelSoundIDs + Ch5]
+	cp SFX_SAFARI_ZONE_PA
+	jr nz, .waitForMusicToPlay
+	ld a, TEXT_SAFARI_GAME_OVER
+	ld [hSpriteIndexOrTextID], a
+	call DisplayTextID
+	xor a
+	ld [wPlayerMovingDirection], a
+	ld a, SAFARI_ZONE_GATE
+	ld [hWarpDestinationMap], a
+	ld a, $3
+	ld [wDestinationWarpID], a
+	ld a, $5
+	ld [wSafariZoneGateCurScript], a
+	SetEvent EVENT_SAFARI_GAME_OVER
+	ld a, 1
+	ld [wSafariZoneGameOver], a
+	ret
+
+PrintSafariGameOverText::
+	xor a
+	ld [wJoyIgnore], a
+	ld hl, SafariGameOverText
+	jp PrintText
+
+SafariGameOverText:
+	TX_ASM
+	ld a, [wNumSafariBalls]
+	and a
+	jr z, .noMoreSafariBalls
+	ld hl, TimesUpText
+	call PrintText
+.noMoreSafariBalls
+	ld hl, GameOverText
+	call PrintText
+	jp TextScriptEnd
+
+TimesUpText:
+	TX_FAR _TimesUpText
+	db "@"
+
+GameOverText:
+	TX_FAR _GameOverText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/school_blackboard.asm
@@ -1,0 +1,222 @@
+PrintBlackboardLinkCableText:
+	call EnableAutoTextBoxDrawing
+	ld a, $1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	ld a, [wHiddenObjectFunctionArgument]
+	call PrintPredefTextID
+	ret
+
+LinkCableHelp::
+	TX_ASM
+	call SaveScreenTilesToBuffer1
+	ld hl, LinkCableHelpText1
+	call PrintText
+	xor a
+	ld [wMenuItemOffset], a ; not used
+	ld [wCurrentMenuItem], a
+	ld [wLastMenuItem], a
+	ld a, A_BUTTON | B_BUTTON
+	ld [wMenuWatchedKeys], a
+	ld a, 3
+	ld [wMaxMenuItem], a
+	ld a, 2
+	ld [wTopMenuItemY], a
+	ld a, 1
+	ld [wTopMenuItemX], a
+.linkHelpLoop
+	ld hl, wd730
+	set 6, [hl]
+	coord hl, 0, 0
+	ld b, 8
+	ld c, 13
+	call TextBoxBorder
+	coord hl, 2, 2
+	ld de, HowToLinkText
+	call PlaceString
+	ld hl, LinkCableHelpText2
+	call PrintText
+	call HandleMenuInput
+	bit 1, a ; pressed b
+	jr nz, .exit
+	ld a, [wCurrentMenuItem]
+	cp 3 ; pressed a on "STOP READING"
+	jr z, .exit
+	ld hl, wd730
+	res 6, [hl]
+	ld hl, LinkCableInfoTexts
+	add a
+	ld d, 0
+	ld e, a
+	add hl, de
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	call PrintText
+	jp .linkHelpLoop
+.exit
+	ld hl, wd730
+	res 6, [hl]
+	call LoadScreenTilesFromBuffer1
+	jp TextScriptEnd
+
+LinkCableHelpText1:
+	TX_FAR _LinkCableHelpText1
+	db "@"
+
+LinkCableHelpText2:
+	TX_FAR _LinkCableHelpText2
+	db "@"
+
+HowToLinkText:
+	db   "HOW TO LINK"
+	next "COLOSSEUM"
+	next "TRADE CENTER"
+	next "STOP READING@"
+
+LinkCableInfoTexts:
+	dw LinkCableInfoText1
+	dw LinkCableInfoText2
+	dw LinkCableInfoText3
+
+LinkCableInfoText1:
+	TX_FAR _LinkCableInfoText1
+	db "@"
+
+LinkCableInfoText2:
+	TX_FAR _LinkCableInfoText2
+	db "@"
+
+LinkCableInfoText3:
+	TX_FAR _LinkCableInfoText3
+	db "@"
+
+ViridianSchoolBlackboard::
+	TX_ASM
+	call SaveScreenTilesToBuffer1
+	ld hl, ViridianSchoolBlackboardText1
+	call PrintText
+	xor a
+	ld [wMenuItemOffset], a
+	ld [wCurrentMenuItem], a
+	ld [wLastMenuItem], a
+	ld a, D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON
+	ld [wMenuWatchedKeys], a
+	ld a, 2
+	ld [wMaxMenuItem], a
+	ld a, 2
+	ld [wTopMenuItemY], a
+	ld a, 1
+	ld [wTopMenuItemX], a
+.blackboardLoop
+	ld hl, wd730
+	set 6, [hl]
+	coord hl, 0, 0
+	lb bc, 6, 10
+	call TextBoxBorder
+	coord hl, 1, 2
+	ld de, StatusAilmentText1
+	call PlaceString
+	coord hl, 6, 2
+	ld de, StatusAilmentText2
+	call PlaceString
+	ld hl, ViridianSchoolBlackboardText2
+	call PrintText
+	call HandleMenuInput ; pressing up and down is handled in here
+	bit 1, a ; pressed b
+	jr nz, .exitBlackboard
+	bit 4, a ; pressed right
+	jr z, .didNotPressRight
+	; move cursor to right column
+	ld a, 2
+	ld [wMaxMenuItem], a
+	ld a, 2
+	ld [wTopMenuItemY], a
+	ld a, 6
+	ld [wTopMenuItemX], a
+	ld a, 3 ; in the the right column, use an offset to prevent overlap
+	ld [wMenuItemOffset], a
+	jr .blackboardLoop
+.didNotPressRight
+	bit 5, a ; pressed left
+	jr z, .didNotPressLeftOrRight
+	; move cursor to left column
+	ld a, 2
+	ld [wMaxMenuItem], a
+	ld a, 2
+	ld [wTopMenuItemY], a
+	ld a, 1
+	ld [wTopMenuItemX], a
+	xor a
+	ld [wMenuItemOffset], a
+	jr .blackboardLoop
+.didNotPressLeftOrRight
+	ld a, [wCurrentMenuItem]
+	ld b, a
+	ld a, [wMenuItemOffset]
+	add b
+	cp 5 ; cursor is pointing to "QUIT"
+	jr z, .exitBlackboard
+	; we must have pressed a on a status condition
+	; so print the text
+	ld hl, wd730
+	res 6, [hl]
+	ld hl, ViridianBlackboardStatusPointers
+	add a
+	ld d, 0
+	ld e, a
+	add hl, de
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	call PrintText
+	jp .blackboardLoop
+.exitBlackboard
+	ld hl, wd730
+	res 6, [hl]
+	call LoadScreenTilesFromBuffer1
+	jp TextScriptEnd
+
+ViridianSchoolBlackboardText1:
+	TX_FAR _ViridianSchoolBlackboardText1
+	db "@"
+
+ViridianSchoolBlackboardText2:
+	TX_FAR _ViridianSchoolBlackboardText2
+	db "@"
+
+StatusAilmentText1:
+	db   " SLP"
+	next " PSN"
+	next " PAR@"
+
+StatusAilmentText2:
+	db   " BRN"
+	next " FRZ"
+	next " QUIT@@"
+
+ViridianBlackboardStatusPointers:
+	dw ViridianBlackboardSleepText
+	dw ViridianBlackboardPoisonText
+	dw ViridianBlackboardPrlzText
+	dw ViridianBlackboardBurnText
+	dw ViridianBlackboardFrozenText
+
+ViridianBlackboardSleepText:
+	TX_FAR _ViridianBlackboardSleepText
+	db "@"
+
+ViridianBlackboardPoisonText:
+	TX_FAR _ViridianBlackboardPoisonText
+	db "@"
+
+ViridianBlackboardPrlzText:
+	TX_FAR _ViridianBlackboardPrlzText
+	db "@"
+
+ViridianBlackboardBurnText:
+	TX_FAR _ViridianBlackboardBurnText
+	db "@"
+
+ViridianBlackboardFrozenText:
+	TX_FAR _ViridianBlackboardFrozenText
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/school_notebooks.asm
@@ -1,0 +1,65 @@
+PrintNotebookText:
+	call EnableAutoTextBoxDrawing
+	ld a, $1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	ld a, [wHiddenObjectFunctionArgument]
+	jp PrintPredefTextID
+
+TMNotebook::
+	TX_FAR TMNotebookText
+	TX_WAIT
+	db "@"
+
+ViridianSchoolNotebook::
+	TX_ASM
+	ld hl, ViridianSchoolNotebookText1
+	call PrintText
+	call TurnPageSchoolNotebook
+	jr nz, .doneReading
+	ld hl, ViridianSchoolNotebookText2
+	call PrintText
+	call TurnPageSchoolNotebook
+	jr nz, .doneReading
+	ld hl, ViridianSchoolNotebookText3
+	call PrintText
+	call TurnPageSchoolNotebook
+	jr nz, .doneReading
+	ld hl, ViridianSchoolNotebookText4
+	call PrintText
+	ld hl, ViridianSchoolNotebookText5
+	call PrintText
+.doneReading
+	jp TextScriptEnd
+
+TurnPageSchoolNotebook:
+	ld hl, TurnPageText
+	call PrintText
+	call YesNoChoice
+	ld a, [wCurrentMenuItem]
+	and a
+	ret
+
+TurnPageText:
+	TX_FAR _TurnPageText
+	db "@"
+
+ViridianSchoolNotebookText5:
+	TX_FAR _ViridianSchoolNotebookText5
+	TX_WAIT
+	db "@"
+
+ViridianSchoolNotebookText1:
+	TX_FAR _ViridianSchoolNotebookText1
+	db "@"
+
+ViridianSchoolNotebookText2:
+	TX_FAR _ViridianSchoolNotebookText2
+	db "@"
+
+ViridianSchoolNotebookText3:
+	TX_FAR _ViridianSchoolNotebookText3
+	db "@"
+
+ViridianSchoolNotebookText4:
+	TX_FAR _ViridianSchoolNotebookText4
+	db "@"
--- /dev/null
+++ b/engine/events/hidden_objects/town_map.asm
@@ -1,0 +1,22 @@
+TownMapText::
+	TX_FAR _TownMapText
+	TX_BLINK
+	TX_ASM
+	ld a, $1
+	ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+	ld hl, wd730
+	set 6, [hl]
+	call GBPalWhiteOutWithDelay3
+	xor a
+	ld [hWY], a
+	inc a
+	ld [H_AUTOBGTRANSFERENABLED], a
+	call LoadFontTilePatterns
+	callba DisplayTownMap
+	ld hl, wd730
+	res 6, [hl]
+	ld de, TextScriptEnd
+	push de
+	ld a, [H_LOADEDROMBANK]
+	push af
+	jp CloseTextDisplay
--- /dev/null
+++ b/engine/events/hidden_objects/vermilion_gym_trash.asm
@@ -1,0 +1,169 @@
+PrintTrashText:
+	call EnableAutoTextBoxDrawing
+	tx_pre_jump VermilionGymTrashText
+
+VermilionGymTrashText::
+	TX_FAR _VermilionGymTrashText
+	db "@"
+
+GymTrashScript:
+	call EnableAutoTextBoxDrawing
+	ld a, [wHiddenObjectFunctionArgument]
+	ld [wGymTrashCanIndex], a
+
+; Don't do the trash can puzzle if it's already been done.
+	CheckEvent EVENT_2ND_LOCK_OPENED
+	jr z, .ok
+
+	tx_pre_jump VermilionGymTrashText
+
+.ok
+	CheckEventReuseA EVENT_1ST_LOCK_OPENED
+	jr nz, .trySecondLock
+
+	ld a, [wFirstLockTrashCanIndex]
+	ld b, a
+	ld a, [wGymTrashCanIndex]
+	cp b
+	jr z, .openFirstLock
+
+	tx_pre_id VermilionGymTrashText
+	jr .done
+
+.openFirstLock
+; Next can is trying for the second switch.
+	SetEvent EVENT_1ST_LOCK_OPENED
+
+	ld hl, GymTrashCans
+	ld a, [wGymTrashCanIndex]
+	; * 5
+	ld b, a
+	add a
+	add a
+	add b
+
+	ld d, 0
+	ld e, a
+	add hl, de
+	ld a, [hli]
+
+; There is a bug in this code. It should calculate a value in the range [0, 3]
+; but if the mask and random number don't have any 1 bits in common, then
+; the result of the AND will be 0. When 1 is subtracted from that, the value
+; will become $ff. This will result in 255 being added to hl, which will cause
+; hl to point to one of the zero bytes that pad the end of the ROM bank.
+; Trash can 0 was intended to be able to have the second lock only when the
+; first lock was in trash can 1 or 3. However, due to this bug, trash can 0 can
+; have the second lock regardless of which trash can had the first lock.
+
+	ld [hGymTrashCanRandNumMask], a
+	push hl
+	call Random
+	swap a
+	ld b, a
+	ld a, [hGymTrashCanRandNumMask]
+	and b
+	dec a
+	pop hl
+
+	ld d, 0
+	ld e, a
+	add hl, de
+	ld a, [hl]
+	and $f
+	ld [wSecondLockTrashCanIndex], a
+
+	tx_pre_id VermilionGymTrashSuccessText1
+	jr .done
+
+.trySecondLock
+	ld a, [wSecondLockTrashCanIndex]
+	ld b, a
+	ld a, [wGymTrashCanIndex]
+	cp b
+	jr z, .openSecondLock
+
+; Reset the cans.
+	ResetEvent EVENT_1ST_LOCK_OPENED
+	call Random
+
+	and $e
+	ld [wFirstLockTrashCanIndex], a
+
+	tx_pre_id VermilionGymTrashFailText
+	jr .done
+
+.openSecondLock
+; Completed the trash can puzzle.
+	SetEvent EVENT_2ND_LOCK_OPENED
+	ld hl, wCurrentMapScriptFlags
+	set 6, [hl]
+
+	tx_pre_id VermilionGymTrashSuccessText3
+
+.done
+	jp PrintPredefTextID
+
+GymTrashCans:
+; byte 0: mask for random number
+; bytes 1-4: indices of the trash cans that can have the second lock
+;            (but see the comment above explaining a bug regarding this)
+; Note that the mask is simply the number of valid trash can indices that
+; follow. The remaining bytes are filled with 0 to pad the length of each entry
+; to 5 bytes.
+	db 2,  1,  3,  0,  0 ; 0
+	db 3,  0,  2,  4,  0 ; 1
+	db 2,  1,  5,  0,  0 ; 2
+	db 3,  0,  4,  6,  0 ; 3
+	db 4,  1,  3,  5,  7 ; 4
+	db 3,  2,  4,  8,  0 ; 5
+	db 3,  3,  7,  9,  0 ; 6
+	db 4,  4,  6,  8, 10 ; 7
+	db 3,  5,  7, 11,  0 ; 8
+	db 3,  6, 10, 12,  0 ; 9
+	db 4,  7,  9, 11, 13 ; 10
+	db 3,  8, 10, 14,  0 ; 11
+	db 2,  9, 13,  0,  0 ; 12
+	db 3, 10, 12, 14,  0 ; 13
+	db 2, 11, 13,  0,  0 ; 14
+
+VermilionGymTrashSuccessText1::
+	TX_FAR _VermilionGymTrashSuccessText1
+	TX_ASM
+	call WaitForSoundToFinish
+	ld a, SFX_SWITCH
+	call PlaySound
+	call WaitForSoundToFinish
+	jp TextScriptEnd
+
+; unused
+VermilionGymTrashSuccessText2::
+	TX_FAR _VermilionGymTrashSuccessText2
+	db "@"
+
+; unused
+VermilionGymTrashSuccesPlaySfx:
+	TX_ASM
+	call WaitForSoundToFinish
+	ld a, SFX_SWITCH
+	call PlaySound
+	call WaitForSoundToFinish
+	jp TextScriptEnd
+
+VermilionGymTrashSuccessText3::
+	TX_FAR _VermilionGymTrashSuccessText3
+	TX_ASM
+	call WaitForSoundToFinish
+	ld a, SFX_GO_INSIDE
+	call PlaySound
+	call WaitForSoundToFinish
+	jp TextScriptEnd
+
+VermilionGymTrashFailText::
+	TX_FAR _VermilionGymTrashFailText
+	TX_ASM
+	call WaitForSoundToFinish
+	ld a, SFX_DENIED
+	call PlaySound
+	call WaitForSoundToFinish
+	jp TextScriptEnd
--- a/main.asm
+++ b/main.asm
@@ -74,7 +74,12 @@
 INCLUDE "engine/items/get_bag_item_quantity.asm"
 INCLUDE "engine/overworld/pathfinding.asm"
 INCLUDE "engine/gfx/hp_bar.asm"
-INCLUDE "engine/events/hidden_object_functions3.asm"
+INCLUDE "engine/events/hidden_objects/bookshelves.asm"
+INCLUDE "engine/events/hidden_objects/indigo_plateau_statues.asm"
+INCLUDE "engine/events/hidden_objects/diglett_sculpture.asm"
+INCLUDE "engine/events/hidden_objects/elevator.asm"
+INCLUDE "engine/events/hidden_objects/town_map.asm"
+INCLUDE "engine/events/hidden_objects/pokemon_stuff.asm"
 
 
 SECTION "Graphics (BANK 4)", ROMX
@@ -157,7 +162,13 @@
 SECTION "bank7_2", ROMX
 
 INCLUDE "engine/menus/oaks_pc.asm"
-INCLUDE "engine/events/hidden_object_functions7.asm"
+INCLUDE "engine/events/hidden_objects/new_bike.asm"
+INCLUDE "engine/events/hidden_objects/oaks_lab_posters.asm"
+INCLUDE "engine/events/hidden_objects/safari_game.asm"
+INCLUDE "engine/events/hidden_objects/cinnabar_gym_quiz.asm"
+INCLUDE "engine/events/hidden_objects/magazines.asm"
+INCLUDE "engine/events/hidden_objects/bills_house_pc.asm"
+INCLUDE "engine/events/hidden_objects/oaks_lab_email.asm"
 
 
 SECTION "Bill's PC", ROMX
@@ -274,7 +285,9 @@
 INCLUDE "engine/battle/move_effects/paralyze.asm"
 INCLUDE "engine/events/card_key.asm"
 INCLUDE "engine/events/prize_menu.asm"
-INCLUDE "engine/events/hidden_object_functions14.asm"
+INCLUDE "engine/events/hidden_objects/school_notebooks.asm"
+INCLUDE "engine/events/hidden_objects/fighting_dojo.asm"
+INCLUDE "engine/events/hidden_objects/indigo_plateau_hq.asm"
 
 
 SECTION "bank15_1", ROMX
@@ -308,7 +321,11 @@
 SECTION "bank17_2", ROMX
 
 INCLUDE "engine/pokemon/set_types.asm"
-INCLUDE "engine/events/hidden_object_functions17.asm"
+INCLUDE "engine/events/hidden_objects/reds_room.asm"
+INCLUDE "engine/events/hidden_objects/route_15_binoculars.asm"
+INCLUDE "engine/events/hidden_objects/museum_fossils.asm"
+INCLUDE "engine/events/hidden_objects/school_blackboard.asm"
+INCLUDE "engine/events/hidden_objects/vermilion_gym_trash.asm"
 
 
 SECTION "bank18_1", ROMX
@@ -318,7 +335,10 @@
 
 SECTION "bank18_2", ROMX
 
-INCLUDE "engine/events/hidden_object_functions18.asm"
+INCLUDE "engine/events/hidden_objects/gym_statues.asm"
+INCLUDE "engine/events/hidden_objects/bench_guys.asm"
+INCLUDE "engine/events/hidden_objects/blues_room.asm"
+INCLUDE "engine/events/hidden_objects/pokecenter_pc.asm"
 
 
 SECTION "bank1A", ROMX