summaryrefslogtreecommitdiff
path: root/en
diff options
context:
space:
mode:
authorIIMarckus <iimarckus@gmail.com>2018-06-02 03:58:54 -0600
committerIIMarckus <iimarckus@gmail.com>2018-06-02 03:58:54 -0600
commit5e32a29c2e25641c17d794d8e321904cdf7de950 (patch)
treed7bf99ff898027beee690e67dab6c847b6783582 /en
parent1a13f92d5db9cf08ddd87a5fc79f446375138b77 (diff)
Migrate language-dependent files to a subdirectory.
Diffstat (limited to 'en')
-rw-r--r--en/charmap.asm265
-rw-r--r--en/constants/credits_constants.asm67
-rwxr-xr-xen/data/credits_order.asm39
-rwxr-xr-xen/data/pokedex_entries.asm1259
-rwxr-xr-xen/data/prizes.asm72
-rwxr-xr-xen/data/trades.asm12
-rwxr-xr-xen/engine/HoF_room_pc.asm270
-rwxr-xr-xen/engine/battle/core.asm8719
-rwxr-xr-xen/engine/battle/end_of_battle.asm88
-rw-r--r--en/engine/battle/link_battle_versus_text.asm23
-rw-r--r--en/engine/battle/save_trainer_name.asm112
-rwxr-xr-xen/engine/cable_club.asm977
-rwxr-xr-xen/engine/clear_save.asm23
-rwxr-xr-xen/engine/evolve_trade.asm44
-rwxr-xr-xen/engine/hall_of_fame.asm288
-rwxr-xr-xen/engine/hidden_object_functions17.asm475
-rwxr-xr-xen/engine/hidden_object_functions7.asm467
-rwxr-xr-xen/engine/items/items.asm2989
-rwxr-xr-xen/engine/learn_move.asm226
-rw-r--r--en/engine/menu/bills_pc.asm554
-rwxr-xr-xen/engine/menu/diploma.asm113
-rw-r--r--en/engine/menu/draw_start_menu.asm89
-rwxr-xr-xen/engine/menu/league_pc.asm120
-rwxr-xr-xen/engine/menu/main_menu.asm712
-rwxr-xr-xen/engine/menu/naming_screen.asm512
-rwxr-xr-xen/engine/menu/party_menu.asm325
-rwxr-xr-xen/engine/menu/players_pc.asm303
-rwxr-xr-xen/engine/menu/pokedex.asm665
-rwxr-xr-xen/engine/menu/prize_menu.asm306
-rwxr-xr-xen/engine/menu/start_sub_menus.asm854
-rwxr-xr-xen/engine/menu/status_screen.asm481
-rw-r--r--en/engine/menu/text_box.asm767
-rwxr-xr-xen/engine/menu/vending_machine.asm139
-rwxr-xr-xen/engine/oak_speech2.asm272
-rw-r--r--en/engine/overworld/movement.asm880
-rwxr-xr-xen/engine/overworld/pokemart.asm272
-rw-r--r--en/engine/print_waiting_text.asm20
-rwxr-xr-xen/engine/save.asm708
-rwxr-xr-xen/engine/slot_machine.asm892
-rwxr-xr-xen/engine/status_ailments.asm46
-rwxr-xr-xen/engine/titlescreen.asm403
-rwxr-xr-xen/engine/town_map.asm619
-rwxr-xr-xen/engine/trade.asm853
-rw-r--r--en/gfx/ED_tile.pngbin0 -> 79 bytes
-rw-r--r--en/gfx/battle_hud1.pngbin0 -> 94 bytes
-rw-r--r--en/gfx/blue/blueversion.pngbin0 -> 116 bytes
-rw-r--r--en/gfx/blue/sgbborder.pngbin0 -> 1117 bytes
-rw-r--r--en/gfx/blue/slotmachine1.pngbin0 -> 459 bytes
-rw-r--r--en/gfx/copyright.pngbin0 -> 220 bytes
-rw-r--r--en/gfx/font.pngbin0 -> 625 bytes
-rw-r--r--en/gfx/hp_bar_and_status.pngbin0 -> 262 bytes
-rw-r--r--en/gfx/overworld.pngbin0 -> 1309 bytes
-rw-r--r--en/gfx/pokedex.pngbin0 -> 179 bytes
-rw-r--r--en/gfx/red/redgreenversion.pngbin0 -> 126 bytes
-rw-r--r--en/gfx/red/sgbborder.pngbin0 -> 1048 bytes
-rw-r--r--en/gfx/red/slotmachine1.pngbin0 -> 471 bytes
-rw-r--r--en/gfx/town_map.pngbin0 -> 256 bytes
-rw-r--r--en/home.asm4721
-rw-r--r--en/home/text.asm711
-rwxr-xr-xen/main.asm2090
-rwxr-xr-xen/scripts/bikeshop.asm147
-rwxr-xr-xen/scripts/celadongamecorner.asm527
-rwxr-xr-xen/scripts/celadongym.asm335
-rwxr-xr-xen/scripts/ceruleangym.asm219
-rwxr-xr-xen/scripts/cinnabargym.asm472
-rwxr-xr-xen/scripts/fuchsiagym.asm329
-rwxr-xr-xen/scripts/pewtercity.asm322
-rwxr-xr-xen/scripts/pewtergym.asm228
-rwxr-xr-xen/scripts/route23.asm236
-rwxr-xr-xen/scripts/saffrongym.asm358
-rwxr-xr-xen/scripts/vermiliongym.asm267
-rwxr-xr-xen/scripts/viridiangym.asm496
-rwxr-xr-xen/text/credits_text.asm199
-rwxr-xr-xen/text/item_names.asm98
-rwxr-xr-xen/text/map_names.asm107
-rw-r--r--en/text/maps/agatha.asm44
-rw-r--r--en/text/maps/bike_shop.asm70
-rw-r--r--en/text/maps/bills_house.asm87
-rw-r--r--en/text/maps/blues_house.asm41
-rw-r--r--en/text/maps/bruno.asm37
-rw-r--r--en/text/maps/celadon_city.asm152
-rw-r--r--en/text/maps/celadon_dept_store_1f.asm31
-rw-r--r--en/text/maps/celadon_dept_store_2f.asm22
-rw-r--r--en/text/maps/celadon_dept_store_3f.asm98
-rw-r--r--en/text/maps/celadon_dept_store_4f.asm26
-rw-r--r--en/text/maps/celadon_dept_store_5f.asm28
-rw-r--r--en/text/maps/celadon_dept_store_roof.asm138
-rw-r--r--en/text/maps/celadon_diner.asm59
-rw-r--r--en/text/maps/celadon_game_corner.asm186
-rw-r--r--en/text/maps/celadon_gym.asm218
-rw-r--r--en/text/maps/celadon_hotel.asm21
-rw-r--r--en/text/maps/celadon_house.asm22
-rw-r--r--en/text/maps/celadon_mansion_1f.asm23
-rw-r--r--en/text/maps/celadon_mansion_2f.asm4
-rw-r--r--en/text/maps/celadon_mansion_3f.asm66
-rw-r--r--en/text/maps/celadon_mansion_4f_inside.asm10
-rw-r--r--en/text/maps/celadon_mansion_4f_outside.asm3
-rw-r--r--en/text/maps/celadon_pokecenter.asm12
-rw-r--r--en/text/maps/celadon_prize_room.asm12
-rw-r--r--en/text/maps/cerulean_badge_house.asm97
-rw-r--r--en/text/maps/cerulean_city.asm232
-rw-r--r--en/text/maps/cerulean_gym.asm131
-rw-r--r--en/text/maps/cerulean_mart.asm19
-rw-r--r--en/text/maps/cerulean_pokecenter.asm24
-rw-r--r--en/text/maps/cerulean_trade_house.asm9
-rw-r--r--en/text/maps/cerulean_trashed_house.asm36
-rw-r--r--en/text/maps/champion.asm146
-rw-r--r--en/text/maps/cinnabar_gym.asm209
-rw-r--r--en/text/maps/cinnabar_island.asm37
-rw-r--r--en/text/maps/cinnabar_lab.asm29
-rw-r--r--en/text/maps/cinnabar_lab_fossil_room.asm78
-rw-r--r--en/text/maps/cinnabar_lab_metronome_room.asm63
-rw-r--r--en/text/maps/cinnabar_lab_trade_room.asm9
-rw-r--r--en/text/maps/cinnabar_mart.asm10
-rw-r--r--en/text/maps/cinnabar_pokecenter.asm21
-rw-r--r--en/text/maps/copycats_house_1f.asm20
-rw-r--r--en/text/maps/copycats_house_2f.asm96
-rw-r--r--en/text/maps/daycare_1.asm62
-rw-r--r--en/text/maps/daycare_2.asm33
-rw-r--r--en/text/maps/digletts_cave_route_11_entrance.asm8
-rw-r--r--en/text/maps/digletts_cave_route_2_entrance.asm9
-rw-r--r--en/text/maps/fan_club.asm143
-rw-r--r--en/text/maps/fighting_dojo.asm130
-rw-r--r--en/text/maps/fuchsia_city.asm119
-rw-r--r--en/text/maps/fuchsia_fishing_house.asm43
-rw-r--r--en/text/maps/fuchsia_gym_1.asm26
-rw-r--r--en/text/maps/fuchsia_gym_2.asm193
-rw-r--r--en/text/maps/fuchsia_house.asm27
-rw-r--r--en/text/maps/fuchsia_mart.asm14
-rw-r--r--en/text/maps/fuchsia_meeting_room.asm26
-rw-r--r--en/text/maps/fuchsia_pokecenter.asm20
-rw-r--r--en/text/maps/fujis_house.asm85
-rw-r--r--en/text/maps/hall_of_fame.asm28
-rw-r--r--en/text/maps/indigo_plateau_lobby.asm25
-rw-r--r--en/text/maps/lance.asm63
-rw-r--r--en/text/maps/lavender_house.asm24
-rw-r--r--en/text/maps/lavender_mart.asm30
-rw-r--r--en/text/maps/lavender_pokecenter.asm12
-rw-r--r--en/text/maps/lavender_town.asm64
-rw-r--r--en/text/maps/lorelei.asm42
-rw-r--r--en/text/maps/mansion_1f.asm29
-rw-r--r--en/text/maps/mansion_2f.asm47
-rw-r--r--en/text/maps/mansion_3f.asm37
-rw-r--r--en/text/maps/mansion_b1f.asm39
-rw-r--r--en/text/maps/mr_psychics_house.asm25
-rw-r--r--en/text/maps/mt_moon_1f.asm119
-rw-r--r--en/text/maps/mt_moon_b1f.asm3
-rw-r--r--en/text/maps/mt_moon_b2f.asm122
-rw-r--r--en/text/maps/mt_moon_pokecenter.asm48
-rw-r--r--en/text/maps/museum_1f.asm107
-rw-r--r--en/text/maps/museum_2f.asm45
-rw-r--r--en/text/maps/name_rater.asm60
-rw-r--r--en/text/maps/oaks_lab.asm477
-rw-r--r--en/text/maps/pallet_town.asm55
-rw-r--r--en/text/maps/pewter_city.asm117
-rw-r--r--en/text/maps/pewter_gym_1.asm18
-rw-r--r--en/text/maps/pewter_gym_2.asm142
-rw-r--r--en/text/maps/pewter_house_1.asm24
-rw-r--r--en/text/maps/pewter_house_2.asm19
-rw-r--r--en/text/maps/pewter_mart.asm17
-rw-r--r--en/text/maps/pewter_pokecenter.asm14
-rw-r--r--en/text/maps/pokemon_league_gate.asm19
-rw-r--r--en/text/maps/pokemon_tower_1f.asm31
-rw-r--r--en/text/maps/pokemon_tower_2f.asm57
-rw-r--r--en/text/maps/pokemon_tower_3f.asm45
-rw-r--r--en/text/maps/pokemon_tower_4f.asm45
-rw-r--r--en/text/maps/pokemon_tower_5f.asm71
-rw-r--r--en/text/maps/pokemon_tower_6f.asm61
-rw-r--r--en/text/maps/pokemon_tower_7f.asm78
-rw-r--r--en/text/maps/power_plant.asm6
-rw-r--r--en/text/maps/reds_house_1f.asm37
-rw-r--r--en/text/maps/rock_tunnel_b1f.asm115
-rw-r--r--en/text/maps/rock_tunnel_b2f_1.asm108
-rw-r--r--en/text/maps/rock_tunnel_b2f_2.asm20
-rw-r--r--en/text/maps/rock_tunnel_pokecenter.asm13
-rw-r--r--en/text/maps/rocket_hideout_b1f.asm73
-rw-r--r--en/text/maps/rocket_hideout_b2f.asm17
-rw-r--r--en/text/maps/rocket_hideout_b3f.asm35
-rw-r--r--en/text/maps/rocket_hideout_b4f.asm74
-rw-r--r--en/text/maps/rocket_hideout_elevator.asm3
-rw-r--r--en/text/maps/route_1.asm49
-rw-r--r--en/text/maps/route_10.asm109
-rw-r--r--en/text/maps/route_11_1.asm133
-rw-r--r--en/text/maps/route_11_2.asm28
-rw-r--r--en/text/maps/route_11_gate.asm14
-rw-r--r--en/text/maps/route_11_gate_upstairs.asm40
-rw-r--r--en/text/maps/route_12.asm139
-rw-r--r--en/text/maps/route_12_gate.asm4
-rw-r--r--en/text/maps/route_12_gate_upstairs.asm42
-rw-r--r--en/text/maps/route_12_house.asm60
-rw-r--r--en/text/maps/route_13.asm179
-rw-r--r--en/text/maps/route_14.asm173
-rw-r--r--en/text/maps/route_15.asm171
-rw-r--r--en/text/maps/route_15_gate.asm7
-rw-r--r--en/text/maps/route_15_gate_upstairs.asm24
-rw-r--r--en/text/maps/route_16.asm120
-rw-r--r--en/text/maps/route_16_gate.asm22
-rw-r--r--en/text/maps/route_16_gate_upstairs.asm26
-rw-r--r--en/text/maps/route_16_house.asm31
-rw-r--r--en/text/maps/route_17.asm195
-rw-r--r--en/text/maps/route_18.asm58
-rw-r--r--en/text/maps/route_18_gate.asm14
-rw-r--r--en/text/maps/route_18_gate_upstairs.asm15
-rw-r--r--en/text/maps/route_19.asm157
-rw-r--r--en/text/maps/route_2.asm9
-rw-r--r--en/text/maps/route_20.asm156
-rw-r--r--en/text/maps/route_21.asm137
-rw-r--r--en/text/maps/route_22.asm104
-rw-r--r--en/text/maps/route_23.asm38
-rw-r--r--en/text/maps/route_24_1.asm64
-rw-r--r--en/text/maps/route_24_2.asm90
-rw-r--r--en/text/maps/route_25.asm156
-rw-r--r--en/text/maps/route_2_gate.asm12
-rw-r--r--en/text/maps/route_2_house.asm6
-rw-r--r--en/text/maps/route_3.asm145
-rw-r--r--en/text/maps/route_4.asm35
-rw-r--r--en/text/maps/route_5.asm5
-rw-r--r--en/text/maps/route_6.asm97
-rw-r--r--en/text/maps/route_7.asm5
-rw-r--r--en/text/maps/route_8.asm154
-rw-r--r--en/text/maps/route_9.asm157
-rw-r--r--en/text/maps/safari_zone_center.asm11
-rw-r--r--en/text/maps/safari_zone_east.asm16
-rw-r--r--en/text/maps/safari_zone_entrance.asm93
-rw-r--r--en/text/maps/safari_zone_north.asm33
-rw-r--r--en/text/maps/safari_zone_rest_house_1.asm11
-rw-r--r--en/text/maps/safari_zone_rest_house_2.asm19
-rw-r--r--en/text/maps/safari_zone_rest_house_3.asm18
-rw-r--r--en/text/maps/safari_zone_rest_house_4.asm27
-rw-r--r--en/text/maps/safari_zone_secret_house.asm44
-rw-r--r--en/text/maps/safari_zone_west.asm31
-rw-r--r--en/text/maps/saffron_city.asm151
-rw-r--r--en/text/maps/saffron_gates.asm36
-rw-r--r--en/text/maps/saffron_gym.asm236
-rw-r--r--en/text/maps/saffron_house.asm26
-rw-r--r--en/text/maps/saffron_mart.asm13
-rw-r--r--en/text/maps/saffron_pokecenter.asm12
-rw-r--r--en/text/maps/school.asm13
-rw-r--r--en/text/maps/seafoam_islands_b4f.asm13
-rw-r--r--en/text/maps/silph_co_10f.asm42
-rw-r--r--en/text/maps/silph_co_11f.asm134
-rw-r--r--en/text/maps/silph_co_1f.asm7
-rw-r--r--en/text/maps/silph_co_2f.asm96
-rw-r--r--en/text/maps/silph_co_3f.asm46
-rw-r--r--en/text/maps/silph_co_4f.asm56
-rw-r--r--en/text/maps/silph_co_5f_1.asm51
-rw-r--r--en/text/maps/silph_co_5f_2.asm55
-rw-r--r--en/text/maps/silph_co_6f.asm107
-rw-r--r--en/text/maps/silph_co_7f.asm209
-rw-r--r--en/text/maps/silph_co_8f.asm56
-rw-r--r--en/text/maps/silph_co_9f.asm62
-rw-r--r--en/text/maps/ss_anne_1.asm21
-rw-r--r--en/text/maps/ss_anne_10.asm112
-rw-r--r--en/text/maps/ss_anne_2.asm63
-rw-r--r--en/text/maps/ss_anne_3.asm7
-rw-r--r--en/text/maps/ss_anne_5.asm52
-rw-r--r--en/text/maps/ss_anne_6.asm69
-rw-r--r--en/text/maps/ss_anne_7.asm62
-rw-r--r--en/text/maps/ss_anne_8.asm104
-rw-r--r--en/text/maps/ss_anne_9.asm113
-rw-r--r--en/text/maps/underground_path_route_6_entrance.asm5
-rw-r--r--en/text/maps/underground_path_route_7_entrance.asm5
-rw-r--r--en/text/maps/underground_path_route_7_entrance_unused.asm35
-rw-r--r--en/text/maps/underground_path_route_8_entrance.asm5
-rw-r--r--en/text/maps/unknown_dungeon_b1f.asm2
-rw-r--r--en/text/maps/vermilion_city.asm126
-rw-r--r--en/text/maps/vermilion_dock.asm3
-rw-r--r--en/text/maps/vermilion_fishing_house.asm53
-rw-r--r--en/text/maps/vermilion_gym_1.asm21
-rw-r--r--en/text/maps/vermilion_gym_2.asm143
-rw-r--r--en/text/maps/vermilion_house.asm21
-rw-r--r--en/text/maps/vermilion_mart.asm23
-rw-r--r--en/text/maps/vermilion_pokecenter.asm19
-rw-r--r--en/text/maps/victory_road_1f.asm31
-rw-r--r--en/text/maps/victory_road_2f.asm85
-rw-r--r--en/text/maps/victory_road_3f.asm63
-rw-r--r--en/text/maps/viridian_city.asm180
-rw-r--r--en/text/maps/viridian_forest.asm123
-rw-r--r--en/text/maps/viridian_forest_entrance.asm13
-rw-r--r--en/text/maps/viridian_forest_exit.asm19
-rw-r--r--en/text/maps/viridian_gym.asm236
-rw-r--r--en/text/maps/viridian_house.asm23
-rw-r--r--en/text/maps/viridian_mart.asm30
-rw-r--r--en/text/maps/viridian_pokecenter.asm16
-rw-r--r--en/text/maps/wardens_house.asm83
-rwxr-xr-xen/text/monster_names.asm191
-rw-r--r--en/text/move_names.asm3
-rw-r--r--en/text/oakspeech.asm55
-rw-r--r--en/text/pokedex_text.asm3
-rw-r--r--en/text/text1.asm49
-rw-r--r--en/text/text10.asm23
-rw-r--r--en/text/text11.asm3
-rw-r--r--en/text/text2.asm59
-rw-r--r--en/text/text3.asm25
-rw-r--r--en/text/text4.asm73
-rw-r--r--en/text/text5.asm31
-rw-r--r--en/text/text6.asm29
-rw-r--r--en/text/text7.asm59
-rw-r--r--en/text/text8.asm59
-rw-r--r--en/text/text9.asm45
-rwxr-xr-xen/text/trainer_names.asm48
-rwxr-xr-xen/text/type_names.asm48
302 files changed, 53005 insertions, 224 deletions
diff --git a/en/charmap.asm b/en/charmap.asm
new file mode 100644
index 00000000..4b5278c6
--- /dev/null
+++ b/en/charmap.asm
@@ -0,0 +1,265 @@
+charmap "ガ", $05
+charmap "ギ", $06
+charmap "グ", $07
+charmap "ゲ", $08
+charmap "ゴ", $09
+charmap "ザ", $0A
+charmap "ジ", $0B
+charmap "ズ", $0C
+charmap "ゼ", $0D
+charmap "ゾ", $0E
+charmap "ダ", $0F
+charmap "ヂ", $10
+charmap "ヅ", $11
+charmap "デ", $12
+charmap "ド", $13
+charmap "バ", $19
+charmap "ビ", $1A
+charmap "ブ", $1B
+charmap "ボ", $1C
+charmap "が", $26
+charmap "ぎ", $27
+charmap "ぐ", $28
+charmap "げ", $29
+charmap "ご", $2A
+charmap "ざ", $2B
+charmap "じ", $2C
+charmap "ず", $2D
+charmap "ぜ", $2E
+charmap "ぞ", $2F
+charmap "だ", $30
+charmap "ぢ", $31
+charmap "づ", $32
+charmap "で", $33
+charmap "ど", $34
+charmap "ば", $3A
+charmap "び", $3B
+charmap "ぶ", $3C
+charmap "べ", $3D
+charmap "ぼ", $3E
+charmap "パ", $40
+charmap "ピ", $41
+charmap "プ", $42
+charmap "ポ", $43
+charmap "ぱ", $44
+charmap "ぴ", $45
+charmap "ぷ", $46
+charmap "ぺ", $47
+charmap "ぽ", $48
+charmap "ア", $80
+charmap "イ", $81
+charmap "ウ", $82
+charmap "エ", $83
+charmap "ォ", $84
+charmap "カ", $85
+charmap "キ", $86
+charmap "ク", $87
+charmap "ケ", $88
+charmap "コ", $89
+charmap "サ", $8A
+charmap "シ", $8B
+charmap "ス", $8C
+charmap "セ", $8D
+charmap "ソ", $8E
+charmap "タ", $8F
+charmap "チ", $90
+charmap "ツ", $91
+charmap "テ", $92
+charmap "ト", $93
+charmap "ナ", $94
+charmap "ニ", $95
+charmap "ヌ", $96
+charmap "ネ", $97
+charmap "ノ", $98
+charmap "ハ", $99
+charmap "ヒ", $9A
+charmap "フ", $9B
+charmap "ホ", $9C
+charmap "マ", $9D
+charmap "ミ", $9E
+charmap "ム", $9F
+charmap "メ", $A0
+charmap "モ", $A1
+charmap "ヤ", $A2
+charmap "ユ", $A3
+charmap "ヨ", $A4
+charmap "ラ", $A5
+charmap "ル", $A6
+charmap "レ", $A7
+charmap "ロ", $A8
+charmap "ワ", $A9
+charmap "ヲ", $AA
+charmap "ン", $AB
+charmap "ッ", $AC
+charmap "ャ", $AD
+charmap "ュ", $AE
+charmap "ョ", $AF
+charmap "ィ", $B0
+charmap "あ", $B1
+charmap "い", $B2
+charmap "う", $B3
+charmap "え", $B4
+charmap "お", $B5
+charmap "か", $B6
+charmap "き", $B7
+charmap "く", $B8
+charmap "け", $B9
+charmap "こ", $BA
+charmap "さ", $BB
+charmap "し", $BC
+charmap "す", $BD
+charmap "せ", $BE
+charmap "そ", $BF
+charmap "た", $C0
+charmap "ち", $C1
+charmap "つ", $C2
+charmap "て", $C3
+charmap "と", $C4
+charmap "な", $C5
+charmap "に", $C6
+charmap "ぬ", $C7
+charmap "ね", $C8
+charmap "の", $C9
+charmap "は", $CA
+charmap "ひ", $CB
+charmap "ふ", $CC
+charmap "へ", $CD
+charmap "ほ", $CE
+charmap "ま", $CF
+charmap "み", $D0
+charmap "む", $D1
+charmap "め", $D2
+charmap "も", $D3
+charmap "や", $D4
+charmap "ゆ", $D5
+charmap "よ", $D6
+charmap "ら", $D7
+charmap "り", $D8
+charmap "る", $D9
+charmap "れ", $DA
+charmap "ろ", $DB
+charmap "わ", $DC
+charmap "を", $DD
+charmap "ん", $DE
+charmap "っ", $DF
+charmap "ゃ", $E0
+charmap "ゅ", $E1
+charmap "ょ", $E2
+charmap "ー", $E3
+
+charmap "<pkmn>", $4A ; PkMn
+charmap "@", $50
+charmap "<PLAYER>", $52
+charmap "<RIVAL>", $53
+charmap "#", $54
+;charmap "POKé", $54
+charmap "<TARGET>", $59
+charmap "<USER>", $5A
+charmap "′", $71
+charmap "″", $73
+charmap "№", $74
+charmap "…", $75
+
+charmap "┌", $79
+charmap "─", $7A
+charmap "┐", $7B
+charmap "│", $7C
+charmap "└", $7D
+charmap "┘", $7E
+
+charmap " ", $7F
+charmap "A", $80
+charmap "B", $81
+charmap "C", $82
+charmap "D", $83
+charmap "E", $84
+charmap "F", $85
+charmap "G", $86
+charmap "H", $87
+charmap "I", $88
+charmap "J", $89
+charmap "K", $8A
+charmap "L", $8B
+charmap "M", $8C
+charmap "N", $8D
+charmap "O", $8E
+charmap "P", $8F
+charmap "Q", $90
+charmap "R", $91
+charmap "S", $92
+charmap "T", $93
+charmap "U", $94
+charmap "V", $95
+charmap "W", $96
+charmap "X", $97
+charmap "Y", $98
+charmap "Z", $99
+charmap "(", $9A
+charmap ")", $9B
+charmap ":", $9C
+charmap ";", $9D
+charmap "[", $9E
+charmap "]", $9F
+charmap "a", $A0
+charmap "b", $A1
+charmap "c", $A2
+charmap "d", $A3
+charmap "e", $A4
+charmap "f", $A5
+charmap "g", $A6
+charmap "h", $A7
+charmap "i", $A8
+charmap "j", $A9
+charmap "k", $AA
+charmap "l", $AB
+charmap "m", $AC
+charmap "n", $AD
+charmap "o", $AE
+charmap "p", $AF
+charmap "q", $B0
+charmap "r", $B1
+charmap "s", $B2
+charmap "t", $B3
+charmap "u", $B4
+charmap "v", $B5
+charmap "w", $B6
+charmap "x", $B7
+charmap "y", $B8
+charmap "z", $B9
+charmap "é", $BA
+charmap "'d", $BB
+charmap "'l", $BC
+charmap "'s", $BD
+charmap "'t", $BE
+charmap "'v", $BF
+
+charmap "'", $E0
+
+charmap "-", $E3
+charmap "'r", $E4
+charmap "'m", $E5
+charmap "?", $E6
+charmap "!", $E7
+charmap ".", $E8
+
+charmap "▷", $EC
+charmap "▶", $ED
+charmap "▲", $ED
+charmap "▼", $EE
+charmap "♂", $EF
+charmap "¥", $F0
+charmap "×", $F1
+charmap "⠄", $F2
+charmap "/", $F3
+charmap ",", $F4
+charmap "♀", $F5
+charmap "0", $F6
+charmap "1", $F7
+charmap "2", $F8
+charmap "3", $F9
+charmap "4", $FA
+charmap "5", $FB
+charmap "6", $FC
+charmap "7", $FD
+charmap "8", $FE
+charmap "9", $FF
diff --git a/en/constants/credits_constants.asm b/en/constants/credits_constants.asm
new file mode 100644
index 00000000..f5715072
--- /dev/null
+++ b/en/constants/credits_constants.asm
@@ -0,0 +1,67 @@
+const_value = 0
+
+ const CRED_VERSION ; $00
+ const CRED_TAJIRI ; $01
+ const CRED_TA_OOTA ; $02
+ const CRED_MORIMOTO ; $03
+ const CRED_WATANABE ; $04
+ const CRED_MASUDE ; $05
+ const CRED_NISINO ; $06
+ const CRED_SUGIMORI ; $07
+ const CRED_NISHIDA ; $08
+ const CRED_MIYAMOTO ; $09
+ const CRED_KAWAGUCHI ; $0A
+ const CRED_ISHIHARA ; $0B
+ const CRED_YAMAUCHI ; $0C
+ const CRED_ZINNAI ; $0D
+ const CRED_HISHIDA ; $0E
+ const CRED_SAKAI ; $0F
+ const CRED_YAMAGUCHI ; $10
+ const CRED_YAMAMOTO ; $11
+ const CRED_TANIGUCHI ; $12
+ const CRED_NONOMURA ; $13
+ const CRED_FUZIWARA ; $14
+ const CRED_MATSUSIMA ; $15
+ const CRED_TOMISAWA ; $16
+ const CRED_KAWAMOTO ; $17
+ const CRED_KAKEI ; $18
+ const CRED_TSUCHIYA ; $19
+ const CRED_TA_NAKAMURA ; $1A
+ const CRED_YUDA ; $1B
+ const CRED_MON ; $1C
+ const CRED_DIRECTOR ; $1D
+ const CRED_PROGRAMMERS ; $1E
+ const CRED_CHAR_DESIGN ; $1F
+ const CRED_MUSIC ; $20
+ const CRED_SOUND_EFFECTS ; $21
+ const CRED_GAME_DESIGN ; $22
+ const CRED_MONSTER_DESIGN ; $23
+ const CRED_GAME_SCENE ; $24
+ const CRED_PARAM ; $25
+ const CRED_MAP ; $26
+ const CRED_TEST ; $27
+ const CRED_SPECIAL ; $28
+ const CRED_PRODUCERS ; $29
+ const CRED_PRODUCER ; $2A
+ const CRED_EXECUTIVE ; $2B
+ const CRED_TAMADA ; $2C
+ const CRED_SA_OOTA ; $2D
+ const CRED_YOSHIKAWA ; $2E
+ const CRED_TO_OOTA ; $2F
+ const CRED_US_STAFF ; $30
+ const CRED_US_COORD ; $31
+ const CRED_TILDEN ; $32
+ const CRED_KAWAKAMI ; $33
+ const CRED_HI_NAKAMURA ; $34
+ const CRED_GIESE ; $35
+ const CRED_OSBORNE ; $36
+ const CRED_TRANS ; $37
+ const CRED_OGASAWARA ; $38
+ const CRED_IWATA ; $39
+ const CRED_IZUSHI ; $3A
+ const CRED_HARADA ; $3B
+ const CRED_MURAKAWA ; $3C
+ const CRED_FUKUI ; $3D
+ const CRED_CLUB ; $3E
+ const CRED_PAAD ; $3F
+
diff --git a/en/data/credits_order.asm b/en/data/credits_order.asm
new file mode 100755
index 00000000..20b9137f
--- /dev/null
+++ b/en/data/credits_order.asm
@@ -0,0 +1,39 @@
+CreditsOrder:
+; subsequent credits elements will be displayed on separate lines.
+; $FF, $FE, $FD, $FC, $FB, and $FA are commands that are used
+; to go to the next set of credits texts.
+ db CRED_MON, CRED_VERSION, $FF
+ db CRED_DIRECTOR, CRED_TAJIRI, $FF
+ db CRED_PROGRAMMERS, CRED_TA_OOTA, CRED_MORIMOTO, $FD
+ db CRED_PROGRAMMERS, CRED_WATANABE, CRED_MASUDE, CRED_TAMADA, $FE
+ db CRED_CHAR_DESIGN, CRED_SUGIMORI, CRED_NISHIDA, $FF
+ db CRED_MUSIC, CRED_MASUDE, $FD
+ db CRED_SOUND_EFFECTS, CRED_MASUDE, $FE
+ db CRED_GAME_DESIGN, CRED_TAJIRI, $FF
+ db CRED_MONSTER_DESIGN, CRED_SUGIMORI, CRED_NISHIDA, CRED_FUZIWARA, $FD
+ db CRED_MONSTER_DESIGN, CRED_MORIMOTO, CRED_SA_OOTA, CRED_YOSHIKAWA, $FE
+ db CRED_GAME_SCENE, CRED_TAJIRI, $FD
+ db CRED_GAME_SCENE, CRED_TANIGUCHI, CRED_NONOMURA, CRED_ZINNAI, $FE
+ db CRED_PARAM, CRED_NISINO, CRED_TA_NAKAMURA, $FF
+ db CRED_MAP, CRED_TAJIRI, CRED_NISINO, $FD
+ db CRED_MAP, CRED_MATSUSIMA, CRED_NONOMURA, CRED_TANIGUCHI, $FE
+ db CRED_TEST, CRED_KAKEI, CRED_TSUCHIYA, $FD
+ db CRED_TEST, CRED_TA_NAKAMURA, CRED_YUDA, $FE
+ db CRED_SPECIAL, CRED_HISHIDA, CRED_SAKAI, $FD
+ db CRED_SPECIAL, CRED_YAMAGUCHI, CRED_YAMAMOTO, $FC
+ db CRED_SPECIAL, CRED_TOMISAWA, CRED_KAWAMOTO, CRED_TO_OOTA, $FE
+ db CRED_PRODUCERS, CRED_MIYAMOTO, $FD
+ db CRED_PRODUCERS, CRED_KAWAGUCHI, $FC
+ db CRED_PRODUCERS, CRED_ISHIHARA, $FE
+ db CRED_US_STAFF, $FD
+ db CRED_US_COORD, CRED_TILDEN, $FD
+ db CRED_US_COORD, CRED_KAWAKAMI, CRED_HI_NAKAMURA, $FC
+ db CRED_US_COORD, CRED_GIESE, CRED_OSBORNE, $FC
+ db CRED_TRANS, CRED_OGASAWARA, $FD
+ db CRED_PROGRAMMERS, CRED_MURAKAWA, CRED_FUKUI, $FD
+ db CRED_SPECIAL, CRED_IWATA, $FD
+ db CRED_SPECIAL, CRED_HARADA, $FC
+ db CRED_TEST, CRED_PAAD, CRED_CLUB, $FD
+ db CRED_PRODUCER, CRED_IZUSHI, $FD
+ db CRED_EXECUTIVE, CRED_YAMAUCHI, $FF
+ db $FB, $FF, $FA
diff --git a/en/data/pokedex_entries.asm b/en/data/pokedex_entries.asm
new file mode 100755
index 00000000..3fb2d3c6
--- /dev/null
+++ b/en/data/pokedex_entries.asm
@@ -0,0 +1,1259 @@
+PokedexEntryPointers:
+ dw RhydonDexEntry
+ dw KangaskhanDexEntry
+ dw NidoranMDexEntry
+ dw ClefairyDexEntry
+ dw SpearowDexEntry
+ dw VoltorbDexEntry
+ dw NidokingDexEntry
+ dw SlowbroDexEntry
+ dw IvysaurDexEntry
+ dw ExeggutorDexEntry
+ dw LickitungDexEntry
+ dw ExeggcuteDexEntry
+ dw GrimerDexEntry
+ dw GengarDexEntry
+ dw NidoranFDexEntry
+ dw NidoqueenDexEntry
+ dw CuboneDexEntry
+ dw RhyhornDexEntry
+ dw LaprasDexEntry
+ dw ArcanineDexEntry
+ dw MewDexEntry
+ dw GyaradosDexEntry
+ dw ShellderDexEntry
+ dw TentacoolDexEntry
+ dw GastlyDexEntry
+ dw ScytherDexEntry
+ dw StaryuDexEntry
+ dw BlastoiseDexEntry
+ dw PinsirDexEntry
+ dw TangelaDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw GrowlitheDexEntry
+ dw OnixDexEntry
+ dw FearowDexEntry
+ dw PidgeyDexEntry
+ dw SlowpokeDexEntry
+ dw KadabraDexEntry
+ dw GravelerDexEntry
+ dw ChanseyDexEntry
+ dw MachokeDexEntry
+ dw MrMimeDexEntry
+ dw HitmonleeDexEntry
+ dw HitmonchanDexEntry
+ dw ArbokDexEntry
+ dw ParasectDexEntry
+ dw PsyduckDexEntry
+ dw DrowzeeDexEntry
+ dw GolemDexEntry
+ dw MissingNoDexEntry
+ dw MagmarDexEntry
+ dw MissingNoDexEntry
+ dw ElectabuzzDexEntry
+ dw MagnetonDexEntry
+ dw KoffingDexEntry
+ dw MissingNoDexEntry
+ dw MankeyDexEntry
+ dw SeelDexEntry
+ dw DiglettDexEntry
+ dw TaurosDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw FarfetchdDexEntry
+ dw VenonatDexEntry
+ dw DragoniteDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw DoduoDexEntry
+ dw PoliwagDexEntry
+ dw JynxDexEntry
+ dw MoltresDexEntry
+ dw ArticunoDexEntry
+ dw ZapdosDexEntry
+ dw DittoDexEntry
+ dw MeowthDexEntry
+ dw KrabbyDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw VulpixDexEntry
+ dw NinetalesDexEntry
+ dw PikachuDexEntry
+ dw RaichuDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw DratiniDexEntry
+ dw DragonairDexEntry
+ dw KabutoDexEntry
+ dw KabutopsDexEntry
+ dw HorseaDexEntry
+ dw SeadraDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw SandshrewDexEntry
+ dw SandslashDexEntry
+ dw OmanyteDexEntry
+ dw OmastarDexEntry
+ dw JigglypuffDexEntry
+ dw WigglytuffDexEntry
+ dw EeveeDexEntry
+ dw FlareonDexEntry
+ dw JolteonDexEntry
+ dw VaporeonDexEntry
+ dw MachopDexEntry
+ dw ZubatDexEntry
+ dw EkansDexEntry
+ dw ParasDexEntry
+ dw PoliwhirlDexEntry
+ dw PoliwrathDexEntry
+ dw WeedleDexEntry
+ dw KakunaDexEntry
+ dw BeedrillDexEntry
+ dw MissingNoDexEntry
+ dw DodrioDexEntry
+ dw PrimeapeDexEntry
+ dw DugtrioDexEntry
+ dw VenomothDexEntry
+ dw DewgongDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw CaterpieDexEntry
+ dw MetapodDexEntry
+ dw ButterfreeDexEntry
+ dw MachampDexEntry
+ dw MissingNoDexEntry
+ dw GolduckDexEntry
+ dw HypnoDexEntry
+ dw GolbatDexEntry
+ dw MewtwoDexEntry
+ dw SnorlaxDexEntry
+ dw MagikarpDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MukDexEntry
+ dw MissingNoDexEntry
+ dw KinglerDexEntry
+ dw CloysterDexEntry
+ dw MissingNoDexEntry
+ dw ElectrodeDexEntry
+ dw ClefableDexEntry
+ dw WeezingDexEntry
+ dw PersianDexEntry
+ dw MarowakDexEntry
+ dw MissingNoDexEntry
+ dw HaunterDexEntry
+ dw AbraDexEntry
+ dw AlakazamDexEntry
+ dw PidgeottoDexEntry
+ dw PidgeotDexEntry
+ dw StarmieDexEntry
+ dw BulbasaurDexEntry
+ dw VenusaurDexEntry
+ dw TentacruelDexEntry
+ dw MissingNoDexEntry
+ dw GoldeenDexEntry
+ dw SeakingDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw PonytaDexEntry
+ dw RapidashDexEntry
+ dw RattataDexEntry
+ dw RaticateDexEntry
+ dw NidorinoDexEntry
+ dw NidorinaDexEntry
+ dw GeodudeDexEntry
+ dw PorygonDexEntry
+ dw AerodactylDexEntry
+ dw MissingNoDexEntry
+ dw MagnemiteDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw CharmanderDexEntry
+ dw SquirtleDexEntry
+ dw CharmeleonDexEntry
+ dw WartortleDexEntry
+ dw CharizardDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw MissingNoDexEntry
+ dw OddishDexEntry
+ dw GloomDexEntry
+ dw VileplumeDexEntry
+ dw BellsproutDexEntry
+ dw WeepinbellDexEntry
+ dw VictreebelDexEntry
+
+; string: species name
+; height in feet, inches
+; weight in pounds
+; text entry
+
+RhydonDexEntry:
+ db "DRILL@"
+ db 6,3
+ dw 2650
+ TX_FAR _RhydonDexEntry
+ db "@"
+
+KangaskhanDexEntry:
+ db "PARENT@"
+ db 7,3
+ dw 1760
+ TX_FAR _KangaskhanDexEntry
+ db "@"
+
+NidoranMDexEntry:
+ db "POISON PIN@"
+ db 1,8
+ dw 200
+ TX_FAR _NidoranMDexEntry
+ db "@"
+
+ClefairyDexEntry:
+ db "FAIRY@"
+ db 2,0
+ dw 170
+ TX_FAR _ClefairyDexEntry
+ db "@"
+
+SpearowDexEntry:
+ db "TINY BIRD@"
+ db 1,0
+ dw 40
+ TX_FAR _SpearowDexEntry
+ db "@"
+
+VoltorbDexEntry:
+ db "BALL@"
+ db 1,8
+ dw 230
+ TX_FAR _VoltorbDexEntry
+ db "@"
+
+NidokingDexEntry:
+ db "DRILL@"
+ db 4,7
+ dw 1370
+ TX_FAR _NidokingDexEntry
+ db "@"
+
+SlowbroDexEntry:
+ db "HERMITCRAB@"
+ db 5,3
+ dw 1730
+ TX_FAR _SlowbroDexEntry
+ db "@"
+
+IvysaurDexEntry:
+ db "SEED@"
+ db 3,3
+ dw 290
+ TX_FAR _IvysaurDexEntry
+ db "@"
+
+ExeggutorDexEntry:
+ db "COCONUT@"
+ db 6,7
+ dw 2650
+ TX_FAR _ExeggutorDexEntry
+ db "@"
+
+LickitungDexEntry:
+ db "LICKING@"
+ db 3,11
+ dw 1440
+ TX_FAR _LickitungDexEntry
+ db "@"
+
+ExeggcuteDexEntry:
+ db "EGG@"
+ db 1,4
+ dw 60
+ TX_FAR _ExeggcuteDexEntry
+ db "@"
+
+GrimerDexEntry:
+ db "SLUDGE@"
+ db 2,11
+ dw 660
+ TX_FAR _GrimerDexEntry
+ db "@"
+
+GengarDexEntry:
+ db "SHADOW@"
+ db 4,11
+ dw 890
+ TX_FAR _GengarDexEntry
+ db "@"
+
+NidoranFDexEntry:
+ db "POISON PIN@"
+ db 1,4
+ dw 150
+ TX_FAR _NidoranFDexEntry
+ db "@"
+
+NidoqueenDexEntry:
+ db "DRILL@"
+ db 4,3
+ dw 1320
+ TX_FAR _NidoqueenDexEntry
+ db "@"
+
+CuboneDexEntry:
+ db "LONELY@"
+ db 1,4
+ dw 140
+ TX_FAR _CuboneDexEntry
+ db "@"
+
+RhyhornDexEntry:
+ db "SPIKES@"
+ db 3,3
+ dw 2540
+ TX_FAR _RhyhornDexEntry
+ db "@"
+
+LaprasDexEntry:
+ db "TRANSPORT@"
+ db 8,2
+ dw 4850
+ TX_FAR _LaprasDexEntry
+ db "@"
+
+ArcanineDexEntry:
+ db "LEGENDARY@"
+ db 6,3
+ dw 3420
+ TX_FAR _ArcanineDexEntry
+ db "@"
+
+MewDexEntry:
+ db "NEW SPECIE@"
+ db 1,4
+ dw 90
+ TX_FAR _MewDexEntry
+ db "@"
+
+GyaradosDexEntry:
+ db "ATROCIOUS@"
+ db 21,4
+ dw 5180
+ TX_FAR _GyaradosDexEntry
+ db "@"
+
+ShellderDexEntry:
+ db "BIVALVE@"
+ db 1,0
+ dw 90
+ TX_FAR _ShellderDexEntry
+ db "@"
+
+TentacoolDexEntry:
+ db "JELLYFISH@"
+ db 2,11
+ dw 1000
+ TX_FAR _TentacoolDexEntry
+ db "@"
+
+GastlyDexEntry:
+ db "GAS@"
+ db 4,3
+ dw 2
+ TX_FAR _GastlyDexEntry
+ db "@"
+
+ScytherDexEntry:
+ db "MANTIS@"
+ db 4,11
+ dw 1230
+ TX_FAR _ScytherDexEntry
+ db "@"
+
+StaryuDexEntry:
+ db "STARSHAPE@"
+ db 2,7
+ dw 760
+ TX_FAR _StaryuDexEntry
+ db "@"
+
+BlastoiseDexEntry:
+ db "SHELLFISH@"
+ db 5,3
+ dw 1890
+ TX_FAR _BlastoiseDexEntry
+ db "@"
+
+PinsirDexEntry:
+ db "STAGBEETLE@"
+ db 4,11
+ dw 1210
+ TX_FAR _PinsirDexEntry
+ db "@"
+
+TangelaDexEntry:
+ db "VINE@"
+ db 3,3
+ dw 770
+ TX_FAR _TangelaDexEntry
+ db "@"
+
+GrowlitheDexEntry:
+ db "PUPPY@"
+ db 2,4
+ dw 420
+ TX_FAR _GrowlitheDexEntry
+ db "@"
+
+OnixDexEntry:
+ db "ROCK SNAKE@"
+ db 28,10
+ dw 4630
+ TX_FAR _OnixDexEntry
+ db "@"
+
+FearowDexEntry:
+ db "BEAK@"
+ db 3,11
+ dw 840
+ TX_FAR _FearowDexEntry
+ db "@"
+
+PidgeyDexEntry:
+ db "TINY BIRD@"
+ db 1,0
+ dw 40
+ TX_FAR _PidgeyDexEntry
+ db "@"
+
+SlowpokeDexEntry:
+ db "DOPEY@"
+ db 3,11
+ dw 790
+ TX_FAR _SlowpokeDexEntry
+ db "@"
+
+KadabraDexEntry:
+ db "PSI@"
+ db 4,3
+ dw 1250
+ TX_FAR _KadabraDexEntry
+ db "@"
+
+GravelerDexEntry:
+ db "ROCK@"
+ db 3,3
+ dw 2320
+ TX_FAR _GravelerDexEntry
+ db "@"
+
+ChanseyDexEntry:
+ db "EGG@"
+ db 3,7
+ dw 760
+ TX_FAR _ChanseyDexEntry
+ db "@"
+
+MachokeDexEntry:
+ db "SUPERPOWER@"
+ db 4,11
+ dw 1550
+ TX_FAR _MachokeDexEntry
+ db "@"
+
+MrMimeDexEntry:
+ db "BARRIER@"
+ db 4,3
+ dw 1200
+ TX_FAR _MrMimeDexEntry
+ db "@"
+
+HitmonleeDexEntry:
+ db "KICKING@"
+ db 4,11
+ dw 1100
+ TX_FAR _HitmonleeDexEntry
+ db "@"
+
+HitmonchanDexEntry:
+ db "PUNCHING@"
+ db 4,7
+ dw 1110
+ TX_FAR _HitmonchanDexEntry
+ db "@"
+
+ArbokDexEntry:
+ db "COBRA@"
+ db 11,6
+ dw 1430
+ TX_FAR _ArbokDexEntry
+ db "@"
+
+ParasectDexEntry:
+ db "MUSHROOM@"
+ db 3,3
+ dw 650
+ TX_FAR _ParasectDexEntry
+ db "@"
+
+PsyduckDexEntry:
+ db "DUCK@"
+ db 2,7
+ dw 430
+ TX_FAR _PsyduckDexEntry
+ db "@"
+
+DrowzeeDexEntry:
+ db "HYPNOSIS@"
+ db 3,3
+ dw 710
+ TX_FAR _DrowzeeDexEntry
+ db "@"
+
+GolemDexEntry:
+ db "MEGATON@"
+ db 4,7
+ dw 6620
+ TX_FAR _GolemDexEntry
+ db "@"
+
+MagmarDexEntry:
+ db "SPITFIRE@"
+ db 4,3
+ dw 980
+ TX_FAR _MagmarDexEntry
+ db "@"
+
+ElectabuzzDexEntry:
+ db "ELECTRIC@"
+ db 3,7
+ dw 660
+ TX_FAR _ElectabuzzDexEntry
+ db "@"
+
+MagnetonDexEntry:
+ db "MAGNET@"
+ db 3,3
+ dw 1320
+ TX_FAR _MagnetonDexEntry
+ db "@"
+
+KoffingDexEntry:
+ db "POISON GAS@"
+ db 2,0
+ dw 20
+ TX_FAR _KoffingDexEntry
+ db "@"
+
+MankeyDexEntry:
+ db "PIG MONKEY@"
+ db 1,8
+ dw 620
+ TX_FAR _MankeyDexEntry
+ db "@"
+
+SeelDexEntry:
+ db "SEA LION@"
+ db 3,7
+ dw 1980
+ TX_FAR _SeelDexEntry
+ db "@"
+
+DiglettDexEntry:
+ db "MOLE@"
+ db 0,8
+ dw 20
+ TX_FAR _DiglettDexEntry
+ db "@"
+
+TaurosDexEntry:
+ db "WILD BULL@"
+ db 4,7
+ dw 1950
+ TX_FAR _TaurosDexEntry
+ db "@"
+
+FarfetchdDexEntry:
+ db "WILD DUCK@"
+ db 2,7
+ dw 330
+ TX_FAR _FarfetchdDexEntry
+ db "@"
+
+VenonatDexEntry:
+ db "INSECT@"
+ db 3,3
+ dw 660
+ TX_FAR _VenonatDexEntry
+ db "@"
+
+DragoniteDexEntry:
+ db "DRAGON@"
+ db 7,3
+ dw 4630
+ TX_FAR _DragoniteDexEntry
+ db "@"
+
+DoduoDexEntry:
+ db "TWIN BIRD@"
+ db 4,7
+ dw 860
+ TX_FAR _DoduoDexEntry
+ db "@"
+
+PoliwagDexEntry:
+ db "TADPOLE@"
+ db 2,0
+ dw 270
+ TX_FAR _PoliwagDexEntry
+ db "@"
+
+JynxDexEntry:
+ db "HUMANSHAPE@"
+ db 4,7
+ dw 900
+ TX_FAR _JynxDexEntry
+ db "@"
+
+MoltresDexEntry:
+ db "FLAME@"
+ db 6,7
+ dw 1320
+ TX_FAR _MoltresDexEntry
+ db "@"
+
+ArticunoDexEntry:
+ db "FREEZE@"
+ db 5,7
+ dw 1220
+ TX_FAR _ArticunoDexEntry
+ db "@"
+
+ZapdosDexEntry:
+ db "ELECTRIC@"
+ db 5,3
+ dw 1160
+ TX_FAR _ZapdosDexEntry
+ db "@"
+
+DittoDexEntry:
+ db "TRANSFORM@"
+ db 1,0
+ dw 90
+ TX_FAR _DittoDexEntry
+ db "@"
+
+MeowthDexEntry:
+ db "SCRATCHCAT@"
+ db 1,4
+ dw 90
+ TX_FAR _MeowthDexEntry
+ db "@"
+
+KrabbyDexEntry:
+ db "RIVER CRAB@"
+ db 1,4
+ dw 140
+ TX_FAR _KrabbyDexEntry
+ db "@"
+
+VulpixDexEntry:
+ db "FOX@"
+ db 2,0
+ dw 220
+ TX_FAR _VulpixDexEntry
+ db "@"
+
+NinetalesDexEntry:
+ db "FOX@"
+ db 3,7
+ dw 440
+ TX_FAR _NinetalesDexEntry
+ db "@"
+
+PikachuDexEntry:
+ db "MOUSE@"
+ db 1,4
+ dw 130
+ TX_FAR _PikachuDexEntry
+ db "@"
+
+RaichuDexEntry:
+ db "MOUSE@"
+ db 2,7
+ dw 660
+ TX_FAR _RaichuDexEntry
+ db "@"
+
+DratiniDexEntry:
+ db "DRAGON@"
+ db 5,11
+ dw 70
+ TX_FAR _DratiniDexEntry
+ db "@"
+
+DragonairDexEntry:
+ db "DRAGON@"
+ db 13,1
+ dw 360
+ TX_FAR _DragonairDexEntry
+ db "@"
+
+KabutoDexEntry:
+ db "SHELLFISH@"
+ db 1,8
+ dw 250
+ TX_FAR _KabutoDexEntry
+ db "@"
+
+KabutopsDexEntry:
+ db "SHELLFISH@"
+ db 4,3
+ dw 890
+ TX_FAR _KabutopsDexEntry
+ db "@"
+
+HorseaDexEntry:
+ db "DRAGON@"
+ db 1,4
+ dw 180
+ TX_FAR _HorseaDexEntry
+ db "@"
+
+SeadraDexEntry:
+ db "DRAGON@"
+ db 3,11
+ dw 550
+ TX_FAR _SeadraDexEntry
+ db "@"
+
+SandshrewDexEntry:
+ db "MOUSE@"
+ db 2,0
+ dw 260
+ TX_FAR _SandshrewDexEntry
+ db "@"
+
+SandslashDexEntry:
+ db "MOUSE@"
+ db 3,3
+ dw 650
+ TX_FAR _SandslashDexEntry
+ db "@"
+
+OmanyteDexEntry:
+ db "SPIRAL@"
+ db 1,4
+ dw 170
+ TX_FAR _OmanyteDexEntry
+ db "@"
+
+OmastarDexEntry:
+ db "SPIRAL@"
+ db 3,3
+ dw 770
+ TX_FAR _OmastarDexEntry
+ db "@"
+
+JigglypuffDexEntry:
+ db "BALLOON@"
+ db 1,8
+ dw 120
+ TX_FAR _JigglypuffDexEntry
+ db "@"
+
+WigglytuffDexEntry:
+ db "BALLOON@"
+ db 3,3
+ dw 260
+ TX_FAR _WigglytuffDexEntry
+ db "@"
+
+EeveeDexEntry:
+ db "EVOLUTION@"
+ db 1,0
+ dw 140
+ TX_FAR _EeveeDexEntry
+ db "@"
+
+FlareonDexEntry:
+ db "FLAME@"
+ db 2,11
+ dw 550
+ TX_FAR _FlareonDexEntry
+ db "@"
+
+JolteonDexEntry:
+ db "LIGHTNING@"
+ db 2,7
+ dw 540
+ TX_FAR _JolteonDexEntry
+ db "@"
+
+VaporeonDexEntry:
+ db "BUBBLE JET@"
+ db 3,3
+ dw 640
+ TX_FAR _VaporeonDexEntry
+ db "@"
+
+MachopDexEntry:
+ db "SUPERPOWER@"
+ db 2,7
+ dw 430
+ TX_FAR _MachopDexEntry
+ db "@"
+
+ZubatDexEntry:
+ db "BAT@"
+ db 2,7
+ dw 170
+ TX_FAR _ZubatDexEntry
+ db "@"
+
+EkansDexEntry:
+ db "SNAKE@"
+ db 6,7
+ dw 150
+ TX_FAR _EkansDexEntry
+ db "@"
+
+ParasDexEntry:
+ db "MUSHROOM@"
+ db 1,0
+ dw 120
+ TX_FAR _ParasDexEntry
+ db "@"
+
+PoliwhirlDexEntry:
+ db "TADPOLE@"
+ db 3,3
+ dw 440
+ TX_FAR _PoliwhirlDexEntry
+ db "@"
+
+PoliwrathDexEntry:
+ db "TADPOLE@"
+ db 4,3
+ dw 1190
+ TX_FAR _PoliwrathDexEntry
+ db "@"
+
+WeedleDexEntry:
+ db "HAIRY BUG@"
+ db 1,0
+ dw 70
+ TX_FAR _WeedleDexEntry
+ db "@"
+
+KakunaDexEntry:
+ db "COCOON@"
+ db 2,0
+ dw 220
+ TX_FAR _KakunaDexEntry
+ db "@"
+
+BeedrillDexEntry:
+ db "POISON BEE@"
+ db 3,3
+ dw 650
+ TX_FAR _BeedrillDexEntry
+ db "@"
+
+DodrioDexEntry:
+ db "TRIPLEBIRD@"
+ db 5,11
+ dw 1880
+ TX_FAR _DodrioDexEntry
+ db "@"
+
+PrimeapeDexEntry:
+ db "PIG MONKEY@"
+ db 3,3
+ dw 710
+ TX_FAR _PrimeapeDexEntry
+ db "@"
+
+DugtrioDexEntry:
+ db "MOLE@"
+ db 2,4
+ dw 730
+ TX_FAR _DugtrioDexEntry
+ db "@"
+
+VenomothDexEntry:
+ db "POISONMOTH@"
+ db 4,11
+ dw 280
+ TX_FAR _VenomothDexEntry
+ db "@"
+
+DewgongDexEntry:
+ db "SEA LION@"
+ db 5,7
+ dw 2650
+ TX_FAR _DewgongDexEntry
+ db "@"
+
+CaterpieDexEntry:
+ db "WORM@"
+ db 1,0
+ dw 60
+ TX_FAR _CaterpieDexEntry
+ db "@"
+
+MetapodDexEntry:
+ db "COCOON@"
+ db 2,4
+ dw 220
+ TX_FAR _MetapodDexEntry
+ db "@"
+
+ButterfreeDexEntry:
+ db "BUTTERFLY@"
+ db 3,7
+ dw 710
+ TX_FAR _ButterfreeDexEntry
+ db "@"
+
+MachampDexEntry:
+ db "SUPERPOWER@"
+ db 5,3
+ dw 2870
+ TX_FAR _MachampDexEntry
+ db "@"
+
+GolduckDexEntry:
+ db "DUCK@"
+ db 5,7
+ dw 1690
+ TX_FAR _GolduckDexEntry
+ db "@"
+
+HypnoDexEntry:
+ db "HYPNOSIS@"
+ db 5,3
+ dw 1670
+ TX_FAR _HypnoDexEntry
+ db "@"
+
+GolbatDexEntry:
+ db "BAT@"
+ db 5,3
+ dw 1210
+ TX_FAR _GolbatDexEntry
+ db "@"
+
+MewtwoDexEntry:
+ db "GENETIC@"
+ db 6,7
+ dw 2690
+ TX_FAR _MewtwoDexEntry
+ db "@"
+
+SnorlaxDexEntry:
+ db "SLEEPING@"
+ db 6,11
+ dw 10140
+ TX_FAR _SnorlaxDexEntry
+ db "@"
+
+MagikarpDexEntry:
+ db "FISH@"
+ db 2,11
+ dw 220
+ TX_FAR _MagikarpDexEntry
+ db "@"
+
+MukDexEntry:
+ db "SLUDGE@"
+ db 3,11
+ dw 660
+ TX_FAR _MukDexEntry
+ db "@"
+
+KinglerDexEntry:
+ db "PINCER@"
+ db 4,3
+ dw 1320
+ TX_FAR _KinglerDexEntry
+ db "@"
+
+CloysterDexEntry:
+ db "BIVALVE@"
+ db 4,11
+ dw 2920
+ TX_FAR _CloysterDexEntry
+ db "@"
+
+ElectrodeDexEntry:
+ db "BALL@"
+ db 3,11
+ dw 1470
+ TX_FAR _ElectrodeDexEntry
+ db "@"
+
+ClefableDexEntry:
+ db "FAIRY@"
+ db 4,3
+ dw 880
+ TX_FAR _ClefableDexEntry
+ db "@"
+
+WeezingDexEntry:
+ db "POISON GAS@"
+ db 3,11
+ dw 210
+ TX_FAR _WeezingDexEntry
+ db "@"
+
+PersianDexEntry:
+ db "CLASSY CAT@"
+ db 3,3
+ dw 710
+ TX_FAR _PersianDexEntry
+ db "@"
+
+MarowakDexEntry:
+ db "BONEKEEPER@"
+ db 3,3
+ dw 990
+ TX_FAR _MarowakDexEntry
+ db "@"
+
+HaunterDexEntry:
+ db "GAS@"
+ db 5,3
+ dw 2
+ TX_FAR _HaunterDexEntry
+ db "@"
+
+AbraDexEntry:
+ db "PSI@"
+ db 2,11
+ dw 430
+ TX_FAR _AbraDexEntry
+ db "@"
+
+AlakazamDexEntry:
+ db "PSI@"
+ db 4,11
+ dw 1060
+ TX_FAR _AlakazamDexEntry
+ db "@"
+
+PidgeottoDexEntry:
+ db "BIRD@"
+ db 3,7
+ dw 660
+ TX_FAR _PidgeottoDexEntry
+ db "@"
+
+PidgeotDexEntry:
+ db "BIRD@"
+ db 4,11
+ dw 870
+ TX_FAR _PidgeotDexEntry
+ db "@"
+
+StarmieDexEntry:
+ db "MYSTERIOUS@"
+ db 3,7
+ dw 1760
+ TX_FAR _StarmieDexEntry
+ db "@"
+
+BulbasaurDexEntry:
+ db "SEED@"
+ db 2,4
+ dw 150
+ TX_FAR _BulbasaurDexEntry
+ db "@"
+
+VenusaurDexEntry:
+ db "SEED@"
+ db 6,7
+ dw 2210
+ TX_FAR _VenusaurDexEntry
+ db "@"
+
+TentacruelDexEntry:
+ db "JELLYFISH@"
+ db 5,3
+ dw 1210
+ TX_FAR _TentacruelDexEntry
+ db "@"
+
+GoldeenDexEntry:
+ db "GOLDFISH@"
+ db 2,0
+ dw 330
+ TX_FAR _GoldeenDexEntry
+ db "@"
+
+SeakingDexEntry:
+ db "GOLDFISH@"
+ db 4,3
+ dw 860
+ TX_FAR _SeakingDexEntry
+ db "@"
+
+PonytaDexEntry:
+ db "FIRE HORSE@"
+ db 3,3
+ dw 660
+ TX_FAR _PonytaDexEntry
+ db "@"
+
+RapidashDexEntry:
+ db "FIRE HORSE@"
+ db 5,7
+ dw 2090
+ TX_FAR _RapidashDexEntry
+ db "@"
+
+RattataDexEntry:
+ db "RAT@"
+ db 1,0
+ dw 80
+ TX_FAR _RattataDexEntry
+ db "@"
+
+RaticateDexEntry:
+ db "RAT@"
+ db 2,4
+ dw 410
+ TX_FAR _RaticateDexEntry
+ db "@"
+
+NidorinoDexEntry:
+ db "POISON PIN@"
+ db 2,11
+ dw 430
+ TX_FAR _NidorinoDexEntry
+ db "@"
+
+NidorinaDexEntry:
+ db "POISON PIN@"
+ db 2,7
+ dw 440
+ TX_FAR _NidorinaDexEntry
+ db "@"
+
+GeodudeDexEntry:
+ db "ROCK@"
+ db 1,4
+ dw 440
+ TX_FAR _GeodudeDexEntry
+ db "@"
+
+PorygonDexEntry:
+ db "VIRTUAL@"
+ db 2,7
+ dw 800
+ TX_FAR _PorygonDexEntry
+ db "@"
+
+AerodactylDexEntry:
+ db "FOSSIL@"
+ db 5,11
+ dw 1300
+ TX_FAR _AerodactylDexEntry
+ db "@"
+
+MagnemiteDexEntry:
+ db "MAGNET@"
+ db 1,0
+ dw 130
+ TX_FAR _MagnemiteDexEntry
+ db "@"
+
+CharmanderDexEntry:
+ db "LIZARD@"
+ db 2,0
+ dw 190
+ TX_FAR _CharmanderDexEntry
+ db "@"
+
+SquirtleDexEntry:
+ db "TINYTURTLE@"
+ db 1,8
+ dw 200
+ TX_FAR _SquirtleDexEntry
+ db "@"
+
+CharmeleonDexEntry:
+ db "FLAME@"
+ db 3,7
+ dw 420
+ TX_FAR _CharmeleonDexEntry
+ db "@"
+
+WartortleDexEntry:
+ db "TURTLE@"
+ db 3,3
+ dw 500
+ TX_FAR _WartortleDexEntry
+ db "@"
+
+CharizardDexEntry:
+ db "FLAME@"
+ db 5,7
+ dw 2000
+ TX_FAR _CharizardDexEntry
+ db "@"
+
+OddishDexEntry:
+ db "WEED@"
+ db 1,8
+ dw 120
+ TX_FAR _OddishDexEntry
+ db "@"
+
+GloomDexEntry:
+ db "WEED@"
+ db 2,7
+ dw 190
+ TX_FAR _GloomDexEntry
+ db "@"
+
+VileplumeDexEntry:
+ db "FLOWER@"
+ db 3,11
+ dw 410
+ TX_FAR _VileplumeDexEntry
+ db "@"
+
+BellsproutDexEntry:
+ db "FLOWER@"
+ db 2,4
+ dw 90
+ TX_FAR _BellsproutDexEntry
+ db "@"
+
+WeepinbellDexEntry:
+ db "FLYCATCHER@"
+ db 3,3
+ dw 140
+ TX_FAR _WeepinbellDexEntry
+ db "@"
+
+VictreebelDexEntry:
+ db "FLYCATCHER@"
+ db 5,7
+ dw 340
+ TX_FAR _VictreebelDexEntry
+ db "@"
+
+MissingNoDexEntry:
+ db "???@"
+ db 10 ; 1.0 m
+ db 100 ; 10.0 kg
+ db 0,"コメント さくせいちゅう@" ; コメント作成中 (Comment to be written)
diff --git a/en/data/prizes.asm b/en/data/prizes.asm
new file mode 100755
index 00000000..1120c0d0
--- /dev/null
+++ b/en/data/prizes.asm
@@ -0,0 +1,72 @@
+PrizeDifferentMenuPtrs:
+ dw PrizeMenuMon1Entries
+ dw PrizeMenuMon1Cost
+
+ dw PrizeMenuMon2Entries
+ dw PrizeMenuMon2Cost
+
+ dw PrizeMenuTMsEntries
+ dw PrizeMenuTMsCost
+
+NoThanksText:
+ db "NO THANKS@"
+
+PrizeMenuMon1Entries:
+ db ABRA
+ db CLEFAIRY
+IF DEF(_RED)
+ db NIDORINA
+ENDC
+IF DEF(_BLUE)
+ db NIDORINO
+ENDC
+ db "@"
+
+PrizeMenuMon1Cost:
+IF DEF(_RED)
+ coins 180
+ coins 500
+ENDC
+IF DEF(_BLUE)
+ coins 120
+ coins 750
+ENDC
+ coins 1200
+ db "@"
+
+PrizeMenuMon2Entries:
+IF DEF(_RED)
+ db DRATINI
+ db SCYTHER
+ENDC
+IF DEF(_BLUE)
+ db PINSIR
+ db DRATINI
+ENDC
+ db PORYGON
+ db "@"
+
+PrizeMenuMon2Cost:
+IF DEF(_RED)
+ coins 2800
+ coins 5500
+ coins 9999
+ENDC
+IF DEF(_BLUE)
+ coins 2500
+ coins 4600
+ coins 6500
+ENDC
+ db "@"
+
+PrizeMenuTMsEntries:
+ db TM_23
+ db TM_15
+ db TM_50
+ db "@"
+
+PrizeMenuTMsCost:
+ coins 3300
+ coins 5500
+ coins 7700
+ db "@"
diff --git a/en/data/trades.asm b/en/data/trades.asm
new file mode 100755
index 00000000..cf0fcbfd
--- /dev/null
+++ b/en/data/trades.asm
@@ -0,0 +1,12 @@
+TradeMons:
+; givemonster, getmonster, textstring, nickname (11 bytes), 14 bytes total
+ db NIDORINO, NIDORINA, 0,"TERRY@@@@@@"
+ db ABRA, MR_MIME, 0,"MARCEL@@@@@"
+ db BUTTERFREE,BEEDRILL, 2,"CHIKUCHIKU@"
+ db PONYTA, SEEL, 0,"SAILOR@@@@@"
+ db SPEAROW, FARFETCHD,2,"DUX@@@@@@@@"
+ db SLOWBRO, LICKITUNG,0,"MARC@@@@@@@"
+ db POLIWHIRL, JYNX, 1,"LOLA@@@@@@@"
+ db RAICHU, ELECTRODE,1,"DORIS@@@@@@"
+ db VENONAT, TANGELA, 2,"CRINKLES@@@"
+ db NIDORAN_M, NIDORAN_F,2,"SPOT@@@@@@@"
diff --git a/en/engine/HoF_room_pc.asm b/en/engine/HoF_room_pc.asm
new file mode 100755
index 00000000..390de962
--- /dev/null
+++ b/en/engine/HoF_room_pc.asm
@@ -0,0 +1,270 @@
+HallOfFamePC:
+ callba AnimateHallOfFame
+ call ClearScreen
+ ld c, 100
+ call DelayFrames
+ call DisableLCD
+ ld hl, vFont
+ ld bc, $800 / 2
+ call ZeroMemory
+ ld hl, vChars2 + $600
+ ld bc, $200 / 2
+ call ZeroMemory
+ ld hl, vChars2 + $7e0
+ ld bc, $10
+ ld a, $ff
+ call FillMemory
+ coord hl, 0, 0
+ call FillFourRowsWithBlack
+ coord hl, 0, 14
+ call FillFourRowsWithBlack
+ ld a, %11000000
+ ld [rBGP], a
+ call EnableLCD
+ ld a, $ff
+ call PlaySoundWaitForCurrent
+ ld c, BANK(Music_Credits)
+ ld a, MUSIC_CREDITS
+ call PlayMusic
+ ld c, 128
+ call DelayFrames
+ xor a
+ ld [wUnusedCD3D], a ; not read
+ ld [wNumCreditsMonsDisplayed], a
+ jp Credits
+
+FadeInCreditsText:
+ ld hl, HoFGBPalettes
+ ld b, 4
+.loop
+ ld a, [hli]
+ ld [rBGP], a
+ ld c, 5
+ call DelayFrames
+ dec b
+ jr nz, .loop
+ ret
+
+DisplayCreditsMon:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call SaveScreenTilesToBuffer1
+ call FillMiddleOfScreenWithWhite
+
+ ; display the next monster from CreditsMons
+ ld hl, wNumCreditsMonsDisplayed
+ ld c, [hl] ; how many monsters have we displayed so far?
+ inc [hl]
+ ld b, 0
+ ld hl, CreditsMons
+ add hl, bc ; go that far in the list of monsters and get the next one
+ ld a, [hl]
+ ld [wcf91], a
+ ld [wd0b5], a
+ coord hl, 8, 6
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ ld hl, vBGMap0 + $c
+ call CreditsCopyTileMapToVRAM
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call LoadScreenTilesFromBuffer1
+ ld hl, vBGMap0
+ call CreditsCopyTileMapToVRAM
+ ld a, $A7
+ ld [rWX], a
+ ld hl, vBGMap1
+ call CreditsCopyTileMapToVRAM
+ call FillMiddleOfScreenWithWhite
+ ld a, %11111100 ; make the mon a black silhouette
+ ld [rBGP], a
+
+; scroll the mon left by one tile 7 times
+ ld bc, 7
+.scrollLoop1
+ call ScrollCreditsMonLeft
+ dec c
+ jr nz, .scrollLoop1
+
+; scroll the mon left by one tile 20 times
+; This time, we have to move the window left too in order to hide the text that
+; is wrapping around to the right side of the screen.
+ ld c, 20
+.scrollLoop2
+ call ScrollCreditsMonLeft
+ ld a, [rWX]
+ sub 8
+ ld [rWX], a
+ dec c
+ jr nz, .scrollLoop2
+
+ xor a
+ ld [hWY], a
+ ld a, %11000000
+ ld [rBGP], a
+ ret
+
+INCLUDE "data/credit_mons.asm"
+
+ScrollCreditsMonLeft:
+ ld h, b
+ ld l, $20
+ call ScrollCreditsMonLeft_SetSCX
+ ld h, $0
+ ld l, $70
+ call ScrollCreditsMonLeft_SetSCX
+ ld a, b
+ add $8
+ ld b, a
+ ret
+
+ScrollCreditsMonLeft_SetSCX:
+ ld a, [rLY]
+ cp l
+ jr nz, ScrollCreditsMonLeft_SetSCX
+ ld a, h
+ ld [rSCX], a
+.loop
+ ld a, [rLY]
+ cp h
+ jr z, .loop
+ ret
+
+HoFGBPalettes:
+ db %11000000
+ db %11010000
+ db %11100000
+ db %11110000
+
+CreditsCopyTileMapToVRAM:
+ ld a, l
+ ld [H_AUTOBGTRANSFERDEST], a
+ ld a, h
+ ld [H_AUTOBGTRANSFERDEST + 1], a
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ jp Delay3
+
+ZeroMemory:
+; zero bc bytes at hl
+ ld [hl], 0
+ inc hl
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, ZeroMemory
+ ret
+
+FillFourRowsWithBlack:
+ ld bc, SCREEN_WIDTH * 4
+ ld a, $7e
+ jp FillMemory
+
+FillMiddleOfScreenWithWhite:
+ coord hl, 0, 4
+ ld bc, SCREEN_WIDTH * 10
+ ld a, " "
+ jp FillMemory
+
+Credits:
+ ld de, CreditsOrder
+ push de
+.nextCreditsScreen
+ pop de
+ coord hl, 9, 6
+ push hl
+ call FillMiddleOfScreenWithWhite
+ pop hl
+.nextCreditsCommand
+ ld a, [de]
+ inc de
+ push de
+ cp $ff
+ jr z, .fadeInTextAndShowMon
+ cp $fe
+ jr z, .showTextAndShowMon
+ cp $fd
+ jr z, .fadeInText
+ cp $fc
+ jr z, .showText
+ cp $fb
+ jr z, .showCopyrightText
+ cp $fa
+ jr z, .showTheEnd
+ push hl
+ push hl
+ ld hl, CreditsTextPointers
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld a, [de]
+ inc de
+ ld c, a
+ ld b, $ff
+ pop hl
+ add hl, bc
+ call PlaceString
+ pop hl
+ ld bc, SCREEN_WIDTH * 2
+ add hl, bc
+ pop de
+ jr .nextCreditsCommand
+.fadeInTextAndShowMon
+ call FadeInCreditsText
+ ld c, 90
+ jr .next1
+.showTextAndShowMon
+ ld c, 110
+.next1
+ call DelayFrames
+ call DisplayCreditsMon
+ jr .nextCreditsScreen
+.fadeInText
+ call FadeInCreditsText
+ ld c, 120
+ jr .next2
+.showText
+ ld c, 140
+.next2
+ call DelayFrames
+ jr .nextCreditsScreen
+.showCopyrightText
+ push de
+ callba LoadCopyrightTiles
+ pop de
+ pop de
+ jr .nextCreditsCommand
+.showTheEnd
+ ld c, 16
+ call DelayFrames
+ call FillMiddleOfScreenWithWhite
+ pop de
+ ld de, TheEndGfx
+ ld hl, vChars2 + $600
+ lb bc, BANK(TheEndGfx), (TheEndGfxEnd - TheEndGfx) / $10
+ call CopyVideoData
+ coord hl, 4, 8
+ ld de, TheEndTextString
+ call PlaceString
+ coord hl, 4, 9
+ inc de
+ call PlaceString
+ jp FadeInCreditsText
+
+TheEndTextString:
+; "T H E E N D"
+ db $60," ",$62," ",$64," ",$64," ",$66," ",$68,"@"
+ db $61," ",$63," ",$65," ",$65," ",$67," ",$69,"@"
+
+ inclang data/credits_order.asm
+
+ inclang text/credits_text.asm
+
+TheEndGfx:
+ INCBIN "gfx/theend.2bpp"
+TheEndGfxEnd:
diff --git a/en/engine/battle/core.asm b/en/engine/battle/core.asm
new file mode 100755
index 00000000..9265503d
--- /dev/null
+++ b/en/engine/battle/core.asm
@@ -0,0 +1,8719 @@
+BattleCore:
+
+; These are move effects (second value from the Moves table in bank $E).
+ResidualEffects1:
+; most non-side effects
+ db CONVERSION_EFFECT
+ db HAZE_EFFECT
+ db SWITCH_AND_TELEPORT_EFFECT
+ db MIST_EFFECT
+ db FOCUS_ENERGY_EFFECT
+ db CONFUSION_EFFECT
+ db HEAL_EFFECT
+ db TRANSFORM_EFFECT
+ db LIGHT_SCREEN_EFFECT
+ db REFLECT_EFFECT
+ db POISON_EFFECT
+ db PARALYZE_EFFECT
+ db SUBSTITUTE_EFFECT
+ db MIMIC_EFFECT
+ db LEECH_SEED_EFFECT
+ db SPLASH_EFFECT
+ db -1
+SetDamageEffects:
+; moves that do damage but not through normal calculations
+; e.g., Super Fang, Psywave
+ db SUPER_FANG_EFFECT
+ db SPECIAL_DAMAGE_EFFECT
+ db -1
+ResidualEffects2:
+; non-side effects not included in ResidualEffects1
+; stat-affecting moves, sleep-inflicting moves, and Bide
+; e.g., Meditate, Bide, Hypnosis
+ db $01
+ db ATTACK_UP1_EFFECT
+ db DEFENSE_UP1_EFFECT
+ db SPEED_UP1_EFFECT
+ db SPECIAL_UP1_EFFECT
+ db ACCURACY_UP1_EFFECT
+ db EVASION_UP1_EFFECT
+ db ATTACK_DOWN1_EFFECT
+ db DEFENSE_DOWN1_EFFECT
+ db SPEED_DOWN1_EFFECT
+ db SPECIAL_DOWN1_EFFECT
+ db ACCURACY_DOWN1_EFFECT
+ db EVASION_DOWN1_EFFECT
+ db BIDE_EFFECT
+ db SLEEP_EFFECT
+ db ATTACK_UP2_EFFECT
+ db DEFENSE_UP2_EFFECT
+ db SPEED_UP2_EFFECT
+ db SPECIAL_UP2_EFFECT
+ db ACCURACY_UP2_EFFECT
+ db EVASION_UP2_EFFECT
+ db ATTACK_DOWN2_EFFECT
+ db DEFENSE_DOWN2_EFFECT
+ db SPEED_DOWN2_EFFECT
+ db SPECIAL_DOWN2_EFFECT
+ db ACCURACY_DOWN2_EFFECT
+ db EVASION_DOWN2_EFFECT
+ db -1
+AlwaysHappenSideEffects:
+; Attacks that aren't finished after they faint the opponent.
+ db DRAIN_HP_EFFECT
+ db EXPLODE_EFFECT
+ db DREAM_EATER_EFFECT
+ db PAY_DAY_EFFECT
+ db TWO_TO_FIVE_ATTACKS_EFFECT
+ db $1E
+ db ATTACK_TWICE_EFFECT
+ db RECOIL_EFFECT
+ db TWINEEDLE_EFFECT
+ db RAGE_EFFECT
+ db -1
+SpecialEffects:
+; Effects from arrays 2, 4, and 5B, minus Twineedle and Rage.
+; Includes all effects that do not need to be called at the end of
+; ExecutePlayerMove (or ExecuteEnemyMove), because they have already been handled
+ db DRAIN_HP_EFFECT
+ db EXPLODE_EFFECT
+ db DREAM_EATER_EFFECT
+ db PAY_DAY_EFFECT
+ db SWIFT_EFFECT
+ db TWO_TO_FIVE_ATTACKS_EFFECT
+ db $1E
+ db CHARGE_EFFECT
+ db SUPER_FANG_EFFECT
+ db SPECIAL_DAMAGE_EFFECT
+ db FLY_EFFECT
+ db ATTACK_TWICE_EFFECT
+ db JUMP_KICK_EFFECT
+ db RECOIL_EFFECT
+ ; fallthrough to Next EffectsArray
+SpecialEffectsCont:
+; damaging moves whose effect is executed prior to damage calculation
+ db THRASH_PETAL_DANCE_EFFECT
+ db TRAPPING_EFFECT
+ db -1
+
+SlidePlayerAndEnemySilhouettesOnScreen:
+ call LoadPlayerBackPic
+ ld a, MESSAGE_BOX ; the usual text box at the bottom of the screen
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ coord hl, 1, 5
+ lb bc, 3, 7
+ call ClearScreenArea
+ call DisableLCD
+ call LoadFontTilePatterns
+ call LoadHudAndHpBarAndStatusTilePatterns
+ ld hl, vBGMap0
+ ld bc, $400
+.clearBackgroundLoop
+ ld a, " "
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .clearBackgroundLoop
+; copy the work RAM tile map to VRAM
+ coord hl, 0, 0
+ ld de, vBGMap0
+ ld b, 18 ; number of rows
+.copyRowLoop
+ ld c, 20 ; number of columns
+.copyColumnLoop
+ ld a, [hli]
+ ld [de], a
+ inc e
+ dec c
+ jr nz, .copyColumnLoop
+ ld a, 12 ; number of off screen tiles to the right of screen in VRAM
+ add e ; skip the off screen tiles
+ ld e, a
+ jr nc, .noCarry
+ inc d
+.noCarry
+ dec b
+ jr nz, .copyRowLoop
+ call EnableLCD
+ ld a, $90
+ ld [hWY], a
+ ld [rWY], a
+ xor a
+ ld [hTilesetType], a
+ ld [hSCY], a
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld b, $70
+ ld c, $90
+ ld a, c
+ ld [hSCX], a
+ call DelayFrame
+ ld a, %11100100 ; inverted palette for silhouette effect
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
+.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen
+ ld h, b
+ ld l, $40
+ call SetScrollXForSlidingPlayerBodyLeft ; begin background scrolling on line $40
+ inc b
+ inc b
+ ld h, $0
+ ld l, $60
+ call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60
+ call SlidePlayerHeadLeft
+ ld a, c
+ ld [hSCX], a
+ dec c
+ dec c
+ jr nz, .slideSilhouettesLoop
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, $31
+ ld [hStartTileID], a
+ coord hl, 1, 5
+ predef CopyUncompressedPicToTilemap
+ xor a
+ ld [hWY], a
+ ld [rWY], a
+ inc a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld b, SET_PAL_BATTLE
+ call RunPaletteCommand
+ call HideSprites
+ jpab PrintBeginningBattleText
+
+; when a battle is starting, silhouettes of the player's pic and the enemy's pic are slid onto the screen
+; the lower of the player's pic (his body) is part of the background, but his head is a sprite
+; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics
+; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop
+SlidePlayerHeadLeft:
+ push bc
+ ld hl, wOAMBuffer + $01
+ ld c, $15 ; number of OAM entries
+ ld de, $4 ; size of OAM entry
+.loop
+ dec [hl] ; decrement X
+ dec [hl] ; decrement X
+ add hl, de ; next OAM entry
+ dec c
+ jr nz, .loop
+ pop bc
+ ret
+
+SetScrollXForSlidingPlayerBodyLeft:
+ ld a, [rLY]
+ cp l
+ jr nz, SetScrollXForSlidingPlayerBodyLeft
+ ld a, h
+ ld [rSCX], a
+.loop
+ ld a, [rLY]
+ cp h
+ jr z, .loop
+ ret
+
+StartBattle:
+ xor a
+ ld [wPartyGainExpFlags], a
+ ld [wPartyFoughtCurrentEnemyFlags], a
+ ld [wActionResultOrTookBattleTurn], a
+ inc a
+ ld [wFirstMonsNotOutYet], a
+ ld hl, wEnemyMon1HP
+ ld bc, wEnemyMon2 - wEnemyMon1 - 1
+ ld d, $3
+.findFirstAliveEnemyMonLoop
+ inc d
+ ld a, [hli]
+ or [hl]
+ jr nz, .foundFirstAliveEnemyMon
+ add hl, bc
+ jr .findFirstAliveEnemyMonLoop
+.foundFirstAliveEnemyMon
+ ld a, d
+ ld [wSerialExchangeNybbleReceiveData], a
+ ld a, [wIsInBattle]
+ dec a ; is it a trainer battle?
+ call nz, EnemySendOutFirstMon ; if it is a trainer battle, send out enemy mon
+ ld c, 40
+ call DelayFrames
+ call SaveScreenTilesToBuffer1
+.checkAnyPartyAlive
+ call AnyPartyAlive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut ; jump if no mon is alive
+ call LoadScreenTilesFromBuffer1
+ ld a, [wBattleType]
+ and a ; is it a normal battle?
+ jp z, .playerSendOutFirstMon ; if so, send out player mon
+; safari zone battle
+.displaySafariZoneBattleMenu
+ call DisplayBattleMenu
+ ret c ; return if the player ran from battle
+ ld a, [wActionResultOrTookBattleTurn]
+ and a ; was the item used successfully?
+ jr z, .displaySafariZoneBattleMenu ; if not, display the menu again; XXX does this ever jump?
+ ld a, [wNumSafariBalls]
+ and a
+ jr nz, .notOutOfSafariBalls
+ call LoadScreenTilesFromBuffer1
+ ld hl, .outOfSafariBallsText
+ jp PrintText
+.notOutOfSafariBalls
+ callab PrintSafariZoneBattleText
+ ld a, [wEnemyMonSpeed + 1]
+ add a
+ ld b, a ; init b (which is later compared with random value) to (enemy speed % 256) * 2
+ jp c, EnemyRan ; if (enemy speed % 256) > 127, the enemy runs
+ ld a, [wSafariBaitFactor]
+ and a ; is bait factor 0?
+ jr z, .checkEscapeFactor
+; bait factor is not 0
+; divide b by 4 (making the mon less likely to run)
+ srl b
+ srl b
+.checkEscapeFactor
+ ld a, [wSafariEscapeFactor]
+ and a ; is escape factor 0?
+ jr z, .compareWithRandomValue
+; escape factor is not 0
+; multiply b by 2 (making the mon more likely to run)
+ sla b
+ jr nc, .compareWithRandomValue
+; cap b at 255
+ ld b, $ff
+.compareWithRandomValue
+ call Random
+ cp b
+ jr nc, .checkAnyPartyAlive
+ jr EnemyRan ; if b was greater than the random value, the enemy runs
+
+.outOfSafariBallsText
+ TX_FAR _OutOfSafariBallsText
+ db "@"
+
+.playerSendOutFirstMon
+ xor a
+ ld [wWhichPokemon], a
+.findFirstAliveMonLoop
+ call HasMonFainted
+ jr nz, .foundFirstAliveMon
+; fainted, go to the next one
+ ld hl, wWhichPokemon
+ inc [hl]
+ jr .findFirstAliveMonLoop
+.foundFirstAliveMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ inc a
+ ld hl, wPartySpecies - 1
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl] ; species
+ ld [wcf91], a
+ ld [wBattleMonSpecies2], a
+ call LoadScreenTilesFromBuffer1
+ coord hl, 1, 5
+ ld a, $9
+ call SlideTrainerPicOffScreen
+ call SaveScreenTilesToBuffer1
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, FLAG_SET
+ push bc
+ ld hl, wPartyGainExpFlags
+ predef FlagActionPredef
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ pop bc
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call LoadScreenTilesFromBuffer1
+ call SendOutMon
+ jr MainInBattleLoop
+
+; wild mon or link battle enemy ran from battle
+EnemyRan:
+ call LoadScreenTilesFromBuffer1
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ld hl, WildRanText
+ jr nz, .printText
+; link battle
+ xor a
+ ld [wBattleResult], a
+ ld hl, EnemyRanText
+.printText
+ call PrintText
+ ld a, SFX_RUN
+ call PlaySoundWaitForCurrent
+ xor a
+ ld [H_WHOSETURN], a
+ jpab AnimationSlideEnemyMonOff
+
+WildRanText:
+ TX_FAR _WildRanText
+ db "@"
+
+EnemyRanText:
+ TX_FAR _EnemyRanText
+ db "@"
+
+MainInBattleLoop:
+ call ReadPlayerMonCurHPAndStatus
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; is battle mon HP 0?
+ jp z, HandlePlayerMonFainted ; if battle mon HP is 0, jump
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon HP 0?
+ jp z, HandleEnemyMonFainted ; if enemy mon HP is 0, jump
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wFirstMonsNotOutYet], a
+ ld a, [wPlayerBattleStatus2]
+ and (1 << NEEDS_TO_RECHARGE) | (1 << USING_RAGE) ; check if the player is using Rage or needs to recharge
+ jr nz, .selectEnemyMove
+; the player is not using Rage and doesn't need to recharge
+ ld hl, wEnemyBattleStatus1
+ res FLINCHED, [hl] ; reset flinch bit
+ ld hl, wPlayerBattleStatus1
+ res FLINCHED, [hl] ; reset flinch bit
+ ld a, [hl]
+ and (1 << THRASHING_ABOUT) | (1 << CHARGING_UP) ; check if the player is thrashing about or charging for an attack
+ jr nz, .selectEnemyMove ; if so, jump
+; the player is neither thrashing about nor charging for an attack
+ call DisplayBattleMenu ; show battle menu
+ ret c ; return if player ran from battle
+ ld a, [wEscapedFromBattle]
+ and a
+ ret nz ; return if pokedoll was used to escape from battle
+ ld a, [wBattleMonStatus]
+ and (1 << FRZ) | SLP ; is mon frozen or asleep?
+ jr nz, .selectEnemyMove ; if so, jump
+ ld a, [wPlayerBattleStatus1]
+ and (1 << STORING_ENERGY) | (1 << USING_TRAPPING_MOVE) ; check player is using Bide or using a multi-turn attack like wrap
+ jr nz, .selectEnemyMove ; if so, jump
+ ld a, [wEnemyBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; check if enemy is using a multi-turn attack like wrap
+ jr z, .selectPlayerMove ; if not, jump
+; enemy is using a multi-turn attack like wrap, so player is trapped and cannot execute a move
+ ld a, $ff
+ ld [wPlayerSelectedMove], a
+ jr .selectEnemyMove
+.selectPlayerMove
+ ld a, [wActionResultOrTookBattleTurn]
+ and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon)
+ jr nz, .selectEnemyMove
+ ld [wMoveMenuType], a
+ inc a
+ ld [wAnimationID], a
+ xor a
+ ld [wMenuItemToSwap], a
+ call MoveSelectionMenu
+ push af
+ call LoadScreenTilesFromBuffer1
+ call DrawHUDsAndHPBars
+ pop af
+ jr nz, MainInBattleLoop ; if the player didn't select a move, jump
+.selectEnemyMove
+ call SelectEnemyMove
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .noLinkBattle
+; link battle
+ ld a, [wSerialExchangeNybbleReceiveData]
+ cp LINKBATTLE_RUN
+ jp z, EnemyRan
+ cp LINKBATTLE_STRUGGLE
+ jr z, .noLinkBattle
+ cp LINKBATTLE_NO_ACTION
+ jr z, .noLinkBattle
+ sub 4
+ jr c, .noLinkBattle
+; the link battle enemy has switched mons
+ ld a, [wPlayerBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; check if using multi-turn move like Wrap
+ jr z, .specialMoveNotUsed
+ ld a, [wPlayerMoveListIndex]
+ ld hl, wBattleMonMoves
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ cp METRONOME ; a MIRROR MOVE check is missing, might lead to a desync in link battles
+ ; when combined with multi-turn moves
+ jr nz, .specialMoveNotUsed
+ ld [wPlayerSelectedMove], a
+.specialMoveNotUsed
+ callab SwitchEnemyMon
+.noLinkBattle
+ ld a, [wPlayerSelectedMove]
+ cp QUICK_ATTACK
+ jr nz, .playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .compareSpeed ; if both used Quick Attack
+ jp .playerMovesFirst ; if player used Quick Attack and enemy didn't
+.playerDidNotUseQuickAttack
+ ld a, [wEnemySelectedMove]
+ cp QUICK_ATTACK
+ jr z, .enemyMovesFirst ; if enemy used Quick Attack and player didn't
+ ld a, [wPlayerSelectedMove]
+ cp COUNTER
+ jr nz, .playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .compareSpeed ; if both used Counter
+ jr .enemyMovesFirst ; if player used Counter and enemy didn't
+.playerDidNotUseCounter
+ ld a, [wEnemySelectedMove]
+ cp COUNTER
+ jr z, .playerMovesFirst ; if enemy used Counter and player didn't
+.compareSpeed
+ ld de, wBattleMonSpeed ; player speed value
+ ld hl, wEnemyMonSpeed ; enemy speed value
+ ld c, $2
+ call StringCmp ; compare speed values
+ jr z, .speedEqual
+ jr nc, .playerMovesFirst ; if player is faster
+ jr .enemyMovesFirst ; if enemy is faster
+.speedEqual ; 50/50 chance for both players
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .invertOutcome
+ call BattleRandom
+ cp $80
+ jr c, .playerMovesFirst
+ jr .enemyMovesFirst
+.invertOutcome
+ call BattleRandom
+ cp $80
+ jr c, .enemyMovesFirst
+ jr .playerMovesFirst
+.enemyMovesFirst
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedEnemyFirst
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedEnemyFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call DrawHUDsAndHPBars
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
+ jp MainInBattleLoop
+.playerMovesFirst
+ call ExecutePlayerMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandleEnemyMonFainted
+ call HandlePoisonBurnLeechSeed
+ jp z, HandlePlayerMonFainted
+ call DrawHUDsAndHPBars
+ ld a, $1
+ ld [H_WHOSETURN], a
+ callab TrainerAI
+ jr c, .AIActionUsedPlayerFirst
+ call ExecuteEnemyMove
+ ld a, [wEscapedFromBattle]
+ and a ; was Teleport, Road, or Whirlwind used to escape from battle?
+ ret nz ; if so, return
+ ld a, b
+ and a
+ jp z, HandlePlayerMonFainted
+.AIActionUsedPlayerFirst
+ call HandlePoisonBurnLeechSeed
+ jp z, HandleEnemyMonFainted
+ call DrawHUDsAndHPBars
+ call CheckNumAttacksLeft
+ jp MainInBattleLoop
+
+HandlePoisonBurnLeechSeed:
+ ld hl, wBattleMonHP
+ ld de, wBattleMonStatus
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, wEnemyMonHP
+ ld de, wEnemyMonStatus
+.playersTurn
+ ld a, [de]
+ and (1 << BRN) | (1 << PSN)
+ jr z, .notBurnedOrPoisoned
+ push hl
+ ld hl, HurtByPoisonText
+ ld a, [de]
+ and 1 << BRN
+ jr z, .poisoned
+ ld hl, HurtByBurnText
+.poisoned
+ call PrintText
+ xor a
+ ld [wAnimationType], a
+ ld a, BURN_PSN_ANIM
+ call PlayMoveAnimation ; play burn/poison animation
+ pop hl
+ call HandlePoisonBurnLeechSeed_DecreaseOwnHP
+.notBurnedOrPoisoned
+ ld de, wPlayerBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn2
+ ld de, wEnemyBattleStatus2
+.playersTurn2
+ ld a, [de]
+ add a
+ jr nc, .notLeechSeeded
+ push hl
+ ld a, [H_WHOSETURN]
+ push af
+ xor $1
+ ld [H_WHOSETURN], a
+ xor a
+ ld [wAnimationType], a
+ ld a, ABSORB
+ call PlayMoveAnimation ; play leech seed animation (from opposing mon)
+ pop af
+ ld [H_WHOSETURN], a
+ pop hl
+ call HandlePoisonBurnLeechSeed_DecreaseOwnHP
+ call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
+ push hl
+ ld hl, HurtByLeechSeedText
+ call PrintText
+ pop hl
+.notLeechSeeded
+ ld a, [hli]
+ or [hl]
+ ret nz ; test if fainted
+ call DrawHUDsAndHPBars
+ ld c, 20
+ call DelayFrames
+ xor a
+ ret
+
+HurtByPoisonText:
+ TX_FAR _HurtByPoisonText
+ db "@"
+
+HurtByBurnText:
+ TX_FAR _HurtByBurnText
+ db "@"
+
+HurtByLeechSeedText:
+ TX_FAR _HurtByLeechSeedText
+ db "@"
+
+; decreases the mon's current HP by 1/16 of the Max HP (multiplied by number of toxic ticks if active)
+; note that the toxic ticks are considered even if the damage is not poison (hence the Leech Seed glitch)
+; hl: HP pointer
+; bc (out): total damage
+HandlePoisonBurnLeechSeed_DecreaseOwnHP:
+ push hl
+ push hl
+ ld bc, $e ; skip to max HP
+ add hl, bc
+ ld a, [hli] ; load max HP
+ ld [wHPBarMaxHP+1], a
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld c, a
+ srl b
+ rr c
+ srl b
+ rr c
+ srl c
+ srl c ; c = max HP/16 (assumption: HP < 1024)
+ ld a, c
+ and a
+ jr nz, .nonZeroDamage
+ inc c ; damage is at least 1
+.nonZeroDamage
+ ld hl, wPlayerBattleStatus3
+ ld de, wPlayerToxicCounter
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, wEnemyBattleStatus3
+ ld de, wEnemyToxicCounter
+.playersTurn
+ bit BADLY_POISONED, [hl]
+ jr z, .noToxic
+ ld a, [de] ; increment toxic counter
+ inc a
+ ld [de], a
+ ld hl, $0000
+.toxicTicksLoop
+ add hl, bc
+ dec a
+ jr nz, .toxicTicksLoop
+ ld b, h ; bc = damage * toxic counter
+ ld c, l
+.noToxic
+ pop hl
+ inc hl
+ ld a, [hl] ; subtract total damage from current HP
+ ld [wHPBarOldHP], a
+ sub c
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [hl], a
+ ld [wHPBarNewHP+1], a
+ jr nc, .noOverkill
+ xor a ; overkill: zero HP
+ ld [hli], a
+ ld [hl], a
+ ld [wHPBarNewHP], a
+ ld [wHPBarNewHP+1], a
+.noOverkill
+ call UpdateCurMonHPBar
+ pop hl
+ ret
+
+; adds bc to enemy HP
+; bc isn't updated if HP subtracted was capped to prevent overkill
+HandlePoisonBurnLeechSeed_IncreaseEnemyHP:
+ push hl
+ ld hl, wEnemyMonMaxHP
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld hl, wBattleMonMaxHP
+.playersTurn
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld de, wBattleMonHP - wBattleMonMaxHP
+ add hl, de ; skip back from max hp to current hp
+ ld a, [hl]
+ ld [wHPBarOldHP], a ; add bc to current HP
+ add c
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ adc b
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ ld a, [wHPBarMaxHP]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ld a, [wHPBarMaxHP+1]
+ ld b, a
+ ld a, [hl]
+ sbc b
+ jr c, .noOverfullHeal
+ ld a, b ; overfull heal, set HP to max HP
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ ld a, c
+ ld [hl], a
+ ld [wHPBarNewHP], a
+.noOverfullHeal
+ ld a, [H_WHOSETURN]
+ xor $1
+ ld [H_WHOSETURN], a
+ call UpdateCurMonHPBar
+ ld a, [H_WHOSETURN]
+ xor $1
+ ld [H_WHOSETURN], a
+ pop hl
+ ret
+
+UpdateCurMonHPBar:
+ coord hl, 10, 9 ; tile pointer to player HP bar
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, $1
+ jr z, .playersTurn
+ coord hl, 2, 2 ; tile pointer to enemy HP bar
+ xor a
+.playersTurn
+ push bc
+ ld [wHPBarType], a
+ predef UpdateHPBar2
+ pop bc
+ ret
+
+CheckNumAttacksLeft:
+ ld a, [wPlayerNumAttacksLeft]
+ and a
+ jr nz, .checkEnemy
+; player has 0 attacks left
+ ld hl, wPlayerBattleStatus1
+ res USING_TRAPPING_MOVE, [hl] ; player not using multi-turn attack like wrap any more
+.checkEnemy
+ ld a, [wEnemyNumAttacksLeft]
+ and a
+ ret nz
+; enemy has 0 attacks left
+ ld hl, wEnemyBattleStatus1
+ res USING_TRAPPING_MOVE, [hl] ; enemy not using multi-turn attack like wrap any more
+ ret
+
+HandleEnemyMonFainted:
+ xor a
+ ld [wInHandlePlayerMonFainted], a
+ call FaintEnemyPokemon
+ call AnyPartyAlive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut ; if no party mons are alive, the player blacks out
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; is battle mon HP zero?
+ call nz, DrawPlayerHUDAndHPBar ; if battle mon HP is not zero, draw player HD and HP bar
+ ld a, [wIsInBattle]
+ dec a
+ ret z ; return if it's a wild battle
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl] ; does battle mon have 0 HP?
+ jr nz, .skipReplacingBattleMon ; if not, skip replacing battle mon
+ call DoUseNextMonDialogue ; this call is useless in a trainer battle. it shouldn't be here
+ ret c
+ call ChooseNextMon
+.skipReplacingBattleMon
+ ld a, $1
+ ld [wActionResultOrTookBattleTurn], a
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan
+ xor a
+ ld [wActionResultOrTookBattleTurn], a
+ jp MainInBattleLoop
+
+FaintEnemyPokemon:
+ call ReadPlayerMonCurHPAndStatus
+ ld a, [wIsInBattle]
+ dec a
+ jr z, .wild
+ ld a, [wEnemyMonPartyPos]
+ ld hl, wEnemyMon1HP
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ xor a
+ ld [hli], a
+ ld [hl], a
+.wild
+ ld hl, wPlayerBattleStatus1
+ res ATTACKING_MULTIPLE_TIMES, [hl]
+; Bug. This only zeroes the high byte of the player's accumulated damage,
+; setting the accumulated damage to itself mod 256 instead of 0 as was probably
+; intended. That alone is problematic, but this mistake has another more severe
+; effect. This function's counterpart for when the player mon faints,
+; RemoveFaintedPlayerMon, zeroes both the high byte and the low byte. In a link
+; battle, the other player's Game Boy will call that function in response to
+; the enemy mon (the player mon from the other side's perspective) fainting,
+; and the states of the two Game Boys will go out of sync unless the damage
+; was congruent to 0 modulo 256.
+ xor a
+ ld [wPlayerBideAccumulatedDamage], a
+ ld hl, wEnemyStatsToDouble ; clear enemy statuses
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wEnemyDisabledMove], a
+ ld [wEnemyDisabledMoveNumber], a
+ ld [wEnemyMonMinimized], a
+ ld hl, wPlayerUsedMove
+ ld [hli], a
+ ld [hl], a
+ coord hl, 12, 5
+ coord de, 12, 6
+ call SlideDownFaintedMonPic
+ coord hl, 0, 0
+ lb bc, 4, 11
+ call ClearScreenArea
+ ld a, [wIsInBattle]
+ dec a
+ jr z, .wild_win
+ xor a
+ ld [wFrequencyModifier], a
+ ld [wTempoModifier], a
+ ld a, SFX_FAINT_FALL
+ call PlaySoundWaitForCurrent
+.sfxwait
+ ld a, [wChannelSoundIDs + Ch4]
+ cp SFX_FAINT_FALL
+ jr z, .sfxwait
+ ld a, SFX_FAINT_THUD
+ call PlaySound
+ call WaitForSoundToFinish
+ jr .sfxplayed
+.wild_win
+ call EndLowHealthAlarm
+ ld a, MUSIC_DEFEATED_WILD_MON
+ call PlayBattleVictoryMusic
+.sfxplayed
+; bug: win sfx is played for wild battles before checking for player mon HP
+; this can lead to odd scenarios where both player and enemy faint, as the win sfx plays yet the player never won the battle
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr nz, .playermonnotfaint
+ ld a, [wInHandlePlayerMonFainted]
+ and a ; was this called by HandlePlayerMonFainted?
+ jr nz, .playermonnotfaint ; if so, don't call RemoveFaintedPlayerMon twice
+ call RemoveFaintedPlayerMon
+.playermonnotfaint
+ call AnyPartyAlive
+ ld a, d
+ and a
+ ret z
+ ld hl, EnemyMonFaintedText
+ call PrintText
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wBattleResult], a
+ ld b, EXP_ALL
+ call IsItemInBag
+ push af
+ jr z, .giveExpToMonsThatFought ; if no exp all, then jump
+
+; the player has exp all
+; first, we halve the values that determine exp gain
+; the enemy mon base stats are added to stat exp, so they are halved
+; the base exp (which determines normal exp) is also halved
+ ld hl, wEnemyMonBaseStats
+ ld b, $7
+.halveExpDataLoop
+ srl [hl]
+ inc hl
+ dec b
+ jr nz, .halveExpDataLoop
+
+; give exp (divided evenly) to the mons that actually fought in battle against the enemy mon that has fainted
+; if exp all is in the bag, this will be only be half of the stat exp and normal exp, due to the above loop
+.giveExpToMonsThatFought
+ xor a
+ ld [wBoostExpByExpAll], a
+ callab GainExperience
+ pop af
+ ret z ; return if no exp all
+
+; the player has exp all
+; now, set the gain exp flag for every party member
+; half of the total stat exp and normal exp will divided evenly amongst every party member
+ ld a, $1
+ ld [wBoostExpByExpAll], a
+ ld a, [wPartyCount]
+ ld b, 0
+.gainExpFlagsLoop
+ scf
+ rl b
+ dec a
+ jr nz, .gainExpFlagsLoop
+ ld a, b
+ ld [wPartyGainExpFlags], a
+ jpab GainExperience
+
+EnemyMonFaintedText:
+ TX_FAR _EnemyMonFaintedText
+ db "@"
+
+EndLowHealthAlarm:
+; This function is called when the player has the won the battle. It turns off
+; the low health alarm and prevents it from reactivating until the next battle.
+ xor a
+ ld [wLowHealthAlarm], a ; turn off low health alarm
+ ld [wChannelSoundIDs + Ch4], a
+ inc a
+ ld [wLowHealthAlarmDisabled], a ; prevent it from reactivating
+ ret
+
+AnyEnemyPokemonAliveCheck:
+ ld a, [wEnemyPartyCount]
+ ld b, a
+ xor a
+ ld hl, wEnemyMon1HP
+ ld de, wEnemyMon2 - wEnemyMon1
+.nextPokemon
+ or [hl]
+ inc hl
+ or [hl]
+ dec hl
+ add hl, de
+ dec b
+ jr nz, .nextPokemon
+ and a
+ ret
+
+; stores whether enemy ran in Z flag
+ReplaceFaintedEnemyMon:
+ ld hl, wEnemyHPBarColor
+ ld e, $30
+ call GetBattleHealthBarColor
+ callab DrawEnemyPokeballs
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .notLinkBattle
+; link battle
+ call LinkBattleExchangeData
+ ld a, [wSerialExchangeNybbleReceiveData]
+ cp LINKBATTLE_RUN
+ ret z
+ call LoadScreenTilesFromBuffer1
+.notLinkBattle
+ call EnemySendOut
+ xor a
+ ld [wEnemyMoveNum], a
+ ld [wActionResultOrTookBattleTurn], a
+ ld [wAILayer2Encouragement], a
+ inc a ; reset Z flag
+ ret
+
+TrainerBattleVictory:
+ call EndLowHealthAlarm
+ ld b, MUSIC_DEFEATED_GYM_LEADER
+ ld a, [wGymLeaderNo]
+ and a
+ jr nz, .gymleader
+ ld b, MUSIC_DEFEATED_TRAINER
+.gymleader
+ ld a, [wTrainerClass]
+ cp SONY3 ; final battle against rival
+ jr nz, .notrival
+ ld b, MUSIC_DEFEATED_GYM_LEADER
+ ld hl, wFlags_D733
+ set 1, [hl]
+.notrival
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ld a, b
+ call nz, PlayBattleVictoryMusic
+ ld hl, TrainerDefeatedText
+ call PrintText
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ret z
+ call ScrollTrainerPicAfterBattle
+ ld c, 40
+ call DelayFrames
+ call PrintEndBattleText
+; win money
+ ld hl, MoneyForWinningText
+ call PrintText
+ ld de, wPlayerMoney + 2
+ ld hl, wAmountMoneyWon + 2
+ ld c, $3
+ predef_jump AddBCDPredef
+
+MoneyForWinningText:
+ TX_FAR _MoneyForWinningText
+ db "@"
+
+TrainerDefeatedText:
+ TX_FAR _TrainerDefeatedText
+ db "@"
+
+PlayBattleVictoryMusic:
+ push af
+ ld a, $ff
+ ld [wNewSoundID], a
+ call PlaySoundWaitForCurrent
+ ld c, BANK(Music_DefeatedTrainer)
+ pop af
+ call PlayMusic
+ jp Delay3
+
+HandlePlayerMonFainted:
+ ld a, 1
+ ld [wInHandlePlayerMonFainted], a
+ call RemoveFaintedPlayerMon
+ call AnyPartyAlive ; test if any more mons are alive
+ ld a, d
+ and a
+ jp z, HandlePlayerBlackOut
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon's HP 0?
+ jr nz, .doUseNextMonDialogue ; if not, jump
+; the enemy mon has 0 HP
+ call FaintEnemyPokemon
+ ld a, [wIsInBattle]
+ dec a
+ ret z ; if wild encounter, battle is over
+ call AnyEnemyPokemonAliveCheck
+ jp z, TrainerBattleVictory
+.doUseNextMonDialogue
+ call DoUseNextMonDialogue
+ ret c ; return if the player ran from battle
+ call ChooseNextMon
+ jp nz, MainInBattleLoop ; if the enemy mon has more than 0 HP, go back to battle loop
+; the enemy mon has 0 HP
+ ld a, $1
+ ld [wActionResultOrTookBattleTurn], a
+ call ReplaceFaintedEnemyMon
+ jp z, EnemyRan ; if enemy ran from battle rather than sending out another mon, jump
+ xor a
+ ld [wActionResultOrTookBattleTurn], a
+ jp MainInBattleLoop
+
+; resets flags, slides mon's pic down, plays cry, and prints fainted message
+RemoveFaintedPlayerMon:
+ ld a, [wPlayerMonNumber]
+ ld c, a
+ ld hl, wPartyGainExpFlags
+ ld b, FLAG_RESET
+ predef FlagActionPredef ; clear gain exp flag for fainted mon
+ ld hl, wEnemyBattleStatus1
+ res 2, [hl] ; reset "attacking multiple times" flag
+ ld a, [wLowHealthAlarm]
+ bit 7, a ; skip sound flag (red bar (?))
+ jr z, .skipWaitForSound
+ ld a, $ff
+ ld [wLowHealthAlarm], a ;disable low health alarm
+ call WaitForSoundToFinish
+.skipWaitForSound
+; a is 0, so this zeroes the enemy's accumulated damage.
+ ld hl, wEnemyBideAccumulatedDamage
+ ld [hli], a
+ ld [hl], a
+ ld [wBattleMonStatus], a
+ call ReadPlayerMonCurHPAndStatus
+ coord hl, 9, 7
+ lb bc, 5, 11
+ call ClearScreenArea
+ coord hl, 1, 10
+ coord de, 1, 11
+ call SlideDownFaintedMonPic
+ ld a, $1
+ ld [wBattleResult], a
+
+; When the player mon and enemy mon faint at the same time and the fact that the
+; enemy mon has fainted is detected first (e.g. when the player mon knocks out
+; the enemy mon using a move with recoil and faints due to the recoil), don't
+; play the player mon's cry or show the "[player mon] fainted!" message.
+ ld a, [wInHandlePlayerMonFainted]
+ and a ; was this called by HandleEnemyMonFainted?
+ ret z ; if so, return
+
+ ld a, [wBattleMonSpecies]
+ call PlayCry
+ ld hl, PlayerMonFaintedText
+ jp PrintText
+
+PlayerMonFaintedText:
+ TX_FAR _PlayerMonFaintedText
+ db "@"
+
+; asks if you want to use next mon
+; stores whether you ran in C flag
+DoUseNextMonDialogue:
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ ld a, [wIsInBattle]
+ and a
+ dec a
+ ret nz ; return if it's a trainer battle
+ ld hl, UseNextMonText
+ call PrintText
+.displayYesNoBox
+ coord hl, 13, 9
+ lb bc, 10, 14
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, [wMenuExitMethod]
+ cp CHOSE_SECOND_ITEM ; did the player choose NO?
+ jr z, .tryRunning ; if the player chose NO, try running
+ and a ; reset carry
+ ret
+.tryRunning
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .displayYesNoBox ; xxx when does this happen?
+ ld hl, wPartyMon1Speed
+ ld de, wEnemyMonSpeed
+ jp TryRunningFromBattle
+
+UseNextMonText:
+ TX_FAR _UseNextMonText
+ db "@"
+
+; choose next player mon to send out
+; stores whether enemy mon has no HP left in Z flag
+ChooseNextMon:
+ ld a, BATTLE_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call DisplayPartyMenu
+.checkIfMonChosen
+ jr nc, .monChosen
+.goBackToPartyMenu
+ call GoBackToPartyMenu
+ jr .checkIfMonChosen
+.monChosen
+ call HasMonFainted
+ jr z, .goBackToPartyMenu ; if mon fainted, you have to choose another
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .notLinkBattle
+ inc a
+ ld [wActionResultOrTookBattleTurn], a
+ call LinkBattleExchangeData
+.notLinkBattle
+ xor a
+ ld [wActionResultOrTookBattleTurn], a
+ call ClearSprites
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ ld c, a
+ ld hl, wPartyGainExpFlags
+ ld b, FLAG_SET
+ push bc
+ predef FlagActionPredef
+ pop bc
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+ call RunDefaultPaletteCommand
+ call GBPalNormal
+ call SendOutMon
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl]
+ ret
+
+; called when player is out of usable mons.
+; prints appropriate lose message, sets carry flag if player blacked out (special case for initial rival fight)
+HandlePlayerBlackOut:
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .notSony1Battle
+ ld a, [wCurOpponent]
+ cp OPP_SONY1
+ jr nz, .notSony1Battle
+ coord hl, 0, 0 ; sony 1 battle
+ lb bc, 8, 21
+ call ClearScreenArea
+ call ScrollTrainerPicAfterBattle
+ ld c, 40
+ call DelayFrames
+ ld hl, Sony1WinText
+ call PrintText
+ ld a, [wCurMap]
+ cp OAKS_LAB
+ ret z ; starter battle in oak's lab: don't black out
+.notSony1Battle
+ ld b, SET_PAL_BATTLE_BLACK
+ call RunPaletteCommand
+ ld hl, PlayerBlackedOutText2
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .noLinkBattle
+ ld hl, LinkBattleLostText
+.noLinkBattle
+ call PrintText
+ ld a, [wd732]
+ res 5, a
+ ld [wd732], a
+ call ClearScreen
+ scf
+ ret
+
+Sony1WinText:
+ TX_FAR _Sony1WinText
+ db "@"
+
+PlayerBlackedOutText2:
+ TX_FAR _PlayerBlackedOutText2
+ db "@"
+
+LinkBattleLostText:
+ TX_FAR _LinkBattleLostText
+ db "@"
+
+; slides pic of fainted mon downwards until it disappears
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideDownFaintedMonPic:
+ ld a, [wd730]
+ push af
+ set 6, a
+ ld [wd730], a
+ ld b, 7 ; number of times to slide
+.slideStepLoop ; each iteration, the mon is slid down one row
+ push bc
+ push de
+ push hl
+ ld b, 6 ; number of rows
+.rowLoop
+ push bc
+ push hl
+ push de
+ ld bc, $7
+ call CopyData
+ pop de
+ pop hl
+ ld bc, -SCREEN_WIDTH
+ add hl, bc
+ push hl
+ ld h, d
+ ld l, e
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ dec b
+ jr nz, .rowLoop
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld de, SevenSpacesText
+ call PlaceString
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop de
+ pop bc
+ dec b
+ jr nz, .slideStepLoop
+ pop af
+ ld [wd730], a
+ ret
+
+SevenSpacesText:
+ db " @"
+
+; slides the player or enemy trainer off screen
+; a is the number of tiles to slide it horizontally (always 9 for the player trainer or 8 for the enemy trainer)
+; if a is 8, the slide is to the right, else it is to the left
+; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+SlideTrainerPicOffScreen:
+ ld [hSlideAmount], a
+ ld c, a
+.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
+ push bc
+ push hl
+ ld b, 7 ; number of rows
+.rowLoop
+ push hl
+ ld a, [hSlideAmount]
+ ld c, a
+.columnLoop
+ ld a, [hSlideAmount]
+ cp 8
+ jr z, .slideRight
+.slideLeft ; slide player sprite off screen
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+ jr .nextColumn
+.slideRight ; slide enemy trainer sprite off screen
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+.nextColumn
+ dec c
+ jr nz, .columnLoop
+ pop hl
+ ld de, 20
+ add hl, de
+ dec b
+ jr nz, .rowLoop
+ ld c, 2
+ call DelayFrames
+ pop hl
+ pop bc
+ dec c
+ jr nz, .slideStepLoop
+ ret
+
+; send out a trainer's mon
+EnemySendOut:
+ ld hl, wPartyGainExpFlags
+ xor a
+ ld [hl], a
+ ld a, [wPlayerMonNumber]
+ ld c, a
+ ld b, FLAG_SET
+ push bc
+ predef FlagActionPredef
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ xor a
+ ld [hl], a
+ pop bc
+ predef FlagActionPredef
+
+; don't change wPartyGainExpFlags or wPartyFoughtCurrentEnemyFlags
+EnemySendOutFirstMon:
+ xor a
+ ld hl, wEnemyStatsToDouble ; clear enemy statuses
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wEnemyDisabledMove], a
+ ld [wEnemyDisabledMoveNumber], a
+ ld [wEnemyMonMinimized], a
+ ld hl, wPlayerUsedMove
+ ld [hli], a
+ ld [hl], a
+ dec a
+ ld [wAICount], a
+ ld hl, wPlayerBattleStatus1
+ res 5, [hl]
+ coord hl, 18, 0
+ ld a, 8
+ call SlideTrainerPicOffScreen
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .next
+ ld a, [wSerialExchangeNybbleReceiveData]
+ sub 4
+ ld [wWhichPokemon], a
+ jr .next3
+.next
+ ld b, $FF
+.next2
+ inc b
+ ld a, [wEnemyMonPartyPos]
+ cp b
+ jr z, .next2
+ ld hl, wEnemyMon1
+ ld a, b
+ ld [wWhichPokemon], a
+ push bc
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ pop bc
+ inc hl
+ ld a, [hli]
+ ld c, a
+ ld a, [hl]
+ or c
+ jr z, .next2
+.next3
+ ld a, [wWhichPokemon]
+ ld hl, wEnemyMon1Level
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [hl]
+ ld [wCurEnemyLVL], a
+ ld a, [wWhichPokemon]
+ inc a
+ ld hl, wEnemyPartyCount
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wEnemyMonSpecies2], a
+ ld [wcf91], a
+ call LoadEnemyMonData
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [wLastSwitchInEnemyMonHP], a
+ ld a, [hl]
+ ld [wLastSwitchInEnemyMonHP + 1], a
+ ld a, 1
+ ld [wCurrentMenuItem], a
+ ld a, [wFirstMonsNotOutYet]
+ dec a
+ jr z, .next4
+ ld a, [wPartyCount]
+ dec a
+ jr z, .next4
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .next4
+ ld a, [wOptions]
+ bit 6, a
+ jr nz, .next4
+ ld hl, TrainerAboutToUseText
+ call PrintText
+ coord hl, 0, 7
+ lb bc, 8, 1
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .next4
+ ld a, BATTLE_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call DisplayPartyMenu
+.next9
+ ld a, 1
+ ld [wCurrentMenuItem], a
+ jr c, .next7
+ ld hl, wPlayerMonNumber
+ ld a, [wWhichPokemon]
+ cp [hl]
+ jr nz, .next6
+ ld hl, AlreadyOutText
+ call PrintText
+.next8
+ call GoBackToPartyMenu
+ jr .next9
+.next6
+ call HasMonFainted
+ jr z, .next8
+ xor a
+ ld [wCurrentMenuItem], a
+.next7
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+.next4
+ call ClearSprites
+ coord hl, 0, 0
+ lb bc, 4, 11
+ call ClearScreenArea
+ ld b, SET_PAL_BATTLE
+ call RunPaletteCommand
+ call GBPalNormal
+ ld hl, TrainerSentOutText
+ call PrintText
+ ld a, [wEnemyMonSpecies2]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld de, vFrontPic
+ call LoadMonFrontSprite
+ ld a, -$31
+ ld [hStartTileID], a
+ coord hl, 15, 6
+ predef AnimateSendingOutMon
+ ld a, [wEnemyMonSpecies2]
+ call PlayCry
+ call DrawEnemyHUDAndHPBar
+ ld a, [wCurrentMenuItem]
+ and a
+ ret nz
+ xor a
+ ld [wPartyGainExpFlags], a
+ ld [wPartyFoughtCurrentEnemyFlags], a
+ call SaveScreenTilesToBuffer1
+ jp SwitchPlayerMon
+
+TrainerAboutToUseText:
+ TX_FAR _TrainerAboutToUseText
+ db "@"
+
+TrainerSentOutText:
+ TX_FAR _TrainerSentOutText
+ db "@"
+
+; tests if the player has any pokemon that are not fainted
+; sets d = 0 if all fainted, d != 0 if some mons are still alive
+AnyPartyAlive:
+ ld a, [wPartyCount]
+ ld e, a
+ xor a
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1 - 1
+.partyMonsLoop
+ or [hl]
+ inc hl
+ or [hl]
+ add hl, bc
+ dec e
+ jr nz, .partyMonsLoop
+ ld d, a
+ ret
+
+; tests if player mon has fainted
+; stores whether mon has fainted in Z flag
+HasMonFainted:
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ or [hl]
+ ret nz
+ ld a, [wFirstMonsNotOutYet]
+ and a
+ jr nz, .done
+ ld hl, NoWillText
+ call PrintText
+.done
+ xor a
+ ret
+
+NoWillText:
+ TX_FAR _NoWillText
+ db "@"
+
+; try to run from battle (hl = player speed, de = enemy speed)
+; stores whether the attempt was successful in carry flag
+TryRunningFromBattle:
+ call IsGhostBattle
+ jp z, .canEscape ; jump if it's a ghost battle
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jp z, .canEscape ; jump if it's a safari battle
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jp z, .canEscape
+ ld a, [wIsInBattle]
+ dec a
+ jr nz, .trainerBattle ; jump if it's a trainer battle
+ ld a, [wNumRunAttempts]
+ inc a
+ ld [wNumRunAttempts], a
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [de]
+ ld [hEnemySpeed], a
+ inc de
+ ld a, [de]
+ ld [hEnemySpeed + 1], a
+ call LoadScreenTilesFromBuffer1
+ ld de, H_MULTIPLICAND + 1
+ ld hl, hEnemySpeed
+ ld c, 2
+ call StringCmp
+ jr nc, .canEscape ; jump if player speed greater than enemy speed
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 32
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply player speed by 32
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
+ ld a, [hEnemySpeed]
+ ld b, a
+ ld a, [hEnemySpeed + 1]
+; divide enemy speed by 4
+ srl b
+ rr a
+ srl b
+ rr a
+ and a
+ jr z, .canEscape ; jump if enemy speed divided by 4, mod 256 is 0
+ ld [H_DIVISOR], a ; ((enemy speed / 4) % 256)
+ ld b, $2
+ call Divide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
+ ld a, [H_QUOTIENT + 2]
+ and a ; is the quotient greater than 256?
+ jr nz, .canEscape ; if so, the player can escape
+ ld a, [wNumRunAttempts]
+ ld c, a
+; add 30 to the quotient for each run attempt
+.loop
+ dec c
+ jr z, .compareWithRandomValue
+ ld b, 30
+ ld a, [H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3], a
+ jr c, .canEscape
+ jr .loop
+.compareWithRandomValue
+ call BattleRandom
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ cp b
+ jr nc, .canEscape ; if the random value was less than or equal to the quotient
+ ; plus 30 times the number of attempts, the player can escape
+; can't escape
+ ld a, $1
+ ld [wActionResultOrTookBattleTurn], a ; you lose your turn when you can't escape
+ ld hl, CantEscapeText
+ jr .printCantEscapeOrNoRunningText
+.trainerBattle
+ ld hl, NoRunningText
+.printCantEscapeOrNoRunningText
+ call PrintText
+ ld a, 1
+ ld [wForcePlayerToChooseMon], a
+ call SaveScreenTilesToBuffer1
+ and a ; reset carry
+ ret
+.canEscape
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ld a, $2
+ jr nz, .playSound
+; link battle
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wActionResultOrTookBattleTurn], a
+ ld a, LINKBATTLE_RUN
+ ld [wPlayerMoveListIndex], a
+ call LinkBattleExchangeData
+ call LoadScreenTilesFromBuffer1
+ ld a, [wSerialExchangeNybbleReceiveData]
+ cp LINKBATTLE_RUN
+ ld a, $2
+ jr z, .playSound
+ dec a
+.playSound
+ ld [wBattleResult], a
+ ld a, SFX_RUN
+ call PlaySoundWaitForCurrent
+ ld hl, GotAwayText
+ call PrintText
+ call WaitForSoundToFinish
+ call SaveScreenTilesToBuffer1
+ scf ; set carry
+ ret
+
+CantEscapeText:
+ TX_FAR _CantEscapeText
+ db "@"
+
+NoRunningText:
+ TX_FAR _NoRunningText
+ db "@"
+
+GotAwayText:
+ TX_FAR _GotAwayText
+ db "@"
+
+; copies from party data to battle mon data when sending out a new player mon
+LoadBattleMonFromParty:
+ ld a, [wWhichPokemon]
+ ld bc, wPartyMon2 - wPartyMon1
+ ld hl, wPartyMon1Species
+ call AddNTimes
+ ld de, wBattleMonSpecies
+ ld bc, wBattleMonDVs - wBattleMonSpecies
+ call CopyData
+ ld bc, wPartyMon1DVs - wPartyMon1OTID
+ add hl, bc
+ ld de, wBattleMonDVs
+ ld bc, NUM_DVS
+ call CopyData
+ ld de, wBattleMonPP
+ ld bc, NUM_MOVES
+ call CopyData
+ ld de, wBattleMonLevel
+ ld bc, wBattleMonPP - wBattleMonLevel
+ call CopyData
+ ld a, [wBattleMonSpecies2]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wPartyMonNicks
+ ld a, [wPlayerMonNumber]
+ call SkipFixedLengthTextEntries
+ ld de, wBattleMonNick
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wBattleMonLevel
+ ld de, wPlayerMonUnmodifiedLevel ; block of memory used for unmodified stats
+ ld bc, 1 + NUM_STATS * 2
+ call CopyData
+ call ApplyBurnAndParalysisPenaltiesToPlayer
+ call ApplyBadgeStatBoosts
+ ld a, $7 ; default stat modifier
+ ld b, NUM_STAT_MODS
+ ld hl, wPlayerMonAttackMod
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ret
+
+; copies from enemy party data to current enemy mon data when sending out a new enemy mon
+LoadEnemyMonFromParty:
+ ld a, [wWhichPokemon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ ld hl, wEnemyMons
+ call AddNTimes
+ ld de, wEnemyMonSpecies
+ ld bc, wEnemyMonDVs - wEnemyMonSpecies
+ call CopyData
+ ld bc, wEnemyMon1DVs - wEnemyMon1OTID
+ add hl, bc
+ ld de, wEnemyMonDVs
+ ld bc, NUM_DVS
+ call CopyData
+ ld de, wEnemyMonPP
+ ld bc, NUM_MOVES
+ call CopyData
+ ld de, wEnemyMonLevel
+ ld bc, wEnemyMonPP - wEnemyMonLevel
+ call CopyData
+ ld a, [wEnemyMonSpecies]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wEnemyMonNicks
+ ld a, [wWhichPokemon]
+ call SkipFixedLengthTextEntries
+ ld de, wEnemyMonNick
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel ; block of memory used for unmodified stats
+ ld bc, 1 + NUM_STATS * 2
+ call CopyData
+ call ApplyBurnAndParalysisPenaltiesToEnemy
+ ld hl, wMonHBaseStats
+ ld de, wEnemyMonBaseStats
+ ld b, NUM_STATS
+.copyBaseStatsLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyBaseStatsLoop
+ ld a, $7 ; default stat modifier
+ ld b, NUM_STAT_MODS
+ ld hl, wEnemyMonStatMods
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ld a, [wWhichPokemon]
+ ld [wEnemyMonPartyPos], a
+ ret
+
+SendOutMon:
+ callab PrintSendOutMonMessage
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ or [hl] ; is enemy mon HP zero?
+ jp z, .skipDrawingEnemyHUDAndHPBar; if HP is zero, skip drawing the HUD and HP bar
+ call DrawEnemyHUDAndHPBar
+.skipDrawingEnemyHUDAndHPBar
+ call DrawPlayerHUDAndHPBar
+ predef LoadMonBackPic
+ xor a
+ ld [hStartTileID], a
+ ld hl, wBattleAndStartSavedMenuItem
+ ld [hli], a
+ ld [hl], a
+ ld [wBoostExpByExpAll], a
+ ld [wDamageMultipliers], a
+ ld [wPlayerMoveNum], a
+ ld hl, wPlayerUsedMove
+ ld [hli], a
+ ld [hl], a
+ ld hl, wPlayerStatsToDouble
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerDisabledMove], a
+ ld [wPlayerDisabledMoveNumber], a
+ ld [wPlayerMonMinimized], a
+ ld b, SET_PAL_BATTLE
+ call RunPaletteCommand
+ ld hl, wEnemyBattleStatus1
+ res USING_TRAPPING_MOVE, [hl]
+ ld a, $1
+ ld [H_WHOSETURN], a
+ ld a, POOF_ANIM
+ call PlayMoveAnimation
+ coord hl, 4, 11
+ predef AnimateSendingOutMon
+ ld a, [wcf91]
+ call PlayCry
+ call PrintEmptyString
+ jp SaveScreenTilesToBuffer1
+
+; show 2 stages of the player mon getting smaller before disappearing
+AnimateRetreatingPlayerMon:
+ coord hl, 1, 5
+ lb bc, 7, 7
+ call ClearScreenArea
+ coord hl, 3, 7
+ lb bc, 5, 5
+ xor a
+ ld [wDownscaledMonSize], a
+ ld [hBaseTileID], a
+ predef CopyDownscaledMonTiles
+ ld c, 4
+ call DelayFrames
+ call .clearScreenArea
+ coord hl, 4, 9
+ lb bc, 3, 3
+ ld a, 1
+ ld [wDownscaledMonSize], a
+ xor a
+ ld [hBaseTileID], a
+ predef CopyDownscaledMonTiles
+ call Delay3
+ call .clearScreenArea
+ ld a, $4c
+ Coorda 5, 11
+.clearScreenArea
+ coord hl, 1, 5
+ lb bc, 7, 7
+ jp ClearScreenArea
+
+; reads player's current mon's HP into wBattleMonHP
+ReadPlayerMonCurHPAndStatus:
+ ld a, [wPlayerMonNumber]
+ ld hl, wPartyMon1HP
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, wBattleMonHP
+ ld bc, $4 ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
+ jp CopyData
+
+DrawHUDsAndHPBars:
+ call DrawPlayerHUDAndHPBar
+ jp DrawEnemyHUDAndHPBar
+
+DrawPlayerHUDAndHPBar:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 9, 7
+ lb bc, 5, 11
+ call ClearScreenArea
+ callab PlacePlayerHUDTiles
+ coord hl, 18, 9
+ ld [hl], $73
+ ld de, wBattleMonNick
+ coord hl, 10, 7
+ call CenterMonName
+ call PlaceString
+ ld hl, wBattleMonSpecies
+ ld de, wLoadedMon
+ ld bc, wBattleMonDVs - wBattleMonSpecies
+ call CopyData
+ ld hl, wBattleMonLevel
+ ld de, wLoadedMonLevel
+ ld bc, wBattleMonPP - wBattleMonLevel
+ call CopyData
+ coord hl, 14, 8
+ push hl
+ inc hl
+ ld de, wLoadedMonStatus
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .doNotPrintLevel
+ call PrintLevel
+.doNotPrintLevel
+ ld a, [wLoadedMonSpecies]
+ ld [wcf91], a
+ coord hl, 10, 9
+ predef DrawHP
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wPlayerHPBarColor
+ call GetBattleHealthBarColor
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ or [hl]
+ jr z, .fainted
+ ld a, [wLowHealthAlarmDisabled]
+ and a ; has the alarm been disabled because the player has already won?
+ ret nz ; if so, return
+ ld a, [wPlayerHPBarColor]
+ cp HP_BAR_RED
+ jr z, .setLowHealthAlarm
+.fainted
+ ld hl, wLowHealthAlarm
+ bit 7, [hl] ;low health alarm enabled?
+ ld [hl], $0
+ ret z
+ xor a
+ ld [wChannelSoundIDs + Ch4], a
+ ret
+.setLowHealthAlarm
+ ld hl, wLowHealthAlarm
+ set 7, [hl] ;enable low health alarm
+ ret
+
+DrawEnemyHUDAndHPBar:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 0, 0
+ lb bc, 4, 12
+ call ClearScreenArea
+ callab PlaceEnemyHUDTiles
+ ld de, wEnemyMonNick
+ coord hl, 1, 0
+ call CenterMonName
+ call PlaceString
+ coord hl, 4, 1
+ push hl
+ inc hl
+ ld de, wEnemyMonStatus
+ call PrintStatusConditionNotFainted
+ pop hl
+ jr nz, .skipPrintLevel ; if the mon has a status condition, skip printing the level
+ ld a, [wEnemyMonLevel]
+ ld [wLoadedMonLevel], a
+ call PrintLevel
+.skipPrintLevel
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hld]
+ ld [H_MULTIPLICAND + 2], a
+ or [hl] ; is current HP zero?
+ jr nz, .hpNonzero
+; current HP is 0
+; set variables for DrawHPBar
+ ld c, a
+ ld e, a
+ ld d, $6
+ jp .drawHPBar
+.hpNonzero
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, 48
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply current HP by 48
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld a, b
+ and a ; is max HP > 255?
+ jr z, .doDivide
+; if max HP > 255, scale both (current HP * 48) and max HP by dividing by 4 so that max HP fits in one byte
+; (it needs to be one byte so it can be used as the divisor for the Divide function)
+ ld a, [H_DIVISOR]
+ srl b
+ rr a
+ srl b
+ rr a
+ ld [H_DIVISOR], a
+ ld a, [H_PRODUCT + 2]
+ ld b, a
+ srl b
+ ld a, [H_PRODUCT + 3]
+ rr a
+ srl b
+ rr a
+ ld [H_PRODUCT + 3], a
+ ld a, b
+ ld [H_PRODUCT + 2], a
+.doDivide
+ ld a, [H_PRODUCT + 2]
+ ld [H_DIVIDEND], a
+ ld a, [H_PRODUCT + 3]
+ ld [H_DIVIDEND + 1], a
+ ld a, $2
+ ld b, a
+ call Divide ; divide (current HP * 48) by max HP
+ ld a, [H_QUOTIENT + 3]
+; set variables for DrawHPBar
+ ld e, a
+ ld a, $6
+ ld d, a
+ ld c, a
+.drawHPBar
+ xor a
+ ld [wHPBarType], a
+ coord hl, 2, 2
+ call DrawHPBar
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wEnemyHPBarColor
+
+GetBattleHealthBarColor:
+ ld b, [hl]
+ call GetHealthBarColor
+ ld a, [hl]
+ cp b
+ ret z
+ ld b, SET_PAL_BATTLE
+ jp RunPaletteCommand
+
+; center's mon's name on the battle screen
+; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual
+; (i.e. for names longer than 4 letters)
+; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual
+; (i.e. for names longer than 4 letters)
+CenterMonName:
+ push de
+ inc hl
+ inc hl
+ ld b, $2
+.loop
+ inc de
+ ld a, [de]
+ cp "@"
+ jr z, .done
+ inc de
+ ld a, [de]
+ cp "@"
+ jr z, .done
+ dec hl
+ dec b
+ jr nz, .loop
+.done
+ pop de
+ ret
+
+DisplayBattleMenu:
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ ld a, [wBattleType]
+ and a
+ jr nz, .nonstandardbattle
+ call DrawHUDsAndHPBars
+ call PrintEmptyString
+ call SaveScreenTilesToBuffer1
+.nonstandardbattle
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ ld a, BATTLE_MENU_TEMPLATE
+ jr nz, .menuselected
+ ld a, SAFARI_BATTLE_MENU_TEMPLATE
+.menuselected
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, [wBattleType]
+ dec a
+ jp nz, .handleBattleMenuInput ; handle menu input if it's not the old man tutorial
+; the following happens for the old man tutorial
+ ld hl, wPlayerName
+ ld de, wGrassRate
+ ld bc, NAME_LENGTH
+ call CopyData ; temporarily save the player name in unused space,
+ ; which is supposed to get overwritten when entering a
+ ; map with wild Pokémon. Due to an oversight, the data
+ ; may not get overwritten (cinnabar) and the infamous
+ ; Missingno. glitch can show up.
+ ld hl, .oldManName
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+; the following simulates the keystrokes by drawing menus on screen
+ coord hl, 9, 14
+ ld [hl], "▶"
+ ld c, 80
+ call DelayFrames
+ ld [hl], " "
+ coord hl, 9, 16
+ ld [hl], "▶"
+ ld c, 50
+ call DelayFrames
+ ld [hl], "▷"
+ ld a, $2 ; select the "ITEM" menu
+ jp .upperLeftMenuItemWasNotSelected
+.oldManName
+ db "OLD MAN@"
+.handleBattleMenuInput
+ ld a, [wBattleAndStartSavedMenuItem]
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ sub 2 ; check if the cursor is in the left column
+ jr c, .leftColumn
+; cursor is in the right column
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ jr .rightColumn
+.leftColumn ; put cursor in left column of menu
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ ld a, " "
+ jr z, .safariLeftColumn
+; put cursor in left column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 15, 14 ; clear upper cursor position in right column
+ Coorda 15, 16 ; clear lower cursor position in right column
+ ld b, $9 ; top menu item X
+ jr .leftColumn_WaitForInput
+.safariLeftColumn
+ Coorda 13, 14
+ Coorda 13, 16
+ coord hl, 7, 14
+ ld de, wNumSafariBalls
+ lb bc, 1, 2
+ call PrintNumber
+ ld b, $1 ; top menu item X
+.leftColumn_WaitForInput
+ ld hl, wTopMenuItemY
+ ld a, $e
+ ld [hli], a ; wTopMenuItemY
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a ; wMaxMenuItem
+ ld [hl], D_RIGHT | A_BUTTON ; wMenuWatchedKeys
+ call HandleMenuInput
+ bit 4, a ; check if right was pressed
+ jr nz, .rightColumn
+ jr .AButtonPressed ; the A button was pressed
+.rightColumn ; put cursor in right column of menu
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ ld a, " "
+ jr z, .safariRightColumn
+; put cursor in right column for normal battle menu (i.e. when it's not a Safari battle)
+ Coorda 9, 14 ; clear upper cursor position in left column
+ Coorda 9, 16 ; clear lower cursor position in left column
+ ld b, $f ; top menu item X
+ jr .rightColumn_WaitForInput
+.safariRightColumn
+ Coorda 1, 14 ; clear upper cursor position in left column
+ Coorda 1, 16 ; clear lower cursor position in left column
+ coord hl, 7, 14
+ ld de, wNumSafariBalls
+ lb bc, 1, 2
+ call PrintNumber
+ ld b, $d ; top menu item X
+.rightColumn_WaitForInput
+ ld hl, wTopMenuItemY
+ ld a, $e
+ ld [hli], a ; wTopMenuItemY
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, $1
+ ld [hli], a ; wMaxMenuItem
+ ld a, D_LEFT | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ call HandleMenuInput
+ bit 5, a ; check if left was pressed
+ jr nz, .leftColumn ; if left was pressed, jump
+ ld a, [wCurrentMenuItem]
+ add $2 ; if we're in the right column, the actual id is +2
+ ld [wCurrentMenuItem], a
+.AButtonPressed
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ ld a, [wCurrentMenuItem]
+ ld [wBattleAndStartSavedMenuItem], a
+ jr z, .handleMenuSelection
+; not Safari battle
+; swap the IDs of the item menu and party menu (this is probably because they swapped the positions
+; of these menu items in first generation English versions)
+ cp $1 ; was the item menu selected?
+ jr nz, .notItemMenu
+; item menu was selected
+ inc a ; increment a to 2
+ jr .handleMenuSelection
+.notItemMenu
+ cp $2 ; was the party menu selected?
+ jr nz, .handleMenuSelection
+; party menu selected
+ dec a ; decrement a to 1
+.handleMenuSelection
+ and a
+ jr nz, .upperLeftMenuItemWasNotSelected
+; the upper left menu item was selected
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr z, .throwSafariBallWasSelected
+; the "FIGHT" menu was selected
+ xor a
+ ld [wNumRunAttempts], a
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen and return
+.throwSafariBallWasSelected
+ ld a, SAFARI_BALL
+ ld [wcf91], a
+ jr UseBagItem
+
+.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
+ cp $2
+ jp nz, PartyMenuOrRockOrRun
+
+; either the bag (normal battle) or bait (safari battle) was selected
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .notLinkBattle
+
+; can't use items in link battles
+ ld hl, ItemsCantBeUsedHereText
+ call PrintText
+ jp DisplayBattleMenu
+
+.notLinkBattle
+ call SaveScreenTilesToBuffer2
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr nz, BagWasSelected
+
+; bait was selected
+ ld a, SAFARI_BAIT
+ ld [wcf91], a
+ jr UseBagItem
+
+BagWasSelected:
+ call LoadScreenTilesFromBuffer1
+ ld a, [wBattleType]
+ and a ; is it a normal battle?
+ jr nz, .next
+
+; normal battle
+ call DrawHUDsAndHPBars
+.next
+ ld a, [wBattleType]
+ dec a ; is it the old man tutorial?
+ jr nz, DisplayPlayerBag ; no, it is a normal battle
+ ld hl, OldManItemList
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ jr DisplayBagMenu
+
+OldManItemList:
+ db 1 ; # items
+ db POKE_BALL, 50
+ db -1
+
+DisplayPlayerBag:
+ ; get the pointer to player's bag when in a normal battle
+ ld hl, wNumBagItems
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+
+DisplayBagMenu:
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ ld a, [wBagSavedMenuItem]
+ ld [wCurrentMenuItem], a
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem]
+ ld [wBagSavedMenuItem], a
+ ld a, $0
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld [wMenuItemToSwap], a
+ jp c, DisplayBattleMenu ; go back to battle menu if an item was not selected
+
+UseBagItem:
+ ; either use an item from the bag or use a safari zone item
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name
+ xor a
+ ld [wPseudoItemID], a
+ call UseItem
+ call LoadHudTilePatterns
+ call ClearSprites
+ xor a
+ ld [wCurrentMenuItem], a
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr z, .checkIfMonCaptured
+
+ ld a, [wActionResultOrTookBattleTurn]
+ and a ; was the item used successfully?
+ jp z, BagWasSelected ; if not, go back to the bag menu
+
+ ld a, [wPlayerBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; is the player using a multi-turn move like wrap?
+ jr z, .checkIfMonCaptured
+ ld hl, wPlayerNumAttacksLeft
+ dec [hl]
+ jr nz, .checkIfMonCaptured
+ ld hl, wPlayerBattleStatus1
+ res USING_TRAPPING_MOVE, [hl] ; not using multi-turn move any more
+
+.checkIfMonCaptured
+ ld a, [wCapturedMonSpecies]
+ and a ; was the enemy mon captured with a ball?
+ jr nz, .returnAfterCapturingMon
+
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr z, .returnAfterUsingItem_NoCapture
+; not a safari battle
+ call LoadScreenTilesFromBuffer1
+ call DrawHUDsAndHPBars
+ call Delay3
+.returnAfterUsingItem_NoCapture
+
+ call GBPalNormal
+ and a ; reset carry
+ ret
+
+.returnAfterCapturingMon
+ call GBPalNormal
+ xor a
+ ld [wCapturedMonSpecies], a
+ ld a, $2
+ ld [wBattleResult], a
+ scf ; set carry
+ ret
+
+ItemsCantBeUsedHereText:
+ TX_FAR _ItemsCantBeUsedHereText
+ db "@"
+
+PartyMenuOrRockOrRun:
+ dec a ; was Run selected?
+ jp nz, BattleMenu_RunWasSelected
+; party menu or rock was selected
+ call SaveScreenTilesToBuffer2
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr nz, .partyMenuWasSelected
+; safari battle
+ ld a, SAFARI_ROCK
+ ld [wcf91], a
+ jp UseBagItem
+.partyMenuWasSelected
+ call LoadScreenTilesFromBuffer1
+ xor a ; NORMAL_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ ld [wMenuItemToSwap], a
+ call DisplayPartyMenu
+.checkIfPartyMonWasSelected
+ jp nc, .partyMonWasSelected ; if a party mon was selected, jump, else we quit the party menu
+.quitPartyMenu
+ call ClearSprites
+ call GBPalWhiteOut
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer2
+ call RunDefaultPaletteCommand
+ call GBPalNormal
+ jp DisplayBattleMenu
+.partyMonDeselected
+ coord hl, 11, 11
+ ld bc, 6 * SCREEN_WIDTH + 9
+ ld a, " "
+ call FillMemory
+ xor a ; NORMAL_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call GoBackToPartyMenu
+ jr .checkIfPartyMonWasSelected
+.partyMonWasSelected
+ ld a, SWITCH_STATS_CANCEL_MENU_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld hl, wTopMenuItemY
+ ld a, $c
+ ld [hli], a ; wTopMenuItemY
+ ld [hli], a ; wTopMenuItemX
+ xor a
+ ld [hli], a ; wCurrentMenuItem
+ inc hl
+ ld a, $2
+ ld [hli], a ; wMaxMenuItem
+ ld a, B_BUTTON | A_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hl], a ; wLastMenuItem
+ call HandleMenuInput
+ bit 1, a ; was A pressed?
+ jr nz, .partyMonDeselected ; if B was pressed, jump
+; A was pressed
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem]
+ cp $2 ; was Cancel selected?
+ jr z, .quitPartyMenu ; if so, quit the party menu entirely
+ and a ; was Switch selected?
+ jr z, .switchMon ; if so, jump
+; Stats was selected
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ ld hl, wPartyMon1
+ call ClearSprites
+; display the two status screens
+ predef StatusScreen
+ predef StatusScreen2
+; now we need to reload the enemy mon pic
+ ld a, [wEnemyBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a ; does the enemy mon have a substitute?
+ ld hl, AnimationSubstitute
+ jr nz, .doEnemyMonAnimation
+; enemy mon doesn't have substitute
+ ld a, [wEnemyMonMinimized]
+ and a ; has the enemy mon used Minimise?
+ ld hl, AnimationMinimizeMon
+ jr nz, .doEnemyMonAnimation
+; enemy mon is not minimised
+ ld a, [wEnemyMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld de, vFrontPic
+ call LoadMonFrontSprite
+ jr .enemyMonPicReloaded
+.doEnemyMonAnimation
+ ld b, BANK(AnimationSubstitute) ; BANK(AnimationMinimizeMon)
+ call Bankswitch
+.enemyMonPicReloaded ; enemy mon pic has been reloaded, so return to the party menu
+ jp .partyMenuWasSelected
+.switchMon
+ ld a, [wPlayerMonNumber]
+ ld d, a
+ ld a, [wWhichPokemon]
+ cp d ; check if the mon to switch to is already out
+ jr nz, .notAlreadyOut
+; mon is already out
+ ld hl, AlreadyOutText
+ call PrintText
+ jp .partyMonDeselected
+.notAlreadyOut
+ call HasMonFainted
+ jp z, .partyMonDeselected ; can't switch to fainted mon
+ ld a, $1
+ ld [wActionResultOrTookBattleTurn], a
+ call GBPalWhiteOut
+ call ClearSprites
+ call LoadHudTilePatterns
+ call LoadScreenTilesFromBuffer1
+ call RunDefaultPaletteCommand
+ call GBPalNormal
+; fall through to SwitchPlayerMon
+
+SwitchPlayerMon:
+ callab RetreatMon
+ ld c, 50
+ call DelayFrames
+ call AnimateRetreatingPlayerMon
+ ld a, [wWhichPokemon]
+ ld [wPlayerMonNumber], a
+ ld c, a
+ ld b, FLAG_SET
+ push bc
+ ld hl, wPartyGainExpFlags
+ predef FlagActionPredef
+ pop bc
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ predef FlagActionPredef
+ call LoadBattleMonFromParty
+ call SendOutMon
+ call SaveScreenTilesToBuffer1
+ ld a, $2
+ ld [wCurrentMenuItem], a
+ and a
+ ret
+
+AlreadyOutText:
+ TX_FAR _AlreadyOutText
+ db "@"
+
+BattleMenu_RunWasSelected:
+ call LoadScreenTilesFromBuffer1
+ ld a, $3
+ ld [wCurrentMenuItem], a
+ ld hl, wBattleMonSpeed
+ ld de, wEnemyMonSpeed
+ call TryRunningFromBattle
+ ld a, 0
+ ld [wForcePlayerToChooseMon], a
+ ret c
+ ld a, [wActionResultOrTookBattleTurn]
+ and a
+ ret nz ; return if the player couldn't escape
+ jp DisplayBattleMenu
+
+MoveSelectionMenu:
+ ld a, [wMoveMenuType]
+ dec a
+ jr z, .mimicmenu
+ dec a
+ jr z, .relearnmenu
+ jr .regularmenu
+
+.loadmoves
+ ld de, wMoves
+ ld bc, NUM_MOVES
+ call CopyData
+ callab FormatMovesString
+ ret
+
+.writemoves
+ ld de, wMovesString
+ ld a, [hFlags_0xFFF6]
+ set 2, a
+ ld [hFlags_0xFFF6], a
+ call PlaceString
+ ld a, [hFlags_0xFFF6]
+ res 2, a
+ ld [hFlags_0xFFF6], a
+ ret
+
+.regularmenu
+ call AnyMoveToSelect
+ ret z
+ ld hl, wBattleMonMoves
+ call .loadmoves
+ coord hl, 4, 12
+ ld b, 4
+ ld c, 14
+ di ; out of pure coincidence, it is possible for vblank to occur between the di and ei
+ ; so it is necessary to put the di ei block to not cause tearing
+ call TextBoxBorder
+ coord hl, 4, 12
+ ld [hl], $7a
+ coord hl, 10, 12
+ ld [hl], $7e
+ ei
+ coord hl, 6, 13
+ call .writemoves
+ ld b, $5
+ ld a, $c
+ jr .menuset
+.mimicmenu
+ ld hl, wEnemyMonMoves
+ call .loadmoves
+ coord hl, 0, 7
+ ld b, 4
+ ld c, 14
+ call TextBoxBorder
+ coord hl, 2, 8
+ call .writemoves
+ ld b, $1
+ ld a, $7
+ jr .menuset
+.relearnmenu
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ call .loadmoves
+ coord hl, 4, 7
+ ld b, 4
+ ld c, 14
+ call TextBoxBorder
+ coord hl, 6, 8
+ call .writemoves
+ ld b, $5
+ ld a, $7
+.menuset
+ ld hl, wTopMenuItemY
+ ld [hli], a ; wTopMenuItemY
+ ld a, b
+ ld [hli], a ; wTopMenuItemX
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .selectedmoveknown
+ ld a, $1
+ jr nc, .selectedmoveknown
+ ld a, [wPlayerMoveListIndex]
+ inc a
+.selectedmoveknown
+ ld [hli], a ; wCurrentMenuItem
+ inc hl ; wTileBehindCursor untouched
+ ld a, [wNumMovesMinusOne]
+ inc a
+ inc a
+ ld [hli], a ; wMaxMenuItem
+ ld a, [wMoveMenuType]
+ dec a
+ ld b, D_UP | D_DOWN | A_BUTTON
+ jr z, .matchedkeyspicked
+ dec a
+ ld b, D_UP | D_DOWN | A_BUTTON | B_BUTTON
+ jr z, .matchedkeyspicked
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .matchedkeyspicked
+ ld a, [wFlags_D733]
+ bit BIT_TEST_BATTLE, a
+ ld b, D_UP | D_DOWN | A_BUTTON | B_BUTTON | SELECT
+ jr z, .matchedkeyspicked
+ ld b, $ff
+.matchedkeyspicked
+ ld a, b
+ ld [hli], a ; wMenuWatchedKeys
+ ld a, [wMoveMenuType]
+ cp $1
+ jr z, .movelistindex1
+ ld a, [wPlayerMoveListIndex]
+ inc a
+.movelistindex1
+ ld [hl], a
+; fallthrough
+
+SelectMenuItem:
+ ld a, [wMoveMenuType]
+ and a
+ jr z, .battleselect
+ dec a
+ jr nz, .select
+ coord hl, 1, 14
+ ld de, WhichTechniqueString
+ call PlaceString
+ jr .select
+.battleselect
+ ld a, [wFlags_D733]
+ bit BIT_TEST_BATTLE, a
+ jr nz, .select
+ call PrintMenuItem
+ ld a, [wMenuItemToSwap]
+ and a
+ jr z, .select
+ coord hl, 5, 13
+ dec a
+ ld bc, SCREEN_WIDTH
+ call AddNTimes
+ ld [hl], "▷"
+.select
+ ld hl, hFlags_0xFFF6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, hFlags_0xFFF6
+ res 1, [hl]
+ bit 6, a
+ jp nz, SelectMenuItem_CursorUp ; up
+ bit 7, a
+ jp nz, SelectMenuItem_CursorDown ; down
+ bit 2, a
+ jp nz, SwapMovesInMenu ; select
+ bit 1, a ; B, but was it reset above?
+ push af
+ xor a
+ ld [wMenuItemToSwap], a
+ ld a, [wCurrentMenuItem]
+ dec a
+ ld [wCurrentMenuItem], a
+ ld b, a
+ ld a, [wMoveMenuType]
+ dec a ; if not mimic
+ jr nz, .notB
+ pop af
+ ret
+.notB
+ dec a
+ ld a, b
+ ld [wPlayerMoveListIndex], a
+ jr nz, .moveselected
+ pop af
+ ret
+.moveselected
+ pop af
+ ret nz
+ ld hl, wBattleMonPP
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ jr z, .noPP
+ ld a, [wPlayerDisabledMove]
+ swap a
+ and $f
+ dec a
+ cp c
+ jr z, .disabled
+ ld a, [wPlayerBattleStatus3]
+ bit 3, a ; transformed
+ jr nz, .dummy ; game freak derp
+.dummy
+ ld a, [wCurrentMenuItem]
+ ld hl, wBattleMonMoves
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a
+ xor a
+ ret
+.disabled
+ ld hl, MoveDisabledText
+ jr .print
+.noPP
+ ld hl, MoveNoPPText
+.print
+ call PrintText
+ call LoadScreenTilesFromBuffer1
+ jp MoveSelectionMenu
+
+MoveNoPPText:
+ TX_FAR _MoveNoPPText
+ db "@"
+
+MoveDisabledText:
+ TX_FAR _MoveDisabledText
+ db "@"
+
+WhichTechniqueString:
+ db "WHICH TECHNIQUE?@"
+
+SelectMenuItem_CursorUp:
+ ld a, [wCurrentMenuItem]
+ and a
+ jp nz, SelectMenuItem
+ call EraseMenuCursor
+ ld a, [wNumMovesMinusOne]
+ inc a
+ ld [wCurrentMenuItem], a
+ jp SelectMenuItem
+
+SelectMenuItem_CursorDown:
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wNumMovesMinusOne]
+ inc a
+ inc a
+ cp b
+ jp nz, SelectMenuItem
+ call EraseMenuCursor
+ ld a, $1
+ ld [wCurrentMenuItem], a
+ jp SelectMenuItem
+
+AnyMoveToSelect:
+; return z and Struggle as the selected move if all moves have 0 PP and/or are disabled
+ ld a, STRUGGLE
+ ld [wPlayerSelectedMove], a
+ ld a, [wPlayerDisabledMove]
+ and a
+ ld hl, wBattleMonPP
+ jr nz, .handleDisabledMove
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ or [hl]
+ and $3f
+ ret nz
+ jr .noMovesLeft
+.handleDisabledMove
+ swap a
+ and $f ; get disabled move
+ ld b, a
+ ld d, NUM_MOVES + 1
+ xor a
+.handleDisabledMovePPLoop
+ dec d
+ jr z, .allMovesChecked
+ ld c, [hl] ; get move PP
+ inc hl
+ dec b ; is this the disabled move?
+ jr z, .handleDisabledMovePPLoop ; if so, ignore its PP value
+ or c
+ jr .handleDisabledMovePPLoop
+.allMovesChecked
+ and a ; any PP left?
+ ret nz ; return if a move has PP left
+.noMovesLeft
+ ld hl, NoMovesLeftText
+ call PrintText
+ ld c, 60
+ call DelayFrames
+ xor a
+ ret
+
+NoMovesLeftText:
+ TX_FAR _NoMovesLeftText
+ db "@"
+
+SwapMovesInMenu:
+ ld a, [wMenuItemToSwap]
+ and a
+ jr z, .noMenuItemSelected
+ ld hl, wBattleMonMoves
+ call .swapBytes ; swap moves
+ ld hl, wBattleMonPP
+ call .swapBytes ; swap move PP
+; update the index of the disabled move if necessary
+ ld hl, wPlayerDisabledMove
+ ld a, [hl]
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp b
+ jr nz, .next
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wMenuItemToSwap]
+ swap a
+ add b
+ ld [hl], a
+ jr .swapMovesInPartyMon
+.next
+ ld a, [wMenuItemToSwap]
+ cp b
+ jr nz, .swapMovesInPartyMon
+ ld a, [hl]
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ swap a
+ add b
+ ld [hl], a
+.swapMovesInPartyMon
+ ld hl, wPartyMon1Moves
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ push hl
+ call .swapBytes ; swap moves
+ pop hl
+ ld bc, wPartyMon1PP - wPartyMon1Moves
+ add hl, bc
+ call .swapBytes ; swap move PP
+ xor a
+ ld [wMenuItemToSwap], a ; deselect the item
+ jp MoveSelectionMenu
+.swapBytes
+ push hl
+ ld a, [wMenuItemToSwap]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wCurrentMenuItem]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [de]
+ ld b, [hl]
+ ld [hl], a
+ ld a, b
+ ld [de], a
+ ret
+.noMenuItemSelected
+ ld a, [wCurrentMenuItem]
+ ld [wMenuItemToSwap], a ; select the current menu item for swapping
+ jp MoveSelectionMenu
+
+PrintMenuItem:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 0, 8
+ ld b, 3
+ ld c, 9
+ call TextBoxBorder
+ ld a, [wPlayerDisabledMove]
+ and a
+ jr z, .notDisabled
+ swap a
+ and $f
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp b
+ jr nz, .notDisabled
+ coord hl, 1, 10
+ ld de, DisabledText
+ call PlaceString
+ jr .moveDisabled
+.notDisabled
+ ld hl, wCurrentMenuItem
+ dec [hl]
+ xor a
+ ld [H_WHOSETURN], a
+ ld hl, wBattleMonMoves
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0 ; which item in the menu is the cursor pointing to? (0-3)
+ add hl, bc ; point to the item (move) in memory
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a ; update wPlayerSelectedMove even if the move
+ ; isn't actually selected (just pointed to by the cursor)
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ ld a, BATTLE_MON_DATA
+ ld [wMonDataLocation], a
+ callab GetMaxPP
+ ld hl, wCurrentMenuItem
+ ld c, [hl]
+ inc [hl]
+ ld b, $0
+ ld hl, wBattleMonPP
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [wcd6d], a
+; print TYPE/<type> and <curPP>/<maxPP>
+ coord hl, 1, 9
+ ld de, TypeText
+ call PlaceString
+ coord hl, 7, 11
+ ld [hl], "/"
+ coord hl, 5, 9
+ ld [hl], "/"
+ coord hl, 5, 11
+ ld de, wcd6d
+ lb bc, 1, 2
+ call PrintNumber
+ coord hl, 8, 11
+ ld de, wMaxPP
+ lb bc, 1, 2
+ call PrintNumber
+ call GetCurrentMove
+ coord hl, 2, 10
+ predef PrintMoveType
+.moveDisabled
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ jp Delay3
+
+DisabledText:
+ db "disabled!@"
+
+TypeText:
+ db "TYPE@"
+
+SelectEnemyMove:
+ ld a, [wLinkState]
+ sub LINK_STATE_BATTLING
+ jr nz, .noLinkBattle
+; link battle
+ call SaveScreenTilesToBuffer1
+ call LinkBattleExchangeData
+ call LoadScreenTilesFromBuffer1
+ ld a, [wSerialExchangeNybbleReceiveData]
+ cp LINKBATTLE_STRUGGLE
+ jp z, .linkedOpponentUsedStruggle
+ cp LINKBATTLE_NO_ACTION
+ jr z, .unableToSelectMove
+ cp 4
+ ret nc
+ ld [wEnemyMoveListIndex], a
+ ld c, a
+ ld hl, wEnemyMonMoves
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ jr .done
+.noLinkBattle
+ ld a, [wEnemyBattleStatus2]
+ and (1 << NEEDS_TO_RECHARGE) | (1 << USING_RAGE) ; need to recharge or using rage
+ ret nz
+ ld hl, wEnemyBattleStatus1
+ ld a, [hl]
+ and (1 << CHARGING_UP) | (1 << THRASHING_ABOUT) ; using a charging move or thrash/petal dance
+ ret nz
+ ld a, [wEnemyMonStatus]
+ and SLP | 1 << FRZ ; sleeping or frozen
+ ret nz
+ ld a, [wEnemyBattleStatus1]
+ and (1 << USING_TRAPPING_MOVE) | (1 << STORING_ENERGY) ; using a trapping move like wrap or bide
+ ret nz
+ ld a, [wPlayerBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; caught in player's trapping move (e.g. wrap)
+ jr z, .canSelectMove
+.unableToSelectMove
+ ld a, $ff
+ jr .done
+.canSelectMove
+ ld hl, wEnemyMonMoves+1 ; 2nd enemy move
+ ld a, [hld]
+ and a
+ jr nz, .atLeastTwoMovesAvailable
+ ld a, [wEnemyDisabledMove]
+ and a
+ ld a, STRUGGLE ; struggle if the only move is disabled
+ jr nz, .done
+.atLeastTwoMovesAvailable
+ ld a, [wIsInBattle]
+ dec a
+ jr z, .chooseRandomMove ; wild encounter
+ callab AIEnemyTrainerChooseMoves
+.chooseRandomMove
+ push hl
+ call BattleRandom
+ ld b, $1
+ cp $3f ; select move 1, [0,3e] (63/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b
+ cp $7f ; select move 2, [3f,7e] (64/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b
+ cp $be ; select move 3, [7f,bd] (63/256 chance)
+ jr c, .moveChosen
+ inc hl
+ inc b ; select move 4, [be,ff] (66/256 chance)
+.moveChosen
+ ld a, b
+ dec a
+ ld [wEnemyMoveListIndex], a
+ ld a, [wEnemyDisabledMove]
+ swap a
+ and $f
+ cp b
+ ld a, [hl]
+ pop hl
+ jr z, .chooseRandomMove ; move disabled, try again
+ and a
+ jr z, .chooseRandomMove ; move non-existant, try again
+.done
+ ld [wEnemySelectedMove], a
+ ret
+.linkedOpponentUsedStruggle
+ ld a, STRUGGLE
+ jr .done
+
+; this appears to exchange data with the other gameboy during link battles
+LinkBattleExchangeData:
+ ld a, $ff
+ ld [wSerialExchangeNybbleReceiveData], a
+ ld a, [wPlayerMoveListIndex]
+ cp LINKBATTLE_RUN ; is the player running from battle?
+ jr z, .doExchange
+ ld a, [wActionResultOrTookBattleTurn]
+ and a ; is the player switching in another mon?
+ jr nz, .switching
+; the player used a move
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
+ ld b, LINKBATTLE_STRUGGLE
+ jr z, .next
+ dec b ; LINKBATTLE_NO_ACTION
+ inc a ; does move equal -1 (i.e. no action)?
+ jr z, .next
+ ld a, [wPlayerMoveListIndex]
+ jr .doExchange
+.switching
+ ld a, [wWhichPokemon]
+ add 4
+ ld b, a
+.next
+ ld a, b
+.doExchange
+ ld [wSerialExchangeNybbleSendData], a
+ callab PrintWaitingText
+.syncLoop1
+ call Serial_ExchangeNybble
+ call DelayFrame
+ ld a, [wSerialExchangeNybbleReceiveData]
+ inc a
+ jr z, .syncLoop1
+ ld b, 10
+.syncLoop2
+ call DelayFrame
+ call Serial_ExchangeNybble
+ dec b
+ jr nz, .syncLoop2
+ ld b, 10
+.syncLoop3
+ call DelayFrame
+ call Serial_SendZeroByte
+ dec b
+ jr nz, .syncLoop3
+ ret
+
+ExecutePlayerMove:
+ xor a
+ ld [H_WHOSETURN], a ; set player's turn
+ ld a, [wPlayerSelectedMove]
+ inc a
+ jp z, ExecutePlayerMoveDone ; for selected move = FF, skip most of player's turn
+ xor a
+ ld [wMoveMissed], a
+ ld [wMonIsDisobedient], a
+ ld [wMoveDidntMiss], a
+ ld a, $a
+ ld [wDamageMultipliers], a
+ ld a, [wActionResultOrTookBattleTurn]
+ and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon)
+ jp nz, ExecutePlayerMoveDone
+ call PrintGhostText
+ jp z, ExecutePlayerMoveDone
+ call CheckPlayerStatusConditions
+ jr nz, .playerHasNoSpecialCondition
+ jp hl
+.playerHasNoSpecialCondition
+ call GetCurrentMove
+ ld hl, wPlayerBattleStatus1
+ bit CHARGING_UP, [hl] ; charging up for attack
+ jr nz, PlayerCanExecuteChargingMove
+ call CheckForDisobedience
+ jp z, ExecutePlayerMoveDone
+
+CheckIfPlayerNeedsToChargeUp:
+ ld a, [wPlayerMoveEffect]
+ cp CHARGE_EFFECT
+ jp z, JumpMoveEffect
+ cp FLY_EFFECT
+ jp z, JumpMoveEffect
+ jr PlayerCanExecuteMove
+
+; in-battle stuff
+PlayerCanExecuteChargingMove:
+ ld hl, wPlayerBattleStatus1
+ res CHARGING_UP, [hl] ; reset charging up and invulnerability statuses if mon was charging up for an attack
+ ; being fully paralyzed or hurting oneself in confusion removes charging up status
+ ; resulting in the Pokemon being invulnerable for the whole battle
+ res INVULNERABLE, [hl]
+PlayerCanExecuteMove:
+ call PrintMonName1Text
+ ld hl, DecrementPP
+ ld de, wPlayerSelectedMove ; pointer to the move just used
+ ld b, BANK(DecrementPP)
+ call Bankswitch
+ ld a, [wPlayerMoveEffect] ; effect of the move just used
+ ld hl, ResidualEffects1
+ ld de, 1
+ call IsInArray
+ jp c, JumpMoveEffect ; ResidualEffects1 moves skip damage calculation and accuracy tests
+ ; unless executed as part of their exclusive effect functions
+ ld a, [wPlayerMoveEffect]
+ ld hl, SpecialEffectsCont
+ ld de, 1
+ call IsInArray
+ call c, JumpMoveEffect ; execute the effects of SpecialEffectsCont moves (e.g. Wrap, Thrash) but don't skip anything
+PlayerCalcMoveDamage:
+ ld a, [wPlayerMoveEffect]
+ ld hl, SetDamageEffects
+ ld de, 1
+ call IsInArray
+ jp c, .moveHitTest ; SetDamageEffects moves (e.g. Seismic Toss and Super Fang) skip damage calculation
+ call CriticalHitTest
+ call HandleCounterMove
+ jr z, handleIfPlayerMoveMissed
+ call GetDamageVarsForPlayerAttack
+ call CalculateDamage
+ jp z, playerCheckIfFlyOrChargeEffect ; for moves with 0 BP, skip any further damage calculation and, for now, skip MoveHitTest
+ ; for these moves, accuracy tests will only occur if they are called as part of the effect itself
+ call AdjustDamageForMoveType
+ call RandomizeDamage
+.moveHitTest
+ call MoveHitTest
+handleIfPlayerMoveMissed:
+ ld a, [wMoveMissed]
+ and a
+ jr z, getPlayerAnimationType
+ ld a, [wPlayerMoveEffect]
+ sub EXPLODE_EFFECT
+ jr z, playPlayerMoveAnimation ; don't play any animation if the move missed, unless it was EXPLODE_EFFECT
+ jr playerCheckIfFlyOrChargeEffect
+getPlayerAnimationType:
+ ld a, [wPlayerMoveEffect]
+ and a
+ ld a, 4 ; move has no effect other than dealing damage
+ jr z, playPlayerMoveAnimation
+ ld a, 5 ; move has effect
+playPlayerMoveAnimation:
+ push af
+ ld a, [wPlayerBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ pop af
+ ld [wAnimationType], a
+ ld a, [wPlayerMoveNum]
+ call PlayMoveAnimation
+ call HandleExplodingAnimation
+ call DrawPlayerHUDAndHPBar
+ ld a, [wPlayerBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ call nz, Bankswitch
+ jr MirrorMoveCheck
+playerCheckIfFlyOrChargeEffect:
+ ld c, 30
+ call DelayFrames
+ ld a, [wPlayerMoveEffect]
+ cp FLY_EFFECT
+ jr z, .playAnim
+ cp CHARGE_EFFECT
+ jr z, .playAnim
+ jr MirrorMoveCheck
+.playAnim
+ xor a
+ ld [wAnimationType], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+MirrorMoveCheck:
+ ld a, [wPlayerMoveEffect]
+ cp MIRROR_MOVE_EFFECT
+ jr nz, .metronomeCheck
+ call MirrorMoveCopyMove
+ jp z, ExecutePlayerMoveDone
+ xor a
+ ld [wMonIsDisobedient], a
+ jp CheckIfPlayerNeedsToChargeUp ; if Mirror Move was successful go back to damage calculation for copied move
+.metronomeCheck
+ cp METRONOME_EFFECT
+ jr nz, .next
+ call MetronomePickMove
+ jp CheckIfPlayerNeedsToChargeUp ; Go back to damage calculation for the move picked by Metronome
+.next
+ ld a, [wPlayerMoveEffect]
+ ld hl, ResidualEffects2
+ ld de, 1
+ call IsInArray
+ jp c, JumpMoveEffect ; done here after executing effects of ResidualEffects2
+ ld a, [wMoveMissed]
+ and a
+ jr z, .moveDidNotMiss
+ call PrintMoveFailureText
+ ld a, [wPlayerMoveEffect]
+ cp EXPLODE_EFFECT ; even if Explosion or Selfdestruct missed, its effect still needs to be activated
+ jr z, .notDone
+ jp ExecutePlayerMoveDone ; otherwise, we're done if the move missed
+.moveDidNotMiss
+ call ApplyAttackToEnemyPokemon
+ call PrintCriticalOHKOText
+ callab DisplayEffectiveness
+ ld a, 1
+ ld [wMoveDidntMiss], a
+.notDone
+ ld a, [wPlayerMoveEffect]
+ ld hl, AlwaysHappenSideEffects
+ ld de, 1
+ call IsInArray
+ call c, JumpMoveEffect ; not done after executing effects of AlwaysHappenSideEffects
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld b, [hl]
+ or b
+ ret z ; don't do anything else if the enemy fainted
+ call HandleBuildingRage
+
+ ld hl, wPlayerBattleStatus1
+ bit ATTACKING_MULTIPLE_TIMES, [hl]
+ jr z, .executeOtherEffects
+ ld a, [wPlayerNumAttacksLeft]
+ dec a
+ ld [wPlayerNumAttacksLeft], a
+ jp nz, getPlayerAnimationType ; for multi-hit moves, apply attack until PlayerNumAttacksLeft hits 0 or the enemy faints.
+ ; damage calculation and accuracy tests only happen for the first hit
+ res ATTACKING_MULTIPLE_TIMES, [hl] ; clear attacking multiple times status when all attacks are over
+ ld hl, MultiHitText
+ call PrintText
+ xor a
+ ld [wPlayerNumHits], a
+.executeOtherEffects
+ ld a, [wPlayerMoveEffect]
+ and a
+ jp z, ExecutePlayerMoveDone
+ ld hl, SpecialEffects
+ ld de, 1
+ call IsInArray
+ call nc, JumpMoveEffect ; move effects not included in SpecialEffects or in either of the ResidualEffect arrays,
+ ; which are the effects not covered yet. Rage effect will be executed for a second time (though it's irrelevant).
+ ; Includes side effects that only need to be called if the target didn't faint.
+ ; Responsible for executing Twineedle's second side effect (poison).
+ jp ExecutePlayerMoveDone
+
+MultiHitText:
+ TX_FAR _MultiHitText
+ db "@"
+
+ExecutePlayerMoveDone:
+ xor a
+ ld [wActionResultOrTookBattleTurn], a
+ ld b, 1
+ ret
+
+PrintGhostText:
+; print the ghost battle messages
+ call IsGhostBattle
+ ret nz
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .Ghost
+ ld a, [wBattleMonStatus] ; player’s turn
+ and SLP | (1 << FRZ)
+ ret nz
+ ld hl, ScaredText
+ call PrintText
+ xor a
+ ret
+.Ghost ; ghost’s turn
+ ld hl, GetOutText
+ call PrintText
+ xor a
+ ret
+
+ScaredText:
+ TX_FAR _ScaredText
+ db "@"
+
+GetOutText:
+ TX_FAR _GetOutText
+ db "@"
+
+IsGhostBattle:
+ ld a, [wIsInBattle]
+ dec a
+ ret nz
+ ld a, [wCurMap]
+ cp POKEMONTOWER_1
+ jr c, .next
+ cp LAVENDER_HOUSE_1
+ jr nc, .next
+ ld b, SILPH_SCOPE
+ call IsItemInBag
+ ret z
+.next
+ ld a, 1
+ and a
+ ret
+
+; checks for various status conditions affecting the player mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckPlayerStatusConditions:
+ ld hl, wBattleMonStatus
+ ld a, [hl]
+ and SLP ; sleep mask
+ jr z, .FrozenCheck
+; sleeping
+ dec a
+ ld [wBattleMonStatus], a ; decrement number of turns left
+ and a
+ jr z, .WakeUp ; if the number of turns hit 0, wake up
+; fast asleep
+ xor a
+ ld [wAnimationType], a
+ ld a, SLP_ANIM - 1
+ call PlayMoveAnimation
+ ld hl, FastAsleepText
+ call PrintText
+ jr .sleepDone
+.WakeUp
+ ld hl, WokeUpText
+ call PrintText
+.sleepDone
+ xor a
+ ld [wPlayerUsedMove], a
+ ld hl, ExecutePlayerMoveDone ; player can't move this turn
+ jp .returnToHL
+
+.FrozenCheck
+ bit FRZ, [hl] ; frozen?
+ jr z, .HeldInPlaceCheck
+ ld hl, IsFrozenText
+ call PrintText
+ xor a
+ ld [wPlayerUsedMove], a
+ ld hl, ExecutePlayerMoveDone ; player can't move this turn
+ jp .returnToHL
+
+.HeldInPlaceCheck
+ ld a, [wEnemyBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; is enemy using a mult-turn move like wrap?
+ jp z, .FlinchedCheck
+ ld hl, CantMoveText
+ call PrintText
+ ld hl, ExecutePlayerMoveDone ; player can't move this turn
+ jp .returnToHL
+
+.FlinchedCheck
+ ld hl, wPlayerBattleStatus1
+ bit FLINCHED, [hl]
+ jp z, .HyperBeamCheck
+ res FLINCHED, [hl] ; reset player's flinch status
+ ld hl, FlinchedText
+ call PrintText
+ ld hl, ExecutePlayerMoveDone ; player can't move this turn
+ jp .returnToHL
+
+.HyperBeamCheck
+ ld hl, wPlayerBattleStatus2
+ bit NEEDS_TO_RECHARGE, [hl]
+ jr z, .AnyMoveDisabledCheck
+ res NEEDS_TO_RECHARGE, [hl] ; reset player's recharge status
+ ld hl, MustRechargeText
+ call PrintText
+ ld hl, ExecutePlayerMoveDone ; player can't move this turn
+ jp .returnToHL
+
+.AnyMoveDisabledCheck
+ ld hl, wPlayerDisabledMove
+ ld a, [hl]
+ and a
+ jr z, .ConfusedCheck
+ dec a
+ ld [hl], a
+ and $f ; did Disable counter hit 0?
+ jr nz, .ConfusedCheck
+ ld [hl], a
+ ld [wPlayerDisabledMoveNumber], a
+ ld hl, DisabledNoMoreText
+ call PrintText
+
+.ConfusedCheck
+ ld a, [wPlayerBattleStatus1]
+ add a ; is player confused?
+ jr nc, .TriedToUseDisabledMoveCheck
+ ld hl, wPlayerConfusedCounter
+ dec [hl]
+ jr nz, .IsConfused
+ ld hl, wPlayerBattleStatus1
+ res CONFUSED, [hl] ; if confused counter hit 0, reset confusion status
+ ld hl, ConfusedNoMoreText
+ call PrintText
+ jr .TriedToUseDisabledMoveCheck
+.IsConfused
+ ld hl, IsConfusedText
+ call PrintText
+ xor a
+ ld [wAnimationType], a
+ ld a, CONF_ANIM - 1
+ call PlayMoveAnimation
+ call BattleRandom
+ cp $80 ; 50% chance to hurt itself
+ jr c, .TriedToUseDisabledMoveCheck
+ ld hl, wPlayerBattleStatus1
+ ld a, [hl]
+ and 1 << CONFUSED ; if mon hurts itself, clear every other status from wPlayerBattleStatus1
+ ld [hl], a
+ call HandleSelfConfusionDamage
+ jr .MonHurtItselfOrFullyParalysed
+
+.TriedToUseDisabledMoveCheck
+; prevents a disabled move that was selected before being disabled from being used
+ ld a, [wPlayerDisabledMoveNumber]
+ and a
+ jr z, .ParalysisCheck
+ ld hl, wPlayerSelectedMove
+ cp [hl]
+ jr nz, .ParalysisCheck
+ call PrintMoveIsDisabledText
+ ld hl, ExecutePlayerMoveDone ; if a disabled move was somehow selected, player can't move this turn
+ jp .returnToHL
+
+.ParalysisCheck
+ ld hl, wBattleMonStatus
+ bit PAR, [hl]
+ jr z, .BideCheck
+ call BattleRandom
+ cp $3F ; 25% to be fully paralyzed
+ jr nc, .BideCheck
+ ld hl, FullyParalyzedText
+ call PrintText
+
+.MonHurtItselfOrFullyParalysed
+ ld hl, wPlayerBattleStatus1
+ ld a, [hl]
+ ; clear bide, thrashing, charging up, and trapping moves such as warp (already cleared for confusion damage)
+ and $ff ^ ((1 << STORING_ENERGY) | (1 << THRASHING_ABOUT) | (1 << CHARGING_UP) | (1 << USING_TRAPPING_MOVE))
+ ld [hl], a
+ ld a, [wPlayerMoveEffect]
+ cp FLY_EFFECT
+ jr z, .FlyOrChargeEffect
+ cp CHARGE_EFFECT
+ jr z, .FlyOrChargeEffect
+ jr .NotFlyOrChargeEffect
+
+.FlyOrChargeEffect
+ xor a
+ ld [wAnimationType], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.NotFlyOrChargeEffect
+ ld hl, ExecutePlayerMoveDone
+ jp .returnToHL ; if using a two-turn move, we need to recharge the first turn
+
+.BideCheck
+ ld hl, wPlayerBattleStatus1
+ bit STORING_ENERGY, [hl] ; is mon using bide?
+ jr z, .ThrashingAboutCheck
+ xor a
+ ld [wPlayerMoveNum], a
+ ld hl, wDamage
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, wPlayerBideAccumulatedDamage + 1
+ ld a, [hl]
+ add c ; accumulate damage taken
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld hl, wPlayerNumAttacksLeft
+ dec [hl] ; did Bide counter hit 0?
+ jr z, .UnleashEnergy
+ ld hl, ExecutePlayerMoveDone
+ jp .returnToHL ; unless mon unleashes energy, can't move this turn
+.UnleashEnergy
+ ld hl, wPlayerBattleStatus1
+ res STORING_ENERGY, [hl] ; not using bide any more
+ ld hl, UnleashedEnergyText
+ call PrintText
+ ld a, 1
+ ld [wPlayerMovePower], a
+ ld hl, wPlayerBideAccumulatedDamage + 1
+ ld a, [hld]
+ add a
+ ld b, a
+ ld [wDamage + 1], a
+ ld a, [hl]
+ rl a ; double the damage
+ ld [wDamage], a
+ or b
+ jr nz, .next
+ ld a, 1
+ ld [wMoveMissed], a
+.next
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld a, BIDE
+ ld [wPlayerMoveNum], a
+ ld hl, handleIfPlayerMoveMissed ; skip damage calculation, DecrementPP and MoveHitTest
+ jp .returnToHL
+
+.ThrashingAboutCheck
+ bit THRASHING_ABOUT, [hl] ; is mon using thrash or petal dance?
+ jr z, .MultiturnMoveCheck
+ ld a, THRASH
+ ld [wPlayerMoveNum], a
+ ld hl, ThrashingAboutText
+ call PrintText
+ ld hl, wPlayerNumAttacksLeft
+ dec [hl] ; did Thrashing About counter hit 0?
+ ld hl, PlayerCalcMoveDamage ; skip DecrementPP
+ jp nz, .returnToHL
+ push hl
+ ld hl, wPlayerBattleStatus1
+ res THRASHING_ABOUT, [hl] ; no longer thrashing about
+ set CONFUSED, [hl] ; confused
+ call BattleRandom
+ and 3
+ inc a
+ inc a ; confused for 2-5 turns
+ ld [wPlayerConfusedCounter], a
+ pop hl ; skip DecrementPP
+ jp .returnToHL
+
+.MultiturnMoveCheck
+ bit USING_TRAPPING_MOVE, [hl] ; is mon using multi-turn move?
+ jp z, .RageCheck
+ ld hl, AttackContinuesText
+ call PrintText
+ ld a, [wPlayerNumAttacksLeft]
+ dec a ; did multi-turn move end?
+ ld [wPlayerNumAttacksLeft], a
+ ld hl, getPlayerAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
+ ; DecrementPP and MoveHitTest
+ jp nz, .returnToHL
+ jp .returnToHL
+
+.RageCheck
+ ld a, [wPlayerBattleStatus2]
+ bit USING_RAGE, a ; is mon using rage?
+ jp z, .checkPlayerStatusConditionsDone ; if we made it this far, mon can move normally this turn
+ ld a, RAGE
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [wPlayerMoveEffect], a
+ ld hl, PlayerCanExecuteMove
+ jp .returnToHL
+
+.returnToHL
+ xor a
+ ret
+
+.checkPlayerStatusConditionsDone
+ ld a, $1
+ and a
+ ret
+
+FastAsleepText:
+ TX_FAR _FastAsleepText
+ db "@"
+
+WokeUpText:
+ TX_FAR _WokeUpText
+ db "@"
+
+IsFrozenText:
+ TX_FAR _IsFrozenText
+ db "@"
+
+FullyParalyzedText:
+ TX_FAR _FullyParalyzedText
+ db "@"
+
+FlinchedText:
+ TX_FAR _FlinchedText
+ db "@"
+
+MustRechargeText:
+ TX_FAR _MustRechargeText
+ db "@"
+
+DisabledNoMoreText:
+ TX_FAR _DisabledNoMoreText
+ db "@"
+
+IsConfusedText:
+ TX_FAR _IsConfusedText
+ db "@"
+
+HurtItselfText:
+ TX_FAR _HurtItselfText
+ db "@"
+
+ConfusedNoMoreText:
+ TX_FAR _ConfusedNoMoreText
+ db "@"
+
+SavingEnergyText:
+ TX_FAR _SavingEnergyText
+ db "@"
+
+UnleashedEnergyText:
+ TX_FAR _UnleashedEnergyText
+ db "@"
+
+ThrashingAboutText:
+ TX_FAR _ThrashingAboutText
+ db "@"
+
+AttackContinuesText:
+ TX_FAR _AttackContinuesText
+ db "@"
+
+CantMoveText:
+ TX_FAR _CantMoveText
+ db "@"
+
+PrintMoveIsDisabledText:
+ ld hl, wPlayerSelectedMove
+ ld de, wPlayerBattleStatus1
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .removeChargingUp
+ inc hl
+ ld de, wEnemyBattleStatus1
+.removeChargingUp
+ ld a, [de]
+ res CHARGING_UP, a ; end the pokemon's
+ ld [de], a
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMoveName
+ ld hl, MoveIsDisabledText
+ jp PrintText
+
+MoveIsDisabledText:
+ TX_FAR _MoveIsDisabledText
+ db "@"
+
+HandleSelfConfusionDamage:
+ ld hl, HurtItselfText
+ call PrintText
+ ld hl, wEnemyMonDefense
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [wBattleMonDefense]
+ ld [hli], a
+ ld a, [wBattleMonDefense + 1]
+ ld [hl], a
+ ld hl, wPlayerMoveEffect
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [wCriticalHitOrOHKO], a ; self-inflicted confusion damage can't be a Critical Hit
+ ld a, 40 ; 40 base power
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call GetDamageVarsForPlayerAttack
+ call CalculateDamage ; ignores AdjustDamageForMoveType (type-less damage), RandomizeDamage,
+ ; and MoveHitTest (always hits)
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, wEnemyMonDefense + 1
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [wAnimationType], a
+ inc a
+ ld [H_WHOSETURN], a
+ call PlayMoveAnimation
+ call DrawPlayerHUDAndHPBar
+ xor a
+ ld [H_WHOSETURN], a
+ jp ApplyDamageToPlayerPokemon
+
+PrintMonName1Text:
+ ld hl, MonName1Text
+ jp PrintText
+
+; this function wastes time calling DetermineExclamationPointTextNum
+; and choosing between Used1Text and Used2Text, even though
+; those text strings are identical and both continue at PrintInsteadText
+; this likely had to do with Japanese grammar that got translated,
+; but the functionality didn't get removed
+MonName1Text:
+ TX_FAR _MonName1Text
+ TX_ASM
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveNum]
+ ld hl, wPlayerUsedMove
+ jr z, .playerTurn
+ ld a, [wEnemyMoveNum]
+ ld hl, wEnemyUsedMove
+.playerTurn
+ ld [hl], a
+ ld [wd11e], a
+ call DetermineExclamationPointTextNum
+ ld a, [wMonIsDisobedient]
+ and a
+ ld hl, Used2Text
+ ret nz
+ ld a, [wd11e]
+ cp 3
+ ld hl, Used2Text
+ ret c
+ ld hl, Used1Text
+ ret
+
+Used1Text:
+ TX_FAR _Used1Text
+ TX_ASM
+ jr PrintInsteadText
+
+Used2Text:
+ TX_FAR _Used2Text
+ TX_ASM
+ ; fall through
+
+PrintInsteadText:
+ ld a, [wMonIsDisobedient]
+ and a
+ jr z, PrintMoveName
+ ld hl, InsteadText
+ ret
+
+InsteadText:
+ TX_FAR _InsteadText
+ TX_ASM
+ ; fall through
+
+PrintMoveName:
+ ld hl, _PrintMoveName
+ ret
+
+_PrintMoveName:
+ TX_FAR _CF4BText
+ TX_ASM
+ ld hl, ExclamationPointPointerTable
+ ld a, [wd11e] ; exclamation point num
+ add a
+ push bc
+ ld b, $0
+ ld c, a
+ add hl, bc
+ pop bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+ExclamationPointPointerTable:
+ dw ExclamationPoint1Text
+ dw ExclamationPoint2Text
+ dw ExclamationPoint3Text
+ dw ExclamationPoint4Text
+ dw ExclamationPoint5Text
+
+ExclamationPoint1Text:
+ TX_FAR _ExclamationPoint1Text
+ db "@"
+
+ExclamationPoint2Text:
+ TX_FAR _ExclamationPoint2Text
+ db "@"
+
+ExclamationPoint3Text:
+ TX_FAR _ExclamationPoint3Text
+ db "@"
+
+ExclamationPoint4Text:
+ TX_FAR _ExclamationPoint4Text
+ db "@"
+
+ExclamationPoint5Text:
+ TX_FAR _ExclamationPoint5Text
+ db "@"
+
+; this function does nothing useful
+; if the move being used is in set [1-4] from ExclamationPointMoveSets,
+; use ExclamationPoint[1-4]Text
+; otherwise, use ExclamationPoint5Text
+; but all five text strings are identical
+; this likely had to do with Japanese grammar that got translated,
+; but the functionality didn't get removed
+DetermineExclamationPointTextNum:
+ push bc
+ ld a, [wd11e] ; move ID
+ ld c, a
+ ld b, $0
+ ld hl, ExclamationPointMoveSets
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ cp c
+ jr z, .done
+ and a
+ jr nz, .loop
+ inc b
+ jr .loop
+.done
+ ld a, b
+ ld [wd11e], a ; exclamation point num
+ pop bc
+ ret
+
+ExclamationPointMoveSets:
+ db SWORDS_DANCE, GROWTH
+ db $00
+ db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
+ db $00
+ db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
+ db $00
+ db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
+ db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
+ db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN
+ db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS
+ db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE
+ db $00
+ db $FF ; terminator
+
+PrintMoveFailureText:
+ ld de, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playersTurn
+ ld de, wEnemyMoveEffect
+.playersTurn
+ ld hl, DoesntAffectMonText
+ ld a, [wDamageMultipliers]
+ and $7f
+ jr z, .gotTextToPrint
+ ld hl, AttackMissedText
+ ld a, [wCriticalHitOrOHKO]
+ cp $ff
+ jr nz, .gotTextToPrint
+ ld hl, UnaffectedText
+.gotTextToPrint
+ push de
+ call PrintText
+ xor a
+ ld [wCriticalHitOrOHKO], a
+ pop de
+ ld a, [de]
+ cp JUMP_KICK_EFFECT
+ ret nz
+
+ ; if you get here, the mon used jump kick or hi jump kick and missed
+ ld hl, wDamage ; since the move missed, wDamage will always contain 0 at this point.
+ ; Thus, recoil damage will always be equal to 1
+ ; even if it was intended to be potential damage/8.
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hl], b
+ dec hl
+ ld [hli], a
+ or b
+ jr nz, .applyRecoil
+ inc a
+ ld [hl], a
+.applyRecoil
+ ld hl, KeptGoingAndCrashedText
+ call PrintText
+ ld b, $4
+ predef PredefShakeScreenHorizontally
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .enemyTurn
+ jp ApplyDamageToPlayerPokemon
+.enemyTurn
+ jp ApplyDamageToEnemyPokemon
+
+AttackMissedText:
+ TX_FAR _AttackMissedText
+ db "@"
+
+KeptGoingAndCrashedText:
+ TX_FAR _KeptGoingAndCrashedText
+ db "@"
+
+UnaffectedText:
+ TX_FAR _UnaffectedText
+ db "@"
+
+PrintDoesntAffectText:
+ ld hl, DoesntAffectMonText
+ jp PrintText
+
+DoesntAffectMonText:
+ TX_FAR _DoesntAffectMonText
+ db "@"
+
+; if there was a critical hit or an OHKO was successful, print the corresponding text
+PrintCriticalOHKOText:
+ ld a, [wCriticalHitOrOHKO]
+ and a
+ jr z, .done ; do nothing if there was no critical hit or successful OHKO
+ dec a
+ add a
+ ld hl, CriticalOHKOTextPointers
+ ld b, $0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+ xor a
+ ld [wCriticalHitOrOHKO], a
+.done
+ ld c, 20
+ jp DelayFrames
+
+CriticalOHKOTextPointers:
+ dw CriticalHitText
+ dw OHKOText
+
+CriticalHitText:
+ TX_FAR _CriticalHitText
+ db "@"
+
+OHKOText:
+ TX_FAR _OHKOText
+ db "@"
+
+; checks if a traded mon will disobey due to lack of badges
+; stores whether the mon will use a move in Z flag
+CheckForDisobedience:
+ xor a
+ ld [wMonIsDisobedient], a
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .checkIfMonIsTraded
+ ld a, $1
+ and a
+ ret
+; compare the mon's original trainer ID with the player's ID to see if it was traded
+.checkIfMonIsTraded
+ ld hl, wPartyMon1OTID
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wPlayerMonNumber]
+ call AddNTimes
+ ld a, [wPlayerID]
+ cp [hl]
+ jr nz, .monIsTraded
+ inc hl
+ ld a, [wPlayerID + 1]
+ cp [hl]
+ jp z, .canUseMove
+; it was traded
+.monIsTraded
+; what level might disobey?
+ ld hl, wObtainedBadges
+ bit 7, [hl]
+ ld a, 101
+ jr nz, .next
+ bit 5, [hl]
+ ld a, 70
+ jr nz, .next
+ bit 3, [hl]
+ ld a, 50
+ jr nz, .next
+ bit 1, [hl]
+ ld a, 30
+ jr nz, .next
+ ld a, 10
+.next
+ ld b, a
+ ld c, a
+ ld a, [wBattleMonLevel]
+ ld d, a
+ add b
+ ld b, a
+ jr nc, .noCarry
+ ld b, $ff ; cap b at $ff
+.noCarry
+ ld a, c
+ cp d
+ jp nc, .canUseMove
+.loop1
+ call BattleRandom
+ swap a
+ cp b
+ jr nc, .loop1
+ cp c
+ jp c, .canUseMove
+.loop2
+ call BattleRandom
+ cp b
+ jr nc, .loop2
+ cp c
+ jr c, .useRandomMove
+ ld a, d
+ sub c
+ ld b, a
+ call BattleRandom
+ swap a
+ sub b
+ jr c, .monNaps
+ cp b
+ jr nc, .monDoesNothing
+ ld hl, WontObeyText
+ call PrintText
+ call HandleSelfConfusionDamage
+ jp .cannotUseMove
+.monNaps
+ call BattleRandom
+ add a
+ swap a
+ and SLP ; sleep mask
+ jr z, .monNaps ; keep trying until we get at least 1 turn of sleep
+ ld [wBattleMonStatus], a
+ ld hl, BeganToNapText
+ jr .printText
+.monDoesNothing
+ call BattleRandom
+ and $3
+ ld hl, LoafingAroundText
+ and a
+ jr z, .printText
+ ld hl, WontObeyText
+ dec a
+ jr z, .printText
+ ld hl, TurnedAwayText
+ dec a
+ jr z, .printText
+ ld hl, IgnoredOrdersText
+.printText
+ call PrintText
+ jr .cannotUseMove
+.useRandomMove
+ ld a, [wBattleMonMoves + 1]
+ and a ; is the second move slot empty?
+ jr z, .monDoesNothing ; mon will not use move if it only knows one move
+ ld a, [wPlayerDisabledMoveNumber]
+ and a
+ jr nz, .monDoesNothing
+ ld a, [wPlayerSelectedMove]
+ cp STRUGGLE
+ jr z, .monDoesNothing ; mon will not use move if struggling
+; check if only one move has remaining PP
+ ld hl, wBattleMonPP
+ push hl
+ ld a, [hli]
+ and $3f
+ ld b, a
+ ld a, [hli]
+ and $3f
+ add b
+ ld b, a
+ ld a, [hli]
+ and $3f
+ add b
+ ld b, a
+ ld a, [hl]
+ and $3f
+ add b
+ pop hl
+ push af
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld b, a
+ pop af
+ cp b
+ jr z, .monDoesNothing ; mon will not use move if only one move has remaining PP
+ ld a, $1
+ ld [wMonIsDisobedient], a
+ ld a, [wMaxMenuItem]
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ ld c, a
+.chooseMove
+ call BattleRandom
+ and $3
+ cp b
+ jr nc, .chooseMove ; if the random number is greater than the move count, choose another
+ cp c
+ jr z, .chooseMove ; if the random number matches the move the player selected, choose another
+ ld [wCurrentMenuItem], a
+ ld hl, wBattleMonPP
+ ld e, a
+ ld d, $0
+ add hl, de
+ ld a, [hl]
+ and a ; does the move have any PP left?
+ jr z, .chooseMove ; if the move has no PP left, choose another
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ ld hl, wBattleMonMoves
+ add hl, bc
+ ld a, [hl]
+ ld [wPlayerSelectedMove], a
+ call GetCurrentMove
+.canUseMove
+ ld a, $1
+ and a; clear Z flag
+ ret
+.cannotUseMove
+ xor a ; set Z flag
+ ret
+
+LoafingAroundText:
+ TX_FAR _LoafingAroundText
+ db "@"
+
+BeganToNapText:
+ TX_FAR _BeganToNapText
+ db "@"
+
+WontObeyText:
+ TX_FAR _WontObeyText
+ db "@"
+
+TurnedAwayText:
+ TX_FAR _TurnedAwayText
+ db "@"
+
+IgnoredOrdersText:
+ TX_FAR _IgnoredOrdersText
+ db "@"
+
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the player mon
+GetDamageVarsForPlayerAttack:
+ xor a
+ ld hl, wDamage ; damage to eventually inflict, initialise to zero
+ ldi [hl], a
+ ld [hl], a
+ ld hl, wPlayerMovePower
+ ld a, [hli]
+ and a
+ ld d, a ; d = move power
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [wPlayerMoveType]
+ cp FIRE ; types >= FIRE are all special
+ jr nc, .specialAttack
+.physicalAttack
+ ld hl, wEnemyMonDefense
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = enemy defense
+ ld a, [wEnemyBattleStatus3]
+ bit HAS_REFLECT_UP, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the enemy has used Reflect, double the enemy's defense
+ sla c
+ rl b
+.physicalAttackCritCheck
+ ld hl, wBattleMonAttack
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's attack and the enemy's defense to their base values
+ ld c, 3 ; defense stat
+ call GetEnemyMonStat
+ ld a, [H_PRODUCT + 2]
+ ld b, a
+ ld a, [H_PRODUCT + 3]
+ ld c, a
+ push bc
+ ld hl, wPartyMon1Attack
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ pop bc
+ jr .scaleStats
+.specialAttack
+ ld hl, wEnemyMonSpecial
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = enemy special
+ ld a, [wEnemyBattleStatus3]
+ bit HAS_LIGHT_SCREEN_UP, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the enemy has used Light Screen, double the enemy's special
+ sla c
+ rl b
+; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if
+; a Pokemon with 512 or more Defense has used Reflect, or if a Pokemon with 512 or more Special has used Light Screen
+.specialAttackCritCheck
+ ld hl, wBattleMonSpecial
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
+ ld a, [H_PRODUCT + 2]
+ ld b, a
+ ld a, [H_PRODUCT + 3]
+ ld c, a
+ push bc
+ ld hl, wPartyMon1Special
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ pop bc
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a ; hl = player's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+; bc /= 4 (scale enemy's defensive stat)
+ srl b
+ rr c
+ srl b
+ rr c
+; defensive stat can actually end up as 0, leading to a division by 0 freeze during damage calculation
+; hl /= 4 (scale player's offensive stat)
+ srl h
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h ; is the player's offensive stat 0?
+ jr nz, .next
+ inc l ; if the player's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = player's offensive stat (possibly scaled)
+ ; (c already contains enemy's defensive stat (possibly scaled))
+ ld a, [wBattleMonLevel]
+ ld e, a ; e = level
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
+ ld a, 1
+ and a
+ ret
+
+; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the enemy mon
+GetDamageVarsForEnemyAttack:
+ ld hl, wDamage ; damage to eventually inflict, initialise to zero
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wEnemyMovePower
+ ld a, [hli]
+ ld d, a ; d = move power
+ and a
+ ret z ; return if move power is zero
+ ld a, [hl] ; a = [wEnemyMoveType]
+ cp FIRE ; types >= FIRE are all special
+ jr nc, .specialAttack
+.physicalAttack
+ ld hl, wBattleMonDefense
+ ld a, [hli]
+ ld b, a
+ ld c, [hl] ; bc = player defense
+ ld a, [wPlayerBattleStatus3]
+ bit HAS_REFLECT_UP, a ; check for Reflect
+ jr z, .physicalAttackCritCheck
+; if the player has used Reflect, double the player's defense
+ sla c
+ rl b
+.physicalAttackCritCheck
+ ld hl, wEnemyMonAttack
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's defense and the enemy's attack to their base values
+ ld hl, wPartyMon1Defense
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, 2 ; attack stat
+ call GetEnemyMonStat
+ ld hl, H_PRODUCT + 2
+ pop bc
+ jr .scaleStats
+.specialAttack
+ ld hl, wBattleMonSpecial
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld a, [wPlayerBattleStatus3]
+ bit HAS_LIGHT_SCREEN_UP, a ; check for Light Screen
+ jr z, .specialAttackCritCheck
+; if the player has used Light Screen, double the player's special
+ sla c
+ rl b
+; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if
+; a Pokemon with 512 or more Defense has used Reflect, or if a Pokemon with 512 or more Special has used Light Screen
+.specialAttackCritCheck
+ ld hl, wEnemyMonSpecial
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .scaleStats
+; in the case of a critical hit, reset the player's and enemy's specials to their base values
+ ld hl, wPartyMon1Special
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ ld c, 5 ; special stat
+ call GetEnemyMonStat
+ ld hl, H_PRODUCT + 2
+ pop bc
+; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
+; this allows values with up to 10 bits (values up to 1023) to be handled
+; anything larger will wrap around
+.scaleStats
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a ; hl = enemy's offensive stat
+ or b ; is either high byte nonzero?
+ jr z, .next ; if not, we don't need to scale
+; bc /= 4 (scale player's defensive stat)
+ srl b
+ rr c
+ srl b
+ rr c
+; defensive stat can actually end up as 0, leading to a division by 0 freeze during damage calculation
+; hl /= 4 (scale enemy's offensive stat)
+ srl h
+ rr l
+ srl h
+ rr l
+ ld a, l
+ or h ; is the enemy's offensive stat 0?
+ jr nz, .next
+ inc l ; if the enemy's offensive stat is 0, bump it up to 1
+.next
+ ld b, l ; b = enemy's offensive stat (possibly scaled)
+ ; (c already contains player's defensive stat (possibly scaled))
+ ld a, [wEnemyMonLevel]
+ ld e, a
+ ld a, [wCriticalHitOrOHKO]
+ and a ; check for critical hit
+ jr z, .done
+ sla e ; double level if it was a critical hit
+.done
+ ld a, $1
+ and a
+ and a
+ ret
+
+; get stat c of enemy mon
+; c: stat to get (HP=1,Attack=2,Defense=3,Speed=4,Special=5)
+GetEnemyMonStat:
+ push de
+ push bc
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .notLinkBattle
+ ld hl, wEnemyMon1Stats
+ dec c
+ sla c
+ ld b, $0
+ add hl, bc
+ ld a, [wEnemyMonPartyPos]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+ pop bc
+ pop de
+ ret
+.notLinkBattle
+ ld a, [wEnemyMonLevel]
+ ld [wCurEnemyLVL], a
+ ld a, [wEnemyMonSpecies]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld hl, wEnemyMonDVs
+ ld de, wLoadedMonSpeedExp
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ pop bc
+ ld b, $0
+ ld hl, wLoadedMonSpeedExp - $b ; this base address makes CalcStat look in [wLoadedMonSpeedExp] for DVs
+ call CalcStat
+ pop de
+ ret
+
+CalculateDamage:
+; input:
+; b: attack
+; c: opponent defense
+; d: base power
+; e: level
+
+ ld a, [H_WHOSETURN] ; whose turn?
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .effect
+ ld a, [wEnemyMoveEffect]
+.effect
+
+; EXPLODE_EFFECT halves defense.
+ cp EXPLODE_EFFECT
+ jr nz, .ok
+ srl c
+ jr nz, .ok
+ inc c ; ...with a minimum value of 1 (used as a divisor later on)
+.ok
+
+; Multi-hit attacks may or may not have 0 bp.
+ cp TWO_TO_FIVE_ATTACKS_EFFECT
+ jr z, .skipbp
+ cp $1e
+ jr z, .skipbp
+
+; Calculate OHKO damage based on remaining HP.
+ cp OHKO_EFFECT
+ jp z, JumpToOHKOMoveEffect
+
+; Don't calculate damage for moves that don't do any.
+ ld a, d ; base power
+ and a
+ ret z
+.skipbp
+
+ xor a
+ ld hl, H_DIVIDEND
+ ldi [hl], a
+ ldi [hl], a
+ ld [hl], a
+
+; Multiply level by 2
+ ld a, e ; level
+ add a
+ jr nc, .nc
+ push af
+ ld a, 1
+ ld [hl], a
+ pop af
+.nc
+ inc hl
+ ldi [hl], a
+
+; Divide by 5
+ ld a, 5
+ ldd [hl], a
+ push bc
+ ld b, 4
+ call Divide
+ pop bc
+
+; Add 2
+ inc [hl]
+ inc [hl]
+
+ inc hl ; multiplier
+
+; Multiply by attack base power
+ ld [hl], d
+ call Multiply
+
+; Multiply by attack stat
+ ld [hl], b
+ call Multiply
+
+; Divide by defender's defense stat
+ ld [hl], c
+ ld b, 4
+ call Divide
+
+; Divide by 50
+ ld [hl], 50
+ ld b, 4
+ call Divide
+
+ ld hl, wDamage
+ ld b, [hl]
+ ld a, [H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3], a
+ jr nc, .asm_3dfd0
+
+ ld a, [H_QUOTIENT + 2]
+ inc a
+ ld [H_QUOTIENT + 2], a
+ and a
+ jr z, .asm_3e004
+
+.asm_3dfd0
+ ld a, [H_QUOTIENT]
+ ld b, a
+ ld a, [H_QUOTIENT + 1]
+ or a
+ jr nz, .asm_3e004
+
+ ld a, [H_QUOTIENT + 2]
+ cp 998 / $100
+ jr c, .asm_3dfe8
+ cp 998 / $100 + 1
+ jr nc, .asm_3e004
+ ld a, [H_QUOTIENT + 3]
+ cp 998 % $100
+ jr nc, .asm_3e004
+
+.asm_3dfe8
+ inc hl
+ ld a, [H_QUOTIENT + 3]
+ ld b, [hl]
+ add b
+ ld [hld], a
+
+ ld a, [H_QUOTIENT + 2]
+ ld b, [hl]
+ adc b
+ ld [hl], a
+ jr c, .asm_3e004
+
+ ld a, [hl]
+ cp 998 / $100
+ jr c, .asm_3e00a
+ cp 998 / $100 + 1
+ jr nc, .asm_3e004
+ inc hl
+ ld a, [hld]
+ cp 998 % $100
+ jr c, .asm_3e00a
+
+.asm_3e004
+; cap at 997
+ ld a, 997 / $100
+ ld [hli], a
+ ld a, 997 % $100
+ ld [hld], a
+
+.asm_3e00a
+; add 2
+ inc hl
+ ld a, [hl]
+ add 2
+ ld [hld], a
+ jr nc, .done
+ inc [hl]
+
+.done
+; minimum damage is 1
+ ld a, 1
+ and a
+ ret
+
+JumpToOHKOMoveEffect:
+ call JumpMoveEffect
+ ld a, [wMoveMissed]
+ dec a
+ ret
+
+
+UnusedHighCriticalMoves:
+ db KARATE_CHOP
+ db RAZOR_LEAF
+ db CRABHAMMER
+ db SLASH
+ db $FF
+
+; determines if attack is a critical hit
+; azure heights claims "the fastest pokémon (who are,not coincidentally,
+; among the most popular) tend to CH about 20 to 25% of the time."
+CriticalHitTest:
+ xor a
+ ld [wCriticalHitOrOHKO], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wEnemyMonSpecies]
+ jr nz, .handleEnemy
+ ld a, [wBattleMonSpecies]
+.handleEnemy
+ ld [wd0b5], a
+ call GetMonHeader
+ ld a, [wMonHBaseSpeed]
+ ld b, a
+ srl b ; (effective (base speed/2))
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wPlayerMovePower
+ ld de, wPlayerBattleStatus2
+ jr z, .calcCriticalHitProbability
+ ld hl, wEnemyMovePower
+ ld de, wEnemyBattleStatus2
+.calcCriticalHitProbability
+ ld a, [hld] ; read base power from RAM
+ and a
+ ret z ; do nothing if zero
+ dec hl
+ ld c, [hl] ; read move id
+ ld a, [de]
+ bit GETTING_PUMPED, a ; test for focus energy
+ jr nz, .focusEnergyUsed ; bug: using focus energy causes a shift to the right instead of left,
+ ; resulting in 1/4 the usual crit chance
+ sla b ; (effective (base speed/2)*2)
+ jr nc, .noFocusEnergyUsed
+ ld b, $ff ; cap at 255/256
+ jr .noFocusEnergyUsed
+.focusEnergyUsed
+ srl b
+.noFocusEnergyUsed
+ ld hl, HighCriticalMoves ; table of high critical hit moves
+.Loop
+ ld a, [hli] ; read move from move table
+ cp c ; does it match the move about to be used?
+ jr z, .HighCritical ; if so, the move about to be used is a high critical hit ratio move
+ inc a ; move on to the next move, FF terminates loop
+ jr nz, .Loop ; check the next move in HighCriticalMoves
+ srl b ; /2 for regular move (effective (base speed / 2))
+ jr .SkipHighCritical ; continue as a normal move
+.HighCritical
+ sla b ; *2 for high critical hit moves
+ jr nc, .noCarry
+ ld b, $ff ; cap at 255/256
+.noCarry
+ sla b ; *4 for high critical move (effective (base speed/2)*8))
+ jr nc, .SkipHighCritical
+ ld b, $ff
+.SkipHighCritical
+ call BattleRandom ; generates a random value, in "a"
+ rlc a
+ rlc a
+ rlc a
+ cp b ; check a against calculated crit rate
+ ret nc ; no critical hit if no borrow
+ ld a, $1
+ ld [wCriticalHitOrOHKO], a ; set critical hit flag
+ ret
+
+; high critical hit moves
+HighCriticalMoves:
+ db KARATE_CHOP
+ db RAZOR_LEAF
+ db CRABHAMMER
+ db SLASH
+ db $FF
+
+
+; function to determine if Counter hits and if so, how much damage it does
+HandleCounterMove:
+; The variables checked by Counter are updated whenever the cursor points to a new move in the battle selection menu.
+; This is irrelevant for the opponent's side outside of link battles, since the move selection is controlled by the AI.
+; However, in the scenario where the player switches out and the opponent uses Counter,
+; the outcome may be affected by the player's actions in the move selection menu prior to switching the Pokemon.
+; This might also lead to desync glitches in link battles.
+
+ ld a, [H_WHOSETURN] ; whose turn
+ and a
+; player's turn
+ ld hl, wEnemySelectedMove
+ ld de, wEnemyMovePower
+ ld a, [wPlayerSelectedMove]
+ jr z, .next
+; enemy's turn
+ ld hl, wPlayerSelectedMove
+ ld de, wPlayerMovePower
+ ld a, [wEnemySelectedMove]
+.next
+ cp COUNTER
+ ret nz ; return if not using Counter
+ ld a, $01
+ ld [wMoveMissed], a ; initialize the move missed variable to true (it is set to false below if the move hits)
+ ld a, [hl]
+ cp COUNTER
+ ret z ; miss if the opponent's last selected move is Counter.
+ ld a, [de]
+ and a
+ ret z ; miss if the opponent's last selected move's Base Power is 0.
+; check if the move the target last selected was Normal or Fighting type
+ inc de
+ ld a, [de]
+ and a ; normal type
+ jr z, .counterableType
+ cp FIGHTING
+ jr z, .counterableType
+; if the move wasn't Normal or Fighting type, miss
+ xor a
+ ret
+.counterableType
+ ld hl, wDamage
+ ld a, [hli]
+ or [hl]
+ ret z ; If we made it here, Counter still misses if the last move used in battle did no damage to its target.
+ ; wDamage is shared by both players, so Counter may strike back damage dealt by the Counter user itself
+ ; if the conditions meet, even though 99% of the times damage will come from the target.
+; if it did damage, double it
+ ld a, [hl]
+ add a
+ ldd [hl], a
+ ld a, [hl]
+ adc a
+ ld [hl], a
+ jr nc, .noCarry
+; damage is capped at 0xFFFF
+ ld a, $ff
+ ld [hli], a
+ ld [hl], a
+.noCarry
+ xor a
+ ld [wMoveMissed], a
+ call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
+ xor a
+ ret
+
+ApplyAttackToEnemyPokemon:
+ ld a, [wPlayerMoveEffect]
+ cp OHKO_EFFECT
+ jr z, ApplyDamageToEnemyPokemon
+ cp SUPER_FANG_EFFECT
+ jr z, .superFangEffect
+ cp SPECIAL_DAMAGE_EFFECT
+ jr z, .specialDamage
+ ld a, [wPlayerMovePower]
+ and a
+ jp z, ApplyAttackToEnemyPokemonDone ; no attack to apply if base power is 0
+ jr ApplyDamageToEnemyPokemon
+.superFangEffect
+; set the damage to half the target's HP
+ ld hl, wEnemyMonHP
+ ld de, wDamage
+ ld a, [hli]
+ srl a
+ ld [de], a
+ inc de
+ ld b, a
+ ld a, [hl]
+ rr a
+ ld [de], a
+ or b
+ jr nz, ApplyDamageToEnemyPokemon
+; make sure Super Fang's damage is always at least 1
+ ld a, $01
+ ld [de], a
+ jr ApplyDamageToEnemyPokemon
+.specialDamage
+ ld hl, wBattleMonLevel
+ ld a, [hl]
+ ld b, a ; Seismic Toss deals damage equal to the user's level
+ ld a, [wPlayerMoveNum]
+ cp SEISMIC_TOSS
+ jr z, .storeDamage
+ cp NIGHT_SHADE
+ jr z, .storeDamage
+ ld b, SONICBOOM_DAMAGE ; 20
+ cp SONICBOOM
+ jr z, .storeDamage
+ ld b, DRAGON_RAGE_DAMAGE ; 40
+ cp DRAGON_RAGE
+ jr z, .storeDamage
+; Psywave
+ ld a, [hl]
+ ld b, a
+ srl a
+ add b
+ ld b, a ; b = level * 1.5
+; loop until a random number in the range [1, b) is found
+.loop
+ call BattleRandom
+ and a
+ jr z, .loop
+ cp b
+ jr nc, .loop
+ ld b, a
+.storeDamage ; store damage value at b
+ ld hl, wDamage
+ xor a
+ ld [hli], a
+ ld a, b
+ ld [hl], a
+
+ApplyDamageToEnemyPokemon:
+ ld hl, wDamage
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ or b
+ jr z, ApplyAttackToEnemyPokemonDone ; we're done if damage is 0
+ ld a, [wEnemyBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a ; does the enemy have a substitute?
+ jp nz, AttackSubstitute
+; subtract the damage from the pokemon's current HP
+; also, save the current HP at wHPBarOldHP
+ ld a, [hld]
+ ld b, a
+ ld a, [wEnemyMonHP + 1]
+ ld [wHPBarOldHP], a
+ sub b
+ ld [wEnemyMonHP + 1], a
+ ld a, [hl]
+ ld b, a
+ ld a, [wEnemyMonHP]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [wEnemyMonHP], a
+ jr nc, .animateHpBar
+; if more damage was done than the current HP, zero the HP and set the damage (wDamage)
+; equal to how much HP the pokemon had before the attack
+ ld a, [wHPBarOldHP+1]
+ ld [hli], a
+ ld a, [wHPBarOldHP]
+ ld [hl], a
+ xor a
+ ld hl, wEnemyMonHP
+ ld [hli], a
+ ld [hl], a
+.animateHpBar
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld [wHPBarNewHP+1], a
+ ld a, [hl]
+ ld [wHPBarNewHP], a
+ coord hl, 2, 2
+ xor a
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate the HP bar shortening
+ApplyAttackToEnemyPokemonDone:
+ jp DrawHUDsAndHPBars
+
+ApplyAttackToPlayerPokemon:
+ ld a, [wEnemyMoveEffect]
+ cp OHKO_EFFECT
+ jr z, ApplyDamageToPlayerPokemon
+ cp SUPER_FANG_EFFECT
+ jr z, .superFangEffect
+ cp SPECIAL_DAMAGE_EFFECT
+ jr z, .specialDamage
+ ld a, [wEnemyMovePower]
+ and a
+ jp z, ApplyAttackToPlayerPokemonDone
+ jr ApplyDamageToPlayerPokemon
+.superFangEffect
+; set the damage to half the target's HP
+ ld hl, wBattleMonHP
+ ld de, wDamage
+ ld a, [hli]
+ srl a
+ ld [de], a
+ inc de
+ ld b, a
+ ld a, [hl]
+ rr a
+ ld [de], a
+ or b
+ jr nz, ApplyDamageToPlayerPokemon
+; make sure Super Fang's damage is always at least 1
+ ld a, $01
+ ld [de], a
+ jr ApplyDamageToPlayerPokemon
+.specialDamage
+ ld hl, wEnemyMonLevel
+ ld a, [hl]
+ ld b, a
+ ld a, [wEnemyMoveNum]
+ cp SEISMIC_TOSS
+ jr z, .storeDamage
+ cp NIGHT_SHADE
+ jr z, .storeDamage
+ ld b, SONICBOOM_DAMAGE
+ cp SONICBOOM
+ jr z, .storeDamage
+ ld b, DRAGON_RAGE_DAMAGE
+ cp DRAGON_RAGE
+ jr z, .storeDamage
+; Psywave
+ ld a, [hl]
+ ld b, a
+ srl a
+ add b
+ ld b, a ; b = attacker's level * 1.5
+; loop until a random number in the range [0, b) is found
+; this differs from the range when the player attacks, which is [1, b)
+; it's possible for the enemy to do 0 damage with Psywave, but the player always does at least 1 damage
+.loop
+ call BattleRandom
+ cp b
+ jr nc, .loop
+ ld b, a
+.storeDamage
+ ld hl, wDamage
+ xor a
+ ld [hli], a
+ ld a, b
+ ld [hl], a
+
+ApplyDamageToPlayerPokemon:
+ ld hl, wDamage
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ or b
+ jr z, ApplyAttackToPlayerPokemonDone ; we're done if damage is 0
+ ld a, [wPlayerBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a ; does the player have a substitute?
+ jp nz, AttackSubstitute
+; subtract the damage from the pokemon's current HP
+; also, save the current HP at wHPBarOldHP and the new HP at wHPBarNewHP
+ ld a, [hld]
+ ld b, a
+ ld a, [wBattleMonHP + 1]
+ ld [wHPBarOldHP], a
+ sub b
+ ld [wBattleMonHP + 1], a
+ ld [wHPBarNewHP], a
+ ld b, [hl]
+ ld a, [wBattleMonHP]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [wBattleMonHP], a
+ ld [wHPBarNewHP+1], a
+ jr nc, .animateHpBar
+; if more damage was done than the current HP, zero the HP and set the damage (wDamage)
+; equal to how much HP the pokemon had before the attack
+ ld a, [wHPBarOldHP+1]
+ ld [hli], a
+ ld a, [wHPBarOldHP]
+ ld [hl], a
+ xor a
+ ld hl, wBattleMonHP
+ ld [hli], a
+ ld [hl], a
+ ld hl, wHPBarNewHP
+ ld [hli], a
+ ld [hl], a
+.animateHpBar
+ ld hl, wBattleMonMaxHP
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ coord hl, 10, 9
+ ld a, $01
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate the HP bar shortening
+ApplyAttackToPlayerPokemonDone:
+ jp DrawHUDsAndHPBars
+
+AttackSubstitute:
+; Unlike the two ApplyAttackToPokemon functions, Attack Substitute is shared by player and enemy.
+; Self-confusion damage as well as Hi-Jump Kick and Jump Kick recoil cause a momentary turn swap before being applied.
+; If the user has a Substitute up and would take damage because of that,
+; damage will be applied to the other player's Substitute.
+; Normal recoil such as from Double-Edge isn't affected by this glitch,
+; because this function is never called in that case.
+
+ ld hl, SubstituteTookDamageText
+ call PrintText
+; values for player turn
+ ld de, wEnemySubstituteHP
+ ld bc, wEnemyBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .applyDamageToSubstitute
+; values for enemy turn
+ ld de, wPlayerSubstituteHP
+ ld bc, wPlayerBattleStatus2
+.applyDamageToSubstitute
+ ld hl, wDamage
+ ld a, [hli]
+ and a
+ jr nz, .substituteBroke ; damage > 0xFF always breaks substitutes
+; subtract damage from HP of substitute
+ ld a, [de]
+ sub [hl]
+ ld [de], a
+ ret nc
+.substituteBroke
+; If the target's Substitute breaks, wDamage isn't updated with the amount of HP
+; the Substitute had before being attacked.
+ ld h, b
+ ld l, c
+ res HAS_SUBSTITUTE_UP, [hl] ; unset the substitute bit
+ ld hl, SubstituteBrokeText
+ call PrintText
+; flip whose turn it is for the next function call
+ ld a, [H_WHOSETURN]
+ xor $01
+ ld [H_WHOSETURN], a
+ callab HideSubstituteShowMonAnim ; animate the substitute breaking
+; flip the turn back to the way it was
+ ld a, [H_WHOSETURN]
+ xor $01
+ ld [H_WHOSETURN], a
+ ld hl, wPlayerMoveEffect ; value for player's turn
+ and a
+ jr z, .nullifyEffect
+ ld hl, wEnemyMoveEffect ; value for enemy's turn
+.nullifyEffect
+ xor a
+ ld [hl], a ; zero the effect of the attacker's move
+ jp DrawHUDsAndHPBars
+
+SubstituteTookDamageText:
+ TX_FAR _SubstituteTookDamageText
+ db "@"
+
+SubstituteBrokeText:
+ TX_FAR _SubstituteBrokeText
+ db "@"
+
+; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
+HandleBuildingRage:
+; values for the player turn
+ ld hl, wEnemyBattleStatus2
+ ld de, wEnemyMonStatMods
+ ld bc, wEnemyMoveNum
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .next
+; values for the enemy turn
+ ld hl, wPlayerBattleStatus2
+ ld de, wPlayerMonStatMods
+ ld bc, wPlayerMoveNum
+.next
+ bit USING_RAGE, [hl] ; is the pokemon being attacked under the effect of Rage?
+ ret z ; return if not
+ ld a, [de]
+ cp $0d ; maximum stat modifier value
+ ret z ; return if attack modifier is already maxed
+ ld a, [H_WHOSETURN]
+ xor $01 ; flip turn for the stat modifier raising function
+ ld [H_WHOSETURN], a
+; temporarily change the target pokemon's move to $00 and the effect to the one
+; that causes the attack modifier to go up one stage
+ ld h, b
+ ld l, c
+ ld [hl], $00 ; null move number
+ inc hl
+ ld [hl], ATTACK_UP1_EFFECT
+ push hl
+ ld hl, BuildingRageText
+ call PrintText
+ call StatModifierUpEffect ; stat modifier raising function
+ pop hl
+ xor a
+ ldd [hl], a ; null move effect
+ ld a, RAGE
+ ld [hl], a ; restore the target pokemon's move number to Rage
+ ld a, [H_WHOSETURN]
+ xor $01 ; flip turn back to the way it was
+ ld [H_WHOSETURN], a
+ ret
+
+BuildingRageText:
+ TX_FAR _BuildingRageText
+ db "@"
+
+; copy last move for Mirror Move
+; sets zero flag on failure and unsets zero flag on success
+MirrorMoveCopyMove:
+; Mirror Move makes use of ccf1 (wPlayerUsedMove) and ccf2 (wEnemyUsedMove) addresses,
+; which are mainly used to print the "[Pokemon] used [Move]" text.
+; Both are set to 0 whenever a new Pokemon is sent out
+; ccf1 is also set to 0 whenever the player is fast asleep or frozen solid.
+; ccf2 is also set to 0 whenever the enemy is fast asleep or frozen solid.
+
+ ld a, [H_WHOSETURN]
+ and a
+; values for player turn
+ ld a, [wEnemyUsedMove]
+ ld hl, wPlayerSelectedMove
+ ld de, wPlayerMoveNum
+ jr z, .next
+; values for enemy turn
+ ld a, [wPlayerUsedMove]
+ ld de, wEnemyMoveNum
+ ld hl, wEnemySelectedMove
+.next
+ ld [hl], a
+ cp MIRROR_MOVE ; did the target Pokemon last use Mirror Move, and miss?
+ jr z, .mirrorMoveFailed
+ and a ; has the target selected any move yet?
+ jr nz, ReloadMoveData
+.mirrorMoveFailed
+ ld hl, MirrorMoveFailedText
+ call PrintText
+ xor a
+ ret
+
+MirrorMoveFailedText:
+ TX_FAR _MirrorMoveFailedText
+ db "@"
+
+; function used to reload move data for moves like Mirror Move and Metronome
+ReloadMoveData:
+ ld [wd11e], a
+ dec a
+ ld hl, Moves
+ ld bc, MoveEnd - Moves
+ call AddNTimes
+ ld a, BANK(Moves)
+ call FarCopyData ; copy the move's stats
+ call IncrementMovePP
+; the follow two function calls are used to reload the move name
+ call GetMoveName
+ call CopyStringToCF4B
+ ld a, $01
+ and a
+ ret
+
+; function that picks a random move for metronome
+MetronomePickMove:
+ xor a
+ ld [wAnimationType], a
+ ld a, METRONOME
+ call PlayMoveAnimation ; play Metronome's animation
+; values for player turn
+ ld de, wPlayerMoveNum
+ ld hl, wPlayerSelectedMove
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .pickMoveLoop
+; values for enemy turn
+ ld de, wEnemyMoveNum
+ ld hl, wEnemySelectedMove
+; loop to pick a random number in the range [1, $a5) to be the move used by Metronome
+.pickMoveLoop
+ call BattleRandom
+ and a
+ jr z, .pickMoveLoop
+ cp NUM_ATTACKS + 1 ; max normal move number + 1 (this is Struggle's move number)
+ jr nc, .pickMoveLoop
+ cp METRONOME
+ jr z, .pickMoveLoop
+ ld [hl], a
+ jr ReloadMoveData
+
+; this function increments the current move's PP
+; it's used to prevent moves that run another move within the same turn
+; (like Mirror Move and Metronome) from losing 2 PP
+IncrementMovePP:
+ ld a, [H_WHOSETURN]
+ and a
+; values for player turn
+ ld hl, wBattleMonPP
+ ld de, wPartyMon1PP
+ ld a, [wPlayerMoveListIndex]
+ jr z, .next
+; values for enemy turn
+ ld hl, wEnemyMonPP
+ ld de, wEnemyMon1PP
+ ld a, [wEnemyMoveListIndex]
+.next
+ ld b, $00
+ ld c, a
+ add hl, bc
+ inc [hl] ; increment PP in the currently battling pokemon memory location
+ ld h, d
+ ld l, e
+ add hl, bc
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMonNumber] ; value for player turn
+ jr z, .updatePP
+ ld a, [wEnemyMonPartyPos] ; value for enemy turn
+.updatePP
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ inc [hl] ; increment PP in the party memory location
+ ret
+
+; function to adjust the base damage of an attack to account for type effectiveness
+AdjustDamageForMoveType:
+; values for player turn
+ ld hl, wBattleMonType
+ ld a, [hli]
+ ld b, a ; b = type 1 of attacker
+ ld c, [hl] ; c = type 2 of attacker
+ ld hl, wEnemyMonType
+ ld a, [hli]
+ ld d, a ; d = type 1 of defender
+ ld e, [hl] ; e = type 2 of defender
+ ld a, [wPlayerMoveType]
+ ld [wMoveType], a
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .next
+; values for enemy turn
+ ld hl, wEnemyMonType
+ ld a, [hli]
+ ld b, a ; b = type 1 of attacker
+ ld c, [hl] ; c = type 2 of attacker
+ ld hl, wBattleMonType
+ ld a, [hli]
+ ld d, a ; d = type 1 of defender
+ ld e, [hl] ; e = type 2 of defender
+ ld a, [wEnemyMoveType]
+ ld [wMoveType], a
+.next
+ ld a, [wMoveType]
+ cp b ; does the move type match type 1 of the attacker?
+ jr z, .sameTypeAttackBonus
+ cp c ; does the move type match type 2 of the attacker?
+ jr z, .sameTypeAttackBonus
+ jr .skipSameTypeAttackBonus
+.sameTypeAttackBonus
+; if the move type matches one of the attacker's types
+ ld hl, wDamage + 1
+ ld a, [hld]
+ ld h, [hl]
+ ld l, a ; hl = damage
+ ld b, h
+ ld c, l ; bc = damage
+ srl b
+ rr c ; bc = floor(0.5 * damage)
+ add hl, bc ; hl = floor(1.5 * damage)
+; store damage
+ ld a, h
+ ld [wDamage], a
+ ld a, l
+ ld [wDamage + 1], a
+ ld hl, wDamageMultipliers
+ set 7, [hl]
+.skipSameTypeAttackBonus
+ ld a, [wMoveType]
+ ld b, a
+ ld hl, TypeEffects
+.loop
+ ld a, [hli] ; a = "attacking type" of the current type pair
+ cp $ff
+ jr z, .done
+ cp b ; does move type match "attacking type"?
+ jr nz, .nextTypePair
+ ld a, [hl] ; a = "defending type" of the current type pair
+ cp d ; does type 1 of defender match "defending type"?
+ jr z, .matchingPairFound
+ cp e ; does type 2 of defender match "defending type"?
+ jr z, .matchingPairFound
+ jr .nextTypePair
+.matchingPairFound
+; if the move type matches the "attacking type" and one of the defender's types matches the "defending type"
+ push hl
+ push bc
+ inc hl
+ ld a, [wDamageMultipliers]
+ and $80
+ ld b, a
+ ld a, [hl] ; a = damage multiplier
+ ld [H_MULTIPLIER], a
+ add b
+ ld [wDamageMultipliers], a
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld hl, wDamage
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hld]
+ ld [H_MULTIPLICAND + 2], a
+ call Multiply
+ ld a, 10
+ ld [H_DIVISOR], a
+ ld b, $04
+ call Divide
+ ld a, [H_QUOTIENT + 2]
+ ld [hli], a
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ ld [hl], a
+ or b ; is damage 0?
+ jr nz, .skipTypeImmunity
+.typeImmunity
+; if damage is 0, make the move miss
+; this only occurs if a move that would do 2 or 3 damage is 0.25x effective against the target
+ inc a
+ ld [wMoveMissed], a
+.skipTypeImmunity
+ pop bc
+ pop hl
+.nextTypePair
+ inc hl
+ inc hl
+ jp .loop
+.done
+ ret
+
+; function to tell how effective the type of an enemy attack is on the player's current pokemon
+; this doesn't take into account the effects that dual types can have
+; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
+; the result is stored in [wTypeEffectiveness]
+; ($05 is not very effective, $10 is neutral, $14 is super effective)
+; as far is can tell, this is only used once in some AI code to help decide which move to use
+AIGetTypeEffectiveness:
+ ld a, [wEnemyMoveType]
+ ld d, a ; d = type of enemy move
+ ld hl, wBattleMonType
+ ld b, [hl] ; b = type 1 of player's pokemon
+ inc hl
+ ld c, [hl] ; c = type 2 of player's pokemon
+ ld a, $10
+ ld [wTypeEffectiveness], a ; initialize to neutral effectiveness
+ ld hl, TypeEffects
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ cp d ; match the type of the move
+ jr nz, .nextTypePair1
+ ld a, [hli]
+ cp b ; match with type 1 of pokemon
+ jr z, .done
+ cp c ; or match with type 2 of pokemon
+ jr z, .done
+ jr .nextTypePair2
+.nextTypePair1
+ inc hl
+.nextTypePair2
+ inc hl
+ jr .loop
+.done
+ ld a, [hl]
+ ld [wTypeEffectiveness], a ; store damage multiplier
+ ret
+
+INCLUDE "data/type_effects.asm"
+
+; some tests that need to pass for a move to hit
+MoveHitTest:
+; player's turn
+ ld hl, wEnemyBattleStatus1
+ ld de, wPlayerMoveEffect
+ ld bc, wEnemyMonStatus
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .dreamEaterCheck
+; enemy's turn
+ ld hl, wPlayerBattleStatus1
+ ld de, wEnemyMoveEffect
+ ld bc, wBattleMonStatus
+.dreamEaterCheck
+ ld a, [de]
+ cp DREAM_EATER_EFFECT
+ jr nz, .swiftCheck
+ ld a, [bc]
+ and SLP ; is the target pokemon sleeping?
+ jp z, .moveMissed
+.swiftCheck
+ ld a, [de]
+ cp SWIFT_EFFECT
+ ret z ; Swift never misses (interestingly, Azure Heights lists this is a myth, but it appears to be true)
+ call CheckTargetSubstitute ; substitute check (note that this overwrites a)
+ jr z, .checkForDigOrFlyStatus
+; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
+; since $7b79 overwrites a with either $00 or $01, it never works.
+ cp DRAIN_HP_EFFECT
+ jp z, .moveMissed
+ cp DREAM_EATER_EFFECT
+ jp z, .moveMissed
+.checkForDigOrFlyStatus
+ bit INVULNERABLE, [hl]
+ jp nz, .moveMissed
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .enemyTurn
+.playerTurn
+; this checks if the move effect is disallowed by mist
+ ld a, [wPlayerMoveEffect]
+ cp ATTACK_DOWN1_EFFECT
+ jr c, .skipEnemyMistCheck
+ cp HAZE_EFFECT + 1
+ jr c, .enemyMistCheck
+ cp ATTACK_DOWN2_EFFECT
+ jr c, .skipEnemyMistCheck
+ cp REFLECT_EFFECT + 1
+ jr c, .enemyMistCheck
+ jr .skipEnemyMistCheck
+.enemyMistCheck
+; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
+; i.e. the following moves
+; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
+; FLASH, CONVERSION*, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
+; the moves that are marked with an asterisk are not affected since this
+; function is not called when those moves are used
+ ld a, [wEnemyBattleStatus2]
+ bit PROTECTED_BY_MIST, a ; is mon protected by mist?
+ jp nz, .moveMissed
+.skipEnemyMistCheck
+ ld a, [wPlayerBattleStatus2]
+ bit USING_X_ACCURACY, a ; is the player using X Accuracy?
+ ret nz ; if so, always hit regardless of accuracy/evasion
+ jr .calcHitChance
+.enemyTurn
+ ld a, [wEnemyMoveEffect]
+ cp ATTACK_DOWN1_EFFECT
+ jr c, .skipPlayerMistCheck
+ cp HAZE_EFFECT + 1
+ jr c, .playerMistCheck
+ cp ATTACK_DOWN2_EFFECT
+ jr c, .skipPlayerMistCheck
+ cp REFLECT_EFFECT + 1
+ jr c, .playerMistCheck
+ jr .skipPlayerMistCheck
+.playerMistCheck
+; similar to enemy mist check
+ ld a, [wPlayerBattleStatus2]
+ bit PROTECTED_BY_MIST, a ; is mon protected by mist?
+ jp nz, .moveMissed
+.skipPlayerMistCheck
+ ld a, [wEnemyBattleStatus2]
+ bit USING_X_ACCURACY, a ; is the enemy using X Accuracy?
+ ret nz ; if so, always hit regardless of accuracy/evasion
+.calcHitChance
+ call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
+ ld a, [wPlayerMoveAccuracy]
+ ld b, a
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .doAccuracyCheck
+ ld a, [wEnemyMoveAccuracy]
+ ld b, a
+.doAccuracyCheck
+; if the random number generated is greater than or equal to the scaled accuracy, the move misses
+; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
+ call BattleRandom
+ cp b
+ jr nc, .moveMissed
+ ret
+.moveMissed
+ xor a
+ ld hl, wDamage ; zero the damage
+ ld [hli], a
+ ld [hl], a
+ inc a
+ ld [wMoveMissed], a
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn2
+.enemyTurn2
+ ld hl, wEnemyBattleStatus1
+ res USING_TRAPPING_MOVE, [hl] ; end multi-turn attack e.g. wrap
+ ret
+.playerTurn2
+ ld hl, wPlayerBattleStatus1
+ res USING_TRAPPING_MOVE, [hl] ; end multi-turn attack e.g. wrap
+ ret
+
+; values for player turn
+CalcHitChance:
+ ld hl, wPlayerMoveAccuracy
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMonAccuracyMod]
+ ld b, a
+ ld a, [wEnemyMonEvasionMod]
+ ld c, a
+ jr z, .next
+; values for enemy turn
+ ld hl, wEnemyMoveAccuracy
+ ld a, [wEnemyMonAccuracyMod]
+ ld b, a
+ ld a, [wPlayerMonEvasionMod]
+ ld c, a
+.next
+ ld a, $0e
+ sub c
+ ld c, a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion
+ ; decreases the hit chance instead of increasing the hit chance)
+; zero the high bytes of the multiplicand
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a ; set multiplicand to move accuracy
+ push hl
+ ld d, $02 ; loop has two iterations
+; loop to do the calculations, the first iteration multiplies by the accuracy ratio and
+; the second iteration multiplies by the evasion ratio
+.loop
+ push bc
+ ld hl, StatModifierRatios ; stat modifier ratios
+ dec b
+ sla b
+ ld c, b
+ ld b, $00
+ add hl, bc ; hl = address of stat modifier ratio
+ pop bc
+ ld a, [hli]
+ ld [H_MULTIPLIER], a ; set multiplier to the numerator of the ratio
+ call Multiply
+ ld a, [hl]
+ ld [H_DIVISOR], a ; set divisor to the the denominator of the ratio
+ ; (the dividend is the product of the previous multiplication)
+ ld b, $04 ; number of bytes in the dividend
+ call Divide
+ ld a, [H_QUOTIENT + 3]
+ ld b, a
+ ld a, [H_QUOTIENT + 2]
+ or b
+ jp nz, .nextCalculation
+; make sure the result is always at least one
+ ld [H_QUOTIENT + 2], a
+ ld a, $01
+ ld [H_QUOTIENT + 3], a
+.nextCalculation
+ ld b, c
+ dec d
+ jr nz, .loop
+ ld a, [H_QUOTIENT + 2]
+ and a ; is the calculated hit chance over 0xFF?
+ ld a, [H_QUOTIENT + 3]
+ jr z, .storeAccuracy
+; if calculated hit chance over 0xFF
+ ld a, $ff ; set the hit chance to 0xFF
+.storeAccuracy
+ pop hl
+ ld [hl], a ; store the hit chance in the move accuracy variable
+ ret
+
+; multiplies damage by a random percentage from ~85% to 100%
+RandomizeDamage:
+ ld hl, wDamage
+ ld a, [hli]
+ and a
+ jr nz, .DamageGreaterThanOne
+ ld a, [hl]
+ cp 2
+ ret c ; return if damage is equal to 0 or 1
+.DamageGreaterThanOne
+ xor a
+ ld [H_MULTIPLICAND], a
+ dec hl
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+; loop until a random number greater than or equal to 217 is generated
+.loop
+ call BattleRandom
+ rrca
+ cp 217
+ jr c, .loop
+ ld [H_MULTIPLIER], a
+ call Multiply ; multiply damage by the random number, which is in the range [217, 255]
+ ld a, 255
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide ; divide the result by 255
+; store the modified damage
+ ld a, [H_QUOTIENT + 2]
+ ld hl, wDamage
+ ld [hli], a
+ ld a, [H_QUOTIENT + 3]
+ ld [hl], a
+ ret
+
+; for more detailed commentary, see equivalent function for player side (ExecutePlayerMove)
+ExecuteEnemyMove:
+ ld a, [wEnemySelectedMove]
+ inc a
+ jp z, ExecuteEnemyMoveDone
+ call PrintGhostText
+ jp z, ExecuteEnemyMoveDone
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .executeEnemyMove
+ ld b, $1
+ ld a, [wSerialExchangeNybbleReceiveData]
+ cp LINKBATTLE_STRUGGLE
+ jr z, .executeEnemyMove
+ cp 4
+ ret nc
+.executeEnemyMove
+ ld hl, wAILayer2Encouragement
+ inc [hl]
+ xor a
+ ld [wMoveMissed], a
+ ld [wMoveDidntMiss], a
+ ld a, $a
+ ld [wDamageMultipliers], a
+ call CheckEnemyStatusConditions
+ jr nz, .enemyHasNoSpecialConditions
+ jp hl
+.enemyHasNoSpecialConditions
+ ld hl, wEnemyBattleStatus1
+ bit CHARGING_UP, [hl] ; is the enemy charging up for attack?
+ jr nz, EnemyCanExecuteChargingMove ; if so, jump
+ call GetCurrentMove
+
+CheckIfEnemyNeedsToChargeUp:
+ ld a, [wEnemyMoveEffect]
+ cp CHARGE_EFFECT
+ jp z, JumpMoveEffect
+ cp FLY_EFFECT
+ jp z, JumpMoveEffect
+ jr EnemyCanExecuteMove
+EnemyCanExecuteChargingMove:
+ ld hl, wEnemyBattleStatus1
+ res CHARGING_UP, [hl] ; no longer charging up for attack
+ res INVULNERABLE, [hl] ; no longer invulnerable to typical attacks
+ ld a, [wEnemyMoveNum]
+ ld [wd0b5], a
+ ld a, BANK(MoveNames)
+ ld [wPredefBank], a
+ ld a, MOVE_NAME
+ ld [wNameListType], a
+ call GetName
+ ld de, wcd6d
+ call CopyStringToCF4B
+EnemyCanExecuteMove:
+ xor a
+ ld [wMonIsDisobedient], a
+ call PrintMonName1Text
+ ld a, [wEnemyMoveEffect]
+ ld hl, ResidualEffects1
+ ld de, $1
+ call IsInArray
+ jp c, JumpMoveEffect
+ ld a, [wEnemyMoveEffect]
+ ld hl, SpecialEffectsCont
+ ld de, $1
+ call IsInArray
+ call c, JumpMoveEffect
+EnemyCalcMoveDamage:
+ call SwapPlayerAndEnemyLevels
+ ld a, [wEnemyMoveEffect]
+ ld hl, SetDamageEffects
+ ld de, $1
+ call IsInArray
+ jp c, EnemyMoveHitTest
+ call CriticalHitTest
+ call HandleCounterMove
+ jr z, handleIfEnemyMoveMissed
+ call SwapPlayerAndEnemyLevels
+ call GetDamageVarsForEnemyAttack
+ call SwapPlayerAndEnemyLevels
+ call CalculateDamage
+ jp z, EnemyCheckIfFlyOrChargeEffect
+ call AdjustDamageForMoveType
+ call RandomizeDamage
+
+EnemyMoveHitTest:
+ call MoveHitTest
+handleIfEnemyMoveMissed:
+ ld a, [wMoveMissed]
+ and a
+ jr z, .moveDidNotMiss
+ ld a, [wEnemyMoveEffect]
+ cp EXPLODE_EFFECT
+ jr z, handleExplosionMiss
+ jr EnemyCheckIfFlyOrChargeEffect
+.moveDidNotMiss
+ call SwapPlayerAndEnemyLevels
+
+GetEnemyAnimationType:
+ ld a, [wEnemyMoveEffect]
+ and a
+ ld a, $1
+ jr z, playEnemyMoveAnimation
+ ld a, $2
+ jr playEnemyMoveAnimation
+handleExplosionMiss:
+ call SwapPlayerAndEnemyLevels
+ xor a
+playEnemyMoveAnimation:
+ push af
+ ld a, [wEnemyBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a ; does mon have a substitute?
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ pop af
+ ld [wAnimationType], a
+ ld a, [wEnemyMoveNum]
+ call PlayMoveAnimation
+ call HandleExplodingAnimation
+ call DrawEnemyHUDAndHPBar
+ ld a, [wEnemyBattleStatus2]
+ bit HAS_SUBSTITUTE_UP, a ; does mon have a substitute?
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ call nz, Bankswitch ; slide the substitute's sprite out
+ jr EnemyCheckIfMirrorMoveEffect
+
+EnemyCheckIfFlyOrChargeEffect:
+ call SwapPlayerAndEnemyLevels
+ ld c, 30
+ call DelayFrames
+ ld a, [wEnemyMoveEffect]
+ cp FLY_EFFECT
+ jr z, .playAnim
+ cp CHARGE_EFFECT
+ jr z, .playAnim
+ jr EnemyCheckIfMirrorMoveEffect
+.playAnim
+ xor a
+ ld [wAnimationType], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+EnemyCheckIfMirrorMoveEffect:
+ ld a, [wEnemyMoveEffect]
+ cp MIRROR_MOVE_EFFECT
+ jr nz, .notMirrorMoveEffect
+ call MirrorMoveCopyMove
+ jp z, ExecuteEnemyMoveDone
+ jp CheckIfEnemyNeedsToChargeUp
+.notMirrorMoveEffect
+ cp METRONOME_EFFECT
+ jr nz, .notMetronomeEffect
+ call MetronomePickMove
+ jp CheckIfEnemyNeedsToChargeUp
+.notMetronomeEffect
+ ld a, [wEnemyMoveEffect]
+ ld hl, ResidualEffects2
+ ld de, $1
+ call IsInArray
+ jp c, JumpMoveEffect
+ ld a, [wMoveMissed]
+ and a
+ jr z, .moveDidNotMiss
+ call PrintMoveFailureText
+ ld a, [wEnemyMoveEffect]
+ cp EXPLODE_EFFECT
+ jr z, .handleExplosionMiss
+ jp ExecuteEnemyMoveDone
+.moveDidNotMiss
+ call ApplyAttackToPlayerPokemon
+ call PrintCriticalOHKOText
+ callab DisplayEffectiveness
+ ld a, 1
+ ld [wMoveDidntMiss], a
+.handleExplosionMiss
+ ld a, [wEnemyMoveEffect]
+ ld hl, AlwaysHappenSideEffects
+ ld de, $1
+ call IsInArray
+ call c, JumpMoveEffect
+ ld hl, wBattleMonHP
+ ld a, [hli]
+ ld b, [hl]
+ or b
+ ret z
+ call HandleBuildingRage
+ ld hl, wEnemyBattleStatus1
+ bit ATTACKING_MULTIPLE_TIMES, [hl] ; is mon hitting multiple times? (example: double kick)
+ jr z, .notMultiHitMove
+ push hl
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl]
+ pop hl
+ jp nz, GetEnemyAnimationType
+ res ATTACKING_MULTIPLE_TIMES, [hl] ; mon is no longer hitting multiple times
+ ld hl, HitXTimesText
+ call PrintText
+ xor a
+ ld [wEnemyNumHits], a
+.notMultiHitMove
+ ld a, [wEnemyMoveEffect]
+ and a
+ jr z, ExecuteEnemyMoveDone
+ ld hl, SpecialEffects
+ ld de, $1
+ call IsInArray
+ call nc, JumpMoveEffect
+ jr ExecuteEnemyMoveDone
+
+HitXTimesText:
+ TX_FAR _HitXTimesText
+ db "@"
+
+ExecuteEnemyMoveDone:
+ ld b, $1
+ ret
+
+; checks for various status conditions affecting the enemy mon
+; stores whether the mon cannot use a move this turn in Z flag
+CheckEnemyStatusConditions:
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and SLP ; sleep mask
+ jr z, .checkIfFrozen
+ dec a ; decrement number of turns left
+ ld [wEnemyMonStatus], a
+ and a
+ jr z, .wokeUp ; if the number of turns hit 0, wake up
+ ld hl, FastAsleepText
+ call PrintText
+ xor a
+ ld [wAnimationType], a
+ ld a, SLP_ANIM
+ call PlayMoveAnimation
+ jr .sleepDone
+.wokeUp
+ ld hl, WokeUpText
+ call PrintText
+.sleepDone
+ xor a
+ ld [wEnemyUsedMove], a
+ ld hl, ExecuteEnemyMoveDone ; enemy can't move this turn
+ jp .enemyReturnToHL
+.checkIfFrozen
+ bit FRZ, [hl]
+ jr z, .checkIfTrapped
+ ld hl, IsFrozenText
+ call PrintText
+ xor a
+ ld [wEnemyUsedMove], a
+ ld hl, ExecuteEnemyMoveDone ; enemy can't move this turn
+ jp .enemyReturnToHL
+.checkIfTrapped
+ ld a, [wPlayerBattleStatus1]
+ bit USING_TRAPPING_MOVE, a ; is the player using a multi-turn attack like warp
+ jp z, .checkIfFlinched
+ ld hl, CantMoveText
+ call PrintText
+ ld hl, ExecuteEnemyMoveDone ; enemy can't move this turn
+ jp .enemyReturnToHL
+.checkIfFlinched
+ ld hl, wEnemyBattleStatus1
+ bit FLINCHED, [hl] ; check if enemy mon flinched
+ jp z, .checkIfMustRecharge
+ res FLINCHED, [hl]
+ ld hl, FlinchedText
+ call PrintText
+ ld hl, ExecuteEnemyMoveDone ; enemy can't move this turn
+ jp .enemyReturnToHL
+.checkIfMustRecharge
+ ld hl, wEnemyBattleStatus2
+ bit NEEDS_TO_RECHARGE, [hl] ; check if enemy mon has to recharge after using a move
+ jr z, .checkIfAnyMoveDisabled
+ res NEEDS_TO_RECHARGE, [hl]
+ ld hl, MustRechargeText
+ call PrintText
+ ld hl, ExecuteEnemyMoveDone ; enemy can't move this turn
+ jp .enemyReturnToHL
+.checkIfAnyMoveDisabled
+ ld hl, wEnemyDisabledMove
+ ld a, [hl]
+ and a
+ jr z, .checkIfConfused
+ dec a ; decrement disable counter
+ ld [hl], a
+ and $f ; did disable counter hit 0?
+ jr nz, .checkIfConfused
+ ld [hl], a
+ ld [wEnemyDisabledMoveNumber], a
+ ld hl, DisabledNoMoreText
+ call PrintText
+.checkIfConfused
+ ld a, [wEnemyBattleStatus1]
+ add a ; check if enemy mon is confused
+ jp nc, .checkIfTriedToUseDisabledMove
+ ld hl, wEnemyConfusedCounter
+ dec [hl]
+ jr nz, .isConfused
+ ld hl, wEnemyBattleStatus1
+ res CONFUSED, [hl] ; if confused counter hit 0, reset confusion status
+ ld hl, ConfusedNoMoreText
+ call PrintText
+ jp .checkIfTriedToUseDisabledMove
+.isConfused
+ ld hl, IsConfusedText
+ call PrintText
+ xor a
+ ld [wAnimationType], a
+ ld a, CONF_ANIM
+ call PlayMoveAnimation
+ call BattleRandom
+ cp $80
+ jr c, .checkIfTriedToUseDisabledMove
+ ld hl, wEnemyBattleStatus1
+ ld a, [hl]
+ and 1 << CONFUSED ; if mon hurts itself, clear every other status from wEnemyBattleStatus1
+ ld [hl], a
+ ld hl, HurtItselfText
+ call PrintText
+ ld hl, wBattleMonDefense
+ ld a, [hli]
+ push af
+ ld a, [hld]
+ push af
+ ld a, [wEnemyMonDefense]
+ ld [hli], a
+ ld a, [wEnemyMonDefense + 1]
+ ld [hl], a
+ ld hl, wEnemyMoveEffect
+ push hl
+ ld a, [hl]
+ push af
+ xor a
+ ld [hli], a
+ ld [wCriticalHitOrOHKO], a
+ ld a, 40
+ ld [hli], a
+ xor a
+ ld [hl], a
+ call GetDamageVarsForEnemyAttack
+ call CalculateDamage
+ pop af
+ pop hl
+ ld [hl], a
+ ld hl, wBattleMonDefense + 1
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ xor a
+ ld [wAnimationType], a
+ ld [H_WHOSETURN], a
+ ld a, POUND
+ call PlayMoveAnimation
+ ld a, $1
+ ld [H_WHOSETURN], a
+ call ApplyDamageToEnemyPokemon
+ jr .monHurtItselfOrFullyParalysed
+.checkIfTriedToUseDisabledMove
+; prevents a disabled move that was selected before being disabled from being used
+ ld a, [wEnemyDisabledMoveNumber]
+ and a
+ jr z, .checkIfParalysed
+ ld hl, wEnemySelectedMove
+ cp [hl]
+ jr nz, .checkIfParalysed
+ call PrintMoveIsDisabledText
+ ld hl, ExecuteEnemyMoveDone ; if a disabled move was somehow selected, player can't move this turn
+ jp .enemyReturnToHL
+.checkIfParalysed
+ ld hl, wEnemyMonStatus
+ bit PAR, [hl]
+ jr z, .checkIfUsingBide
+ call BattleRandom
+ cp $3f ; 25% to be fully paralysed
+ jr nc, .checkIfUsingBide
+ ld hl, FullyParalyzedText
+ call PrintText
+.monHurtItselfOrFullyParalysed
+ ld hl, wEnemyBattleStatus1
+ ld a, [hl]
+ ; clear bide, thrashing about, charging up, and multi-turn moves such as warp
+ and $ff ^ ((1 << STORING_ENERGY) | (1 << THRASHING_ABOUT) | (1 << CHARGING_UP) | (1 << USING_TRAPPING_MOVE))
+ ld [hl], a
+ ld a, [wEnemyMoveEffect]
+ cp FLY_EFFECT
+ jr z, .flyOrChargeEffect
+ cp CHARGE_EFFECT
+ jr z, .flyOrChargeEffect
+ jr .notFlyOrChargeEffect
+.flyOrChargeEffect
+ xor a
+ ld [wAnimationType], a
+ ld a, STATUS_AFFECTED_ANIM
+ call PlayMoveAnimation
+.notFlyOrChargeEffect
+ ld hl, ExecuteEnemyMoveDone
+ jp .enemyReturnToHL ; if using a two-turn move, enemy needs to recharge the first turn
+.checkIfUsingBide
+ ld hl, wEnemyBattleStatus1
+ bit STORING_ENERGY, [hl] ; is mon using bide?
+ jr z, .checkIfThrashingAbout
+ xor a
+ ld [wEnemyMoveNum], a
+ ld hl, wDamage
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, wEnemyBideAccumulatedDamage + 1
+ ld a, [hl]
+ add c ; accumulate damage taken
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl] ; did Bide counter hit 0?
+ jr z, .unleashEnergy
+ ld hl, ExecuteEnemyMoveDone
+ jp .enemyReturnToHL ; unless mon unleashes energy, can't move this turn
+.unleashEnergy
+ ld hl, wEnemyBattleStatus1
+ res STORING_ENERGY, [hl] ; not using bide any more
+ ld hl, UnleashedEnergyText
+ call PrintText
+ ld a, $1
+ ld [wEnemyMovePower], a
+ ld hl, wEnemyBideAccumulatedDamage + 1
+ ld a, [hld]
+ add a
+ ld b, a
+ ld [wDamage + 1], a
+ ld a, [hl]
+ rl a ; double the damage
+ ld [wDamage], a
+ or b
+ jr nz, .next
+ ld a, $1
+ ld [wMoveMissed], a
+.next
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld a, BIDE
+ ld [wEnemyMoveNum], a
+ call SwapPlayerAndEnemyLevels
+ ld hl, handleIfEnemyMoveMissed ; skip damage calculation, DecrementPP and MoveHitTest
+ jp .enemyReturnToHL
+.checkIfThrashingAbout
+ bit THRASHING_ABOUT, [hl] ; is mon using thrash or petal dance?
+ jr z, .checkIfUsingMultiturnMove
+ ld a, THRASH
+ ld [wEnemyMoveNum], a
+ ld hl, ThrashingAboutText
+ call PrintText
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl] ; did Thrashing About counter hit 0?
+ ld hl, EnemyCalcMoveDamage ; skip DecrementPP
+ jp nz, .enemyReturnToHL
+ push hl
+ ld hl, wEnemyBattleStatus1
+ res THRASHING_ABOUT, [hl] ; mon is no longer using thrash or petal dance
+ set CONFUSED, [hl] ; mon is now confused
+ call BattleRandom
+ and $3
+ inc a
+ inc a ; confused for 2-5 turns
+ ld [wEnemyConfusedCounter], a
+ pop hl ; skip DecrementPP
+ jp .enemyReturnToHL
+.checkIfUsingMultiturnMove
+ bit USING_TRAPPING_MOVE, [hl] ; is mon using multi-turn move?
+ jp z, .checkIfUsingRage
+ ld hl, AttackContinuesText
+ call PrintText
+ ld hl, wEnemyNumAttacksLeft
+ dec [hl] ; did multi-turn move end?
+ ld hl, GetEnemyAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
+ ; DecrementPP and MoveHitTest
+ jp nz, .enemyReturnToHL
+ jp .enemyReturnToHL
+.checkIfUsingRage
+ ld a, [wEnemyBattleStatus2]
+ bit USING_RAGE, a ; is mon using rage?
+ jp z, .checkEnemyStatusConditionsDone ; if we made it this far, mon can move normally this turn
+ ld a, RAGE
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ xor a
+ ld [wEnemyMoveEffect], a
+ ld hl, EnemyCanExecuteMove
+ jp .enemyReturnToHL
+.enemyReturnToHL
+ xor a ; set Z flag
+ ret
+.checkEnemyStatusConditionsDone
+ ld a, $1
+ and a ; clear Z flag
+ ret
+
+GetCurrentMove:
+ ld a, [H_WHOSETURN]
+ and a
+ jp z, .player
+ ld de, wEnemyMoveNum
+ ld a, [wEnemySelectedMove]
+ jr .selected
+.player
+ ld de, wPlayerMoveNum
+ ld a, [wFlags_D733]
+ bit BIT_TEST_BATTLE, a
+ ld a, [wTestBattlePlayerSelectedMove]
+ jr nz, .selected
+ ld a, [wPlayerSelectedMove]
+.selected
+ ld [wd0b5], a
+ dec a
+ ld hl, Moves
+ ld bc, MoveEnd - Moves
+ call AddNTimes
+ ld a, BANK(Moves)
+ call FarCopyData
+
+ ld a, BANK(MoveNames)
+ ld [wPredefBank], a
+ ld a, MOVE_NAME
+ ld [wNameListType], a
+ call GetName
+ ld de, wcd6d
+ jp CopyStringToCF4B
+
+LoadEnemyMonData:
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jp z, LoadEnemyMonFromParty
+ ld a, [wEnemyMonSpecies2]
+ ld [wEnemyMonSpecies], a
+ ld [wd0b5], a
+ call GetMonHeader
+ ld a, [wEnemyBattleStatus3]
+ bit TRANSFORMED, a ; is enemy mon transformed?
+ ld hl, wTransformedEnemyMonOriginalDVs ; original DVs before transforming
+ ld a, [hli]
+ ld b, [hl]
+ jr nz, .storeDVs
+ ld a, [wIsInBattle]
+ cp $2 ; is it a trainer battle?
+; fixed DVs for trainer mon
+ ld a, $98
+ ld b, $88
+ jr z, .storeDVs
+; random DVs for wild mon
+ call BattleRandom
+ ld b, a
+ call BattleRandom
+.storeDVs
+ ld hl, wEnemyMonDVs
+ ld [hli], a
+ ld [hl], b
+ ld de, wEnemyMonLevel
+ ld a, [wCurEnemyLVL]
+ ld [de], a
+ inc de
+ ld b, $0
+ ld hl, wEnemyMonHP
+ push hl
+ call CalcStats
+ pop hl
+ ld a, [wIsInBattle]
+ cp $2 ; is it a trainer battle?
+ jr z, .copyHPAndStatusFromPartyData
+ ld a, [wEnemyBattleStatus3]
+ bit TRANSFORMED, a ; is enemy mon transformed?
+ jr nz, .copyTypes ; if transformed, jump
+; if it's a wild mon and not transformed, init the current HP to max HP and the status to 0
+ ld a, [wEnemyMonMaxHP]
+ ld [hli], a
+ ld a, [wEnemyMonMaxHP+1]
+ ld [hli], a
+ xor a
+ inc hl
+ ld [hl], a ; init status to 0
+ jr .copyTypes
+; if it's a trainer mon, copy the HP and status from the enemy party data
+.copyHPAndStatusFromPartyData
+ ld hl, wEnemyMon1HP
+ ld a, [wWhichPokemon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [wEnemyMonHP], a
+ ld a, [hli]
+ ld [wEnemyMonHP + 1], a
+ ld a, [wWhichPokemon]
+ ld [wEnemyMonPartyPos], a
+ inc hl
+ ld a, [hl]
+ ld [wEnemyMonStatus], a
+ jr .copyTypes
+.copyTypes
+ ld hl, wMonHTypes
+ ld de, wEnemyMonType
+ ld a, [hli] ; copy type 1
+ ld [de], a
+ inc de
+ ld a, [hli] ; copy type 2
+ ld [de], a
+ inc de
+ ld a, [hli] ; copy catch rate
+ ld [de], a
+ inc de
+ ld a, [wIsInBattle]
+ cp $2 ; is it a trainer battle?
+ jr nz, .copyStandardMoves
+; if it's a trainer battle, copy moves from enemy party data
+ ld hl, wEnemyMon1Moves
+ ld a, [wWhichPokemon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld bc, NUM_MOVES
+ call CopyData
+ jr .loadMovePPs
+.copyStandardMoves
+; for a wild mon, first copy default moves from the mon header
+ ld hl, wMonHMoves
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ dec de
+ dec de
+ dec de
+ xor a
+ ld [wLearningMovesFromDayCare], a
+ predef WriteMonMoves ; get moves based on current level
+.loadMovePPs
+ ld hl, wEnemyMonMoves
+ ld de, wEnemyMonPP - 1
+ predef LoadMovePPs
+ ld hl, wMonHBaseStats
+ ld de, wEnemyMonBaseStats
+ ld b, NUM_STATS
+.copyBaseStatsLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyBaseStatsLoop
+ ld hl, wMonHCatchRate
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl] ; base exp
+ ld [de], a
+ ld a, [wEnemyMonSpecies2]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wcd6d
+ ld de, wEnemyMonNick
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wEnemyMonSpecies2]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, FLAG_SET
+ ld hl, wPokedexSeen
+ predef FlagActionPredef ; mark this mon as seen in the pokedex
+ ld hl, wEnemyMonLevel
+ ld de, wEnemyMonUnmodifiedLevel
+ ld bc, 1 + NUM_STATS * 2
+ call CopyData
+ ld a, $7 ; default stat mod
+ ld b, NUM_STAT_MODS ; number of stat mods
+ ld hl, wEnemyMonStatMods
+.statModLoop
+ ld [hli], a
+ dec b
+ jr nz, .statModLoop
+ ret
+
+; calls BattleTransition to show the battle transition animation and initializes some battle variables
+DoBattleTransitionAndInitBattleVariables:
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .next
+; link battle
+ xor a
+ ld [wMenuJoypadPollCount], a
+ callab DisplayLinkBattleVersusTextBox
+ ld a, $1
+ ld [wUpdateSpritesEnabled], a
+ call ClearScreen
+.next
+ call DelayFrame
+ predef BattleTransition
+ callab LoadHudAndHpBarAndStatusTilePatterns
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ call ClearSprites
+ call ClearScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld [hWY], a
+ ld [rWY], a
+ ld [hTilesetType], a
+ ld hl, wPlayerStatsToDouble
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wPlayerDisabledMove], a
+ ret
+
+; swaps the level values of the BattleMon and EnemyMon structs
+SwapPlayerAndEnemyLevels:
+ push bc
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [wEnemyMonLevel]
+ ld [wBattleMonLevel], a
+ ld a, b
+ ld [wEnemyMonLevel], a
+ pop bc
+ ret
+
+; loads either red back pic or old man back pic
+; also writes OAM data and loads tile patterns for the Red or Old Man back sprite's head
+; (for use when scrolling the player sprite and enemy's silhouettes on screen)
+LoadPlayerBackPic:
+ ld a, [wBattleType]
+ dec a ; is it the old man tutorial?
+ ld de, RedPicBack
+ jr nz, .next
+ ld de, OldManPic
+.next
+ ld a, BANK(RedPicBack)
+ call UncompressSpriteFromDE
+ predef ScaleSpriteByTwo
+ ld hl, wOAMBuffer
+ xor a
+ ld [hOAMTile], a ; initial tile number
+ ld b, $7 ; 7 columns
+ ld e, $a0 ; X for the left-most column
+.loop ; each loop iteration writes 3 OAM entries in a vertical column
+ ld c, $3 ; 3 tiles per column
+ ld d, $38 ; Y for the top of each column
+.innerLoop ; each loop iteration writes 1 OAM entry in the column
+ ld [hl], d ; OAM Y
+ inc hl
+ ld [hl], e ; OAM X
+ ld a, $8 ; height of tile
+ add d ; increase Y by height of tile
+ ld d, a
+ inc hl
+ ld a, [hOAMTile]
+ ld [hli], a ; OAM tile number
+ inc a ; increment tile number
+ ld [hOAMTile], a
+ inc hl
+ dec c
+ jr nz, .innerLoop
+ ld a, [hOAMTile]
+ add $4 ; increase tile number by 4
+ ld [hOAMTile], a
+ ld a, $8 ; width of tile
+ add e ; increase X by width of tile
+ ld e, a
+ dec b
+ jr nz, .loop
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers
+ ld a, $a
+ ld [$0], a
+ xor a
+ ld [$4000], a
+ ld hl, vSprites
+ ld de, sSpriteBuffer1
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ ld c, 7 * 7
+ call CopyVideoData
+ xor a
+ ld [$0], a
+ ld a, $31
+ ld [hStartTileID], a
+ coord hl, 1, 5
+ predef_jump CopyUncompressedPicToTilemap
+
+; does nothing since no stats are ever selected (barring glitches)
+DoubleOrHalveSelectedStats:
+ callab DoubleSelectedStats
+ jpab HalveSelectedStats
+
+ScrollTrainerPicAfterBattle:
+ jpab _ScrollTrainerPicAfterBattle
+
+ApplyBurnAndParalysisPenaltiesToPlayer:
+ ld a, $1
+ jr ApplyBurnAndParalysisPenalties
+
+ApplyBurnAndParalysisPenaltiesToEnemy:
+ xor a
+
+ApplyBurnAndParalysisPenalties:
+ ld [H_WHOSETURN], a
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+QuarterSpeedDueToParalysis:
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+.enemyTurn ; quarter the player's speed
+ ld a, [wBattleMonStatus]
+ and 1 << PAR
+ ret z ; return if player not paralysed
+ ld hl, wBattleMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storePlayerSpeed
+ ld b, 1 ; give the player a minimum of at least one speed point
+.storePlayerSpeed
+ ld [hl], b
+ ret
+.playerTurn ; quarter the enemy's speed
+ ld a, [wEnemyMonStatus]
+ and 1 << PAR
+ ret z ; return if enemy not paralysed
+ ld hl, wEnemyMonSpeed + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storeEnemySpeed
+ ld b, 1 ; give the enemy a minimum of at least one speed point
+.storeEnemySpeed
+ ld [hl], b
+ ret
+
+HalveAttackDueToBurn:
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+.enemyTurn ; halve the player's attack
+ ld a, [wBattleMonStatus]
+ and 1 << BRN
+ ret z ; return if player not burnt
+ ld hl, wBattleMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storePlayerAttack
+ ld b, 1 ; give the player a minimum of at least one attack point
+.storePlayerAttack
+ ld [hl], b
+ ret
+.playerTurn ; halve the enemy's attack
+ ld a, [wEnemyMonStatus]
+ and 1 << BRN
+ ret z ; return if enemy not burnt
+ ld hl, wEnemyMonAttack + 1
+ ld a, [hld]
+ ld b, a
+ ld a, [hl]
+ srl a
+ rr b
+ ld [hli], a
+ or b
+ jr nz, .storeEnemyAttack
+ ld b, 1 ; give the enemy a minimum of at least one attack point
+.storeEnemyAttack
+ ld [hl], b
+ ret
+
+CalculateModifiedStats:
+ ld c, 0
+.loop
+ call CalculateModifiedStat
+ inc c
+ ld a, c
+ cp NUM_STATS - 1
+ jr nz, .loop
+ ret
+
+; calculate modified stat for stat c (0 = attack, 1 = defense, 2 = speed, 3 = special)
+CalculateModifiedStat:
+ push bc
+ push bc
+ ld a, [wCalculateWhoseStats]
+ and a
+ ld a, c
+ ld hl, wBattleMonAttack
+ ld de, wPlayerMonUnmodifiedAttack
+ ld bc, wPlayerMonStatMods
+ jr z, .next
+ ld hl, wEnemyMonAttack
+ ld de, wEnemyMonUnmodifiedAttack
+ ld bc, wEnemyMonStatMods
+.next
+ add c
+ ld c, a
+ jr nc, .noCarry1
+ inc b
+.noCarry1
+ ld a, [bc]
+ pop bc
+ ld b, a
+ push bc
+ sla c
+ ld b, 0
+ add hl, bc
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .noCarry2
+ inc d
+.noCarry2
+ pop bc
+ push hl
+ ld hl, StatModifierRatios
+ dec b
+ sla b
+ ld c, b
+ ld b, 0
+ add hl, bc
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [de]
+ ld [H_MULTIPLICAND + 1], a
+ inc de
+ ld a, [de]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [hli]
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [H_DIVIDEND + 3]
+ sub 999 % $100
+ ld a, [H_DIVIDEND + 2]
+ sbc 999 / $100
+ jp c, .storeNewStatValue
+; cap the stat at 999
+ ld a, 999 / $100
+ ld [H_DIVIDEND + 2], a
+ ld a, 999 % $100
+ ld [H_DIVIDEND + 3], a
+.storeNewStatValue
+ ld a, [H_DIVIDEND + 2]
+ ld [hli], a
+ ld b, a
+ ld a, [H_DIVIDEND + 3]
+ ld [hl], a
+ or b
+ jr nz, .done
+ inc [hl] ; if the stat is 0, bump it up to 1
+.done
+ pop bc
+ ret
+
+ApplyBadgeStatBoosts:
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ ret z ; return if link battle
+ ld a, [wObtainedBadges]
+ ld b, a
+ ld hl, wBattleMonAttack
+ ld c, $4
+; the boost is applied for badges whose bit position is even
+; the order of boosts matches the order they are laid out in RAM
+; Boulder (bit 0) - attack
+; Thunder (bit 2) - defense
+; Soul (bit 4) - speed
+; Volcano (bit 6) - special
+.loop
+ srl b
+ call c, .applyBoostToStat
+ inc hl
+ inc hl
+ srl b
+ dec c
+ jr nz, .loop
+ ret
+
+; multiply stat at hl by 1.125
+; cap stat at 999
+.applyBoostToStat
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ srl d
+ rr e
+ srl d
+ rr e
+ srl d
+ rr e
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hli], a
+ ld a, [hld]
+ sub 999 % $100
+ ld a, [hl]
+ sbc 999 / $100
+ ret c
+ ld a, 999 / $100
+ ld [hli], a
+ ld a, 999 % $100
+ ld [hld], a
+ ret
+
+LoadHudAndHpBarAndStatusTilePatterns:
+ call LoadHpBarAndStatusTilePatterns
+
+LoadHudTilePatterns:
+ ld a, [rLCDC]
+ add a ; is LCD disabled?
+ jr c, .lcdEnabled
+.lcdDisabled
+ ld hl, BattleHudTiles1
+ ld de, vChars2 + $6d0
+ ld bc, BattleHudTiles1End - BattleHudTiles1
+ ld a, BANK(BattleHudTiles1)
+ call FarCopyDataDouble
+ ld hl, BattleHudTiles2
+ ld de, vChars2 + $730
+ ld bc, BattleHudTiles3End - BattleHudTiles2
+ ld a, BANK(BattleHudTiles2)
+ jp FarCopyDataDouble
+.lcdEnabled
+ ld de, BattleHudTiles1
+ ld hl, vChars2 + $6d0
+ lb bc, BANK(BattleHudTiles1), (BattleHudTiles1End - BattleHudTiles1) / $8
+ call CopyVideoDataDouble
+ ld de, BattleHudTiles2
+ ld hl, vChars2 + $730
+ lb bc, BANK(BattleHudTiles2), (BattleHudTiles3End - BattleHudTiles2) / $8
+ jp CopyVideoDataDouble
+
+PrintEmptyString:
+ ld hl, .emptyString
+ jp PrintText
+.emptyString
+ db "@"
+
+
+BattleRandom:
+; Link battles use a shared PRNG.
+
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jp nz, Random
+
+ push hl
+ push bc
+ ld a, [wLinkBattleRandomNumberListIndex]
+ ld c, a
+ ld b, 0
+ ld hl, wLinkBattleRandomNumberList
+ add hl, bc
+ inc a
+ ld [wLinkBattleRandomNumberListIndex], a
+ cp 9
+ ld a, [hl]
+ pop bc
+ pop hl
+ ret c
+
+; if we picked the last seed, we need to recalculate the nine seeds
+ push hl
+ push bc
+ push af
+
+; point to seed 0 so we pick the first number the next time
+ xor a
+ ld [wLinkBattleRandomNumberListIndex], a
+
+ ld hl, wLinkBattleRandomNumberList
+ ld b, 9
+.loop
+ ld a, [hl]
+ ld c, a
+; multiply by 5
+ add a
+ add a
+ add c
+; add 1
+ inc a
+ ld [hli], a
+ dec b
+ jr nz, .loop
+
+ pop af
+ pop bc
+ pop hl
+ ret
+
+
+HandleExplodingAnimation:
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wEnemyMonType1
+ ld de, wEnemyBattleStatus1
+ ld a, [wPlayerMoveNum]
+ jr z, .player
+ ld hl, wBattleMonType1
+ ld de, wEnemyBattleStatus1
+ ld a, [wEnemyMoveNum]
+.player
+ cp SELFDESTRUCT
+ jr z, .isExplodingMove
+ cp EXPLOSION
+ ret nz
+.isExplodingMove
+ ld a, [de]
+ bit INVULNERABLE, a ; fly/dig
+ ret nz
+ ld a, [hli]
+ cp GHOST
+ ret z
+ ld a, [hl]
+ cp GHOST
+ ret z
+ ld a, [wMoveMissed]
+ and a
+ ret nz
+ ld a, 5
+ ld [wAnimationType], a
+
+PlayMoveAnimation:
+ ld [wAnimationID], a
+ call Delay3
+ predef_jump MoveAnimation
+
+InitBattle:
+ ld a, [wCurOpponent]
+ and a
+ jr z, DetermineWildOpponent
+
+InitOpponent:
+ ld a, [wCurOpponent]
+ ld [wcf91], a
+ ld [wEnemyMonSpecies2], a
+ jr InitBattleCommon
+
+DetermineWildOpponent:
+ ld a, [wd732]
+ bit 1, a
+ jr z, .asm_3ef2f
+ ld a, [hJoyHeld]
+ bit 1, a ; B button pressed?
+ ret nz
+.asm_3ef2f
+ ld a, [wNumberOfNoRandomBattleStepsLeft]
+ and a
+ ret nz
+ callab TryDoWildEncounter
+ ret nz
+InitBattleCommon:
+ ld a, [wMapPalOffset]
+ push af
+ ld hl, wLetterPrintingDelayFlags
+ ld a, [hl]
+ push af
+ res 1, [hl]
+ callab InitBattleVariables
+ ld a, [wEnemyMonSpecies2]
+ sub 200
+ jp c, InitWildBattle
+ ld [wTrainerClass], a
+ call GetTrainerInformation
+ callab ReadTrainer
+ call DoBattleTransitionAndInitBattleVariables
+ call _LoadTrainerPic
+ xor a
+ ld [wEnemyMonSpecies2], a
+ ld [hStartTileID], a
+ dec a
+ ld [wAICount], a
+ coord hl, 12, 0
+ predef CopyUncompressedPicToTilemap
+ ld a, $ff
+ ld [wEnemyMonPartyPos], a
+ ld a, $2
+ ld [wIsInBattle], a
+ jp _InitBattleCommon
+
+InitWildBattle:
+ ld a, $1
+ ld [wIsInBattle], a
+ call LoadEnemyMonData
+ call DoBattleTransitionAndInitBattleVariables
+ ld a, [wCurOpponent]
+ cp MAROWAK
+ jr z, .isGhost
+ call IsGhostBattle
+ jr nz, .isNoGhost
+.isGhost
+ ld hl, wMonHSpriteDim
+ ld a, $66
+ ld [hli], a ; write sprite dimensions
+ ld bc, GhostPic
+ ld a, c
+ ld [hli], a ; write front sprite pointer
+ ld [hl], b
+ ld hl, wEnemyMonNick ; set name to "GHOST"
+ ld a, "G"
+ ld [hli], a
+ ld a, "H"
+ ld [hli], a
+ ld a, "O"
+ ld [hli], a
+ ld a, "S"
+ ld [hli], a
+ ld a, "T"
+ ld [hli], a
+ ld [hl], "@"
+ ld a, [wcf91]
+ push af
+ ld a, MON_GHOST
+ ld [wcf91], a
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load ghost sprite
+ pop af
+ ld [wcf91], a
+ jr .spriteLoaded
+.isNoGhost
+ ld de, vFrontPic
+ call LoadMonFrontSprite ; load mon sprite
+.spriteLoaded
+ xor a
+ ld [wTrainerClass], a
+ ld [hStartTileID], a
+ coord hl, 12, 0
+ predef CopyUncompressedPicToTilemap
+
+; common code that executes after init battle code specific to trainer or wild battles
+_InitBattleCommon:
+ ld b, SET_PAL_BATTLE_BLACK
+ call RunPaletteCommand
+ call SlidePlayerAndEnemySilhouettesOnScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, .emptyString
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ call ClearScreen
+ ld a, $98
+ ld [H_AUTOBGTRANSFERDEST + 1], a
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld a, $9c
+ ld [H_AUTOBGTRANSFERDEST + 1], a
+ call LoadScreenTilesFromBuffer1
+ coord hl, 9, 7
+ lb bc, 5, 10
+ call ClearScreenArea
+ coord hl, 1, 0
+ lb bc, 4, 10
+ call ClearScreenArea
+ call ClearSprites
+ ld a, [wIsInBattle]
+ dec a ; is it a wild battle?
+ call z, DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle
+ call StartBattle
+ callab EndOfBattle
+ pop af
+ ld [wLetterPrintingDelayFlags], a
+ pop af
+ ld [wMapPalOffset], a
+ ld a, [wSavedTilesetType]
+ ld [hTilesetType], a
+ scf
+ ret
+.emptyString
+ db "@"
+
+_LoadTrainerPic:
+; wd033-wd034 contain pointer to pic
+ ld a, [wTrainerPicPointer]
+ ld e, a
+ ld a, [wTrainerPicPointer + 1]
+ ld d, a ; de contains pointer to trainer pic
+ ld a, [wLinkState]
+ and a
+ ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
+ jr z, .loadSprite
+ ld a, Bank(RedPicFront)
+.loadSprite
+ call UncompressSpriteFromDE
+ ld de, vFrontPic
+ ld a, $77
+ ld c, a
+ jp LoadUncompressedSpriteData
+
+; unreferenced
+ResetCryModifiers:
+ xor a
+ ld [wFrequencyModifier], a
+ ld [wTempoModifier], a
+ jp PlaySound
+
+; animates the mon "growing" out of the pokeball
+AnimateSendingOutMon:
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ ld l, a
+ ld a, [hStartTileID]
+ ld [hBaseTileID], a
+ ld b, $4c
+ ld a, [wIsInBattle]
+ and a
+ jr z, .notInBattle
+ add b
+ ld [hl], a
+ call Delay3
+ ld bc, -(SCREEN_WIDTH * 2 + 1)
+ add hl, bc
+ ld a, 1
+ ld [wDownscaledMonSize], a
+ lb bc, 3, 3
+ predef CopyDownscaledMonTiles
+ ld c, 4
+ call DelayFrames
+ ld bc, -(SCREEN_WIDTH * 2 + 1)
+ add hl, bc
+ xor a
+ ld [wDownscaledMonSize], a
+ lb bc, 5, 5
+ predef CopyDownscaledMonTiles
+ ld c, 5
+ call DelayFrames
+ ld bc, -(SCREEN_WIDTH * 2 + 1)
+ jr .next
+.notInBattle
+ ld bc, -(SCREEN_WIDTH * 6 + 3)
+.next
+ add hl, bc
+ ld a, [hBaseTileID]
+ add $31
+ jr CopyUncompressedPicToHL
+
+CopyUncompressedPicToTilemap:
+ ld a, [wPredefRegisters]
+ ld h, a
+ ld a, [wPredefRegisters + 1]
+ ld l, a
+ ld a, [hStartTileID]
+CopyUncompressedPicToHL:
+ lb bc, 7, 7
+ ld de, SCREEN_WIDTH
+ push af
+ ld a, [wSpriteFlipped]
+ and a
+ jr nz, .flipped
+ pop af
+.loop
+ push bc
+ push hl
+.innerLoop
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .innerLoop
+ pop hl
+ inc hl
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+.flipped
+ push bc
+ ld b, 0
+ dec c
+ add hl, bc
+ pop bc
+ pop af
+.flippedLoop
+ push bc
+ push hl
+.flippedInnerLoop
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .flippedInnerLoop
+ pop hl
+ dec hl
+ pop bc
+ dec b
+ jr nz, .flippedLoop
+ ret
+
+LoadMonBackPic:
+; Assumes the monster's attributes have
+; been loaded with GetMonHeader.
+ ld a, [wBattleMonSpecies2]
+ ld [wcf91], a
+ coord hl, 1, 5
+ ld b, 7
+ ld c, 8
+ call ClearScreenArea
+ ld hl, wMonHBackSprite - wMonHeader
+ call UncompressMonSprite
+ predef ScaleSpriteByTwo
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
+ ld hl, vSprites
+ ld de, vBackPic
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+JumpMoveEffect:
+ call _JumpMoveEffect
+ ld b, $1
+ ret
+
+_JumpMoveEffect:
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .next1
+ ld a, [wEnemyMoveEffect]
+.next1
+ dec a ; subtract 1, there is no special effect for 00
+ add a ; x2, 16bit pointers
+ ld hl, MoveEffectPointerTable
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl ; jump to special effect handler
+
+MoveEffectPointerTable:
+ dw SleepEffect ; unused effect
+ dw PoisonEffect ; POISON_SIDE_EFFECT1
+ dw DrainHPEffect ; DRAIN_HP_EFFECT
+ dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT1
+ dw FreezeBurnParalyzeEffect ; FREEZE_SIDE_EFFECT
+ dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT1
+ dw ExplodeEffect ; EXPLODE_EFFECT
+ dw DrainHPEffect ; DREAM_EATER_EFFECT
+ dw $0000 ; MIRROR_MOVE_EFFECT
+ dw StatModifierUpEffect ; ATTACK_UP1_EFFECT
+ dw StatModifierUpEffect ; DEFENSE_UP1_EFFECT
+ dw StatModifierUpEffect ; SPEED_UP1_EFFECT
+ dw StatModifierUpEffect ; SPECIAL_UP1_EFFECT
+ dw StatModifierUpEffect ; ACCURACY_UP1_EFFECT
+ dw StatModifierUpEffect ; EVASION_UP1_EFFECT
+ dw PayDayEffect ; PAY_DAY_EFFECT
+ dw $0000 ; SWIFT_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN1_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN1_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN1_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN1_EFFECT
+ dw StatModifierDownEffect ; ACCURACY_DOWN1_EFFECT
+ dw StatModifierDownEffect ; EVASION_DOWN1_EFFECT
+ dw ConversionEffect ; CONVERSION_EFFECT
+ dw HazeEffect ; HAZE_EFFECT
+ dw BideEffect ; BIDE_EFFECT
+ dw ThrashPetalDanceEffect ; THRASH_PETAL_DANCE_EFFECT
+ dw SwitchAndTeleportEffect ; SWITCH_AND_TELEPORT_EFFECT
+ dw TwoToFiveAttacksEffect ; TWO_TO_FIVE_ATTACKS_EFFECT
+ dw TwoToFiveAttacksEffect ; unused effect
+ dw FlinchSideEffect ; FLINCH_SIDE_EFFECT1
+ dw SleepEffect ; SLEEP_EFFECT
+ dw PoisonEffect ; POISON_SIDE_EFFECT2
+ dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT2
+ dw FreezeBurnParalyzeEffect ; unused effect
+ dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT2
+ dw FlinchSideEffect ; FLINCH_SIDE_EFFECT2
+ dw OneHitKOEffect ; OHKO_EFFECT
+ dw ChargeEffect ; CHARGE_EFFECT
+ dw $0000 ; SUPER_FANG_EFFECT
+ dw $0000 ; SPECIAL_DAMAGE_EFFECT
+ dw TrappingEffect ; TRAPPING_EFFECT
+ dw ChargeEffect ; FLY_EFFECT
+ dw TwoToFiveAttacksEffect ; ATTACK_TWICE_EFFECT
+ dw $0000 ; JUMP_KICK_EFFECT
+ dw MistEffect ; MIST_EFFECT
+ dw FocusEnergyEffect ; FOCUS_ENERGY_EFFECT
+ dw RecoilEffect ; RECOIL_EFFECT
+ dw ConfusionEffect ; CONFUSION_EFFECT
+ dw StatModifierUpEffect ; ATTACK_UP2_EFFECT
+ dw StatModifierUpEffect ; DEFENSE_UP2_EFFECT
+ dw StatModifierUpEffect ; SPEED_UP2_EFFECT
+ dw StatModifierUpEffect ; SPECIAL_UP2_EFFECT
+ dw StatModifierUpEffect ; ACCURACY_UP2_EFFECT
+ dw StatModifierUpEffect ; EVASION_UP2_EFFECT
+ dw HealEffect ; HEAL_EFFECT
+ dw TransformEffect ; TRANSFORM_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN2_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN2_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN2_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN2_EFFECT
+ dw StatModifierDownEffect ; ACCURACY_DOWN2_EFFECT
+ dw StatModifierDownEffect ; EVASION_DOWN2_EFFECT
+ dw ReflectLightScreenEffect ; LIGHT_SCREEN_EFFECT
+ dw ReflectLightScreenEffect ; REFLECT_EFFECT
+ dw PoisonEffect ; POISON_EFFECT
+ dw ParalyzeEffect ; PARALYZE_EFFECT
+ dw StatModifierDownEffect ; ATTACK_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; DEFENSE_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; SPEED_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; SPECIAL_DOWN_SIDE_EFFECT
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw StatModifierDownEffect ; unused effect
+ dw ConfusionSideEffect ; CONFUSION_SIDE_EFFECT
+ dw TwoToFiveAttacksEffect ; TWINEEDLE_EFFECT
+ dw $0000 ; unused effect
+ dw SubstituteEffect ; SUBSTITUTE_EFFECT
+ dw HyperBeamEffect ; HYPER_BEAM_EFFECT
+ dw RageEffect ; RAGE_EFFECT
+ dw MimicEffect ; MIMIC_EFFECT
+ dw $0000 ; METRONOME_EFFECT
+ dw LeechSeedEffect ; LEECH_SEED_EFFECT
+ dw SplashEffect ; SPLASH_EFFECT
+ dw DisableEffect ; DISABLE_EFFECT
+
+SleepEffect:
+ ld de, wEnemyMonStatus
+ ld bc, wEnemyBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jp z, .sleepEffect
+ ld de, wBattleMonStatus
+ ld bc, wPlayerBattleStatus2
+
+.sleepEffect
+ ld a, [bc]
+ bit NEEDS_TO_RECHARGE, a ; does the target need to recharge? (hyper beam)
+ res NEEDS_TO_RECHARGE, a ; target no longer needs to recharge
+ ld [bc], a
+ jr nz, .setSleepCounter ; if the target had to recharge, all hit tests will be skipped
+ ; including the event where the target already has another status
+ ld a, [de]
+ ld b, a
+ and $7
+ jr z, .notAlreadySleeping ; can't affect a mon that is already asleep
+ ld hl, AlreadyAsleepText
+ jp PrintText
+.notAlreadySleeping
+ ld a, b
+ and a
+ jr nz, .didntAffect ; can't affect a mon that is already statused
+ push de
+ call MoveHitTest ; apply accuracy tests
+ pop de
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .didntAffect
+.setSleepCounter
+; set target's sleep counter to a random number between 1 and 7
+ call BattleRandom
+ and $7
+ jr z, .setSleepCounter
+ ld [de], a
+ call PlayCurrentMoveAnimation2
+ ld hl, FellAsleepText
+ jp PrintText
+.didntAffect
+ jp PrintDidntAffectText
+
+FellAsleepText:
+ TX_FAR _FellAsleepText
+ db "@"
+
+AlreadyAsleepText:
+ TX_FAR _AlreadyAsleepText
+ db "@"
+
+PoisonEffect:
+ ld hl, wEnemyMonStatus
+ ld de, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .poisonEffect
+ ld hl, wBattleMonStatus
+ ld de, wEnemyMoveEffect
+.poisonEffect
+ call CheckTargetSubstitute
+ jr nz, .noEffect ; can't poison a substitute target
+ ld a, [hli]
+ ld b, a
+ and a
+ jr nz, .noEffect ; miss if target is already statused
+ ld a, [hli]
+ cp POISON ; can't poison a poison-type target
+ jr z, .noEffect
+ ld a, [hld]
+ cp POISON ; can't poison a poison-type target
+ jr z, .noEffect
+ ld a, [de]
+ cp POISON_SIDE_EFFECT1
+ ld b, $34 ; ~20% chance of poisoning
+ jr z, .sideEffectTest
+ cp POISON_SIDE_EFFECT2
+ ld b, $67 ; ~40% chance of poisoning
+ jr z, .sideEffectTest
+ push hl
+ push de
+ call MoveHitTest ; apply accuracy tests
+ pop de
+ pop hl
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .didntAffect
+ jr .inflictPoison
+.sideEffectTest
+ call BattleRandom
+ cp b ; was side effect successful?
+ ret nc
+.inflictPoison
+ dec hl
+ set 3, [hl] ; mon is now poisoned
+ push de
+ dec de
+ ld a, [H_WHOSETURN]
+ and a
+ ld b, ANIM_C7
+ ld hl, wPlayerBattleStatus3
+ ld a, [de]
+ ld de, wPlayerToxicCounter
+ jr nz, .ok
+ ld b, ANIM_A9
+ ld hl, wEnemyBattleStatus3
+ ld de, wEnemyToxicCounter
+.ok
+ cp TOXIC
+ jr nz, .normalPoison ; done if move is not Toxic
+ set BADLY_POISONED, [hl] ; else set Toxic battstatus
+ xor a
+ ld [de], a
+ ld hl, BadlyPoisonedText
+ jr .continue
+.normalPoison
+ ld hl, PoisonedText
+.continue
+ pop de
+ ld a, [de]
+ cp POISON_EFFECT
+ jr z, .regularPoisonEffect
+ ld a, b
+ call PlayBattleAnimation2
+ jp PrintText
+.regularPoisonEffect
+ call PlayCurrentMoveAnimation2
+ jp PrintText
+.noEffect
+ ld a, [de]
+ cp POISON_EFFECT
+ ret nz
+.didntAffect
+ ld c, 50
+ call DelayFrames
+ jp PrintDidntAffectText
+
+PoisonedText:
+ TX_FAR _PoisonedText
+ db "@"
+
+BadlyPoisonedText:
+ TX_FAR _BadlyPoisonedText
+ db "@"
+
+DrainHPEffect:
+ jpab DrainHPEffect_
+
+ExplodeEffect:
+ ld hl, wBattleMonHP
+ ld de, wPlayerBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .faintUser
+ ld hl, wEnemyMonHP
+ ld de, wEnemyBattleStatus2
+.faintUser
+ xor a
+ ld [hli], a ; set the mon's HP to 0
+ ld [hli], a
+ inc hl
+ ld [hl], a ; set mon's status to 0
+ ld a, [de]
+ res SEEDED, a ; clear mon's leech seed status
+ ld [de], a
+ ret
+
+FreezeBurnParalyzeEffect:
+ xor a
+ ld [wAnimationType], a
+ call CheckTargetSubstitute ; test bit 4 of d063/d068 flags [target has substitute flag]
+ ret nz ; return if they have a substitute, can't effect them
+ ld a, [H_WHOSETURN]
+ and a
+ jp nz, opponentAttacker
+ ld a, [wEnemyMonStatus]
+ and a
+ jp nz, CheckDefrost ; can't inflict status if opponent is already statused
+ ld a, [wPlayerMoveType]
+ ld b, a
+ ld a, [wEnemyMonType1]
+ cp b ; do target type 1 and move type match?
+ ret z ; return if they match (an ice move can't freeze an ice-type, body slam can't paralyze a normal-type, etc.)
+ ld a, [wEnemyMonType2]
+ cp b ; do target type 2 and move type match?
+ ret z ; return if they match
+ ld a, [wPlayerMoveEffect]
+ cp PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those
+ ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
+ jr c, .next1 ; branch ahead if this is a 10% chance effect..
+ ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
+ sub $1e ; subtract $1E to map to equivalent 10% chance effects
+.next1
+ push af
+ call BattleRandom ; get random 8bit value for probability test
+ cp b
+ pop bc
+ ret nc ; do nothing if random value is >= 1A or 4D [no status applied]
+ ld a, b ; what type of effect is this?
+ cp BURN_SIDE_EFFECT1
+ jr z, .burn
+ cp FREEZE_SIDE_EFFECT
+ jr z, .freeze
+; .paralyze
+ ld a, 1 << PAR
+ ld [wEnemyMonStatus], a
+ call QuarterSpeedDueToParalysis ; quarter speed of affected mon
+ ld a, ANIM_A9
+ call PlayBattleAnimation
+ jp PrintMayNotAttackText ; print paralysis text
+.burn
+ ld a, 1 << BRN
+ ld [wEnemyMonStatus], a
+ call HalveAttackDueToBurn ; halve attack of affected mon
+ ld a, ANIM_A9
+ call PlayBattleAnimation
+ ld hl, BurnedText
+ jp PrintText
+.freeze
+ call ClearHyperBeam ; resets hyper beam (recharge) condition from target
+ ld a, 1 << FRZ
+ ld [wEnemyMonStatus], a
+ ld a, ANIM_A9
+ call PlayBattleAnimation
+ ld hl, FrozenText
+ jp PrintText
+opponentAttacker:
+ ld a, [wBattleMonStatus] ; mostly same as above with addresses swapped for opponent
+ and a
+ jp nz, CheckDefrost
+ ld a, [wEnemyMoveType]
+ ld b, a
+ ld a, [wBattleMonType1]
+ cp b
+ ret z
+ ld a, [wBattleMonType2]
+ cp b
+ ret z
+ ld a, [wEnemyMoveEffect]
+ cp PARALYZE_SIDE_EFFECT1 + 1
+ ld b, $1a
+ jr c, .next1
+ ld b, $4d
+ sub $1e
+.next1
+ push af
+ call BattleRandom
+ cp b
+ pop bc
+ ret nc
+ ld a, b
+ cp BURN_SIDE_EFFECT1
+ jr z, .burn
+ cp FREEZE_SIDE_EFFECT
+ jr z, .freeze
+ ld a, 1 << PAR
+ ld [wBattleMonStatus], a
+ call QuarterSpeedDueToParalysis
+ jp PrintMayNotAttackText
+.burn
+ ld a, 1 << BRN
+ ld [wBattleMonStatus], a
+ call HalveAttackDueToBurn
+ ld hl, BurnedText
+ jp PrintText
+.freeze
+; hyper beam bits aren't reseted for opponent's side
+ ld a, 1 << FRZ
+ ld [wBattleMonStatus], a
+ ld hl, FrozenText
+ jp PrintText
+
+BurnedText:
+ TX_FAR _BurnedText
+ db "@"
+
+FrozenText:
+ TX_FAR _FrozenText
+ db "@"
+
+CheckDefrost:
+; any fire-type move that has a chance inflict burn (all but Fire Spin) will defrost a frozen target
+ and 1 << FRZ ; are they frozen?
+ ret z ; return if so
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .opponent
+ ;player [attacker]
+ ld a, [wPlayerMoveType]
+ sub FIRE
+ ret nz ; return if type of move used isn't fire
+ ld [wEnemyMonStatus], a ; set opponent status to 00 ["defrost" a frozen monster]
+ ld hl, wEnemyMon1Status
+ ld a, [wEnemyMonPartyPos]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ xor a
+ ld [hl], a ; clear status in roster
+ ld hl, FireDefrostedText
+ jr .common
+.opponent
+ ld a, [wEnemyMoveType] ; same as above with addresses swapped
+ sub FIRE
+ ret nz
+ ld [wBattleMonStatus], a
+ ld hl, wPartyMon1Status
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ xor a
+ ld [hl], a
+ ld hl, FireDefrostedText
+.common
+ jp PrintText
+
+FireDefrostedText:
+ TX_FAR _FireDefrostedText
+ db "@"
+
+StatModifierUpEffect:
+ ld hl, wPlayerMonStatMods
+ ld de, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .statModifierUpEffect
+ ld hl, wEnemyMonStatMods
+ ld de, wEnemyMoveEffect
+.statModifierUpEffect
+ ld a, [de]
+ sub ATTACK_UP1_EFFECT
+ cp EVASION_UP1_EFFECT + $3 - ATTACK_UP1_EFFECT ; covers all +1 effects
+ jr c, .incrementStatMod
+ sub ATTACK_UP2_EFFECT - ATTACK_UP1_EFFECT ; map +2 effects to equivalent +1 effect
+.incrementStatMod
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl]
+ inc b ; increment corresponding stat mod
+ ld a, $d
+ cp b ; can't raise stat past +6 ($d or 13)
+ jp c, PrintNothingHappenedText
+ ld a, [de]
+ cp ATTACK_UP1_EFFECT + $8 ; is it a +2 effect?
+ jr c, .ok
+ inc b ; if so, increment stat mod again
+ ld a, $d
+ cp b ; unless it's already +6
+ jr nc, .ok
+ ld b, a
+.ok
+ ld [hl], b
+ ld a, c
+ cp $4
+ jr nc, UpdateStatDone ; jump if mod affected is evasion/accuracy
+ push hl
+ ld hl, wBattleMonAttack + 1
+ ld de, wPlayerMonUnmodifiedAttack
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .pointToStats
+ ld hl, wEnemyMonAttack + 1
+ ld de, wEnemyMonUnmodifiedAttack
+.pointToStats
+ push bc
+ sla c
+ ld b, $0
+ add hl, bc ; hl = modified stat
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .checkIf999
+ inc d ; de = unmodified (original) stat
+.checkIf999
+ pop bc
+ ld a, [hld]
+ sub 999 % $100 ; check if stat is already 999
+ jr nz, .recalculateStat
+ ld a, [hl]
+ sbc 999 / $100
+ jp z, RestoreOriginalStatModifier
+.recalculateStat ; recalculate affected stat
+ ; paralysis and burn penalties, as well as badge boosts are ignored
+ push hl
+ push bc
+ ld hl, StatModifierRatios
+ dec b
+ sla b
+ ld c, b
+ ld b, $0
+ add hl, bc
+ pop bc
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [de]
+ ld [H_MULTIPLICAND + 1], a
+ inc de
+ ld a, [de]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [hli]
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide
+ pop hl
+; cap at 999
+ ld a, [H_PRODUCT + 3]
+ sub 999 % $100
+ ld a, [H_PRODUCT + 2]
+ sbc 999 / $100
+ jp c, UpdateStat
+ ld a, 999 / $100
+ ld [H_MULTIPLICAND + 1], a
+ ld a, 999 % $100
+ ld [H_MULTIPLICAND + 2], a
+
+UpdateStat:
+ ld a, [H_PRODUCT + 2]
+ ld [hli], a
+ ld a, [H_PRODUCT + 3]
+ ld [hl], a
+ pop hl
+UpdateStatDone:
+ ld b, c
+ inc b
+ call PrintStatText
+ ld hl, wPlayerBattleStatus2
+ ld de, wPlayerMoveNum
+ ld bc, wPlayerMonMinimized
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .asm_3f4e6
+ ld hl, wEnemyBattleStatus2
+ ld de, wEnemyMoveNum
+ ld bc, wEnemyMonMinimized
+.asm_3f4e6
+ ld a, [de]
+ cp MINIMIZE
+ jr nz, .asm_3f4f9
+ ; if a substitute is up, slide off the substitute and show the mon pic before
+ ; playing the minimize animation
+ bit HAS_SUBSTITUTE_UP, [hl]
+ push af
+ push bc
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ push de
+ call nz, Bankswitch
+ pop de
+.asm_3f4f9
+ call PlayCurrentMoveAnimation
+ ld a, [de]
+ cp MINIMIZE
+ jr nz, .applyBadgeBoostsAndStatusPenalties
+ pop bc
+ ld a, $1
+ ld [bc], a
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ pop af
+ call nz, Bankswitch
+.applyBadgeBoostsAndStatusPenalties
+ ld a, [H_WHOSETURN]
+ and a
+ call z, ApplyBadgeStatBoosts ; whenever the player uses a stat-up move, badge boosts get reapplied again to every stat,
+ ; even to those not affected by the stat-up move (will be boosted further)
+ ld hl, MonsStatsRoseText
+ call PrintText
+
+; these shouldn't be here
+ call QuarterSpeedDueToParalysis ; apply speed penalty to the player whose turn is not, if it's paralyzed
+ jp HalveAttackDueToBurn ; apply attack penalty to the player whose turn is not, if it's burned
+
+RestoreOriginalStatModifier:
+ pop hl
+ dec [hl]
+
+PrintNothingHappenedText:
+ ld hl, NothingHappenedText
+ jp PrintText
+
+MonsStatsRoseText:
+ TX_FAR _MonsStatsRoseText
+ TX_ASM
+ ld hl, GreatlyRoseText
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .playerTurn
+ ld a, [wEnemyMoveEffect]
+.playerTurn
+ cp ATTACK_DOWN1_EFFECT
+ ret nc
+ ld hl, RoseText
+ ret
+
+GreatlyRoseText:
+ TX_DELAY
+ TX_FAR _GreatlyRoseText
+; fallthrough
+RoseText:
+ TX_FAR _RoseText
+ db "@"
+
+StatModifierDownEffect:
+ ld hl, wEnemyMonStatMods
+ ld de, wPlayerMoveEffect
+ ld bc, wEnemyBattleStatus1
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .statModifierDownEffect
+ ld hl, wPlayerMonStatMods
+ ld de, wEnemyMoveEffect
+ ld bc, wPlayerBattleStatus1
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .statModifierDownEffect
+ call BattleRandom
+ cp $40 ; 1/4 chance to miss by in regular battle
+ jp c, MoveMissed
+.statModifierDownEffect
+ call CheckTargetSubstitute ; can't hit through substitute
+ jp nz, MoveMissed
+ ld a, [de]
+ cp ATTACK_DOWN_SIDE_EFFECT
+ jr c, .nonSideEffect
+ call BattleRandom
+ cp $55 ; 85/256 chance for side effects
+ jp nc, CantLowerAnymore
+ ld a, [de]
+ sub ATTACK_DOWN_SIDE_EFFECT ; map each stat to 0-3
+ jr .decrementStatMod
+.nonSideEffect ; non-side effects only
+ push hl
+ push de
+ push bc
+ call MoveHitTest ; apply accuracy tests
+ pop bc
+ pop de
+ pop hl
+ ld a, [wMoveMissed]
+ and a
+ jp nz, MoveMissed
+ ld a, [bc]
+ bit INVULNERABLE, a ; fly/dig
+ jp nz, MoveMissed
+ ld a, [de]
+ sub ATTACK_DOWN1_EFFECT
+ cp EVASION_DOWN1_EFFECT + $3 - ATTACK_DOWN1_EFFECT ; covers all -1 effects
+ jr c, .decrementStatMod
+ sub ATTACK_DOWN2_EFFECT - ATTACK_DOWN1_EFFECT ; map -2 effects to corresponding -1 effect
+.decrementStatMod
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl]
+ dec b ; dec corresponding stat mod
+ jp z, CantLowerAnymore ; if stat mod is 1 (-6), can't lower anymore
+ ld a, [de]
+ cp ATTACK_DOWN2_EFFECT - $16 ; $24
+ jr c, .ok
+ cp EVASION_DOWN2_EFFECT + $5 ; $44
+ jr nc, .ok
+ dec b ; stat down 2 effects only (dec mod again)
+ jr nz, .ok
+ inc b ; increment mod to 1 (-6) if it would become 0 (-7)
+.ok
+ ld [hl], b ; save modified mod
+ ld a, c
+ cp $4
+ jr nc, UpdateLoweredStatDone ; jump for evasion/accuracy
+ push hl
+ push de
+ ld hl, wEnemyMonAttack + 1
+ ld de, wEnemyMonUnmodifiedAttack
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .pointToStat
+ ld hl, wBattleMonAttack + 1
+ ld de, wPlayerMonUnmodifiedAttack
+.pointToStat
+ push bc
+ sla c
+ ld b, $0
+ add hl, bc ; hl = modified stat
+ ld a, c
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d ; de = unmodified stat
+.noCarry
+ pop bc
+ ld a, [hld]
+ sub $1 ; can't lower stat below 1 (-6)
+ jr nz, .recalculateStat
+ ld a, [hl]
+ and a
+ jp z, CantLowerAnymore_Pop
+.recalculateStat
+; recalculate affected stat
+; paralysis and burn penalties, as well as badge boosts are ignored
+ push hl
+ push bc
+ ld hl, StatModifierRatios
+ dec b
+ sla b
+ ld c, b
+ ld b, $0
+ add hl, bc
+ pop bc
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [de]
+ ld [H_MULTIPLICAND + 1], a
+ inc de
+ ld a, [de]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, [hli]
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hl]
+ ld [H_DIVISOR], a
+ ld b, $4
+ call Divide
+ pop hl
+ ld a, [H_PRODUCT + 3]
+ ld b, a
+ ld a, [H_PRODUCT + 2]
+ or b
+ jp nz, UpdateLoweredStat
+ ld [H_MULTIPLICAND + 1], a
+ ld a, $1
+ ld [H_MULTIPLICAND + 2], a
+
+UpdateLoweredStat:
+ ld a, [H_PRODUCT + 2]
+ ld [hli], a
+ ld a, [H_PRODUCT + 3]
+ ld [hl], a
+ pop de
+ pop hl
+UpdateLoweredStatDone:
+ ld b, c
+ inc b
+ push de
+ call PrintStatText
+ pop de
+ ld a, [de]
+ cp $44
+ jr nc, .ApplyBadgeBoostsAndStatusPenalties
+ call PlayCurrentMoveAnimation2
+.ApplyBadgeBoostsAndStatusPenalties
+ ld a, [H_WHOSETURN]
+ and a
+ call nz, ApplyBadgeStatBoosts ; whenever the player uses a stat-down move, badge boosts get reapplied again to every stat,
+ ; even to those not affected by the stat-up move (will be boosted further)
+ ld hl, MonsStatsFellText
+ call PrintText
+
+; These where probably added given that a stat-down move affecting speed or attack will override
+; the stat penalties from paralysis and burn respectively.
+; But they are always called regardless of the stat affected by the stat-down move.
+ call QuarterSpeedDueToParalysis
+ jp HalveAttackDueToBurn
+
+CantLowerAnymore_Pop:
+ pop de
+ pop hl
+ inc [hl]
+
+CantLowerAnymore:
+ ld a, [de]
+ cp ATTACK_DOWN_SIDE_EFFECT
+ ret nc
+ ld hl, NothingHappenedText
+ jp PrintText
+
+MoveMissed:
+ ld a, [de]
+ cp $44
+ ret nc
+ jp ConditionalPrintButItFailed
+
+MonsStatsFellText:
+ TX_FAR _MonsStatsFellText
+ TX_ASM
+ ld hl, FellText
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .playerTurn
+ ld a, [wEnemyMoveEffect]
+.playerTurn
+; check if the move's effect decreases a stat by 2
+ cp BIDE_EFFECT
+ ret c
+ cp ATTACK_DOWN_SIDE_EFFECT
+ ret nc
+ ld hl, GreatlyFellText
+ ret
+
+GreatlyFellText:
+ TX_DELAY
+ TX_FAR _GreatlyFellText
+; fallthrough
+FellText:
+ TX_FAR _FellText
+ db "@"
+
+PrintStatText:
+ ld hl, StatsTextStrings
+ ld c, "@"
+.findStatName_outer
+ dec b
+ jr z, .foundStatName
+.findStatName_inner
+ ld a, [hli]
+ cp c
+ jr z, .findStatName_outer
+ jr .findStatName_inner
+.foundStatName
+ ld de, wcf4b
+ ld bc, $a
+ jp CopyData
+
+StatsTextStrings:
+ db "ATTACK@"
+ db "DEFENSE@"
+ db "SPEED@"
+ db "SPECIAL@"
+ db "ACCURACY@"
+ db "EVADE@"
+
+StatModifierRatios:
+; first byte is numerator, second byte is denominator
+ db 25, 100 ; 0.25
+ db 28, 100 ; 0.28
+ db 33, 100 ; 0.33
+ db 40, 100 ; 0.40
+ db 50, 100 ; 0.50
+ db 66, 100 ; 0.66
+ db 1, 1 ; 1.00
+ db 15, 10 ; 1.50
+ db 2, 1 ; 2.00
+ db 25, 10 ; 2.50
+ db 3, 1 ; 3.00
+ db 35, 10 ; 3.50
+ db 4, 1 ; 4.00
+
+BideEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerBideAccumulatedDamage
+ ld bc, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .bideEffect
+ ld hl, wEnemyBattleStatus1
+ ld de, wEnemyBideAccumulatedDamage
+ ld bc, wEnemyNumAttacksLeft
+.bideEffect
+ set STORING_ENERGY, [hl] ; mon is now using bide
+ xor a
+ ld [de], a
+ inc de
+ ld [de], a
+ ld [wPlayerMoveEffect], a
+ ld [wEnemyMoveEffect], a
+ call BattleRandom
+ and $1
+ inc a
+ inc a
+ ld [bc], a ; set Bide counter to 2 or 3 at random
+ ld a, [H_WHOSETURN]
+ add XSTATITEM_ANIM
+ jp PlayBattleAnimation2
+
+ThrashPetalDanceEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .thrashPetalDanceEffect
+ ld hl, wEnemyBattleStatus1
+ ld de, wEnemyNumAttacksLeft
+.thrashPetalDanceEffect
+ set THRASHING_ABOUT, [hl] ; mon is now using thrash/petal dance
+ call BattleRandom
+ and $1
+ inc a
+ inc a
+ ld [de], a ; set thrash/petal dance counter to 2 or 3 at random
+ ld a, [H_WHOSETURN]
+ add ANIM_B0
+ jp PlayBattleAnimation2
+
+SwitchAndTeleportEffect:
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .handleEnemy
+ ld a, [wIsInBattle]
+ dec a
+ jr nz, .notWildBattle1
+ ld a, [wCurEnemyLVL]
+ ld b, a
+ ld a, [wBattleMonLevel]
+ cp b ; is the player's level greater than the enemy's level?
+ jr nc, .playerMoveWasSuccessful ; if so, teleport will always succeed
+ add b
+ ld c, a
+ inc c ; c = sum of player level and enemy level
+.rejectionSampleLoop1
+ call BattleRandom
+ cp c ; get a random number between 0 and c
+ jr nc, .rejectionSampleLoop1
+ srl b
+ srl b ; b = enemyLevel / 4
+ cp b ; is rand[0, playerLevel + enemyLevel) >= (enemyLevel / 4)?
+ jr nc, .playerMoveWasSuccessful ; if so, allow teleporting
+ ld c, 50
+ call DelayFrames
+ ld a, [wPlayerMoveNum]
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.playerMoveWasSuccessful
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [wAnimationType], a
+ inc a
+ ld [wEscapedFromBattle], a
+ ld a, [wPlayerMoveNum]
+ jr .playAnimAndPrintText
+.notWildBattle1
+ ld c, 50
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [wPlayerMoveNum]
+ cp TELEPORT
+ jp nz, PrintText
+ jp PrintButItFailedText_
+.handleEnemy
+ ld a, [wIsInBattle]
+ dec a
+ jr nz, .notWildBattle2
+ ld a, [wBattleMonLevel]
+ ld b, a
+ ld a, [wCurEnemyLVL]
+ cp b
+ jr nc, .enemyMoveWasSuccessful
+ add b
+ ld c, a
+ inc c
+.rejectionSampleLoop2
+ call BattleRandom
+ cp c
+ jr nc, .rejectionSampleLoop2
+ srl b
+ srl b
+ cp b
+ jr nc, .enemyMoveWasSuccessful
+ ld c, 50
+ call DelayFrames
+ ld a, [wEnemyMoveNum]
+ cp TELEPORT
+ jp nz, PrintDidntAffectText
+ jp PrintButItFailedText_
+.enemyMoveWasSuccessful
+ call ReadPlayerMonCurHPAndStatus
+ xor a
+ ld [wAnimationType], a
+ inc a
+ ld [wEscapedFromBattle], a
+ ld a, [wEnemyMoveNum]
+ jr .playAnimAndPrintText
+.notWildBattle2
+ ld c, 50
+ call DelayFrames
+ ld hl, IsUnaffectedText
+ ld a, [wEnemyMoveNum]
+ cp TELEPORT
+ jp nz, PrintText
+ jp ConditionalPrintButItFailed
+.playAnimAndPrintText
+ push af
+ call PlayBattleAnimation
+ ld c, 20
+ call DelayFrames
+ pop af
+ ld hl, RanFromBattleText
+ cp TELEPORT
+ jr z, .printText
+ ld hl, RanAwayScaredText
+ cp ROAR
+ jr z, .printText
+ ld hl, WasBlownAwayText
+.printText
+ jp PrintText
+
+RanFromBattleText:
+ TX_FAR _RanFromBattleText
+ db "@"
+
+RanAwayScaredText:
+ TX_FAR _RanAwayScaredText
+ db "@"
+
+WasBlownAwayText:
+ TX_FAR _WasBlownAwayText
+ db "@"
+
+TwoToFiveAttacksEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ld bc, wPlayerNumHits
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .twoToFiveAttacksEffect
+ ld hl, wEnemyBattleStatus1
+ ld de, wEnemyNumAttacksLeft
+ ld bc, wEnemyNumHits
+.twoToFiveAttacksEffect
+ bit ATTACKING_MULTIPLE_TIMES, [hl] ; is mon attacking multiple times?
+ ret nz
+ set ATTACKING_MULTIPLE_TIMES, [hl] ; mon is now attacking multiple times
+ ld hl, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .setNumberOfHits
+ ld hl, wEnemyMoveEffect
+.setNumberOfHits
+ ld a, [hl]
+ cp TWINEEDLE_EFFECT
+ jr z, .twineedle
+ cp ATTACK_TWICE_EFFECT
+ ld a, $2 ; number of hits it's always 2 for ATTACK_TWICE_EFFECT
+ jr z, .saveNumberOfHits
+; for TWO_TO_FIVE_ATTACKS_EFFECT 3/8 chance for 2 and 3 hits, and 1/8 chance for 4 and 5 hits
+ call BattleRandom
+ and $3
+ cp $2
+ jr c, .gotNumHits
+; if the number of hits was greater than 2, re-roll again for a lower chance
+ call BattleRandom
+ and $3
+.gotNumHits
+ inc a
+ inc a
+.saveNumberOfHits
+ ld [de], a
+ ld [bc], a
+ ret
+.twineedle
+ ld a, POISON_SIDE_EFFECT1
+ ld [hl], a ; set Twineedle's effect to poison effect
+ jr .saveNumberOfHits
+
+FlinchSideEffect:
+ call CheckTargetSubstitute
+ ret nz
+ ld hl, wEnemyBattleStatus1
+ ld de, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .flinchSideEffect
+ ld hl, wPlayerBattleStatus1
+ ld de, wEnemyMoveEffect
+.flinchSideEffect
+ ld a, [de]
+ cp FLINCH_SIDE_EFFECT1
+ ld b, $1a ; ~10% chance of flinch
+ jr z, .gotEffectChance
+ ld b, $4d ; ~30% chance of flinch
+.gotEffectChance
+ call BattleRandom
+ cp b
+ ret nc
+ set FLINCHED, [hl] ; set mon's status to flinching
+ call ClearHyperBeam
+ ret
+
+OneHitKOEffect:
+ jpab OneHitKOEffect_
+
+ChargeEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerMoveEffect
+ ld a, [H_WHOSETURN]
+ and a
+ ld b, XSTATITEM_ANIM
+ jr z, .chargeEffect
+ ld hl, wEnemyBattleStatus1
+ ld de, wEnemyMoveEffect
+ ld b, ANIM_AF
+.chargeEffect
+ set CHARGING_UP, [hl]
+ ld a, [de]
+ dec de ; de contains enemy or player MOVENUM
+ cp FLY_EFFECT
+ jr nz, .notFly
+ set INVULNERABLE, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
+ ld b, TELEPORT ; load Teleport's animation
+.notFly
+ ld a, [de]
+ cp DIG
+ jr nz, .notDigOrFly
+ set INVULNERABLE, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
+ ld b, ANIM_C0
+.notDigOrFly
+ xor a
+ ld [wAnimationType], a
+ ld a, b
+ call PlayBattleAnimation
+ ld a, [de]
+ ld [wChargeMoveNum], a
+ ld hl, ChargeMoveEffectText
+ jp PrintText
+
+ChargeMoveEffectText:
+ TX_FAR _ChargeMoveEffectText
+ TX_ASM
+ ld a, [wChargeMoveNum]
+ cp RAZOR_WIND
+ ld hl, MadeWhirlwindText
+ jr z, .gotText
+ cp SOLARBEAM
+ ld hl, TookInSunlightText
+ jr z, .gotText
+ cp SKULL_BASH
+ ld hl, LoweredItsHeadText
+ jr z, .gotText
+ cp SKY_ATTACK
+ ld hl, SkyAttackGlowingText
+ jr z, .gotText
+ cp FLY
+ ld hl, FlewUpHighText
+ jr z, .gotText
+ cp DIG
+ ld hl, DugAHoleText
+.gotText
+ ret
+
+MadeWhirlwindText:
+ TX_FAR _MadeWhirlwindText
+ db "@"
+
+TookInSunlightText:
+ TX_FAR _TookInSunlightText
+ db "@"
+
+LoweredItsHeadText:
+ TX_FAR _LoweredItsHeadText
+ db "@"
+
+SkyAttackGlowingText:
+ TX_FAR _SkyAttackGlowingText
+ db "@"
+
+FlewUpHighText:
+ TX_FAR _FlewUpHighText
+ db "@"
+
+DugAHoleText:
+ TX_FAR _DugAHoleText
+ db "@"
+
+TrappingEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .trappingEffect
+ ld hl, wEnemyBattleStatus1
+ ld de, wEnemyNumAttacksLeft
+.trappingEffect
+ bit USING_TRAPPING_MOVE, [hl]
+ ret nz
+ call ClearHyperBeam ; since this effect is called before testing whether the move will hit,
+ ; the target won't need to recharge even if the trapping move missed
+ set USING_TRAPPING_MOVE, [hl] ; mon is now using a trapping move
+ call BattleRandom ; 3/8 chance for 2 and 3 attacks, and 1/8 chance for 4 and 5 attacks
+ and $3
+ cp $2
+ jr c, .setTrappingCounter
+ call BattleRandom
+ and $3
+.setTrappingCounter
+ inc a
+ ld [de], a
+ ret
+
+MistEffect:
+ jpab MistEffect_
+
+FocusEnergyEffect:
+ jpab FocusEnergyEffect_
+
+RecoilEffect:
+ jpab RecoilEffect_
+
+ConfusionSideEffect:
+ call BattleRandom
+ cp $19 ; ~10% chance
+ ret nc
+ jr ConfusionSideEffectSuccess
+
+ConfusionEffect:
+ call CheckTargetSubstitute
+ jr nz, ConfusionEffectFailed
+ call MoveHitTest
+ ld a, [wMoveMissed]
+ and a
+ jr nz, ConfusionEffectFailed
+
+ConfusionSideEffectSuccess:
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wEnemyBattleStatus1
+ ld bc, wEnemyConfusedCounter
+ ld a, [wPlayerMoveEffect]
+ jr z, .confuseTarget
+ ld hl, wPlayerBattleStatus1
+ ld bc, wPlayerConfusedCounter
+ ld a, [wEnemyMoveEffect]
+.confuseTarget
+ bit CONFUSED, [hl] ; is mon confused?
+ jr nz, ConfusionEffectFailed
+ set CONFUSED, [hl] ; mon is now confused
+ push af
+ call BattleRandom
+ and $3
+ inc a
+ inc a
+ ld [bc], a ; confusion status will last 2-5 turns
+ pop af
+ cp CONFUSION_SIDE_EFFECT
+ call nz, PlayCurrentMoveAnimation2
+ ld hl, BecameConfusedText
+ jp PrintText
+
+BecameConfusedText:
+ TX_FAR _BecameConfusedText
+ db "@"
+
+ConfusionEffectFailed:
+ cp CONFUSION_SIDE_EFFECT
+ ret z
+ ld c, 50
+ call DelayFrames
+ jp ConditionalPrintButItFailed
+
+ParalyzeEffect:
+ jpab ParalyzeEffect_
+
+SubstituteEffect:
+ jpab SubstituteEffect_
+
+HyperBeamEffect:
+ ld hl, wPlayerBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .hyperBeamEffect
+ ld hl, wEnemyBattleStatus2
+.hyperBeamEffect
+ set NEEDS_TO_RECHARGE, [hl] ; mon now needs to recharge
+ ret
+
+ClearHyperBeam:
+ push hl
+ ld hl, wEnemyBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .playerTurn
+ ld hl, wPlayerBattleStatus2
+.playerTurn
+ res NEEDS_TO_RECHARGE, [hl] ; mon no longer needs to recharge
+ pop hl
+ ret
+
+RageEffect:
+ ld hl, wPlayerBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .player
+ ld hl, wEnemyBattleStatus2
+.player
+ set USING_RAGE, [hl] ; mon is now in "rage" mode
+ ret
+
+MimicEffect:
+ ld c, 50
+ call DelayFrames
+ call MoveHitTest
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .mimicMissed
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wBattleMonMoves
+ ld a, [wPlayerBattleStatus1]
+ jr nz, .enemyTurn
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .letPlayerChooseMove
+ ld hl, wEnemyMonMoves
+ ld a, [wEnemyBattleStatus1]
+.enemyTurn
+ bit INVULNERABLE, a
+ jr nz, .mimicMissed
+.getRandomMove
+ push hl
+ call BattleRandom
+ and $3
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .getRandomMove
+ ld d, a
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wBattleMonMoves
+ ld a, [wPlayerMoveListIndex]
+ jr z, .playerTurn
+ ld hl, wEnemyMonMoves
+ ld a, [wEnemyMoveListIndex]
+ jr .playerTurn
+.letPlayerChooseMove
+ ld a, [wEnemyBattleStatus1]
+ bit INVULNERABLE, a
+ jr nz, .mimicMissed
+ ld a, [wCurrentMenuItem]
+ push af
+ ld a, $1
+ ld [wMoveMenuType], a
+ call MoveSelectionMenu
+ call LoadScreenTilesFromBuffer1
+ ld hl, wEnemyMonMoves
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld d, [hl]
+ pop af
+ ld hl, wBattleMonMoves
+.playerTurn
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, d
+ ld [hl], a
+ ld [wd11e], a
+ call GetMoveName
+ call PlayCurrentMoveAnimation
+ ld hl, MimicLearnedMoveText
+ jp PrintText
+.mimicMissed
+ jp PrintButItFailedText_
+
+MimicLearnedMoveText:
+ TX_FAR _MimicLearnedMoveText
+ db "@"
+
+LeechSeedEffect:
+ jpab LeechSeedEffect_
+
+SplashEffect:
+ call PlayCurrentMoveAnimation
+ jp PrintNoEffectText
+
+DisableEffect:
+ call MoveHitTest
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .moveMissed
+ ld de, wEnemyDisabledMove
+ ld hl, wEnemyMonMoves
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .disableEffect
+ ld de, wPlayerDisabledMove
+ ld hl, wBattleMonMoves
+.disableEffect
+; no effect if target already has a move disabled
+ ld a, [de]
+ and a
+ jr nz, .moveMissed
+.pickMoveToDisable
+ push hl
+ call BattleRandom
+ and $3
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .pickMoveToDisable ; loop until a non-00 move slot is found
+ ld [wd11e], a ; store move number
+ push hl
+ ld a, [H_WHOSETURN]
+ and a
+ ld hl, wBattleMonPP
+ jr nz, .enemyTurn
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ pop hl ; wEnemyMonMoves
+ jr nz, .playerTurnNotLinkBattle
+; .playerTurnLinkBattle
+ push hl
+ ld hl, wEnemyMonPP
+.enemyTurn
+ push hl
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ or [hl]
+ and $3f
+ pop hl ; wBattleMonPP or wEnemyMonPP
+ jr z, .moveMissedPopHL ; nothing to do if all moves have no PP left
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ and a
+ jr z, .pickMoveToDisable ; pick another move if this one had 0 PP
+.playerTurnNotLinkBattle
+; non-link battle enemies have unlimited PP so the previous checks aren't needed
+ call BattleRandom
+ and $7
+ inc a ; 1-8 turns disabled
+ inc c ; move 1-4 will be disabled
+ swap c
+ add c ; map disabled move to high nibble of wEnemyDisabledMove / wPlayerDisabledMove
+ ld [de], a
+ call PlayCurrentMoveAnimation2
+ ld hl, wPlayerDisabledMoveNumber
+ ld a, [H_WHOSETURN]
+ and a
+ jr nz, .printDisableText
+ inc hl ; wEnemyDisabledMoveNumber
+.printDisableText
+ ld a, [wd11e] ; move number
+ ld [hl], a
+ call GetMoveName
+ ld hl, MoveWasDisabledText
+ jp PrintText
+.moveMissedPopHL
+ pop hl
+.moveMissed
+ jp PrintButItFailedText_
+
+MoveWasDisabledText:
+ TX_FAR _MoveWasDisabledText
+ db "@"
+
+PayDayEffect:
+ jpab PayDayEffect_
+
+ConversionEffect:
+ jpab ConversionEffect_
+
+HazeEffect:
+ jpab HazeEffect_
+
+HealEffect:
+ jpab HealEffect_
+
+TransformEffect:
+ jpab TransformEffect_
+
+ReflectLightScreenEffect:
+ jpab ReflectLightScreenEffect_
+
+NothingHappenedText:
+ TX_FAR _NothingHappenedText
+ db "@"
+
+PrintNoEffectText:
+ ld hl, NoEffectText
+ jp PrintText
+
+NoEffectText:
+ TX_FAR _NoEffectText
+ db "@"
+
+ConditionalPrintButItFailed:
+ ld a, [wMoveDidntMiss]
+ and a
+ ret nz ; return if the side effect failed, yet the attack was successful
+
+PrintButItFailedText_:
+ ld hl, ButItFailedText
+ jp PrintText
+
+ButItFailedText:
+ TX_FAR _ButItFailedText
+ db "@"
+
+PrintDidntAffectText:
+ ld hl, DidntAffectText
+ jp PrintText
+
+DidntAffectText:
+ TX_FAR _DidntAffectText
+ db "@"
+
+IsUnaffectedText:
+ TX_FAR _IsUnaffectedText
+ db "@"
+
+PrintMayNotAttackText:
+ ld hl, ParalyzedMayNotAttackText
+ jp PrintText
+
+ParalyzedMayNotAttackText:
+ TX_FAR _ParalyzedMayNotAttackText
+ db "@"
+
+CheckTargetSubstitute:
+ push hl
+ ld hl, wEnemyBattleStatus2
+ ld a, [H_WHOSETURN]
+ and a
+ jr z, .next1
+ ld hl, wPlayerBattleStatus2
+.next1
+ bit HAS_SUBSTITUTE_UP, [hl]
+ pop hl
+ ret
+
+PlayCurrentMoveAnimation2:
+; animation at MOVENUM will be played unless MOVENUM is 0
+; plays wAnimationType 3 or 6
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveNum]
+ jr z, .notEnemyTurn
+ ld a, [wEnemyMoveNum]
+.notEnemyTurn
+ and a
+ ret z
+
+PlayBattleAnimation2:
+; play animation ID at a and animation type 6 or 3
+ ld [wAnimationID], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, $6
+ jr z, .storeAnimationType
+ ld a, $3
+.storeAnimationType
+ ld [wAnimationType], a
+ jp PlayBattleAnimationGotID
+
+PlayCurrentMoveAnimation:
+; animation at MOVENUM will be played unless MOVENUM is 0
+; resets wAnimationType
+ xor a
+ ld [wAnimationType], a
+ ld a, [H_WHOSETURN]
+ and a
+ ld a, [wPlayerMoveNum]
+ jr z, .notEnemyTurn
+ ld a, [wEnemyMoveNum]
+.notEnemyTurn
+ and a
+ ret z
+
+PlayBattleAnimation:
+; play animation ID at a and predefined animation type
+ ld [wAnimationID], a
+
+PlayBattleAnimationGotID:
+; play animation at wAnimationID
+ push hl
+ push de
+ push bc
+ predef MoveAnimation
+ pop bc
+ pop de
+ pop hl
+ ret
diff --git a/en/engine/battle/end_of_battle.asm b/en/engine/battle/end_of_battle.asm
new file mode 100755
index 00000000..c77e3b39
--- /dev/null
+++ b/en/engine/battle/end_of_battle.asm
@@ -0,0 +1,88 @@
+EndOfBattle:
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr nz, .notLinkBattle
+; link battle
+ ld a, [wEnemyMonPartyPos]
+ ld hl, wEnemyMon1Status
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld a, [wEnemyMonStatus]
+ ld [hl], a
+ call ClearScreen
+ callab DisplayLinkBattleVersusTextBox
+ ld a, [wBattleResult]
+ cp $1
+ ld de, YouWinText
+ jr c, .placeWinOrLoseString
+ ld de, YouLoseText
+ jr z, .placeWinOrLoseString
+ ld de, DrawText
+.placeWinOrLoseString
+ coord hl, 6, 8
+ call PlaceString
+ ld c, 200
+ call DelayFrames
+ jr .evolution
+.notLinkBattle
+ ld a, [wBattleResult]
+ and a
+ jr nz, .resetVariables
+ ld hl, wTotalPayDayMoney
+ ld a, [hli]
+ or [hl]
+ inc hl
+ or [hl]
+ jr z, .evolution ; if pay day money is 0, jump
+ ld de, wPlayerMoney + 2
+ ld c, $3
+ predef AddBCDPredef
+ ld hl, PickUpPayDayMoneyText
+ call PrintText
+.evolution
+ xor a
+ ld [wForceEvolution], a
+ predef EvolutionAfterBattle
+.resetVariables
+ xor a
+ ld [wLowHealthAlarm], a ;disable low health alarm
+ ld [wChannelSoundIDs + Ch4], a
+ ld [wIsInBattle], a
+ ld [wBattleType], a
+ ld [wMoveMissed], a
+ ld [wCurOpponent], a
+ ld [wForcePlayerToChooseMon], a
+ ld [wNumRunAttempts], a
+ ld [wEscapedFromBattle], a
+ ld hl, wPartyAndBillsPCSavedMenuItem
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wListScrollOffset], a
+ ld hl, wPlayerStatsToDouble
+ ld b, $18
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ld hl, wd72c
+ set 0, [hl]
+ call WaitForSoundToFinish
+ call GBPalWhiteOut
+ ld a, $ff
+ ld [wDestinationWarpID], a
+ ret
+
+YouWinText:
+ db "YOU WIN@"
+
+YouLoseText:
+ db "YOU LOSE@"
+
+DrawText:
+ db " DRAW@"
+
+PickUpPayDayMoneyText:
+ TX_FAR _PickUpPayDayMoneyText
+ db "@"
diff --git a/en/engine/battle/link_battle_versus_text.asm b/en/engine/battle/link_battle_versus_text.asm
new file mode 100644
index 00000000..76559117
--- /dev/null
+++ b/en/engine/battle/link_battle_versus_text.asm
@@ -0,0 +1,23 @@
+; display "[player] VS [enemy]" text box with pokeballs representing their parties next to the names
+DisplayLinkBattleVersusTextBox:
+ call LoadTextBoxTilePatterns
+ coord hl, 3, 4
+ ld b, 7
+ ld c, 12
+ call TextBoxBorder
+ coord hl, 4, 5
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 4, 10
+ ld de, wLinkEnemyTrainerName
+ call PlaceString
+; place bold "VS" tiles between the names
+ coord hl, 9, 8
+ ld a, $69
+ ld [hli], a
+ ld [hl], $6a
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ callab SetupPlayerAndEnemyPokeballs
+ ld c, 150
+ jp DelayFrames
diff --git a/en/engine/battle/save_trainer_name.asm b/en/engine/battle/save_trainer_name.asm
new file mode 100644
index 00000000..49d0429f
--- /dev/null
+++ b/en/engine/battle/save_trainer_name.asm
@@ -0,0 +1,112 @@
+SaveTrainerName:
+ ld hl, TrainerNamePointers
+ ld a, [wTrainerClass]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wcd6d
+.CopyCharacter
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp "@"
+ jr nz, .CopyCharacter
+ ret
+
+TrainerNamePointers:
+; what is the point of these?
+ dw YoungsterName
+ dw BugCatcherName
+ dw LassName
+ dw wTrainerName
+ dw JrTrainerMName
+ dw JrTrainerFName
+ dw PokemaniacName
+ dw SuperNerdName
+ dw wTrainerName
+ dw wTrainerName
+ dw BurglarName
+ dw EngineerName
+ dw JugglerXName
+ dw wTrainerName
+ dw SwimmerName
+ dw wTrainerName
+ dw wTrainerName
+ dw BeautyName
+ dw wTrainerName
+ dw RockerName
+ dw JugglerName
+ dw wTrainerName
+ dw wTrainerName
+ dw BlackbeltName
+ dw wTrainerName
+ dw ProfOakName
+ dw ChiefName
+ dw ScientistName
+ dw wTrainerName
+ dw RocketName
+ dw CooltrainerMName
+ dw CooltrainerFName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+ dw wTrainerName
+
+YoungsterName:
+ db "YOUNGSTER@"
+BugCatcherName:
+ db "BUG CATCHER@"
+LassName:
+ db "LASS@"
+JrTrainerMName:
+ db "JR.TRAINER♂@"
+JrTrainerFName:
+ db "JR.TRAINER♀@"
+PokemaniacName:
+ db "POKéMANIAC@"
+SuperNerdName:
+ db "SUPER NERD@"
+BurglarName:
+ db "BURGLAR@"
+EngineerName:
+ db "ENGINEER@"
+JugglerXName:
+ db "JUGGLER@"
+SwimmerName:
+ db "SWIMMER@"
+BeautyName:
+ db "BEAUTY@"
+RockerName:
+ db "ROCKER@"
+JugglerName:
+ db "JUGGLER@"
+BlackbeltName:
+ db "BLACKBELT@"
+ProfOakName:
+ db "PROF.OAK@"
+ChiefName:
+ db "CHIEF@"
+ScientistName:
+ db "SCIENTIST@"
+RocketName:
+ db "ROCKET@"
+CooltrainerMName:
+ db "COOLTRAINER♂@"
+CooltrainerFName:
+ db "COOLTRAINER♀@"
diff --git a/en/engine/cable_club.asm b/en/engine/cable_club.asm
new file mode 100755
index 00000000..3e72daa9
--- /dev/null
+++ b/en/engine/cable_club.asm
@@ -0,0 +1,977 @@
+; performs the appropriate action when the player uses the gameboy on the table in the Colosseum or Trade Center
+; In the Colosseum, it starts a battle. In the Trade Center, it displays the trade selection screen.
+; Before doing either action, it swaps random numbers, trainer names and party data with the other gameboy.
+CableClub_DoBattleOrTrade:
+ ld c, 80
+ call DelayFrames
+ call ClearScreen
+ call UpdateSprites
+ call LoadFontTilePatterns
+ call LoadHpBarAndStatusTilePatterns
+ call LoadTrainerInfoTextBoxTiles
+ coord hl, 3, 8
+ ld b, 2
+ ld c, 12
+ call CableClub_TextBoxBorder
+ coord hl, 4, 10
+ ld de, PleaseWaitString
+ call PlaceString
+ ld hl, wPlayerNumHits
+ xor a
+ ld [hli], a
+ ld [hl], $50
+ ; fall through
+
+; This is called after completing a trade.
+CableClub_DoBattleOrTradeAgain:
+ ld hl, wSerialPlayerDataBlock
+ ld a, SERIAL_PREAMBLE_BYTE
+ ld b, 6
+.writePlayerDataBlockPreambleLoop
+ ld [hli], a
+ dec b
+ jr nz, .writePlayerDataBlockPreambleLoop
+ ld hl, wSerialRandomNumberListBlock
+ ld a, SERIAL_PREAMBLE_BYTE
+ ld b, 7
+.writeRandomNumberListPreambleLoop
+ ld [hli], a
+ dec b
+ jr nz, .writeRandomNumberListPreambleLoop
+ ld b, 10
+.generateRandomNumberListLoop
+ call Random
+ cp SERIAL_PREAMBLE_BYTE ; all the random numbers have to be less than the preamble byte
+ jr nc, .generateRandomNumberListLoop
+ ld [hli], a
+ dec b
+ jr nz, .generateRandomNumberListLoop
+ ld hl, wSerialPartyMonsPatchList
+ ld a, SERIAL_PREAMBLE_BYTE
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld b, $c8
+ xor a
+.zeroPlayerDataPatchListLoop
+ ld [hli], a
+ dec b
+ jr nz, .zeroPlayerDataPatchListLoop
+ ld hl, wGrassRate
+ ld bc, wTrainerHeaderPtr - wGrassRate
+.zeroEnemyPartyLoop
+ xor a
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .zeroEnemyPartyLoop
+ ld hl, wPartyMons - 1
+ ld de, wSerialPartyMonsPatchList + 10
+ ld bc, 0
+.patchPartyMonsLoop
+ inc c
+ ld a, c
+ cp SERIAL_PREAMBLE_BYTE
+ jr z, .startPatchListPart2
+ ld a, b
+ dec a ; are we in part 2 of the patch list?
+ jr nz, .checkPlayerDataByte ; jump if in part 1
+; if we're in part 2
+ ld a, c
+ cp (wPartyMonOT - (wPartyMons - 1)) - (SERIAL_PREAMBLE_BYTE - 1)
+ jr z, .finishedPatchingPlayerData
+.checkPlayerDataByte
+ inc hl
+ ld a, [hl]
+ cp SERIAL_NO_DATA_BYTE
+ jr nz, .patchPartyMonsLoop
+; if the player data byte matches SERIAL_NO_DATA_BYTE, patch it with $FF and record the offset in the patch list
+ ld a, c
+ ld [de], a
+ inc de
+ ld [hl], $ff
+ jr .patchPartyMonsLoop
+.startPatchListPart2
+ ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
+ ld [de], a ; end of part 1
+ inc de
+ lb bc, 1, 0
+ jr .patchPartyMonsLoop
+.finishedPatchingPlayerData
+ ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
+ ld [de], a ; end of part 2
+ call Serial_SyncAndExchangeNybble
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .skipSendingTwoZeroBytes
+; if using internal clock
+; send two zero bytes for syncing purposes?
+ call Delay3
+ xor a
+ ld [hSerialSendData], a
+ ld a, START_TRANSFER_INTERNAL_CLOCK
+ ld [rSC], a
+ call DelayFrame
+ xor a
+ ld [hSerialSendData], a
+ ld a, START_TRANSFER_INTERNAL_CLOCK
+ ld [rSC], a
+.skipSendingTwoZeroBytes
+ call Delay3
+ ld a, (1 << SERIAL)
+ ld [rIE], a
+ ld hl, wSerialRandomNumberListBlock
+ ld de, wSerialOtherGameboyRandomNumberListBlock
+ ld bc, $11
+ call Serial_ExchangeBytes
+ ld a, SERIAL_NO_DATA_BYTE
+ ld [de], a
+ ld hl, wSerialPlayerDataBlock
+ ld de, wSerialEnemyDataBlock
+ ld bc, $1a8
+ call Serial_ExchangeBytes
+ ld a, SERIAL_NO_DATA_BYTE
+ ld [de], a
+ ld hl, wSerialPartyMonsPatchList
+ ld de, wSerialEnemyMonsPatchList
+ ld bc, $c8
+ call Serial_ExchangeBytes
+ ld a, (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK)
+ ld [rIE], a
+ ld a, $ff
+ call PlaySound
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .skipCopyingRandomNumberList ; the list generated by the gameboy clocking the connection is used by both gameboys
+ ld hl, wSerialOtherGameboyRandomNumberListBlock
+.findStartOfRandomNumberListLoop
+ ld a, [hli]
+ and a
+ jr z, .findStartOfRandomNumberListLoop
+ cp SERIAL_PREAMBLE_BYTE
+ jr z, .findStartOfRandomNumberListLoop
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .findStartOfRandomNumberListLoop
+ dec hl
+ ld de, wLinkBattleRandomNumberList
+ ld c, 10
+.copyRandomNumberListLoop
+ ld a, [hli]
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .copyRandomNumberListLoop
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyRandomNumberListLoop
+.skipCopyingRandomNumberList
+ ld hl, wSerialEnemyDataBlock + 3
+.findStartOfEnemyNameLoop
+ ld a, [hli]
+ and a
+ jr z, .findStartOfEnemyNameLoop
+ cp SERIAL_PREAMBLE_BYTE
+ jr z, .findStartOfEnemyNameLoop
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .findStartOfEnemyNameLoop
+ dec hl
+ ld de, wLinkEnemyTrainerName
+ ld c, NAME_LENGTH
+.copyEnemyNameLoop
+ ld a, [hli]
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .copyEnemyNameLoop
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyEnemyNameLoop
+ ld de, wEnemyPartyCount
+ ld bc, wTrainerHeaderPtr - wEnemyPartyCount
+.copyEnemyPartyLoop
+ ld a, [hli]
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .copyEnemyPartyLoop
+ ld [de], a
+ inc de
+ dec bc
+ ld a, b
+ or c
+ jr nz, .copyEnemyPartyLoop
+ ld de, wSerialPartyMonsPatchList
+ ld hl, wPartyMons
+ ld c, 2 ; patch list has 2 parts
+.unpatchPartyMonsLoop
+ ld a, [de]
+ inc de
+ and a
+ jr z, .unpatchPartyMonsLoop
+ cp SERIAL_PREAMBLE_BYTE
+ jr z, .unpatchPartyMonsLoop
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .unpatchPartyMonsLoop
+ cp SERIAL_PATCH_LIST_PART_TERMINATOR
+ jr z, .finishedPartyMonsPatchListPart
+ push hl
+ push bc
+ ld b, 0
+ dec a
+ ld c, a
+ add hl, bc
+ ld a, SERIAL_NO_DATA_BYTE
+ ld [hl], a
+ pop bc
+ pop hl
+ jr .unpatchPartyMonsLoop
+.finishedPartyMonsPatchListPart
+ ld hl, wPartyMons + (SERIAL_PREAMBLE_BYTE - 1)
+ dec c ; is there another part?
+ jr nz, .unpatchPartyMonsLoop
+ ld de, wSerialEnemyMonsPatchList
+ ld hl, wEnemyMons
+ ld c, 2 ; patch list has 2 parts
+.unpatchEnemyMonsLoop
+ ld a, [de]
+ inc de
+ and a
+ jr z, .unpatchEnemyMonsLoop
+ cp SERIAL_PREAMBLE_BYTE
+ jr z, .unpatchEnemyMonsLoop
+ cp SERIAL_NO_DATA_BYTE
+ jr z, .unpatchEnemyMonsLoop
+ cp SERIAL_PATCH_LIST_PART_TERMINATOR
+ jr z, .finishedEnemyMonsPatchListPart
+ push hl
+ push bc
+ ld b, 0
+ dec a
+ ld c, a
+ add hl, bc
+ ld a, SERIAL_NO_DATA_BYTE
+ ld [hl], a
+ pop bc
+ pop hl
+ jr .unpatchEnemyMonsLoop
+.finishedEnemyMonsPatchListPart
+ ld hl, wEnemyMons + (SERIAL_PREAMBLE_BYTE - 1)
+ dec c
+ jr nz, .unpatchEnemyMonsLoop
+ ld a, wEnemyMonOT % $100
+ ld [wUnusedCF8D], a
+ ld a, wEnemyMonOT / $100
+ ld [wUnusedCF8D + 1], a
+ xor a
+ ld [wTradeCenterPointerTableIndex], a
+ ld a, $ff
+ call PlaySound
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ ld c, 66
+ call z, DelayFrames ; delay if using internal clock
+ ld a, [wLinkState]
+ cp LINK_STATE_START_BATTLE
+ ld a, LINK_STATE_TRADING
+ ld [wLinkState], a
+ jr nz, .trading
+ ld a, LINK_STATE_BATTLING
+ ld [wLinkState], a
+ ld a, OPP_SONY1
+ ld [wCurOpponent], a
+ call ClearScreen
+ call Delay3
+ ld hl, wOptions
+ res 7, [hl]
+ predef InitOpponent
+ predef HealParty
+ jp ReturnToCableClubRoom
+.trading
+ ld c, BANK(Music_GameCorner)
+ ld a, MUSIC_GAME_CORNER
+ call PlayMusic
+ jr CallCurrentTradeCenterFunction
+
+PleaseWaitString:
+ db "PLEASE WAIT!@"
+
+CallCurrentTradeCenterFunction:
+ ld hl, TradeCenterPointerTable
+ ld b, 0
+ ld a, [wTradeCenterPointerTableIndex]
+ cp $ff
+ jp z, DisplayTitleScreen
+ add a
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+TradeCenter_SelectMon:
+ call ClearScreen
+ call LoadTrainerInfoTextBoxTiles
+ call TradeCenter_DrawPartyLists
+ call TradeCenter_DrawCancelBox
+ xor a
+ ld hl, wSerialSyncAndExchangeNybbleReceiveData
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wMenuJoypadPollCount], a
+ inc a
+ ld [wSerialExchangeNybbleSendData], a
+ jp .playerMonMenu
+.enemyMonMenu
+ xor a
+ ld [wMenuWatchMovingOutOfBounds], a
+ inc a
+ ld [wWhichTradeMonSelectionMenu], a
+ ld a, D_DOWN | D_LEFT | A_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, [wEnemyPartyCount]
+ ld [wMaxMenuItem], a
+ ld a, 9
+ ld [wTopMenuItemY], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+.enemyMonMenu_HandleInput
+ ld hl, hFlags_0xFFF6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, hFlags_0xFFF6
+ res 1, [hl]
+ and a
+ jp z, .getNewInput
+ bit 0, a ; A button pressed?
+ jr z, .enemyMonMenu_ANotPressed
+; if A button pressed
+ ld a, [wMaxMenuItem]
+ ld c, a
+ ld a, [wCurrentMenuItem]
+ cp c
+ jr c, .displayEnemyMonStats
+ ld a, [wMaxMenuItem]
+ dec a
+ ld [wCurrentMenuItem], a
+.displayEnemyMonStats
+ ld a, INIT_ENEMYOT_LIST
+ ld [wInitListType], a
+ callab InitList ; the list isn't used
+ ld hl, wEnemyMons
+ call TradeCenter_DisplayStats
+ jp .getNewInput
+.enemyMonMenu_ANotPressed
+ bit 5, a ; Left pressed?
+ jr z, .enemyMonMenu_LeftNotPressed
+; if Left pressed, switch back to the player mon menu
+ xor a ; player mon menu
+ ld [wWhichTradeMonSelectionMenu], a
+ ld a, [wMenuCursorLocation]
+ ld l, a
+ ld a, [wMenuCursorLocation + 1]
+ ld h, a
+ ld a, [wTileBehindCursor]
+ ld [hl], a
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wPartyCount]
+ dec a
+ cp b
+ jr nc, .playerMonMenu
+ ld [wCurrentMenuItem], a
+ jr .playerMonMenu
+.enemyMonMenu_LeftNotPressed
+ bit 7, a ; Down pressed?
+ jp z, .getNewInput
+ jp .selectedCancelMenuItem ; jump if Down pressed
+.playerMonMenu
+ xor a ; player mon menu
+ ld [wWhichTradeMonSelectionMenu], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld a, D_DOWN | D_RIGHT | A_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, [wPartyCount]
+ ld [wMaxMenuItem], a
+ ld a, 1
+ ld [wTopMenuItemY], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+ coord hl, 1, 1
+ lb bc, 6, 1
+ call ClearScreenArea
+.playerMonMenu_HandleInput
+ ld hl, hFlags_0xFFF6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, hFlags_0xFFF6
+ res 1, [hl]
+ and a ; was anything pressed?
+ jr nz, .playerMonMenu_SomethingPressed
+ jp .getNewInput
+.playerMonMenu_SomethingPressed
+ bit 0, a ; A button pressed?
+ jr z, .playerMonMenu_ANotPressed
+ jp .chosePlayerMon ; jump if A button pressed
+; unreachable code
+ ld a, INIT_PLAYEROT_LIST
+ ld [wInitListType], a
+ callab InitList ; the list isn't used
+ call TradeCenter_DisplayStats
+ jp .getNewInput
+.playerMonMenu_ANotPressed
+ bit 4, a ; Right pressed?
+ jr z, .playerMonMenu_RightNotPressed
+; if Right pressed, switch to the enemy mon menu
+ ld a, $1 ; enemy mon menu
+ ld [wWhichTradeMonSelectionMenu], a
+ ld a, [wMenuCursorLocation]
+ ld l, a
+ ld a, [wMenuCursorLocation + 1]
+ ld h, a
+ ld a, [wTileBehindCursor]
+ ld [hl], a
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wEnemyPartyCount]
+ dec a
+ cp b
+ jr nc, .notPastLastEnemyMon
+; when switching to the enemy mon menu, if the menu selection would be past the last enemy mon, select the last enemy mon
+ ld [wCurrentMenuItem], a
+.notPastLastEnemyMon
+ jp .enemyMonMenu
+.playerMonMenu_RightNotPressed
+ bit 7, a ; Down pressed?
+ jr z, .getNewInput
+ jp .selectedCancelMenuItem ; jump if Down pressed
+.getNewInput
+ ld a, [wWhichTradeMonSelectionMenu]
+ and a
+ jp z, .playerMonMenu_HandleInput
+ jp .enemyMonMenu_HandleInput
+.chosePlayerMon
+ call SaveScreenTilesToBuffer1
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wMaxMenuItem]
+ ld c, a
+ ld a, [wCurrentMenuItem]
+ cp c
+ jr c, .displayStatsTradeMenu
+ ld a, [wMaxMenuItem]
+ dec a
+.displayStatsTradeMenu
+ push af
+ coord hl, 0, 14
+ ld b, 2
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 2, 16
+ ld de, .statsTrade
+ call PlaceString
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wMenuJoypadPollCount], a
+ ld [wMaxMenuItem], a
+ ld a, 16
+ ld [wTopMenuItemY], a
+.selectStatsMenuItem
+ ld a, " "
+ Coorda 11, 16
+ ld a, D_RIGHT | B_BUTTON | A_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+ call HandleMenuInput
+ bit 4, a ; Right pressed?
+ jr nz, .selectTradeMenuItem
+ bit 1, a ; B button pressed?
+ jr z, .displayPlayerMonStats
+.cancelPlayerMonChoice
+ pop af
+ ld [wCurrentMenuItem], a
+ call LoadScreenTilesFromBuffer1
+ jp .playerMonMenu
+.selectTradeMenuItem
+ ld a, " "
+ Coorda 1, 16
+ ld a, D_LEFT | B_BUTTON | A_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 11
+ ld [wTopMenuItemX], a
+ call HandleMenuInput
+ bit 5, a ; Left pressed?
+ jr nz, .selectStatsMenuItem
+ bit 1, a ; B button pressed?
+ jr nz, .cancelPlayerMonChoice
+ jr .choseTrade
+.displayPlayerMonStats
+ pop af
+ ld [wCurrentMenuItem], a
+ ld a, INIT_PLAYEROT_LIST
+ ld [wInitListType], a
+ callab InitList ; the list isn't used
+ call TradeCenter_DisplayStats
+ call LoadScreenTilesFromBuffer1
+ jp .playerMonMenu
+.choseTrade
+ call PlaceUnfilledArrowMenuCursor
+ pop af
+ ld [wCurrentMenuItem], a
+ ld [wTradingWhichPlayerMon], a
+ ld [wSerialExchangeNybbleSendData], a
+ call Serial_PrintWaitingTextAndSyncAndExchangeNybble
+ ld a, [wSerialSyncAndExchangeNybbleReceiveData]
+ cp $f
+ jp z, CallCurrentTradeCenterFunction ; go back to the beginning of the trade selection menu if the other person cancelled
+ ld [wTradingWhichEnemyMon], a
+ call TradeCenter_PlaceSelectedEnemyMonMenuCursor
+ ld a, $1 ; TradeCenter_Trade
+ ld [wTradeCenterPointerTableIndex], a
+ jp CallCurrentTradeCenterFunction
+.statsTrade
+ db "STATS TRADE@"
+.selectedCancelMenuItem
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wMaxMenuItem]
+ cp b
+ jp nz, .getNewInput
+ ld a, [wMenuCursorLocation]
+ ld l, a
+ ld a, [wMenuCursorLocation + 1]
+ ld h, a
+ ld a, " "
+ ld [hl], a
+.cancelMenuItem_Loop
+ ld a, "▶" ; filled arrow cursor
+ Coorda 1, 16
+.cancelMenuItem_JoypadLoop
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ and a ; pressed anything?
+ jr z, .cancelMenuItem_JoypadLoop
+ bit 0, a ; A button pressed?
+ jr nz, .cancelMenuItem_APressed
+ bit 6, a ; Up pressed?
+ jr z, .cancelMenuItem_JoypadLoop
+; if Up pressed
+ ld a, " "
+ Coorda 1, 16
+ ld a, [wPartyCount]
+ dec a
+ ld [wCurrentMenuItem], a
+ jp .playerMonMenu
+.cancelMenuItem_APressed
+ ld a, "▷" ; unfilled arrow cursor
+ Coorda 1, 16
+ ld a, $f
+ ld [wSerialExchangeNybbleSendData], a
+ call Serial_PrintWaitingTextAndSyncAndExchangeNybble
+ ld a, [wSerialSyncAndExchangeNybbleReceiveData]
+ cp $f ; did the other person choose Cancel too?
+ jr nz, .cancelMenuItem_Loop
+ ; fall through
+
+ReturnToCableClubRoom:
+ call GBPalWhiteOutWithDelay3
+ ld hl, wFontLoaded
+ ld a, [hl]
+ push af
+ push hl
+ res 0, [hl]
+ xor a
+ ld [wd72d], a
+ dec a
+ ld [wDestinationWarpID], a
+ call LoadMapData
+ callba ClearVariablesOnEnterMap
+ pop hl
+ pop af
+ ld [hl], a
+ call GBFadeInFromWhite
+ ret
+
+TradeCenter_DrawCancelBox:
+ coord hl, 11, 15
+ ld a, $7e
+ ld bc, 2 * SCREEN_WIDTH + 9
+ call FillMemory
+ coord hl, 0, 15
+ ld b, 1
+ ld c, 9
+ call CableClub_TextBoxBorder
+ coord hl, 2, 16
+ ld de, CancelTextString
+ jp PlaceString
+
+CancelTextString:
+ db "CANCEL@"
+
+TradeCenter_PlaceSelectedEnemyMonMenuCursor:
+ ld a, [wSerialSyncAndExchangeNybbleReceiveData]
+ coord hl, 1, 9
+ ld bc, SCREEN_WIDTH
+ call AddNTimes
+ ld [hl], "▷" ; cursor
+ ret
+
+TradeCenter_DisplayStats:
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPokemon], a
+ predef StatusScreen
+ predef StatusScreen2
+ call GBPalNormal
+ call LoadTrainerInfoTextBoxTiles
+ call TradeCenter_DrawPartyLists
+ jp TradeCenter_DrawCancelBox
+
+TradeCenter_DrawPartyLists:
+ coord hl, 0, 0
+ ld b, 6
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 0, 8
+ ld b, 6
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 5, 0
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 5, 8
+ ld de, wLinkEnemyTrainerName
+ call PlaceString
+ coord hl, 2, 1
+ ld de, wPartySpecies
+ call TradeCenter_PrintPartyListNames
+ coord hl, 2, 9
+ ld de, wEnemyPartyMons
+ ; fall through
+
+TradeCenter_PrintPartyListNames:
+ ld c, $0
+.loop
+ ld a, [de]
+ cp $ff
+ ret z
+ ld [wd11e], a
+ push bc
+ push hl
+ push de
+ push hl
+ ld a, c
+ ld [$ff95], a
+ call GetMonName
+ pop hl
+ call PlaceString
+ pop de
+ inc de
+ pop hl
+ ld bc, 20
+ add hl, bc
+ pop bc
+ inc c
+ jr .loop
+
+TradeCenter_Trade:
+ ld c, 100
+ call DelayFrames
+ xor a
+ ld [wSerialExchangeNybbleSendData + 1], a ; unnecessary
+ ld [wSerialExchangeNybbleReceiveData], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld [wMenuJoypadPollCount], a
+ coord hl, 0, 12
+ ld b, 4
+ ld c, 18
+ call CableClub_TextBoxBorder
+ ld a, [wTradingWhichPlayerMon]
+ ld hl, wPartySpecies
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wcd6d
+ ld de, wNameOfPlayerMonToBeTraded
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wTradingWhichEnemyMon]
+ ld hl, wEnemyPartyMons
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, WillBeTradedText
+ coord bc, 1, 14
+ call TextCommandProcessor
+ call SaveScreenTilesToBuffer1
+ coord hl, 10, 7
+ lb bc, 8, 11
+ ld a, TRADE_CANCEL_MENU
+ ld [wTwoOptionMenuID], a
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ call LoadScreenTilesFromBuffer1
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .tradeConfirmed
+; if trade cancelled
+ ld a, $1
+ ld [wSerialExchangeNybbleSendData], a
+ coord hl, 0, 12
+ ld b, 4
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 1, 14
+ ld de, TradeCanceled
+ call PlaceString
+ call Serial_PrintWaitingTextAndSyncAndExchangeNybble
+ jp .tradeCancelled
+.tradeConfirmed
+ ld a, $2
+ ld [wSerialExchangeNybbleSendData], a
+ call Serial_PrintWaitingTextAndSyncAndExchangeNybble
+ ld a, [wSerialSyncAndExchangeNybbleReceiveData]
+ dec a ; did the other person cancel?
+ jr nz, .doTrade
+; if the other person cancelled
+ coord hl, 0, 12
+ ld b, 4
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 1, 14
+ ld de, TradeCanceled
+ call PlaceString
+ jp .tradeCancelled
+.doTrade
+ ld a, [wTradingWhichPlayerMon]
+ ld hl, wPartyMonOT
+ call SkipFixedLengthTextEntries
+ ld de, wTradedPlayerMonOT
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wPartyMon1Species
+ ld a, [wTradingWhichPlayerMon]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld bc, wPartyMon1OTID - wPartyMon1
+ add hl, bc
+ ld a, [hli]
+ ld [wTradedPlayerMonOTID], a
+ ld a, [hl]
+ ld [wTradedPlayerMonOTID + 1], a
+ ld a, [wTradingWhichEnemyMon]
+ ld hl, wEnemyMonOT
+ call SkipFixedLengthTextEntries
+ ld de, wTradedEnemyMonOT
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wEnemyMons
+ ld a, [wTradingWhichEnemyMon]
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld bc, wEnemyMon1OTID - wEnemyMon1
+ add hl, bc
+ ld a, [hli]
+ ld [wTradedEnemyMonOTID], a
+ ld a, [hl]
+ ld [wTradedEnemyMonOTID + 1], a
+ ld a, [wTradingWhichPlayerMon]
+ ld [wWhichPokemon], a
+ ld hl, wPartySpecies
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wTradedPlayerMonSpecies], a
+ xor a
+ ld [wRemoveMonFromBox], a
+ call RemovePokemon
+ ld a, [wTradingWhichEnemyMon]
+ ld c, a
+ ld [wWhichPokemon], a
+ ld hl, wEnemyPartyMons
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hl]
+ ld [wcf91], a
+ ld hl, wEnemyMons
+ ld a, c
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call AddNTimes
+ ld de, wLoadedMon
+ ld bc, wEnemyMon2 - wEnemyMon1
+ call CopyData
+ call AddEnemyMonToPlayerParty
+ ld a, [wPartyCount]
+ dec a
+ ld [wWhichPokemon], a
+ ld a, $1
+ ld [wForceEvolution], a
+ ld a, [wTradingWhichEnemyMon]
+ ld hl, wEnemyPartyMons
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wTradedEnemyMonSpecies], a
+ ld a, 10
+ ld [wAudioFadeOutControl], a
+ ld a, $2
+ ld [wAudioSavedROMBank], a
+ ld a, MUSIC_SAFARI_ZONE
+ ld [wNewSoundID], a
+ call PlaySound
+ ld c, 100
+ call DelayFrames
+ call ClearScreen
+ call LoadHpBarAndStatusTilePatterns
+ xor a
+ ld [wUnusedCC5B], a
+ ld a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ jr z, .usingExternalClock
+ predef InternalClockTradeAnim
+ jr .tradeCompleted
+.usingExternalClock
+ predef ExternalClockTradeAnim
+.tradeCompleted
+ callab TryEvolvingMon
+ call ClearScreen
+ call LoadTrainerInfoTextBoxTiles
+ call Serial_PrintWaitingTextAndSyncAndExchangeNybble
+ ld c, 40
+ call DelayFrames
+ coord hl, 0, 12
+ ld b, 4
+ ld c, 18
+ call CableClub_TextBoxBorder
+ coord hl, 1, 14
+ ld de, TradeCompleted
+ call PlaceString
+ predef SaveSAVtoSRAM2
+ ld c, 50
+ call DelayFrames
+ xor a
+ ld [wTradeCenterPointerTableIndex], a
+ jp CableClub_DoBattleOrTradeAgain
+.tradeCancelled
+ ld c, 100
+ call DelayFrames
+ xor a ; TradeCenter_SelectMon
+ ld [wTradeCenterPointerTableIndex], a
+ jp CallCurrentTradeCenterFunction
+
+WillBeTradedText:
+ TX_FAR _WillBeTradedText
+ db "@"
+
+TradeCompleted:
+ db "Trade completed!@"
+
+TradeCanceled:
+ db "Too bad! The trade"
+ next "was canceled!@"
+
+TradeCenterPointerTable:
+ dw TradeCenter_SelectMon
+ dw TradeCenter_Trade
+
+CableClub_Run:
+ ld a, [wLinkState]
+ cp LINK_STATE_START_TRADE
+ jr z, .doBattleOrTrade
+ cp LINK_STATE_START_BATTLE
+ jr z, .doBattleOrTrade
+ cp LINK_STATE_RESET ; this is never used
+ ret nz
+ predef EmptyFunc3
+ jp Init
+.doBattleOrTrade
+ call CableClub_DoBattleOrTrade
+ ld hl, Club_GFX
+ ld a, h
+ ld [wTilesetGfxPtr + 1], a
+ ld a, l
+ ld [wTilesetGfxPtr], a
+ ld a, Bank(Club_GFX)
+ ld [wTilesetBank], a
+ ld hl, Club_Coll
+ ld a, h
+ ld [wTilesetCollisionPtr + 1], a
+ ld a, l
+ ld [wTilesetCollisionPtr], a
+ xor a
+ ld [wGrassRate], a
+ inc a ; LINK_STATE_IN_CABLE_CLUB
+ ld [wLinkState], a
+ ld [hJoy5], a
+ ld a, 10
+ ld [wAudioFadeOutControl], a
+ ld a, BANK(Music_Celadon)
+ ld [wAudioSavedROMBank], a
+ ld a, MUSIC_CELADON
+ ld [wNewSoundID], a
+ jp PlaySound
+
+EmptyFunc3:
+ ret
+
+Diploma_TextBoxBorder:
+ call GetPredefRegisters
+
+; b = height
+; c = width
+CableClub_TextBoxBorder:
+ push hl
+ ld a, $78 ; border upper left corner tile
+ ld [hli], a
+ inc a ; border top horizontal line tile
+ call CableClub_DrawHorizontalLine
+ inc a ; border upper right corner tile
+ ld [hl], a
+ pop hl
+ ld de, 20
+ add hl, de
+.loop
+ push hl
+ ld a, $7b ; border left vertical line tile
+ ld [hli], a
+ ld a, " "
+ call CableClub_DrawHorizontalLine
+ ld [hl], $77 ; border right vertical line tile
+ pop hl
+ ld de, 20
+ add hl, de
+ dec b
+ jr nz, .loop
+ ld a, $7c ; border lower left corner tile
+ ld [hli], a
+ ld a, $76 ; border bottom horizontal line tile
+ call CableClub_DrawHorizontalLine
+ ld [hl], $7d ; border lower right corner tile
+ ret
+
+; c = width
+CableClub_DrawHorizontalLine:
+ ld d, c
+.loop
+ ld [hli], a
+ dec d
+ jr nz, .loop
+ ret
+
+LoadTrainerInfoTextBoxTiles:
+ ld de, TrainerInfoTextBoxTileGraphics
+ ld hl, vChars2 + $760
+ lb bc, BANK(TrainerInfoTextBoxTileGraphics), (TrainerInfoTextBoxTileGraphicsEnd - TrainerInfoTextBoxTileGraphics) / $10
+ jp CopyVideoData
diff --git a/en/engine/clear_save.asm b/en/engine/clear_save.asm
new file mode 100755
index 00000000..b47cd6c4
--- /dev/null
+++ b/en/engine/clear_save.asm
@@ -0,0 +1,23 @@
+DoClearSaveDialogue:
+ call ClearScreen
+ call RunDefaultPaletteCommand
+ call LoadFontTilePatterns
+ call LoadTextBoxTilePatterns
+ ld hl, ClearSaveDataText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, NO_YES_MENU
+ ld [wTwoOptionMenuID], a
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, [wCurrentMenuItem]
+ and a
+ jp z, Init
+ callba ClearSAV
+ jp Init
+
+ClearSaveDataText:
+ TX_FAR _ClearSaveDataText
+ db "@"
diff --git a/en/engine/evolve_trade.asm b/en/engine/evolve_trade.asm
new file mode 100755
index 00000000..e17fc05c
--- /dev/null
+++ b/en/engine/evolve_trade.asm
@@ -0,0 +1,44 @@
+EvolveTradeMon:
+; Verify the TradeMon's species name before
+; attempting to initiate a trade evolution.
+
+; The names of the trade evolutions in Blue (JP)
+; are checked. In that version, TradeMons that
+; can evolve are Graveler and Haunter.
+
+; In localization, this check was translated
+; before monster names were finalized.
+; Then, Haunter's name was "Spectre".
+; Since its name no longer starts with
+; "SP", it is prevented from evolving.
+
+; This may have been why Red/Green's trades
+; were used instead, where none can evolve.
+
+; This was fixed in Yellow.
+
+ ld a, [wInGameTradeReceiveMonName]
+
+ ; GRAVELER
+ cp "G"
+ jr z, .ok
+
+ ; "SPECTRE" (HAUNTER)
+ cp "S"
+ ret nz
+ ld a, [wInGameTradeReceiveMonName + 1]
+ cp "P"
+ ret nz
+
+.ok
+ ld a, [wPartyCount]
+ dec a
+ ld [wWhichPokemon], a
+ ld a, $1
+ ld [wForceEvolution], a
+ ld a, LINK_STATE_TRADING
+ ld [wLinkState], a
+ callab TryEvolvingMon
+ xor a ; LINK_STATE_NONE
+ ld [wLinkState], a
+ jp PlayDefaultMusic
diff --git a/en/engine/hall_of_fame.asm b/en/engine/hall_of_fame.asm
new file mode 100755
index 00000000..3c9b1723
--- /dev/null
+++ b/en/engine/hall_of_fame.asm
@@ -0,0 +1,288 @@
+AnimateHallOfFame:
+ call HoFFadeOutScreenAndMusic
+ call ClearScreen
+ ld c, 100
+ call DelayFrames
+ call LoadFontTilePatterns
+ call LoadTextBoxTilePatterns
+ call DisableLCD
+ ld hl, vBGMap0
+ ld bc, $800
+ ld a, " "
+ call FillMemory
+ call EnableLCD
+ ld hl, rLCDC
+ set 3, [hl]
+ xor a
+ ld hl, wHallOfFame
+ ld bc, HOF_TEAM
+ call FillMemory
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ ld [hTilesetType], a
+ ld [wSpriteFlipped], a
+ ld [wLetterPrintingDelayFlags], a ; no delay
+ ld [wHoFMonOrPlayer], a ; mon
+ inc a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wNumHoFTeams
+ ld a, [hl]
+ inc a
+ jr z, .skipInc ; don't wrap around to 0
+ inc [hl]
+.skipInc
+ ld a, $90
+ ld [hWY], a
+ ld c, BANK(Music_HallOfFame)
+ ld a, MUSIC_HALL_OF_FAME
+ call PlayMusic
+ ld hl, wPartySpecies
+ ld c, $ff
+.partyMonLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .doneShowingParty
+ inc c
+ push hl
+ push bc
+ ld [wHoFMonSpecies], a
+ ld a, c
+ ld [wHoFPartyMonIndex], a
+ ld hl, wPartyMon1Level
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hl]
+ ld [wHoFMonLevel], a
+ call HoFShowMonOrPlayer
+ call HoFDisplayAndRecordMonInfo
+ ld c, 80
+ call DelayFrames
+ coord hl, 2, 13
+ ld b, 3
+ ld c, 14
+ call TextBoxBorder
+ coord hl, 4, 15
+ ld de, HallOfFameText
+ call PlaceString
+ ld c, 180
+ call DelayFrames
+ call GBFadeOutToWhite
+ pop bc
+ pop hl
+ jr .partyMonLoop
+.doneShowingParty
+ ld a, c
+ inc a
+ ld hl, wHallOfFame
+ ld bc, HOF_MON
+ call AddNTimes
+ ld [hl], $ff
+ call SaveHallOfFameTeams
+ xor a
+ ld [wHoFMonSpecies], a
+ inc a
+ ld [wHoFMonOrPlayer], a ; player
+ call HoFShowMonOrPlayer
+ call HoFDisplayPlayerStats
+ call HoFFadeOutScreenAndMusic
+ xor a
+ ld [hWY], a
+ ld hl, rLCDC
+ res 3, [hl]
+ ret
+
+HallOfFameText:
+ db "HALL OF FAME@"
+
+HoFShowMonOrPlayer:
+ call ClearScreen
+ ld a, $d0
+ ld [hSCY], a
+ ld a, $c0
+ ld [hSCX], a
+ ld a, [wHoFMonSpecies]
+ ld [wcf91], a
+ ld [wd0b5], a
+ ld [wBattleMonSpecies2], a
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld a, [wHoFMonOrPlayer]
+ and a
+ jr z, .showMon
+; show player
+ call HoFLoadPlayerPics
+ jr .next1
+.showMon
+ coord hl, 12, 5
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ predef LoadMonBackPic
+.next1
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ ld c, 0
+ call RunPaletteCommand
+ ld a, %11100100
+ ld [rBGP], a
+ ld c, $31 ; back pic
+ call HoFLoadMonPlayerPicTileIDs
+ ld d, $a0
+ ld e, 4
+ ld a, [wOnSGB]
+ and a
+ jr z, .next2
+ sla e ; scroll more slowly on SGB
+.next2
+ call .ScrollPic ; scroll back pic left
+ xor a
+ ld [hSCY], a
+ ld c, a ; front pic
+ call HoFLoadMonPlayerPicTileIDs
+ ld d, 0
+ ld e, -4
+; scroll front pic right
+
+.ScrollPic
+ call DelayFrame
+ ld a, [hSCX]
+ add e
+ ld [hSCX], a
+ cp d
+ jr nz, .ScrollPic
+ ret
+
+HoFDisplayAndRecordMonInfo:
+ ld a, [wHoFPartyMonIndex]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ call HoFDisplayMonInfo
+ jp HoFRecordMonInfo
+
+HoFDisplayMonInfo:
+ coord hl, 0, 2
+ ld b, 9
+ ld c, 10
+ call TextBoxBorder
+ coord hl, 2, 6
+ ld de, HoFMonInfoText
+ call PlaceString
+ coord hl, 1, 4
+ ld de, wcd6d
+ call PlaceString
+ ld a, [wHoFMonLevel]
+ coord hl, 8, 7
+ call PrintLevelCommon
+ ld a, [wHoFMonSpecies]
+ ld [wd0b5], a
+ coord hl, 3, 9
+ predef PrintMonType
+ ld a, [wHoFMonSpecies]
+ jp PlayCry
+
+HoFMonInfoText:
+ db "LEVEL/"
+ next "TYPE1/"
+ next "TYPE2/@"
+
+HoFLoadPlayerPics:
+ ld de, RedPicFront
+ ld a, BANK(RedPicFront)
+ call UncompressSpriteFromDE
+ ld hl, sSpriteBuffer1
+ ld de, sSpriteBuffer0
+ ld bc, $310
+ call CopyData
+ ld de, vFrontPic
+ call InterlaceMergeSpriteBuffers
+ ld de, RedPicBack
+ ld a, BANK(RedPicBack)
+ call UncompressSpriteFromDE
+ predef ScaleSpriteByTwo
+ ld de, vBackPic
+ call InterlaceMergeSpriteBuffers
+ ld c, $1
+
+HoFLoadMonPlayerPicTileIDs:
+; c = base tile ID
+ ld b, 0
+ coord hl, 12, 5
+ predef_jump CopyTileIDsFromList
+
+HoFDisplayPlayerStats:
+ SetEvent EVENT_HALL_OF_FAME_DEX_RATING
+ predef DisplayDexRating
+ coord hl, 0, 4
+ ld b, 6
+ ld c, 10
+ call TextBoxBorder
+ coord hl, 5, 0
+ ld b, 2
+ ld c, 9
+ call TextBoxBorder
+ coord hl, 7, 2
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 1, 6
+ ld de, HoFPlayTimeText
+ call PlaceString
+ coord hl, 5, 7
+ ld de, wPlayTimeHours
+ lb bc, 1, 3
+ call PrintNumber
+ ld [hl], $6d
+ inc hl
+ ld de, wPlayTimeMinutes
+ lb bc, LEADING_ZEROES | 1, 2
+ call PrintNumber
+ coord hl, 1, 9
+ ld de, HoFMoneyText
+ call PlaceString
+ coord hl, 4, 10
+ ld de, wPlayerMoney
+ ld c, $a3
+ call PrintBCDNumber
+ ld hl, DexSeenOwnedText
+ call HoFPrintTextAndDelay
+ ld hl, DexRatingText
+ call HoFPrintTextAndDelay
+ ld hl, wDexRatingText
+
+HoFPrintTextAndDelay:
+ call PrintText
+ ld c, 120
+ jp DelayFrames
+
+HoFPlayTimeText:
+ db "PLAY TIME@"
+
+HoFMoneyText:
+ db "MONEY@"
+
+DexSeenOwnedText:
+ TX_FAR _DexSeenOwnedText
+ db "@"
+
+DexRatingText:
+ TX_FAR _DexRatingText
+ db "@"
+
+HoFRecordMonInfo:
+ ld hl, wHallOfFame
+ ld bc, HOF_MON
+ ld a, [wHoFPartyMonIndex]
+ call AddNTimes
+ ld a, [wHoFMonSpecies]
+ ld [hli], a
+ ld a, [wHoFMonLevel]
+ ld [hli], a
+ ld e, l
+ ld d, h
+ ld hl, wcd6d
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+HoFFadeOutScreenAndMusic:
+ ld a, 10
+ ld [wAudioFadeOutCounterReloadValue], a
+ ld [wAudioFadeOutCounter], a
+ ld a, $ff
+ ld [wAudioFadeOutControl], a
+ jp GBFadeOutToWhite
diff --git a/en/engine/hidden_object_functions17.asm b/en/engine/hidden_object_functions17.asm
new file mode 100755
index 00000000..c1fa5aa4
--- /dev/null
+++ b/en/engine/hidden_object_functions17.asm
@@ -0,0 +1,475 @@
+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
diff --git a/en/engine/hidden_object_functions7.asm b/en/engine/hidden_object_functions7.asm
new file mode 100755
index 00000000..f04c1deb
--- /dev/null
+++ b/en/engine/hidden_object_functions7.asm
@@ -0,0 +1,467 @@
+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 + Ch4]
+ 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_ENTRANCE
+ ld [hWarpDestinationMap], a
+ ld a, $3
+ ld [wDestinationWarpID], a
+ ld a, $5
+ ld [wSafariZoneEntranceCurScript], 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 "@"
diff --git a/en/engine/items/items.asm b/en/engine/items/items.asm
new file mode 100755
index 00000000..3bb2ec9e
--- /dev/null
+++ b/en/engine/items/items.asm
@@ -0,0 +1,2989 @@
+UseItem_:
+ ld a, 1
+ ld [wActionResultOrTookBattleTurn], a ; initialise to success value
+ ld a, [wcf91] ;contains item_ID
+ cp HM_01
+ jp nc, ItemUseTMHM
+ ld hl, ItemUsePtrTable
+ dec a
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+ItemUsePtrTable:
+ dw ItemUseBall ; MASTER_BALL
+ dw ItemUseBall ; ULTRA_BALL
+ dw ItemUseBall ; GREAT_BALL
+ dw ItemUseBall ; POKE_BALL
+ dw ItemUseTownMap ; TOWN_MAP
+ dw ItemUseBicycle ; BICYCLE
+ dw ItemUseSurfboard ; out-of-battle Surf effect
+ dw ItemUseBall ; SAFARI_BALL
+ dw ItemUsePokedex ; POKEDEX
+ dw ItemUseEvoStone ; MOON_STONE
+ dw ItemUseMedicine ; ANTIDOTE
+ dw ItemUseMedicine ; BURN_HEAL
+ dw ItemUseMedicine ; ICE_HEAL
+ dw ItemUseMedicine ; AWAKENING
+ dw ItemUseMedicine ; PARLYZ_HEAL
+ dw ItemUseMedicine ; FULL_RESTORE
+ dw ItemUseMedicine ; MAX_POTION
+ dw ItemUseMedicine ; HYPER_POTION
+ dw ItemUseMedicine ; SUPER_POTION
+ dw ItemUseMedicine ; POTION
+ dw ItemUseBait ; BOULDERBADGE
+ dw ItemUseRock ; CASCADEBADGE
+ dw UnusableItem ; THUNDERBADGE
+ dw UnusableItem ; RAINBOWBADGE
+ dw UnusableItem ; SOULBADGE
+ dw UnusableItem ; MARSHBADGE
+ dw UnusableItem ; VOLCANOBADGE
+ dw UnusableItem ; EARTHBADGE
+ dw ItemUseEscapeRope ; ESCAPE_ROPE
+ dw ItemUseRepel ; REPEL
+ dw UnusableItem ; OLD_AMBER
+ dw ItemUseEvoStone ; FIRE_STONE
+ dw ItemUseEvoStone ; THUNDER_STONE
+ dw ItemUseEvoStone ; WATER_STONE
+ dw ItemUseVitamin ; HP_UP
+ dw ItemUseVitamin ; PROTEIN
+ dw ItemUseVitamin ; IRON
+ dw ItemUseVitamin ; CARBOS
+ dw ItemUseVitamin ; CALCIUM
+ dw ItemUseVitamin ; RARE_CANDY
+ dw UnusableItem ; DOME_FOSSIL
+ dw UnusableItem ; HELIX_FOSSIL
+ dw UnusableItem ; SECRET_KEY
+ dw UnusableItem
+ dw UnusableItem ; BIKE_VOUCHER
+ dw ItemUseXAccuracy ; X_ACCURACY
+ dw ItemUseEvoStone ; LEAF_STONE
+ dw ItemUseCardKey ; CARD_KEY
+ dw UnusableItem ; NUGGET
+ dw UnusableItem ; ??? PP_UP
+ dw ItemUsePokedoll ; POKE_DOLL
+ dw ItemUseMedicine ; FULL_HEAL
+ dw ItemUseMedicine ; REVIVE
+ dw ItemUseMedicine ; MAX_REVIVE
+ dw ItemUseGuardSpec ; GUARD_SPEC
+ dw ItemUseSuperRepel ; SUPER_REPL
+ dw ItemUseMaxRepel ; MAX_REPEL
+ dw ItemUseDireHit ; DIRE_HIT
+ dw UnusableItem ; COIN
+ dw ItemUseMedicine ; FRESH_WATER
+ dw ItemUseMedicine ; SODA_POP
+ dw ItemUseMedicine ; LEMONADE
+ dw UnusableItem ; S_S_TICKET
+ dw UnusableItem ; GOLD_TEETH
+ dw ItemUseXStat ; X_ATTACK
+ dw ItemUseXStat ; X_DEFEND
+ dw ItemUseXStat ; X_SPEED
+ dw ItemUseXStat ; X_SPECIAL
+ dw ItemUseCoinCase ; COIN_CASE
+ dw ItemUseOaksParcel ; OAKS_PARCEL
+ dw ItemUseItemfinder ; ITEMFINDER
+ dw UnusableItem ; SILPH_SCOPE
+ dw ItemUsePokeflute ; POKE_FLUTE
+ dw UnusableItem ; LIFT_KEY
+ dw UnusableItem ; EXP_ALL
+ dw ItemUseOldRod ; OLD_ROD
+ dw ItemUseGoodRod ; GOOD_ROD
+ dw ItemUseSuperRod ; SUPER_ROD
+ dw ItemUsePPUp ; PP_UP (real one)
+ dw ItemUsePPRestore ; ETHER
+ dw ItemUsePPRestore ; MAX_ETHER
+ dw ItemUsePPRestore ; ELIXER
+ dw ItemUsePPRestore ; MAX_ELIXER
+
+ItemUseBall:
+
+; Balls can't be used out of battle.
+ ld a, [wIsInBattle]
+ and a
+ jp z, ItemUseNotTime
+
+; Balls can't catch trainers' Pokémon.
+ dec a
+ jp nz, ThrowBallAtTrainerMon
+
+; If this is for the old man battle, skip checking if the party & box are full.
+ ld a, [wBattleType]
+ dec a
+ jr z, .canUseBall
+
+ ld a, [wPartyCount] ; is party full?
+ cp PARTY_LENGTH
+ jr nz, .canUseBall
+ ld a, [wNumInBox] ; is box full?
+ cp MONS_PER_BOX
+ jp z, BoxFullCannotThrowBall
+
+.canUseBall
+ xor a
+ ld [wCapturedMonSpecies], a
+
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_SAFARI
+ jr nz, .skipSafariZoneCode
+
+.safariZone
+ ld hl, wNumSafariBalls
+ dec [hl] ; remove a Safari Ball
+
+.skipSafariZoneCode
+ call RunDefaultPaletteCommand
+
+ ld a, $43 ; successful capture value
+ ld [wPokeBallAnimData], a
+
+ call LoadScreenTilesFromBuffer1
+ ld hl, ItemUseText00
+ call PrintText
+
+; If the player is fighting an unidentified ghost, set the value that indicates
+; the Pokémon can't be caught and skip the capture calculations.
+ callab IsGhostBattle
+ ld b, $10 ; can't be caught value
+ jp z, .setAnimData
+
+ ld a, [wBattleType]
+ dec a
+ jr nz, .notOldManBattle
+
+.oldManBattle
+ ld hl, wGrassRate
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno. glitch)
+ jp .captured
+
+.notOldManBattle
+; If the player is fighting the ghost Marowak, set the value that indicates the
+; Pokémon can't be caught and skip the capture calculations.
+ ld a, [wCurMap]
+ cp POKEMONTOWER_6
+ jr nz, .loop
+ ld a, [wEnemyMonSpecies2]
+ cp MAROWAK
+ ld b, $10 ; can't be caught value
+ jp z, .setAnimData
+
+; Get the first random number. Let it be called Rand1.
+; Rand1 must be within a certain range according the kind of ball being thrown.
+; The ranges are as follows.
+; Poké Ball: [0, 255]
+; Great Ball: [0, 200]
+; Ultra/Safari Ball: [0, 150]
+; Loop until an acceptable number is found.
+
+.loop
+ call Random
+ ld b, a
+
+; Get the item ID.
+ ld hl, wcf91
+ ld a, [hl]
+
+; The Master Ball always succeeds.
+ cp MASTER_BALL
+ jp z, .captured
+
+; Anything will do for the basic Poké Ball.
+ cp POKE_BALL
+ jr z, .checkForAilments
+
+; If it's a Great/Ultra/Safari Ball and Rand1 is greater than 200, try again.
+ ld a, 200
+ cp b
+ jr c, .loop
+
+; Less than or equal to 200 is good enough for a Great Ball.
+ ld a, [hl]
+ cp GREAT_BALL
+ jr z, .checkForAilments
+
+; If it's an Ultra/Safari Ball and Rand1 is greater than 150, try again.
+ ld a, 150
+ cp b
+ jr c, .loop
+
+.checkForAilments
+; Pokémon can be caught more easily with a status ailment.
+; Depending on the status ailment, a certain value will be subtracted from
+; Rand1. Let this value be called Status.
+; The larger Status is, the more easily the Pokémon can be caught.
+; no status ailment: Status = 0
+; Burn/Paralysis/Poison: Status = 12
+; Freeze/Sleep: Status = 25
+; If Status is greater than Rand1, the Pokémon will be caught for sure.
+ ld a, [wEnemyMonStatus]
+ and a
+ jr z, .skipAilmentValueSubtraction ; no ailments
+ and 1 << FRZ | SLP
+ ld c, 12
+ jr z, .notFrozenOrAsleep
+ ld c, 25
+.notFrozenOrAsleep
+ ld a, b
+ sub c
+ jp c, .captured
+ ld b, a
+
+.skipAilmentValueSubtraction
+ push bc ; save (Rand1 - Status)
+
+; Calculate MaxHP * 255.
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [hl]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, 255
+ ld [H_MULTIPLIER], a
+ call Multiply
+
+; Determine BallFactor. It's 8 for Great Balls and 12 for the others.
+ ld a, [wcf91]
+ cp GREAT_BALL
+ ld a, 12
+ jr nz, .skip1
+ ld a, 8
+
+.skip1
+; Note that the results of all division operations are floored.
+
+; Calculate (MaxHP * 255) / BallFactor.
+ ld [H_DIVISOR], a
+ ld b, 4 ; number of bytes in dividend
+ call Divide
+
+; Divide the enemy's current HP by 4. HP is not supposed to exceed 999 so
+; the result should fit in a. If the division results in a quotient of 0,
+; change it to 1.
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ srl b
+ rr a
+ srl b
+ rr a
+ and a
+ jr nz, .skip2
+ inc a
+
+.skip2
+; Let W = ((MaxHP * 255) / BallFactor) / max(HP / 4, 1). Calculate W.
+ ld [H_DIVISOR], a
+ ld b, 4
+ call Divide
+
+; If W > 255, store 255 in [H_QUOTIENT + 3].
+; Let X = min(W, 255) = [H_QUOTIENT + 3].
+ ld a, [H_QUOTIENT + 2]
+ and a
+ jr z, .skip3
+ ld a, 255
+ ld [H_QUOTIENT + 3], a
+
+.skip3
+ pop bc ; b = Rand1 - Status
+
+; If Rand1 - Status > CatchRate, the ball fails to capture the Pokémon.
+ ld a, [wEnemyMonActualCatchRate]
+ cp b
+ jr c, .failedToCapture
+
+; If W > 255, the ball captures the Pokémon.
+ ld a, [H_QUOTIENT + 2]
+ and a
+ jr nz, .captured
+
+ call Random ; Let this random number be called Rand2.
+
+; If Rand2 > X, the ball fails to capture the Pokémon.
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ cp b
+ jr c, .failedToCapture
+
+.captured
+ jr .skipShakeCalculations
+
+.failedToCapture
+ ld a, [H_QUOTIENT + 3]
+ ld [wPokeBallCaptureCalcTemp], a ; Save X.
+
+; Calculate CatchRate * 100.
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld [H_MULTIPLICAND + 1], a
+ ld a, [wEnemyMonActualCatchRate]
+ ld [H_MULTIPLICAND + 2], a
+ ld a, 100
+ ld [H_MULTIPLIER], a
+ call Multiply
+
+; Determine BallFactor2.
+; Poké Ball: BallFactor2 = 255
+; Great Ball: BallFactor2 = 200
+; Ultra/Safari Ball: BallFactor2 = 150
+ ld a, [wcf91]
+ ld b, 255
+ cp POKE_BALL
+ jr z, .skip4
+ ld b, 200
+ cp GREAT_BALL
+ jr z, .skip4
+ ld b, 150
+ cp ULTRA_BALL
+ jr z, .skip4
+
+.skip4
+; Let Y = (CatchRate * 100) / BallFactor2. Calculate Y.
+ ld a, b
+ ld [H_DIVISOR], a
+ ld b, 4
+ call Divide
+
+; If Y > 255, there are 3 shakes.
+; Note that this shouldn't be possible.
+; The maximum value of Y is (255 * 100) / 150 = 170.
+ ld a, [H_QUOTIENT + 2]
+ and a
+ ld b, $63 ; 3 shakes
+ jr nz, .setAnimData
+
+; Calculate X * Y.
+ ld a, [wPokeBallCaptureCalcTemp]
+ ld [H_MULTIPLIER], a
+ call Multiply
+
+; Calculate (X * Y) / 255.
+ ld a, 255
+ ld [H_DIVISOR], a
+ ld b, 4
+ call Divide
+
+; Determine Status2.
+; no status ailment: Status2 = 0
+; Burn/Paralysis/Poison: Status2 = 5
+; Freeze/Sleep: Status2 = 10
+ ld a, [wEnemyMonStatus]
+ and a
+ jr z, .skip5
+ and 1 << FRZ | SLP
+ ld b, 5
+ jr z, .addAilmentValue
+ ld b, 10
+
+.addAilmentValue
+; If the Pokémon has a status ailment, add Status2.
+ ld a, [H_QUOTIENT + 3]
+ add b
+ ld [H_QUOTIENT + 3], a
+
+.skip5
+; Finally determine the number of shakes.
+; Let Z = ((X * Y) / 255) + Status2 = [H_QUOTIENT + 3].
+; The number of shakes depend on the range Z is in.
+; 0 ≤ Z < 10: 0 shakes (the ball misses)
+; 10 ≤ Z < 30: 1 shake
+; 30 ≤ Z < 70: 2 shakes
+; 70 ≤ Z: 3 shakes
+ ld a, [H_QUOTIENT + 3]
+ cp 10
+ ld b, $20
+ jr c, .setAnimData
+ cp 30
+ ld b, $61
+ jr c, .setAnimData
+ cp 70
+ ld b, $62
+ jr c, .setAnimData
+ ld b, $63
+
+.setAnimData
+ ld a, b
+ ld [wPokeBallAnimData], a
+
+.skipShakeCalculations
+ ld c, 20
+ call DelayFrames
+
+; Do the animation.
+ ld a, TOSS_ANIM
+ ld [wAnimationID], a
+ xor a
+ ld [H_WHOSETURN], a
+ ld [wAnimationType], a
+ ld [wDamageMultipliers], a
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ push af
+ predef MoveAnimation
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+
+; Determine the message to display from the animation.
+ ld a, [wPokeBallAnimData]
+ cp $10
+ ld hl, ItemUseBallText00
+ jp z, .printMessage
+ cp $20
+ ld hl, ItemUseBallText01
+ jp z, .printMessage
+ cp $61
+ ld hl, ItemUseBallText02
+ jp z, .printMessage
+ cp $62
+ ld hl, ItemUseBallText03
+ jp z, .printMessage
+ cp $63
+ ld hl, ItemUseBallText04
+ jp z, .printMessage
+
+; Save current HP.
+ ld hl, wEnemyMonHP
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ push af
+
+; Save status ailment.
+ inc hl
+ ld a, [hl]
+ push af
+
+ push hl
+
+; If the Pokémon is transformed, the Pokémon is assumed to be a Ditto.
+; This is a bug because a wild Pokémon could have used Transform via
+; Mirror Move even though the only wild Pokémon that knows Transform is Ditto.
+ ld hl, wEnemyBattleStatus3
+ bit TRANSFORMED, [hl]
+ jr z, .notTransformed
+ ld a, DITTO
+ ld [wEnemyMonSpecies2], a
+ jr .skip6
+
+.notTransformed
+; If the Pokémon is not transformed, set the transformed bit and copy the
+; DVs to wTransformedEnemyMonOriginalDVs so that LoadEnemyMonData won't generate
+; new DVs.
+ set TRANSFORMED, [hl]
+ ld hl, wTransformedEnemyMonOriginalDVs
+ ld a, [wEnemyMonDVs]
+ ld [hli], a
+ ld a, [wEnemyMonDVs + 1]
+ ld [hl], a
+
+.skip6
+ ld a, [wcf91]
+ push af
+ ld a, [wEnemyMonSpecies2]
+ ld [wcf91], a
+ ld a, [wEnemyMonLevel]
+ ld [wCurEnemyLVL], a
+ callab LoadEnemyMonData
+ pop af
+ ld [wcf91], a
+ pop hl
+ pop af
+ ld [hld], a
+ dec hl
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ ld a, [wEnemyMonSpecies]
+ ld [wCapturedMonSpecies], a
+ ld [wcf91], a
+ ld [wd11e], a
+ ld a, [wBattleType]
+ dec a ; is this the old man battle?
+ jr z, .oldManCaughtMon ; if so, don't give the player the caught Pokémon
+
+ ld hl, ItemUseBallText05
+ call PrintText
+
+; Add the caught Pokémon to the Pokédex.
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, FLAG_TEST
+ ld hl, wPokedexOwned
+ predef FlagActionPredef
+ ld a, c
+ push af
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, FLAG_SET
+ predef FlagActionPredef
+ pop af
+
+ and a ; was the Pokémon already in the Pokédex?
+ jr nz, .skipShowingPokedexData ; if so, don't show the Pokédex data
+
+ ld hl, ItemUseBallText06
+ call PrintText
+ call ClearSprites
+ ld a, [wEnemyMonSpecies]
+ ld [wd11e], a
+ predef ShowPokedexData
+
+.skipShowingPokedexData
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH ; is party full?
+ jr z, .sendToBox
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ call ClearSprites
+ call AddPartyMon
+ jr .done
+
+.sendToBox
+ call ClearSprites
+ call SendNewMonToBox
+ ld hl, ItemUseBallText07
+ CheckEvent EVENT_MET_BILL
+ jr nz, .printTransferredToPCText
+ ld hl, ItemUseBallText08
+.printTransferredToPCText
+ call PrintText
+ jr .done
+
+.oldManCaughtMon
+ ld hl, ItemUseBallText05
+
+.printMessage
+ call PrintText
+ call ClearSprites
+
+.done
+ ld a, [wBattleType]
+ and a ; is this the old man battle?
+ ret nz ; if so, don't remove a ball from the bag
+
+; Remove a ball from the bag.
+ ld hl, wNumBagItems
+ inc a
+ ld [wItemQuantity], a
+ jp RemoveItemFromInventory
+
+ItemUseBallText00:
+;"It dodged the thrown ball!"
+;"This pokemon can't be caught"
+ TX_FAR _ItemUseBallText00
+ db "@"
+ItemUseBallText01:
+;"You missed the pokemon!"
+ TX_FAR _ItemUseBallText01
+ db "@"
+ItemUseBallText02:
+;"Darn! The pokemon broke free!"
+ TX_FAR _ItemUseBallText02
+ db "@"
+ItemUseBallText03:
+;"Aww! It appeared to be caught!"
+ TX_FAR _ItemUseBallText03
+ db "@"
+ItemUseBallText04:
+;"Shoot! It was so close too!"
+ TX_FAR _ItemUseBallText04
+ db "@"
+ItemUseBallText05:
+;"All right! {MonName} was caught!"
+;play sound
+ TX_FAR _ItemUseBallText05
+ TX_SFX_CAUGHT_MON
+ TX_BLINK
+ db "@"
+ItemUseBallText07:
+;"X was transferred to Bill's PC"
+ TX_FAR _ItemUseBallText07
+ db "@"
+ItemUseBallText08:
+;"X was transferred to someone's PC"
+ TX_FAR _ItemUseBallText08
+ db "@"
+
+ItemUseBallText06:
+;"New DEX data will be added..."
+;play sound
+ TX_FAR _ItemUseBallText06
+ TX_SFX_DEX_PAGE_ADDED
+ TX_BLINK
+ db "@"
+
+ItemUseTownMap:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ jpba DisplayTownMap
+
+ItemUseBicycle:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ ld a, [wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy], a
+ cp 2 ; is the player surfing?
+ jp z, ItemUseNotTime
+ dec a ; is player already bicycling?
+ jr nz, .tryToGetOnBike
+.getOffBike
+ call ItemUseReloadOverworldData
+ xor a
+ ld [wWalkBikeSurfState], a ; change player state to walking
+ call PlayDefaultMusic ; play walking music
+ ld hl, GotOffBicycleText
+ jr .printText
+.tryToGetOnBike
+ call IsBikeRidingAllowed
+ jp nc, NoCyclingAllowedHere
+ call ItemUseReloadOverworldData
+ xor a ; no keys pressed
+ ld [hJoyHeld], a ; current joypad state
+ inc a
+ ld [wWalkBikeSurfState], a ; change player state to bicycling
+ ld hl, GotOnBicycleText
+ call PlayDefaultMusic ; play bike riding music
+.printText
+ jp PrintText
+
+; used for Surf out-of-battle effect
+ItemUseSurfboard:
+ ld a, [wWalkBikeSurfState]
+ ld [wWalkBikeSurfStateCopy], a
+ cp 2 ; is the player already surfing?
+ jr z, .tryToStopSurfing
+.tryToSurf
+ call IsNextTileShoreOrWater
+ jp c, SurfingAttemptFailed
+ ld hl, TilePairCollisionsWater
+ call CheckForTilePairCollisions
+ jp c, SurfingAttemptFailed
+.surf
+ call .makePlayerMoveForward
+ ld hl, wd730
+ set 7, [hl]
+ ld a, 2
+ ld [wWalkBikeSurfState], a ; change player state to surfing
+ call PlayDefaultMusic ; play surfing music
+ ld hl, SurfingGotOnText
+ jp PrintText
+.tryToStopSurfing
+ xor a
+ ld [hSpriteIndexOrTextID], a
+ ld d, 16 ; talking range in pixels (normal range)
+ call IsSpriteInFrontOfPlayer2
+ res 7, [hl]
+ ld a, [hSpriteIndexOrTextID]
+ and a ; is there a sprite in the way?
+ jr nz, .cannotStopSurfing
+ ld hl, TilePairCollisionsWater
+ call CheckForTilePairCollisions
+ jr c, .cannotStopSurfing
+ ld hl, wTilesetCollisionPtr ; pointer to list of passable tiles
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; hl now points to passable tiles
+ ld a, [wTileInFrontOfPlayer] ; tile in front of the player
+ ld b, a
+.passableTileLoop
+ ld a, [hli]
+ cp b
+ jr z, .stopSurfing
+ cp $ff
+ jr nz, .passableTileLoop
+.cannotStopSurfing
+ ld hl, SurfingNoPlaceToGetOffText
+ jp PrintText
+.stopSurfing
+ call .makePlayerMoveForward
+ ld hl, wd730
+ set 7, [hl]
+ xor a
+ ld [wWalkBikeSurfState], a ; change player state to walking
+ dec a
+ ld [wJoyIgnore], a
+ call PlayDefaultMusic ; play walking music
+ jp LoadWalkingPlayerSpriteGraphics
+; uses a simulated button press to make the player move forward
+.makePlayerMoveForward
+ ld a, [wPlayerDirection] ; direction the player is going
+ bit PLAYER_DIR_BIT_UP, a
+ ld b, D_UP
+ jr nz, .storeSimulatedButtonPress
+ bit PLAYER_DIR_BIT_DOWN, a
+ ld b, D_DOWN
+ jr nz, .storeSimulatedButtonPress
+ bit PLAYER_DIR_BIT_LEFT, a
+ ld b, D_LEFT
+ jr nz, .storeSimulatedButtonPress
+ ld b, D_RIGHT
+.storeSimulatedButtonPress
+ ld a, b
+ ld [wSimulatedJoypadStatesEnd], a
+ xor a
+ ld [wWastedByteCD39], a
+ inc a
+ ld [wSimulatedJoypadStatesIndex], a
+ ret
+
+SurfingGotOnText:
+ TX_FAR _SurfingGotOnText
+ db "@"
+
+SurfingNoPlaceToGetOffText:
+ TX_FAR _SurfingNoPlaceToGetOffText
+ db "@"
+
+ItemUsePokedex:
+ predef_jump ShowPokedexMenu
+
+ItemUseEvoStone:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ ld [wEvoStoneItemID], a
+ push af
+ ld a, EVO_STONE_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ call DisplayPartyMenu
+ pop bc
+ jr c, .canceledItemUse
+ ld a, b
+ ld [wcf91], a
+ ld a, $01
+ ld [wForceEvolution], a
+ ld a, SFX_HEAL_AILMENT
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ callab TryEvolvingMon ; try to evolve pokemon
+ ld a, [wEvolutionOccurred]
+ and a
+ jr z, .noEffect
+ pop af
+ ld [wWhichPokemon], a
+ ld hl, wNumBagItems
+ ld a, 1 ; remove 1 stone
+ ld [wItemQuantity], a
+ jp RemoveItemFromInventory
+.noEffect
+ call ItemUseNoEffect
+.canceledItemUse
+ xor a
+ ld [wActionResultOrTookBattleTurn], a ; item not used
+ pop af
+ ret
+
+ItemUseVitamin:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+
+ItemUseMedicine:
+ ld a, [wPartyCount]
+ and a
+ jp z, .emptyParty
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ push af
+ ld a, USE_ITEM_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ ld a, [wPseudoItemID]
+ and a ; using Softboiled?
+ jr z, .notUsingSoftboiled
+; if using softboiled
+ call GoBackToPartyMenu
+ jr .getPartyMonDataAddress
+.emptyParty
+ ld hl, .emptyPartyText
+ xor a
+ ld [wActionResultOrTookBattleTurn], a ; item use failed
+ jp PrintText
+.emptyPartyText
+ text "You don't have"
+ line "any #MON!"
+ prompt
+.notUsingSoftboiled
+ call DisplayPartyMenu
+.getPartyMonDataAddress
+ jp c, .canceledItemUse
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ ld a, [wWhichPokemon]
+ ld [wUsedItemOnWhichPokemon], a
+ ld d, a
+ ld a, [wcf91]
+ ld e, a
+ ld [wd0b5], a
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+ ld a, [wPseudoItemID]
+ and a ; using Softboiled?
+ jr z, .checkItemType
+; if using softboiled
+ ld a, [wWhichPokemon]
+ cp d ; is the pokemon trying to use softboiled on itself?
+ jr z, ItemUseMedicine ; if so, force another choice
+.checkItemType
+ ld a, [wcf91]
+ cp REVIVE
+ jr nc, .healHP ; if it's a Revive or Max Revive
+ cp FULL_HEAL
+ jr z, .cureStatusAilment ; if it's a Full Heal
+ cp HP_UP
+ jp nc, .useVitamin ; if it's a vitamin or Rare Candy
+ cp FULL_RESTORE
+ jr nc, .healHP ; if it's a Full Restore or one of the potions
+; fall through if it's one of the status-specific healing items
+.cureStatusAilment
+ ld bc, wPartyMon1Status - wPartyMon1
+ add hl, bc ; hl now points to status
+ ld a, [wcf91]
+ lb bc, ANTIDOTE_MSG, 1 << PSN
+ cp ANTIDOTE
+ jr z, .checkMonStatus
+ lb bc, BURN_HEAL_MSG, 1 << BRN
+ cp BURN_HEAL
+ jr z, .checkMonStatus
+ lb bc, ICE_HEAL_MSG, 1 << FRZ
+ cp ICE_HEAL
+ jr z, .checkMonStatus
+ lb bc, AWAKENING_MSG, SLP
+ cp AWAKENING
+ jr z, .checkMonStatus
+ lb bc, PARALYZ_HEAL_MSG, 1 << PAR
+ cp PARLYZ_HEAL
+ jr z, .checkMonStatus
+ lb bc, FULL_HEAL_MSG, $ff ; Full Heal
+.checkMonStatus
+ ld a, [hl] ; pokemon's status
+ and c ; does the pokemon have a status ailment the item can cure?
+ jp z, .healingItemNoEffect
+; if the pokemon has a status the item can heal
+ xor a
+ ld [hl], a ; remove the status ailment in the party data
+ ld a, b
+ ld [wPartyMenuTypeOrMessageID], a ; the message to display for the item used
+ ld a, [wPlayerMonNumber]
+ cp d ; is pokemon the item was used on active in battle?
+ jp nz, .doneHealing
+; if it is active in battle
+ xor a
+ ld [wBattleMonStatus], a ; remove the status ailment in the in-battle pokemon data
+ push hl
+ ld hl, wPlayerBattleStatus3
+ res BADLY_POISONED, [hl] ; heal Toxic status
+ pop hl
+ ld bc, wPartyMon1Stats - wPartyMon1Status
+ add hl, bc ; hl now points to party stats
+ ld de, wBattleMonStats
+ ld bc, NUM_STATS * 2
+ call CopyData ; copy party stats to in-battle stat data
+ predef DoubleOrHalveSelectedStats
+ jp .doneHealing
+.healHP
+ inc hl ; hl = address of current HP
+ ld a, [hli]
+ ld b, a
+ ld [wHPBarOldHP+1], a
+ ld a, [hl]
+ ld c, a
+ ld [wHPBarOldHP], a ; current HP stored at wHPBarOldHP (2 bytes, big-endian)
+ or b
+ jr nz, .notFainted
+.fainted
+ ld a, [wcf91]
+ cp REVIVE
+ jr z, .updateInBattleFaintedData
+ cp MAX_REVIVE
+ jr z, .updateInBattleFaintedData
+ jp .healingItemNoEffect
+.updateInBattleFaintedData
+ ld a, [wIsInBattle]
+ and a
+ jr z, .compareCurrentHPToMaxHP
+ push hl
+ push de
+ push bc
+ ld a, [wUsedItemOnWhichPokemon]
+ ld c, a
+ ld hl, wPartyFoughtCurrentEnemyFlags
+ ld b, FLAG_TEST
+ predef FlagActionPredef
+ ld a, c
+ and a
+ jr z, .next
+ ld a, [wUsedItemOnWhichPokemon]
+ ld c, a
+ ld hl, wPartyGainExpFlags
+ ld b, FLAG_SET
+ predef FlagActionPredef
+.next
+ pop bc
+ pop de
+ pop hl
+ jr .compareCurrentHPToMaxHP
+.notFainted
+ ld a, [wcf91]
+ cp REVIVE
+ jp z, .healingItemNoEffect
+ cp MAX_REVIVE
+ jp z, .healingItemNoEffect
+.compareCurrentHPToMaxHP
+ push hl
+ push bc
+ ld bc, wPartyMon1MaxHP - (wPartyMon1HP + 1)
+ add hl, bc ; hl now points to max HP
+ pop bc
+ ld a, [hli]
+ cp b
+ jr nz, .skipComparingLSB ; no need to compare the LSB's if the MSB's don't match
+ ld a, [hl]
+ cp c
+.skipComparingLSB
+ pop hl
+ jr nz, .notFullHP
+.fullHP ; if the pokemon's current HP equals its max HP
+ ld a, [wcf91]
+ cp FULL_RESTORE
+ jp nz, .healingItemNoEffect
+ inc hl
+ inc hl
+ ld a, [hld] ; status ailment
+ and a ; does the pokemon have a status ailment?
+ jp z, .healingItemNoEffect
+ ld a, FULL_HEAL
+ ld [wcf91], a
+ dec hl
+ dec hl
+ dec hl
+ jp .cureStatusAilment
+.notFullHP ; if the pokemon's current HP doesn't equal its max HP
+ xor a
+ ld [wLowHealthAlarm], a ;disable low health alarm
+ ld [wChannelSoundIDs + Ch4], a
+ push hl
+ push de
+ ld bc, wPartyMon1MaxHP - (wPartyMon1HP + 1)
+ add hl, bc ; hl now points to max HP
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a ; max HP stored at wHPBarMaxHP (2 bytes, big-endian)
+ ld a, [wPseudoItemID]
+ and a ; using Softboiled?
+ jp z, .notUsingSoftboiled2
+; if using softboiled
+ ld hl, wHPBarMaxHP
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ push af
+ ld a, [hli]
+ push af
+ ld a, [hl]
+ push af
+ ld hl, wPartyMon1MaxHP
+ ld a, [wWhichPokemon]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [wHPBarMaxHP + 1], a
+ ld [H_DIVIDEND], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ld [H_DIVIDEND + 1], a
+ ld a, 5
+ ld [H_DIVISOR], a
+ ld b, 2 ; number of bytes
+ call Divide ; get 1/5 of max HP of pokemon that used Softboiled
+ ld bc, (wPartyMon1HP + 1) - (wPartyMon1MaxHP + 1)
+ add hl, bc ; hl now points to LSB of current HP of pokemon that used Softboiled
+; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
+ ld a, [H_QUOTIENT + 3]
+ push af
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarOldHP], a
+ sub b
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [H_QUOTIENT + 2]
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [hl], a
+ ld [wHPBarNewHP+1], a
+ coord hl, 4, 1
+ ld a, [wWhichPokemon]
+ ld bc, 2 * SCREEN_WIDTH
+ call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
+ ld a, SFX_HEAL_HP
+ call PlaySoundWaitForCurrent
+ ld a, [hFlags_0xFFF6]
+ set 0, a
+ ld [hFlags_0xFFF6], a
+ ld a, $02
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
+ ld a, [hFlags_0xFFF6]
+ res 0, a
+ ld [hFlags_0xFFF6], a
+ pop af
+ ld b, a ; store heal amount (1/5 of max HP)
+ ld hl, wHPBarOldHP + 1
+ pop af
+ ld [hld], a
+ pop af
+ ld [hld], a
+ pop af
+ ld [hld], a
+ pop af
+ ld [hl], a
+ jr .addHealAmount
+.notUsingSoftboiled2
+ ld a, [wcf91]
+ cp SODA_POP
+ ld b, 60 ; Soda Pop heal amount
+ jr z, .addHealAmount
+ ld b, 80 ; Lemonade heal amount
+ jr nc, .addHealAmount
+ cp FRESH_WATER
+ ld b, 50 ; Fresh Water heal amount
+ jr z, .addHealAmount
+ cp SUPER_POTION
+ ld b, 200 ; Hyper Potion heal amount
+ jr c, .addHealAmount
+ ld b, 50 ; Super Potion heal amount
+ jr z, .addHealAmount
+ ld b, 20 ; Potion heal amount
+.addHealAmount
+ pop de
+ pop hl
+ ld a, [hl]
+ add b
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [hl]
+ ld [wHPBarNewHP+1], a
+ jr nc, .noCarry
+ inc [hl]
+ ld a, [hl]
+ ld [wHPBarNewHP + 1], a
+.noCarry
+ push de
+ inc hl
+ ld d, h
+ ld e, l ; de now points to current HP
+ ld hl, (wPartyMon1MaxHP + 1) - (wPartyMon1HP + 1)
+ add hl, de ; hl now points to max HP
+ ld a, [wcf91]
+ cp REVIVE
+ jr z, .setCurrentHPToHalfMaxHP
+ ld a, [hld]
+ ld b, a
+ ld a, [de]
+ sub b
+ dec de
+ ld b, [hl]
+ ld a, [de]
+ sbc b
+ jr nc, .setCurrentHPToMaxHp ; if current HP exceeds max HP after healing
+ ld a, [wcf91]
+ cp HYPER_POTION
+ jr c, .setCurrentHPToMaxHp ; if using a Full Restore or Max Potion
+ cp MAX_REVIVE
+ jr z, .setCurrentHPToMaxHp ; if using a Max Revive
+ jr .updateInBattleData
+.setCurrentHPToHalfMaxHP
+ dec hl
+ dec de
+ ld a, [hli]
+ srl a
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ ld a, [hl]
+ rr a
+ inc de
+ ld [de], a
+ ld [wHPBarNewHP], a
+ dec de
+ jr .doneHealingPartyHP
+.setCurrentHPToMaxHp
+ ld a, [hli]
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld [wHPBarNewHP], a
+ dec de
+.doneHealingPartyHP ; done updating the pokemon's current HP in the party data structure
+ ld a, [wcf91]
+ cp FULL_RESTORE
+ jr nz, .updateInBattleData
+ ld bc, wPartyMon1Status - (wPartyMon1MaxHP + 1)
+ add hl, bc
+ xor a
+ ld [hl], a ; remove the status ailment in the party data
+.updateInBattleData
+ ld h, d
+ ld l, e
+ pop de
+ ld a, [wPlayerMonNumber]
+ cp d ; is pokemon the item was used on active in battle?
+ jr nz, .calculateHPBarCoords
+; copy party HP to in-battle HP
+ ld a, [hli]
+ ld [wBattleMonHP], a
+ ld a, [hld]
+ ld [wBattleMonHP + 1], a
+ ld a, [wcf91]
+ cp FULL_RESTORE
+ jr nz, .calculateHPBarCoords
+ xor a
+ ld [wBattleMonStatus], a ; remove the status ailment in the in-battle pokemon data
+.calculateHPBarCoords
+ ld hl, wOAMBuffer + $90
+ ld bc, 2 * SCREEN_WIDTH
+ inc d
+.calculateHPBarCoordsLoop
+ add hl, bc
+ dec d
+ jr nz, .calculateHPBarCoordsLoop
+ jr .doneHealing
+.healingItemNoEffect
+ call ItemUseNoEffect
+ jp .done
+.doneHealing
+ ld a, [wPseudoItemID]
+ and a ; using Softboiled?
+ jr nz, .skipRemovingItem ; no item to remove if using Softboiled
+ push hl
+ call RemoveUsedItem
+ pop hl
+.skipRemovingItem
+ ld a, [wcf91]
+ cp FULL_RESTORE
+ jr c, .playStatusAilmentCuringSound
+ cp FULL_HEAL
+ jr z, .playStatusAilmentCuringSound
+ ld a, SFX_HEAL_HP
+ call PlaySoundWaitForCurrent
+ ld a, [hFlags_0xFFF6]
+ set 0, a
+ ld [hFlags_0xFFF6], a
+ ld a, $02
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate the HP bar lengthening
+ ld a, [hFlags_0xFFF6]
+ res 0, a
+ ld [hFlags_0xFFF6], a
+ ld a, REVIVE_MSG
+ ld [wPartyMenuTypeOrMessageID], a
+ ld a, [wcf91]
+ cp REVIVE
+ jr z, .showHealingItemMessage
+ cp MAX_REVIVE
+ jr z, .showHealingItemMessage
+ ld a, POTION_MSG
+ ld [wPartyMenuTypeOrMessageID], a
+ jr .showHealingItemMessage
+.playStatusAilmentCuringSound
+ ld a, SFX_HEAL_AILMENT
+ call PlaySoundWaitForCurrent
+.showHealingItemMessage
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ call RedrawPartyMenu ; redraws the party menu and displays the message
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld c, 50
+ call DelayFrames
+ call WaitForTextScrollButtonPress
+ jr .done
+.canceledItemUse
+ xor a
+ ld [wActionResultOrTookBattleTurn], a ; item use failed
+ pop af
+ pop af
+.done
+ ld a, [wPseudoItemID]
+ and a ; using Softboiled?
+ ret nz ; if so, return
+ call GBPalWhiteOut
+ call z, RunDefaultPaletteCommand
+ ld a, [wIsInBattle]
+ and a
+ ret nz
+ jp ReloadMapData
+.useVitamin
+ push hl
+ ld a, [hl]
+ ld [wd0b5], a
+ ld [wd11e], a
+ ld bc, wPartyMon1Level - wPartyMon1
+ add hl, bc ; hl now points to level
+ ld a, [hl] ; a = level
+ ld [wCurEnemyLVL], a ; store level
+ call GetMonHeader
+ push de
+ ld a, d
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ pop de
+ pop hl
+ ld a, [wcf91]
+ cp RARE_CANDY
+ jp z, .useRareCandy
+ push hl
+ sub HP_UP
+ add a
+ ld bc, wPartyMon1HPExp - wPartyMon1
+ add hl, bc
+ add l
+ ld l, a
+ jr nc, .noCarry2
+ inc h
+.noCarry2
+ ld a, 10
+ ld b, a
+ ld a, [hl] ; a = MSB of stat experience of the appropriate stat
+ cp 100 ; is there already at least 25600 (256 * 100) stat experience?
+ jr nc, .vitaminNoEffect ; if so, vitamins can't add any more
+ add b ; add 2560 (256 * 10) stat experience
+ jr nc, .noCarry3 ; a carry should be impossible here, so this will always jump
+ ld a, 255
+.noCarry3
+ ld [hl], a
+ pop hl
+ call .recalculateStats
+ ld hl, VitaminText
+ ld a, [wcf91]
+ sub HP_UP - 1
+ ld c, a
+.statNameLoop ; loop to get the address of the name of the stat the vitamin increases
+ dec c
+ jr z, .gotStatName
+.statNameInnerLoop
+ ld a, [hli]
+ ld b, a
+ ld a, $50
+ cp b
+ jr nz, .statNameInnerLoop
+ jr .statNameLoop
+.gotStatName
+ ld de, wcf4b
+ ld bc, 10
+ call CopyData ; copy the stat's name to wcf4b
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ ld hl, VitaminStatRoseText
+ call PrintText
+ jp RemoveUsedItem
+.vitaminNoEffect
+ pop hl
+ ld hl, VitaminNoEffectText
+ call PrintText
+ jp GBPalWhiteOut
+.recalculateStats
+ ld bc, wPartyMon1Stats - wPartyMon1
+ add hl, bc
+ ld d, h
+ ld e, l ; de now points to stats
+ ld bc, (wPartyMon1Exp + 2) - wPartyMon1Stats
+ add hl, bc ; hl now points to LSB of experience
+ ld b, 1
+ jp CalcStats ; recalculate stats
+.useRareCandy
+ push hl
+ ld bc, wPartyMon1Level - wPartyMon1
+ add hl, bc ; hl now points to level
+ ld a, [hl] ; a = level
+ cp MAX_LEVEL
+ jr z, .vitaminNoEffect ; can't raise level above 100
+ inc a
+ ld [hl], a ; store incremented level
+ ld [wCurEnemyLVL], a
+ push hl
+ push de
+ ld d, a
+ callab CalcExperience ; calculate experience for next level and store it at $ff96
+ pop de
+ pop hl
+ ld bc, wPartyMon1Exp - wPartyMon1Level
+ add hl, bc ; hl now points to MSB of experience
+; update experience to minimum for new level
+ ld a, [hExperience]
+ ld [hli], a
+ ld a, [hExperience + 1]
+ ld [hli], a
+ ld a, [hExperience + 2]
+ ld [hl], a
+ pop hl
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ push af
+ push de
+ push hl
+ ld bc, wPartyMon1MaxHP - wPartyMon1
+ add hl, bc ; hl now points to MSB of max HP
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ pop hl
+ push bc
+ push hl
+ call .recalculateStats
+ pop hl
+ ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1
+ add hl, bc ; hl now points to LSB of max HP
+ pop bc
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a ; bc = the amount of max HP gained from leveling up
+; add the amount gained to the current HP
+ ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
+ add hl, de ; hl now points to LSB of current HP
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ ld a, RARE_CANDY_MSG
+ ld [wPartyMenuTypeOrMessageID], a
+ call RedrawPartyMenu
+ pop de
+ ld a, d
+ ld [wWhichPokemon], a
+ ld a, e
+ ld [wd11e], a
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ call LoadMonData
+ ld d, $01
+ callab PrintStatsBox ; display new stats text box
+ call WaitForTextScrollButtonPress ; wait for button press
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ predef LearnMoveFromLevelUp ; learn level up move, if any
+ xor a
+ ld [wForceEvolution], a
+ callab TryEvolvingMon ; evolve pokemon, if appropriate
+ ld a, $01
+ ld [wUpdateSpritesEnabled], a
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+ jp RemoveUsedItem
+
+VitaminStatRoseText:
+ TX_FAR _VitaminStatRoseText
+ db "@"
+
+VitaminNoEffectText:
+ TX_FAR _VitaminNoEffectText
+ db "@"
+
+VitaminText:
+ db "HEALTH@"
+ db "ATTACK@"
+ db "DEFENSE@"
+ db "SPEED@"
+ db "SPECIAL@"
+
+ItemUseBait:
+ ld hl, ThrewBaitText
+ call PrintText
+ ld hl, wEnemyMonActualCatchRate ; catch rate
+ srl [hl] ; halve catch rate
+ ld a, BAIT_ANIM
+ ld hl, wSafariBaitFactor ; bait factor
+ ld de, wSafariEscapeFactor ; escape factor
+ jr BaitRockCommon
+
+ItemUseRock:
+ ld hl, ThrewRockText
+ call PrintText
+ ld hl, wEnemyMonActualCatchRate ; catch rate
+ ld a, [hl]
+ add a ; double catch rate
+ jr nc, .noCarry
+ ld a, $ff
+.noCarry
+ ld [hl], a
+ ld a, ROCK_ANIM
+ ld hl, wSafariEscapeFactor ; escape factor
+ ld de, wSafariBaitFactor ; bait factor
+
+BaitRockCommon:
+ ld [wAnimationID], a
+ xor a
+ ld [wAnimationType], a
+ ld [H_WHOSETURN], a
+ ld [de], a ; zero escape factor (for bait), zero bait factor (for rock)
+.randomLoop ; loop until a random number less than 5 is generated
+ call Random
+ and 7
+ cp 5
+ jr nc, .randomLoop
+ inc a ; increment the random number, giving a range from 1 to 5 inclusive
+ ld b, a
+ ld a, [hl]
+ add b ; increase bait factor (for bait), increase escape factor (for rock)
+ jr nc, .noCarry
+ ld a, $ff
+.noCarry
+ ld [hl], a
+ predef MoveAnimation ; do animation
+ ld c, 70
+ jp DelayFrames
+
+ThrewBaitText:
+ TX_FAR _ThrewBaitText
+ db "@"
+
+ThrewRockText:
+ TX_FAR _ThrewRockText
+ db "@"
+
+; also used for Dig out-of-battle effect
+ItemUseEscapeRope:
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .notUsable
+ ld a, [wCurMap]
+ cp AGATHAS_ROOM
+ jr z, .notUsable
+ ld a, [wCurMapTileset]
+ ld b, a
+ ld hl, EscapeRopeTilesets
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .notUsable
+ cp b
+ jr nz, .loop
+ ld hl, wd732
+ set 3, [hl]
+ set 6, [hl]
+ ld hl, wd72e
+ res 4, [hl]
+ ResetEvent EVENT_IN_SAFARI_ZONE
+ xor a
+ ld [wNumSafariBalls], a
+ ld [wSafariZoneEntranceCurScript], a
+ inc a
+ ld [wEscapedFromBattle], a
+ ld [wActionResultOrTookBattleTurn], a ; item used
+ ld a, [wPseudoItemID]
+ and a ; using Dig?
+ ret nz ; if so, return
+ call ItemUseReloadOverworldData
+ ld c, 30
+ call DelayFrames
+ jp RemoveUsedItem
+.notUsable
+ jp ItemUseNotTime
+
+EscapeRopeTilesets:
+ db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
+ db $ff ; terminator
+
+ItemUseRepel:
+ ld b, 100
+
+ItemUseRepelCommon:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ ld a, b
+ ld [wRepelRemainingSteps], a
+ jp PrintItemUseTextAndRemoveItem
+
+; handles X Accuracy item
+ItemUseXAccuracy:
+ ld a, [wIsInBattle]
+ and a
+ jp z, ItemUseNotTime
+ ld hl, wPlayerBattleStatus2
+ set USING_X_ACCURACY, [hl] ; X Accuracy bit
+ jp PrintItemUseTextAndRemoveItem
+
+; This function is bugged and never works. It always jumps to ItemUseNotTime.
+; The Card Key is handled in a different way.
+ItemUseCardKey:
+ xor a
+ ld [wUnusedD71F], a
+ call GetTileAndCoordsInFrontOfPlayer
+ ld a, [GetTileAndCoordsInFrontOfPlayer]
+ cp $18
+ jr nz, .next0
+ ld hl, CardKeyTable1
+ jr .next1
+.next0
+ cp $24
+ jr nz, .next2
+ ld hl, CardKeyTable2
+ jr .next1
+.next2
+ cp $5e
+ jp nz, ItemUseNotTime
+ ld hl, CardKeyTable3
+.next1
+ ld a, [wCurMap]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp $ff
+ jp z, ItemUseNotTime
+ cp b
+ jr nz, .nextEntry1
+ ld a, [hli]
+ cp d
+ jr nz, .nextEntry2
+ ld a, [hli]
+ cp e
+ jr nz, .nextEntry3
+ ld a, [hl]
+ ld [wUnusedD71F], a
+ jr .done
+.nextEntry1
+ inc hl
+.nextEntry2
+ inc hl
+.nextEntry3
+ inc hl
+ jr .loop
+.done
+ ld hl, ItemUseText00
+ call PrintText
+ ld hl, wd728
+ set 7, [hl]
+ ret
+
+; These tables are probably supposed to be door locations in Silph Co.,
+; but they are unused.
+; The reason there are 3 tables is unknown.
+
+; Format:
+; 00: Map ID
+; 01: Y
+; 02: X
+; 03: ID?
+
+CardKeyTable1:
+ db SILPH_CO_2F,$04,$04,$00
+ db SILPH_CO_2F,$04,$05,$01
+ db SILPH_CO_4F,$0C,$04,$02
+ db SILPH_CO_4F,$0C,$05,$03
+ db SILPH_CO_7F,$06,$0A,$04
+ db SILPH_CO_7F,$06,$0B,$05
+ db SILPH_CO_9F,$04,$12,$06
+ db SILPH_CO_9F,$04,$13,$07
+ db SILPH_CO_10F,$08,$0A,$08
+ db SILPH_CO_10F,$08,$0B,$09
+ db $ff
+
+CardKeyTable2:
+ db SILPH_CO_3F,$08,$09,$0A
+ db SILPH_CO_3F,$09,$09,$0B
+ db SILPH_CO_5F,$04,$07,$0C
+ db SILPH_CO_5F,$05,$07,$0D
+ db SILPH_CO_6F,$0C,$05,$0E
+ db SILPH_CO_6F,$0D,$05,$0F
+ db SILPH_CO_8F,$08,$07,$10
+ db SILPH_CO_8F,$09,$07,$11
+ db SILPH_CO_9F,$08,$03,$12
+ db SILPH_CO_9F,$09,$03,$13
+ db $ff
+
+CardKeyTable3:
+ db SILPH_CO_11F,$08,$09,$14
+ db SILPH_CO_11F,$09,$09,$15
+ db $ff
+
+ItemUsePokedoll:
+ ld a, [wIsInBattle]
+ dec a
+ jp nz, ItemUseNotTime
+ ld a, $01
+ ld [wEscapedFromBattle], a
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseGuardSpec:
+ ld a, [wIsInBattle]
+ and a
+ jp z, ItemUseNotTime
+ ld hl, wPlayerBattleStatus2
+ set PROTECTED_BY_MIST, [hl] ; Mist bit
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseSuperRepel:
+ ld b, 200
+ jp ItemUseRepelCommon
+
+ItemUseMaxRepel:
+ ld b, 250
+ jp ItemUseRepelCommon
+
+ItemUseDireHit:
+ ld a, [wIsInBattle]
+ and a
+ jp z, ItemUseNotTime
+ ld hl, wPlayerBattleStatus2
+ set GETTING_PUMPED, [hl] ; Focus Energy bit
+ jp PrintItemUseTextAndRemoveItem
+
+ItemUseXStat:
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .inBattle
+ call ItemUseNotTime
+ ld a, 2
+ ld [wActionResultOrTookBattleTurn], a ; item not used
+ ret
+.inBattle
+ ld hl, wPlayerMoveNum
+ ld a, [hli]
+ push af ; save [wPlayerMoveNum]
+ ld a, [hl]
+ push af ; save [wPlayerMoveEffect]
+ push hl
+ ld a, [wcf91]
+ sub X_ATTACK - ATTACK_UP1_EFFECT
+ ld [hl], a ; store player move effect
+ call PrintItemUseTextAndRemoveItem
+ ld a, XSTATITEM_ANIM ; X stat item animation ID
+ ld [wPlayerMoveNum], a
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ call Delay3
+ xor a
+ ld [H_WHOSETURN], a ; set turn to player's turn
+ callba StatModifierUpEffect ; do stat increase move
+ pop hl
+ pop af
+ ld [hld], a ; restore [wPlayerMoveEffect]
+ pop af
+ ld [hl], a ; restore [wPlayerMoveNum]
+ ret
+
+ItemUsePokeflute:
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .inBattle
+; if not in battle
+ call ItemUseReloadOverworldData
+ ld a, [wCurMap]
+ cp ROUTE_12
+ jr nz, .notRoute12
+ CheckEvent EVENT_BEAT_ROUTE12_SNORLAX
+ jr nz, .noSnorlaxToWakeUp
+; if the player hasn't beaten Route 12 Snorlax
+ ld hl, Route12SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc, .noSnorlaxToWakeUp
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ SetEvent EVENT_FIGHT_ROUTE12_SNORLAX
+ ret
+.notRoute12
+ cp ROUTE_16
+ jr nz, .noSnorlaxToWakeUp
+ CheckEvent EVENT_BEAT_ROUTE16_SNORLAX
+ jr nz, .noSnorlaxToWakeUp
+; if the player hasn't beaten Route 16 Snorlax
+ ld hl, Route16SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc, .noSnorlaxToWakeUp
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ SetEvent EVENT_FIGHT_ROUTE16_SNORLAX
+ ret
+.noSnorlaxToWakeUp
+ ld hl, PlayedFluteNoEffectText
+ jp PrintText
+.inBattle
+ xor a
+ ld [wWereAnyMonsAsleep], a
+ ld b, ~SLP & $ff
+ ld hl, wPartyMon1Status
+ call WakeUpEntireParty
+ ld a, [wIsInBattle]
+ dec a ; is it a trainer battle?
+ jr z, .skipWakingUpEnemyParty
+; if it's a trainer battle
+ ld hl, wEnemyMon1Status
+ call WakeUpEntireParty
+.skipWakingUpEnemyParty
+ ld hl, wBattleMonStatus
+ ld a, [hl]
+ and b ; remove Sleep status
+ ld [hl], a
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and b ; remove Sleep status
+ ld [hl], a
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ ld a, [wWereAnyMonsAsleep]
+ and a ; were any pokemon asleep before playing the flute?
+ ld hl, PlayedFluteNoEffectText
+ jp z, PrintText ; if no pokemon were asleep
+; if some pokemon were asleep
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ ld a, [wLowHealthAlarm]
+ and $80
+ jr nz, .skipMusic
+ call WaitForSoundToFinish ; wait for sound to end
+ callba Music_PokeFluteInBattle ; play in-battle pokeflute music
+.musicWaitLoop ; wait for music to finish playing
+ ld a, [wChannelSoundIDs + Ch6]
+ and a ; music off?
+ jr nz, .musicWaitLoop
+.skipMusic
+ ld hl, FluteWokeUpText
+ jp PrintText
+
+; wakes up all party pokemon
+; INPUT:
+; hl must point to status of first pokemon in party (player's or enemy's)
+; b must equal ~SLP
+; [wWereAnyMonsAsleep] should be initialized to 0
+; OUTPUT:
+; [wWereAnyMonsAsleep]: set to 1 if any pokemon were asleep
+WakeUpEntireParty:
+ ld de, 44
+ ld c, 6
+.loop
+ ld a, [hl]
+ push af
+ and SLP ; is pokemon asleep?
+ jr z, .notAsleep
+ ld a, 1
+ ld [wWereAnyMonsAsleep], a ; indicate that a pokemon had to be woken up
+.notAsleep
+ pop af
+ and b ; remove Sleep status
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+; Format:
+; 00: Y
+; 01: X
+Route12SnorlaxFluteCoords:
+ db 62,9 ; one space West of Snorlax
+ db 61,10 ; one space North of Snorlax
+ db 63,10 ; one space South of Snorlax
+ db 62,11 ; one space East of Snorlax
+ db $ff ; terminator
+
+; Format:
+; 00: Y
+; 01: X
+Route16SnorlaxFluteCoords:
+ db 10,27 ; one space East of Snorlax
+ db 10,25 ; one space West of Snorlax
+ db $ff ; terminator
+
+PlayedFluteNoEffectText:
+ TX_FAR _PlayedFluteNoEffectText
+ db "@"
+
+FluteWokeUpText:
+ TX_FAR _FluteWokeUpText
+ db "@"
+
+PlayedFluteHadEffectText:
+ TX_FAR _PlayedFluteHadEffectText
+ TX_BLINK
+ TX_ASM
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .done
+; play out-of-battle pokeflute music
+ ld a, $ff
+ call PlaySound ; turn off music
+ ld a, SFX_POKEFLUTE
+ ld c, BANK(SFX_Pokeflute)
+ call PlayMusic
+.musicWaitLoop ; wait for music to finish playing
+ ld a, [wChannelSoundIDs + Ch2]
+ cp SFX_POKEFLUTE
+ jr z, .musicWaitLoop
+ call PlayDefaultMusic ; start playing normal music again
+.done
+ jp TextScriptEnd ; end text
+
+ItemUseCoinCase:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ ld hl, CoinCaseNumCoinsText
+ jp PrintText
+
+CoinCaseNumCoinsText:
+ TX_FAR _CoinCaseNumCoinsText
+ db "@"
+
+ItemUseOldRod:
+ call FishingInit
+ jp c, ItemUseNotTime
+ lb bc, 5, MAGIKARP
+ ld a, $1 ; set bite
+ jr RodResponse
+
+ItemUseGoodRod:
+ call FishingInit
+ jp c, ItemUseNotTime
+.RandomLoop
+ call Random
+ srl a
+ jr c, .SetBite
+ and %11
+ cp 2
+ jr nc, .RandomLoop
+ ; choose which monster appears
+ ld hl, GoodRodMons
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ and a
+.SetBite
+ ld a, 0
+ rla
+ xor 1
+ jr RodResponse
+
+INCLUDE "data/good_rod.asm"
+
+ItemUseSuperRod:
+ call FishingInit
+ jp c, ItemUseNotTime
+ call ReadSuperRodData
+ ld a, e
+RodResponse:
+ ld [wRodResponse], a
+
+ dec a ; is there a bite?
+ jr nz, .next
+ ; if yes, store level and species data
+ ld a, 1
+ ld [wMoveMissed], a
+ ld a, b ; level
+ ld [wCurEnemyLVL], a
+ ld a, c ; species
+ ld [wCurOpponent], a
+
+.next
+ ld hl, wWalkBikeSurfState
+ ld a, [hl] ; store the value in a
+ push af
+ push hl
+ ld [hl], 0
+ callba FishingAnim
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+
+; checks if fishing is possible and if so, runs initialization code common to all rods
+; unsets carry if fishing is possible, sets carry if not
+FishingInit:
+ ld a, [wIsInBattle]
+ and a
+ jr z, .notInBattle
+ scf ; can't fish during battle
+ ret
+.notInBattle
+ call IsNextTileShoreOrWater
+ ret c
+ ld a, [wWalkBikeSurfState]
+ cp 2 ; Surfing?
+ jr z, .surfing
+ call ItemUseReloadOverworldData
+ ld hl, ItemUseText00
+ call PrintText
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ ld c, 80
+ call DelayFrames
+ and a
+ ret
+.surfing
+ scf ; can't fish when surfing
+ ret
+
+ItemUseOaksParcel:
+ jp ItemUseNotYoursToUse
+
+ItemUseItemfinder:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ call ItemUseReloadOverworldData
+ callba HiddenItemNear ; check for hidden items
+ ld hl, ItemfinderFoundNothingText
+ jr nc, .printText ; if no hidden items
+ ld c, 4
+.loop
+ ld a, SFX_HEALING_MACHINE
+ call PlaySoundWaitForCurrent
+ ld a, SFX_PURCHASE
+ call PlaySoundWaitForCurrent
+ dec c
+ jr nz, .loop
+ ld hl, ItemfinderFoundItemText
+.printText
+ jp PrintText
+
+ItemfinderFoundItemText:
+ TX_FAR _ItemfinderFoundItemText
+ db "@"
+
+ItemfinderFoundNothingText:
+ TX_FAR _ItemfinderFoundNothingText
+ db "@"
+
+ItemUsePPUp:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+
+ItemUsePPRestore:
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ ld [wPPRestoreItem], a
+.chooseMon
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ ld a, USE_ITEM_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call DisplayPartyMenu
+ jr nc, .chooseMove
+ jp .itemNotUsed
+.chooseMove
+ ld a, [wPPRestoreItem]
+ cp ELIXER
+ jp nc, .useElixir ; if Elixir or Max Elixir
+ ld a, $02
+ ld [wMoveMenuType], a
+ ld hl, RaisePPWhichTechniqueText
+ ld a, [wPPRestoreItem]
+ cp ETHER ; is it a PP Up?
+ jr c, .printWhichTechniqueMessage ; if so, print the raise PP message
+ ld hl, RestorePPWhichTechniqueText ; otherwise, print the restore PP message
+.printWhichTechniqueMessage
+ call PrintText
+ xor a
+ ld [wPlayerMoveListIndex], a
+ callab MoveSelectionMenu ; move selection menu
+ ld a, 0
+ ld [wPlayerMoveListIndex], a
+ jr nz, .chooseMon
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ call GetSelectedMoveOffset
+ push hl
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B ; copy name to wcf4b
+ pop hl
+ ld a, [wPPRestoreItem]
+ cp ETHER
+ jr nc, .useEther ; if Ether or Max Ether
+.usePPUp
+ ld bc, wPartyMon1PP - wPartyMon1Moves
+ add hl, bc
+ ld a, [hl] ; move PP
+ cp 3 << 6 ; have 3 PP Ups already been used?
+ jr c, .PPNotMaxedOut
+ ld hl, PPMaxedOutText
+ call PrintText
+ jr .chooseMove
+.PPNotMaxedOut
+ ld a, [hl]
+ add 1 << 6 ; increase PP Up count by 1
+ ld [hl], a
+ ld a, 1 ; 1 PP Up used
+ ld [wd11e], a
+ call RestoreBonusPP ; add the bonus PP to current PP
+ ld hl, PPIncreasedText
+ call PrintText
+.done
+ pop af
+ ld [wWhichPokemon], a
+ call GBPalWhiteOut
+ call RunDefaultPaletteCommand
+ jp RemoveUsedItem
+.afterRestoringPP ; after using a (Max) Ether/Elixir
+ ld a, [wWhichPokemon]
+ ld b, a
+ ld a, [wPlayerMonNumber]
+ cp b ; is the pokemon whose PP was restored active in battle?
+ jr nz, .skipUpdatingInBattleData
+ ld hl, wPartyMon1PP
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld de, wBattleMonPP
+ ld bc, 4
+ call CopyData ; copy party data to in-battle data
+.skipUpdatingInBattleData
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ ld hl, PPRestoredText
+ call PrintText
+ jr .done
+.useEther
+ call .restorePP
+ jr nz, .afterRestoringPP
+ jp .noEffect
+; unsets zero flag if PP was restored, sets zero flag if not
+; however, this is bugged for Max Ethers and Max Elixirs (see below)
+.restorePP
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ call GetMaxPP
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ call GetSelectedMoveOffset
+ ld bc, wPartyMon1PP - wPartyMon1Moves
+ add hl, bc ; hl now points to move's PP
+ ld a, [wMaxPP]
+ ld b, a
+ ld a, [wPPRestoreItem]
+ cp MAX_ETHER
+ jr z, .fullyRestorePP
+ ld a, [hl] ; move PP
+ and %00111111 ; lower 6 bit bits store current PP
+ cp b ; does current PP equal max PP?
+ ret z ; if so, return
+ add 10 ; increase current PP by 10
+; b holds the max PP amount and b will hold the new PP amount.
+; So, if the new amount meets or exceeds the max amount,
+; cap the amount to the max amount by leaving b unchanged.
+; Otherwise, store the new amount in b.
+ cp b ; does the new amount meet or exceed the maximum?
+ jr nc, .storeNewAmount
+ ld b, a
+.storeNewAmount
+ ld a, [hl] ; move PP
+ and %11000000 ; PP Up counter bits
+ add b
+ ld [hl], a
+ ret
+.fullyRestorePP
+ ld a, [hl] ; move PP
+; Note that this code has a bug. It doesn't mask out the upper two bits, which
+; are used to count how many PP Ups have been used on the move. So, Max Ethers
+; and Max Elixirs will not be detected as having no effect on a move with full
+; PP if the move has had any PP Ups used on it.
+ cp b ; does current PP equal max PP?
+ ret z
+ jr .storeNewAmount
+.useElixir
+; decrement the item ID so that ELIXER becomes ETHER and MAX_ELIXER becomes MAX_ETHER
+ ld hl, wPPRestoreItem
+ dec [hl]
+ dec [hl]
+ xor a
+ ld hl, wCurrentMenuItem
+ ld [hli], a
+ ld [hl], a ; zero the counter for number of moves that had their PP restored
+ ld b, 4
+; loop through each move and restore PP
+.elixirLoop
+ push bc
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ call GetSelectedMoveOffset
+ ld a, [hl]
+ and a ; does the current slot have a move?
+ jr z, .nextMove
+ call .restorePP
+ jr z, .nextMove
+; if some PP was restored
+ ld hl, wTileBehindCursor ; counter for number of moves that had their PP restored
+ inc [hl]
+.nextMove
+ ld hl, wCurrentMenuItem
+ inc [hl]
+ pop bc
+ dec b
+ jr nz, .elixirLoop
+ ld a, [wTileBehindCursor]
+ and a ; did any moves have their PP restored?
+ jp nz, .afterRestoringPP
+.noEffect
+ call ItemUseNoEffect
+.itemNotUsed
+ call GBPalWhiteOut
+ call RunDefaultPaletteCommand
+ pop af
+ xor a
+ ld [wActionResultOrTookBattleTurn], a ; item use failed
+ ret
+
+RaisePPWhichTechniqueText:
+ TX_FAR _RaisePPWhichTechniqueText
+ db "@"
+
+RestorePPWhichTechniqueText:
+ TX_FAR _RestorePPWhichTechniqueText
+ db "@"
+
+PPMaxedOutText:
+ TX_FAR _PPMaxedOutText
+ db "@"
+
+PPIncreasedText:
+ TX_FAR _PPIncreasedText
+ db "@"
+
+PPRestoredText:
+ TX_FAR _PPRestoredText
+ db "@"
+
+; for items that can't be used from the Item menu
+UnusableItem:
+ jp ItemUseNotTime
+
+ItemUseTMHM:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ ld a, [wcf91]
+ sub TM_01
+ push af
+ jr nc, .skipAdding
+ add 55 ; if item is an HM, add 55
+.skipAdding
+ inc a
+ ld [wd11e], a
+ predef TMToMove ; get move ID from TM/HM ID
+ ld a, [wd11e]
+ ld [wMoveNum], a
+ call GetMoveName
+ call CopyStringToCF4B ; copy name to wcf4b
+ pop af
+ ld hl, BootedUpTMText
+ jr nc, .printBootedUpMachineText
+ ld hl, BootedUpHMText
+.printBootedUpMachineText
+ call PrintText
+ ld hl, TeachMachineMoveText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .useMachine
+ ld a, 2
+ ld [wActionResultOrTookBattleTurn], a ; item not used
+ ret
+.useMachine
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wcf91]
+ push af
+.chooseMon
+ ld hl, wcf4b
+ ld de, wTempMoveNameBuffer
+ ld bc, 14
+ call CopyData ; save the move name because DisplayPartyMenu will overwrite it
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ ld a, TMHM_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call DisplayPartyMenu
+ push af
+ ld hl, wTempMoveNameBuffer
+ ld de, wcf4b
+ ld bc, 14
+ call CopyData
+ pop af
+ jr nc, .checkIfAbleToLearnMove
+; if the player canceled teaching the move
+ pop af
+ pop af
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ call RunDefaultPaletteCommand
+ jp LoadScreenTilesFromBuffer1 ; restore saved screen
+.checkIfAbleToLearnMove
+ predef CanLearnTM ; check if the pokemon can learn the move
+ push bc
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ pop bc
+ ld a, c
+ and a ; can the pokemon learn the move?
+ jr nz, .checkIfAlreadyLearnedMove
+; if the pokemon can't learn the move
+ ld a, SFX_DENIED
+ call PlaySoundWaitForCurrent
+ ld hl, MonCannotLearnMachineMoveText
+ call PrintText
+ jr .chooseMon
+.checkIfAlreadyLearnedMove
+ callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
+ jr c, .chooseMon
+ predef LearnMove ; teach move
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+ ld a, b
+ and a
+ ret z
+ ld a, [wcf91]
+ call IsItemHM
+ ret c
+ jp RemoveUsedItem
+
+BootedUpTMText:
+ TX_FAR _BootedUpTMText
+ db "@"
+
+BootedUpHMText:
+ TX_FAR _BootedUpHMText
+ db "@"
+
+TeachMachineMoveText:
+ TX_FAR _TeachMachineMoveText
+ db "@"
+
+MonCannotLearnMachineMoveText:
+ TX_FAR _MonCannotLearnMachineMoveText
+ db "@"
+
+PrintItemUseTextAndRemoveItem:
+ ld hl, ItemUseText00
+ call PrintText
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ call WaitForTextScrollButtonPress ; wait for button press
+
+RemoveUsedItem:
+ ld hl, wNumBagItems
+ ld a, 1 ; one item
+ ld [wItemQuantity], a
+ jp RemoveItemFromInventory
+
+ItemUseNoEffect:
+ ld hl, ItemUseNoEffectText
+ jr ItemUseFailed
+
+ItemUseNotTime:
+ ld hl, ItemUseNotTimeText
+ jr ItemUseFailed
+
+ItemUseNotYoursToUse:
+ ld hl, ItemUseNotYoursToUseText
+ jr ItemUseFailed
+
+ThrowBallAtTrainerMon:
+ call RunDefaultPaletteCommand
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ call Delay3
+ ld a, TOSS_ANIM
+ ld [wAnimationID], a
+ predef MoveAnimation ; do animation
+ ld hl, ThrowBallAtTrainerMonText1
+ call PrintText
+ ld hl, ThrowBallAtTrainerMonText2
+ call PrintText
+ jr RemoveUsedItem
+
+NoCyclingAllowedHere:
+ ld hl, NoCyclingAllowedHereText
+ jr ItemUseFailed
+
+BoxFullCannotThrowBall:
+ ld hl, BoxFullCannotThrowBallText
+ jr ItemUseFailed
+
+SurfingAttemptFailed:
+ ld hl, NoSurfingHereText
+
+ItemUseFailed:
+ xor a
+ ld [wActionResultOrTookBattleTurn], a ; item use failed
+ jp PrintText
+
+ItemUseNotTimeText:
+ TX_FAR _ItemUseNotTimeText
+ db "@"
+
+ItemUseNotYoursToUseText:
+ TX_FAR _ItemUseNotYoursToUseText
+ db "@"
+
+ItemUseNoEffectText:
+ TX_FAR _ItemUseNoEffectText
+ db "@"
+
+ThrowBallAtTrainerMonText1:
+ TX_FAR _ThrowBallAtTrainerMonText1
+ db "@"
+
+ThrowBallAtTrainerMonText2:
+ TX_FAR _ThrowBallAtTrainerMonText2
+ db "@"
+
+NoCyclingAllowedHereText:
+ TX_FAR _NoCyclingAllowedHereText
+ db "@"
+
+NoSurfingHereText:
+ TX_FAR _NoSurfingHereText
+ db "@"
+
+BoxFullCannotThrowBallText:
+ TX_FAR _BoxFullCannotThrowBallText
+ db "@"
+
+ItemUseText00:
+ TX_FAR _ItemUseText001
+ TX_LINE
+ TX_FAR _ItemUseText002
+ db "@"
+
+GotOnBicycleText:
+ TX_FAR _GotOnBicycleText1
+ TX_LINE
+ TX_FAR _GotOnBicycleText2
+ db "@"
+
+GotOffBicycleText:
+ TX_FAR _GotOffBicycleText1
+ TX_LINE
+ TX_FAR _GotOffBicycleText2
+ db "@"
+
+; restores bonus PP (from PP Ups) when healing at a pokemon center
+; also, when a PP Up is used, it increases the current PP by one PP Up bonus
+; INPUT:
+; [wWhichPokemon] = index of pokemon in party
+; [wCurrentMenuItem] = index of move (when using a PP Up)
+RestoreBonusPP:
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ push hl
+ ld de, wNormalMaxPPList - 1
+ predef LoadMovePPs ; loads the normal max PP of each of the pokemon's moves to wNormalMaxPPList
+ pop hl
+ ld c, wPartyMon1PP - wPartyMon1Moves
+ ld b, 0
+ add hl, bc ; hl now points to move 1 PP
+ ld de, wNormalMaxPPList
+ ld b, 0 ; initialize move counter to zero
+; loop through the pokemon's moves
+.loop
+ inc b
+ ld a, b
+ cp 5 ; reached the end of the pokemon's moves?
+ ret z ; if so, return
+ ld a, [wUsingPPUp]
+ dec a ; using a PP Up?
+ jr nz, .skipMenuItemIDCheck
+; if using a PP Up, check if this is the move it's being used on
+ ld a, [wCurrentMenuItem]
+ inc a
+ cp b
+ jr nz, .nextMove
+.skipMenuItemIDCheck
+ ld a, [hl]
+ and %11000000 ; have any PP Ups been used?
+ call nz, AddBonusPP ; if so, add bonus PP
+.nextMove
+ inc hl
+ inc de
+ jr .loop
+
+; adds bonus PP from PP Ups to current PP
+; 1/5 of normal max PP (capped at 7) is added for each PP Up
+; INPUT:
+; [de] = normal max PP
+; [hl] = move PP
+AddBonusPP:
+ push bc
+ ld a, [de] ; normal max PP of move
+ ld [H_DIVIDEND + 3], a
+ xor a
+ ld [H_DIVIDEND], a
+ ld [H_DIVIDEND + 1], a
+ ld [H_DIVIDEND + 2], a
+ ld a, 5
+ ld [H_DIVISOR], a
+ ld b, 4
+ call Divide
+ ld a, [hl] ; move PP
+ ld b, a
+ swap a
+ and %00001111
+ srl a
+ srl a
+ ld c, a ; c = number of PP Ups used
+.loop
+ ld a, [H_QUOTIENT + 3]
+ cp 8 ; is the amount greater than or equal to 8?
+ jr c, .addAmount
+ ld a, 7 ; cap the amount at 7
+.addAmount
+ add b
+ ld b, a
+ ld a, [wUsingPPUp]
+ dec a ; is the player using a PP Up right now?
+ jr z, .done ; if so, only add the bonus once
+ dec c
+ jr nz, .loop
+.done
+ ld [hl], b
+ pop bc
+ ret
+
+; gets max PP of a pokemon's move (including PP from PP Ups)
+; INPUT:
+; [wWhichPokemon] = index of pokemon within party/box
+; [wMonDataLocation] = pokemon source
+; 00: player's party
+; 01: enemy's party
+; 02: current box
+; 03: daycare
+; 04: player's in-battle pokemon
+; [wCurrentMenuItem] = move index
+; OUTPUT:
+; [wMaxPP] = max PP
+GetMaxPP:
+ ld a, [wMonDataLocation]
+ and a
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ jr z, .sourceWithMultipleMon
+ ld hl, wEnemyMon1Moves
+ dec a
+ jr z, .sourceWithMultipleMon
+ ld hl, wBoxMon1Moves
+ ld bc, wBoxMon2 - wBoxMon1
+ dec a
+ jr z, .sourceWithMultipleMon
+ ld hl, wDayCareMonMoves
+ dec a
+ jr z, .sourceWithOneMon
+ ld hl, wBattleMonMoves ; player's in-battle pokemon
+.sourceWithOneMon
+ call GetSelectedMoveOffset2
+ jr .next
+.sourceWithMultipleMon
+ call GetSelectedMoveOffset
+.next
+ ld a, [hl]
+ dec a
+ push hl
+ ld hl, Moves
+ ld bc, MoveEnd - Moves
+ call AddNTimes
+ ld de, wcd6d
+ ld a, BANK(Moves)
+ call FarCopyData
+ ld de, wcd6d + 5 ; PP is byte 5 of move data
+ ld a, [de]
+ ld b, a ; b = normal max PP
+ pop hl
+ push bc
+ ld bc, wPartyMon1PP - wPartyMon1Moves ; PP offset if not player's in-battle pokemon data
+ ld a, [wMonDataLocation]
+ cp 4 ; player's in-battle pokemon?
+ jr nz, .addPPOffset
+ ld bc, wBattleMonPP - wBattleMonMoves ; PP offset if player's in-battle pokemon data
+.addPPOffset
+ add hl, bc
+ ld a, [hl] ; a = current PP
+ and %11000000 ; get PP Up count
+ pop bc
+ or b ; place normal max PP in 6 lower bits of a
+ ld h, d
+ ld l, e
+ inc hl ; hl = wcd73
+ ld [hl], a
+ xor a ; add the bonus for the existing PP Up count
+ ld [wUsingPPUp], a
+ call AddBonusPP ; add bonus PP from PP Ups
+ ld a, [hl]
+ and %00111111 ; mask out the PP Up count
+ ld [wMaxPP], a ; store max PP
+ ret
+
+GetSelectedMoveOffset:
+ ld a, [wWhichPokemon]
+ call AddNTimes
+
+GetSelectedMoveOffset2:
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ret
+
+; confirms the item toss and then tosses the item
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wWhichPokemon] = index of item within inventory
+; [wItemQuantity] = quantity to toss
+; OUTPUT:
+; clears carry flag if the item is tossed, sets carry flag if not
+TossItem_:
+ push hl
+ ld a, [wcf91]
+ call IsItemHM
+ pop hl
+ jr c, .tooImportantToToss
+ push hl
+ call IsKeyItem_
+ ld a, [wIsKeyItem]
+ pop hl
+ and a
+ jr nz, .tooImportantToToss
+ push hl
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld hl, IsItOKToTossItemText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wMenuExitMethod]
+ cp CHOSE_SECOND_ITEM
+ pop hl
+ scf
+ ret z ; return if the player chose No
+; if the player chose Yes
+ push hl
+ ld a, [wWhichPokemon]
+ call RemoveItemFromInventory
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld hl, ThrewAwayItemText
+ call PrintText
+ pop hl
+ and a
+ ret
+.tooImportantToToss
+ push hl
+ ld hl, TooImportantToTossText
+ call PrintText
+ pop hl
+ scf
+ ret
+
+ThrewAwayItemText:
+ TX_FAR _ThrewAwayItemText
+ db "@"
+
+IsItOKToTossItemText:
+ TX_FAR _IsItOKToTossItemText
+ db "@"
+
+TooImportantToTossText:
+ TX_FAR _TooImportantToTossText
+ db "@"
+
+; checks if an item is a key item
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wIsKeyItem] = result
+; 00: item is not key item
+; 01: item is key item
+IsKeyItem_:
+ ld a, $01
+ ld [wIsKeyItem], a
+ ld a, [wcf91]
+ cp HM_01 ; is the item an HM or TM?
+ jr nc, .checkIfItemIsHM
+; if the item is not an HM or TM
+ push af
+ ld hl, KeyItemBitfield
+ ld de, wBuffer
+ ld bc, 15 ; only 11 bytes are actually used
+ call CopyData
+ pop af
+ dec a
+ ld c, a
+ ld hl, wBuffer
+ ld b, FLAG_TEST
+ predef FlagActionPredef
+ ld a, c
+ and a
+ ret nz
+.checkIfItemIsHM
+ ld a, [wcf91]
+ call IsItemHM
+ ret c
+ xor a
+ ld [wIsKeyItem], a
+ ret
+
+INCLUDE "data/key_items.asm"
+
+SendNewMonToBox:
+ ld de, wNumInBox
+ ld a, [de]
+ inc a
+ ld [de], a
+ ld a, [wcf91]
+ ld [wd0b5], a
+ ld c, a
+.asm_e7b1
+ inc de
+ ld a, [de]
+ ld b, a
+ ld a, c
+ ld c, b
+ ld [de], a
+ cp $ff
+ jr nz, .asm_e7b1
+ call GetMonHeader
+ ld hl, wBoxMonOT
+ ld bc, NAME_LENGTH
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e7ee
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, NAME_LENGTH
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wNumInBox]
+ dec a
+ ld b, a
+.asm_e7db
+ push bc
+ push hl
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, -NAME_LENGTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e7db
+.asm_e7ee
+ ld hl, wPlayerName
+ ld de, wBoxMonOT
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e82a
+ ld hl, wBoxMonNicks
+ ld bc, NAME_LENGTH
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, NAME_LENGTH
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wNumInBox]
+ dec a
+ ld b, a
+.asm_e817
+ push bc
+ push hl
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, -NAME_LENGTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e817
+.asm_e82a
+ ld hl, wBoxMonNicks
+ ld a, NAME_MON_SCREEN
+ ld [wNamingScreenType], a
+ predef AskName
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e867
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1
+ dec a
+ call AddNTimes
+ push hl
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ ld a, [wNumInBox]
+ dec a
+ ld b, a
+.asm_e854
+ push bc
+ push hl
+ ld bc, wBoxMon2 - wBoxMon1
+ call CopyData
+ pop hl
+ ld d, h
+ ld e, l
+ ld bc, wBoxMon1 - wBoxMon2
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .asm_e854
+.asm_e867
+ ld a, [wEnemyMonLevel]
+ ld [wEnemyMonBoxLevel], a
+ ld hl, wEnemyMon
+ ld de, wBoxMon1
+ ld bc, wEnemyMonDVs - wEnemyMon
+ call CopyData
+ ld hl, wPlayerID
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ inc de
+ push de
+ ld a, [wCurEnemyLVL]
+ ld d, a
+ callab CalcExperience
+ pop de
+ ld a, [hExperience]
+ ld [de], a
+ inc de
+ ld a, [hExperience + 1]
+ ld [de], a
+ inc de
+ ld a, [hExperience + 2]
+ ld [de], a
+ inc de
+ xor a
+ ld b, NUM_STATS * 2
+.asm_e89f
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_e89f
+ ld hl, wEnemyMonDVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld hl, wEnemyMonPP
+ ld b, NUM_MOVES
+.asm_e8b1
+ ld a, [hli]
+ inc de
+ ld [de], a
+ dec b
+ jr nz, .asm_e8b1
+ ret
+
+; checks if the tile in front of the player is a shore or water tile
+; used for surfing and fishing
+; unsets carry if it is, sets carry if not
+IsNextTileShoreOrWater:
+ ld a, [wCurMapTileset]
+ ld hl, WaterTilesets
+ ld de, 1
+ call IsInArray
+ jr nc, .notShoreOrWater
+ ld a, [wCurMapTileset]
+ cp SHIP_PORT ; Vermilion Dock tileset
+ ld a, [wTileInFrontOfPlayer] ; tile in front of player
+ jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
+ cp $48 ; eastern shore tile in Safari Zone
+ jr z, .shoreOrWater
+ cp $32 ; usual eastern shore tile
+ jr z, .shoreOrWater
+.skipShoreTiles
+ cp $14 ; water tile
+ jr z, .shoreOrWater
+.notShoreOrWater
+ scf
+ ret
+.shoreOrWater
+ and a
+ ret
+
+; tilesets with water
+WaterTilesets:
+ db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
+ db $ff ; terminator
+
+ReadSuperRodData:
+; return e = 2 if no fish on this map
+; return e = 1 if a bite, bc = level,species
+; return e = 0 if no bite
+ ld a, [wCurMap]
+ ld de, 3 ; each fishing group is three bytes wide
+ ld hl, SuperRodData
+ call IsInArray
+ jr c, .ReadFishingGroup
+ ld e, $2 ; $2 if no fishing groups found
+ ret
+
+.ReadFishingGroup
+; hl points to the fishing group entry in the index
+ inc hl ; skip map id
+
+ ; read fishing group address
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+
+ ld b, [hl] ; how many mons in group
+ inc hl ; point to data
+ ld e, $0 ; no bite yet
+
+.RandomLoop
+ call Random
+ srl a
+ ret c ; 50% chance of no battle
+
+ and %11 ; 2-bit random number
+ cp b
+ jr nc, .RandomLoop ; if a is greater than the number of mons, regenerate
+
+ ; get the mon
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld b, [hl] ; level
+ inc hl
+ ld c, [hl] ; species
+ ld e, $1 ; $1 if there's a bite
+ ret
+
+INCLUDE "data/super_rod.asm"
+
+; reloads map view and processes sprite data
+; for items that cause the overworld to be displayed
+ItemUseReloadOverworldData:
+ call LoadCurrentMapView
+ jp UpdateSprites
+
+; creates a list at wBuffer of maps where the mon in [wd11e] can be found.
+; this is used by the pokedex to display locations the mon can be found on the map.
+FindWildLocationsOfMon:
+ ld hl, WildDataPointers
+ ld de, wBuffer
+ ld c, $0
+.loop
+ inc hl
+ ld a, [hld]
+ inc a
+ jr z, .done
+ push hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [hli]
+ and a
+ call nz, CheckMapForMon ; land
+ ld a, [hli]
+ and a
+ call nz, CheckMapForMon ; water
+ pop hl
+ inc hl
+ inc hl
+ inc c
+ jr .loop
+.done
+ ld a, $ff ; list terminator
+ ld [de], a
+ ret
+
+CheckMapForMon:
+ inc hl
+ ld b, $a
+.loop
+ ld a, [wd11e]
+ cp [hl]
+ jr nz, .nextEntry
+ ld a, c
+ ld [de], a
+ inc de
+.nextEntry
+ inc hl
+ inc hl
+ dec b
+ jr nz, .loop
+ dec hl
+ ret
diff --git a/en/engine/learn_move.asm b/en/engine/learn_move.asm
new file mode 100755
index 00000000..53c7f87e
--- /dev/null
+++ b/en/engine/learn_move.asm
@@ -0,0 +1,226 @@
+LearnMove:
+ call SaveScreenTilesToBuffer1
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ ld hl, wcd6d
+ ld de, wLearnMoveMonName
+ ld bc, NAME_LENGTH
+ call CopyData
+
+DontAbandonLearning:
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2Moves - wPartyMon1Moves
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld b, NUM_MOVES
+.findEmptyMoveSlotLoop
+ ld a, [hl]
+ and a
+ jr z, .next
+ inc hl
+ dec b
+ jr nz, .findEmptyMoveSlotLoop
+ push de
+ call TryingToLearn
+ pop de
+ jp c, AbandonLearning
+ push hl
+ push de
+ ld [wd11e], a
+ call GetMoveName
+ ld hl, OneTwoAndText
+ call PrintText
+ pop de
+ pop hl
+.next
+ ld a, [wMoveNum]
+ ld [hl], a
+ ld bc, wPartyMon1PP - wPartyMon1Moves
+ add hl, bc
+ push hl
+ push de
+ dec a
+ ld hl, Moves
+ ld bc, MoveEnd - Moves
+ call AddNTimes
+ ld de, wBuffer
+ ld a, BANK(Moves)
+ call FarCopyData
+ ld a, [wBuffer + 5] ; a = move's max PP
+ pop de
+ pop hl
+ ld [hl], a
+ ld a, [wIsInBattle]
+ and a
+ jp z, PrintLearnedMove
+ ld a, [wWhichPokemon]
+ ld b, a
+ ld a, [wPlayerMonNumber]
+ cp b
+ jp nz, PrintLearnedMove
+ ld h, d
+ ld l, e
+ ld de, wBattleMonMoves
+ ld bc, NUM_MOVES
+ call CopyData
+ ld bc, wPartyMon1PP - wPartyMon1OTID
+ add hl, bc
+ ld de, wBattleMonPP
+ ld bc, NUM_MOVES
+ call CopyData
+ jp PrintLearnedMove
+
+AbandonLearning:
+ ld hl, AbandonLearningText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wCurrentMenuItem]
+ and a
+ jp nz, DontAbandonLearning
+ ld hl, DidNotLearnText
+ call PrintText
+ ld b, 0
+ ret
+
+PrintLearnedMove:
+ ld hl, LearnedMove1Text
+ call PrintText
+ ld b, 1
+ ret
+
+TryingToLearn:
+ push hl
+ ld hl, TryingToLearnText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ pop hl
+ ld a, [wCurrentMenuItem]
+ rra
+ ret c
+ ld bc, -NUM_MOVES
+ add hl, bc
+ push hl
+ ld de, wMoves
+ ld bc, NUM_MOVES
+ call CopyData
+ callab FormatMovesString
+ pop hl
+.loop
+ push hl
+ ld hl, WhichMoveToForgetText
+ call PrintText
+ coord hl, 4, 7
+ ld b, 4
+ ld c, 14
+ call TextBoxBorder
+ coord hl, 6, 8
+ ld de, wMovesString
+ ld a, [hFlags_0xFFF6]
+ set 2, a
+ ld [hFlags_0xFFF6], a
+ call PlaceString
+ ld a, [hFlags_0xFFF6]
+ res 2, a
+ ld [hFlags_0xFFF6], a
+ ld hl, wTopMenuItemY
+ ld a, 8
+ ld [hli], a ; wTopMenuItemY
+ ld a, 5
+ ld [hli], a ; wTopMenuItemX
+ xor a
+ ld [hli], a ; wCurrentMenuItem
+ inc hl
+ ld a, [wNumMovesMinusOne]
+ ld [hli], a ; wMaxMenuItem
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ ld [hl], 0 ; wLastMenuItem
+ ld hl, hFlags_0xFFF6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, hFlags_0xFFF6
+ res 1, [hl]
+ push af
+ call LoadScreenTilesFromBuffer1
+ pop af
+ pop hl
+ bit 1, a ; pressed b
+ jr nz, .cancel
+ push hl
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ push af
+ push bc
+ call IsMoveHM
+ pop bc
+ pop de
+ ld a, d
+ jr c, .hm
+ pop hl
+ add hl, bc
+ and a
+ ret
+.hm
+ ld hl, HMCantDeleteText
+ call PrintText
+ pop hl
+ jr .loop
+.cancel
+ scf
+ ret
+
+LearnedMove1Text:
+ TX_FAR _LearnedMove1Text
+ TX_SFX_ITEM_1 ; plays SFX_GET_ITEM_1 in the party menu (rare candy) and plays SFX_LEVEL_UP in battle
+ TX_BLINK
+ db "@"
+
+WhichMoveToForgetText:
+ TX_FAR _WhichMoveToForgetText
+ db "@"
+
+AbandonLearningText:
+ TX_FAR _AbandonLearningText
+ db "@"
+
+DidNotLearnText:
+ TX_FAR _DidNotLearnText
+ db "@"
+
+TryingToLearnText:
+ TX_FAR _TryingToLearnText
+ db "@"
+
+OneTwoAndText:
+ TX_FAR _OneTwoAndText
+ TX_DELAY
+ TX_ASM
+ ld a, SFX_SWAP
+ call PlaySoundWaitForCurrent
+ ld hl, PoofText
+ ret
+
+PoofText:
+ TX_FAR _PoofText
+ TX_DELAY
+ForgotAndText:
+ TX_FAR _ForgotAndText
+ db "@"
+
+HMCantDeleteText:
+ TX_FAR _HMCantDeleteText
+ db "@"
diff --git a/en/engine/menu/bills_pc.asm b/en/engine/menu/bills_pc.asm
new file mode 100644
index 00000000..85a546e1
--- /dev/null
+++ b/en/engine/menu/bills_pc.asm
@@ -0,0 +1,554 @@
+DisplayPCMainMenu::
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call SaveScreenTilesToBuffer2
+ ld a, [wNumHoFTeams]
+ and a
+ jr nz, .leaguePCAvailable
+ CheckEvent EVENT_GOT_POKEDEX
+ jr z, .noOaksPC
+ ld a, [wNumHoFTeams]
+ and a
+ jr nz, .leaguePCAvailable
+ coord hl, 0, 0
+ ld b, 8
+ ld c, 14
+ jr .next
+.noOaksPC
+ coord hl, 0, 0
+ ld b, 6
+ ld c, 14
+ jr .next
+.leaguePCAvailable
+ coord hl, 0, 0
+ ld b, 10
+ ld c, 14
+.next
+ call TextBoxBorder
+ call UpdateSprites
+ ld a, 3
+ ld [wMaxMenuItem], a
+ CheckEvent EVENT_MET_BILL
+ jr nz, .metBill
+ coord hl, 2, 2
+ ld de, SomeonesPCText
+ jr .next2
+.metBill
+ coord hl, 2, 2
+ ld de, BillsPCText
+.next2
+ call PlaceString
+ coord hl, 2, 4
+ ld de, wPlayerName
+ call PlaceString
+ ld l, c
+ ld h, b
+ ld de, PlayersPCText
+ call PlaceString
+ CheckEvent EVENT_GOT_POKEDEX
+ jr z, .noOaksPC2
+ coord hl, 2, 6
+ ld de, OaksPCText
+ call PlaceString
+ ld a, [wNumHoFTeams]
+ and a
+ jr z, .noLeaguePC
+ ld a, 4
+ ld [wMaxMenuItem], a
+ coord hl, 2, 8
+ ld de, PKMNLeaguePCText
+ call PlaceString
+ coord hl, 2, 10
+ ld de, LogOffPCText
+ jr .next3
+.noLeaguePC
+ coord hl, 2, 8
+ ld de, LogOffPCText
+ jr .next3
+.noOaksPC2
+ ld a, $2
+ ld [wMaxMenuItem], a
+ coord hl, 2, 6
+ ld de, LogOffPCText
+.next3
+ call PlaceString
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 2
+ ld [wTopMenuItemY], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+SomeonesPCText: db "SOMEONE's PC@"
+BillsPCText: db "BILL's PC@"
+PlayersPCText: db "'s PC@"
+OaksPCText: db "PROF.OAK's PC@"
+PKMNLeaguePCText: db $4a, "LEAGUE@"
+LogOffPCText: db "LOG OFF@"
+
+BillsPC_::
+ ld hl, wd730
+ set 6, [hl]
+ xor a
+ ld [wParentMenuItem], a
+ inc a ; MONSTER_NAME
+ ld [wNameListType], a
+ call LoadHpBarAndStatusTilePatterns
+ ld a, [wListScrollOffset]
+ push af
+ ld a, [wFlags_0xcd60]
+ bit 3, a ; accessing Bill's PC through another PC?
+ jr nz, BillsPCMenu
+; accessing it directly
+ ld a, $99
+ call PlaySound
+ ld hl, SwitchOnText
+ call PrintText
+
+BillsPCMenu:
+ ld a, [wParentMenuItem]
+ ld [wCurrentMenuItem], a
+ ld hl, vChars2 + $780
+ ld de, PokeballTileGraphics
+ lb bc, BANK(PokeballTileGraphics), $01
+ call CopyVideoData
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ coord hl, 0, 0
+ ld b, 10
+ ld c, 12
+ call TextBoxBorder
+ coord hl, 2, 2
+ ld de, BillsPCMenuText
+ call PlaceString
+ ld hl, wTopMenuItemY
+ ld a, 2
+ ld [hli], a ; wTopMenuItemY
+ dec a
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, 4
+ ld [hli], a ; wMaxMenuItem
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hli], a ; wLastMenuItem
+ ld [hli], a ; wPartyAndBillsPCSavedMenuItem
+ ld hl, wListScrollOffset
+ ld [hli], a ; wListScrollOffset
+ ld [hl], a ; wMenuWatchMovingOutOfBounds
+ ld [wPlayerMonNumber], a
+ ld hl, WhatText
+ call PrintText
+ coord hl, 9, 14
+ ld b, 2
+ ld c, 9
+ call TextBoxBorder
+ ld a, [wCurrentBoxNum]
+ and $7f
+ cp 9
+ jr c, .singleDigitBoxNum
+; two digit box num
+ sub 9
+ coord hl, 17, 16
+ ld [hl], "1"
+ add "0"
+ jr .next
+.singleDigitBoxNum
+ add "1"
+.next
+ Coorda 18, 16
+ coord hl, 10, 16
+ ld de, BoxNoPCText
+ call PlaceString
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ call HandleMenuInput
+ bit 1, a
+ jp nz, ExitBillsPC ; b button
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem]
+ ld [wParentMenuItem], a
+ and a
+ jp z, BillsPCWithdraw ; withdraw
+ cp $1
+ jp z, BillsPCDeposit ; deposit
+ cp $2
+ jp z, BillsPCRelease ; release
+ cp $3
+ jp z, BillsPCChangeBox ; change box
+
+ExitBillsPC:
+ ld a, [wFlags_0xcd60]
+ bit 3, a ; accessing Bill's PC through another PC?
+ jr nz, .next
+; accessing it directly
+ call LoadTextBoxTilePatterns
+ ld a, $9a
+ call PlaySound
+ call WaitForSoundToFinish
+.next
+ ld hl, wFlags_0xcd60
+ res 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ pop af
+ ld [wListScrollOffset], a
+ ld hl, wd730
+ res 6, [hl]
+ ret
+
+BillsPCDeposit:
+ ld a, [wPartyCount]
+ dec a
+ jr nz, .partyLargeEnough
+ ld hl, CantDepositLastMonText
+ call PrintText
+ jp BillsPCMenu
+.partyLargeEnough
+ ld a, [wNumInBox]
+ cp MONS_PER_BOX
+ jr nz, .boxNotFull
+ ld hl, BoxFullText
+ call PrintText
+ jp BillsPCMenu
+.boxNotFull
+ ld hl, wPartyCount
+ call DisplayMonListMenu
+ jp c, BillsPCMenu
+ call DisplayDepositWithdrawMenu
+ jp nc, BillsPCMenu
+ ld a, [wcf91]
+ call GetCryData
+ call PlaySoundWaitForCurrent
+ ld a, PARTY_TO_BOX
+ ld [wMoveMonType], a
+ call MoveMon
+ xor a
+ ld [wRemoveMonFromBox], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld hl, wBoxNumString
+ ld a, [wCurrentBoxNum]
+ and $7f
+ cp 9
+ jr c, .singleDigitBoxNum
+ sub 9
+ ld [hl], "1"
+ inc hl
+ add "0"
+ jr .next
+.singleDigitBoxNum
+ add "1"
+.next
+ ld [hli], a
+ ld [hl], "@"
+ ld hl, MonWasStoredText
+ call PrintText
+ jp BillsPCMenu
+
+BillsPCWithdraw:
+ ld a, [wNumInBox]
+ and a
+ jr nz, .boxNotEmpty
+ ld hl, NoMonText
+ call PrintText
+ jp BillsPCMenu
+.boxNotEmpty
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH
+ jr nz, .partyNotFull
+ ld hl, CantTakeMonText
+ call PrintText
+ jp BillsPCMenu
+.partyNotFull
+ ld hl, wNumInBox
+ call DisplayMonListMenu
+ jp c, BillsPCMenu
+ call DisplayDepositWithdrawMenu
+ jp nc, BillsPCMenu
+ ld a, [wWhichPokemon]
+ ld hl, wBoxMonNicks
+ call GetPartyMonName
+ ld a, [wcf91]
+ call GetCryData
+ call PlaySoundWaitForCurrent
+ xor a ; BOX_TO_PARTY
+ ld [wMoveMonType], a
+ call MoveMon
+ ld a, 1
+ ld [wRemoveMonFromBox], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld hl, MonIsTakenOutText
+ call PrintText
+ jp BillsPCMenu
+
+BillsPCRelease:
+ ld a, [wNumInBox]
+ and a
+ jr nz, .loop
+ ld hl, NoMonText
+ call PrintText
+ jp BillsPCMenu
+.loop
+ ld hl, wNumInBox
+ call DisplayMonListMenu
+ jp c, BillsPCMenu
+ ld hl, OnceReleasedText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .loop
+ inc a
+ ld [wRemoveMonFromBox], a
+ call RemovePokemon
+ call WaitForSoundToFinish
+ ld a, [wcf91]
+ call PlayCry
+ ld hl, MonWasReleasedText
+ call PrintText
+ jp BillsPCMenu
+
+BillsPCChangeBox:
+ callba ChangeBox
+ jp BillsPCMenu
+
+DisplayMonListMenu:
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wPrintItemPrices], a
+ ld [wListMenuID], a
+ inc a ; MONSTER_NAME
+ ld [wNameListType], a
+ ld a, [wPartyAndBillsPCSavedMenuItem]
+ ld [wCurrentMenuItem], a
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem]
+ ld [wPartyAndBillsPCSavedMenuItem], a
+ ret
+
+BillsPCMenuText:
+ db "WITHDRAW ", $4a
+ next "DEPOSIT ", $4a
+ next "RELEASE ", $4a
+ next "CHANGE BOX"
+ next "SEE YA!"
+ db "@"
+
+BoxNoPCText:
+ db "BOX No.@"
+
+KnowsHMMove::
+; returns whether mon with party index [wWhichPokemon] knows an HM move
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ jr .next
+; unreachable
+ ld hl, wBoxMon1Moves
+ ld bc, wBoxMon2 - wBoxMon1
+.next
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ ld b, NUM_MOVES
+.loop
+ ld a, [hli]
+ push hl
+ push bc
+ ld hl, HMMoveArray
+ ld de, 1
+ call IsInArray
+ pop bc
+ pop hl
+ ret c
+ dec b
+ jr nz, .loop
+ and a
+ ret
+
+HMMoveArray:
+ db CUT
+ db FLY
+ db SURF
+ db STRENGTH
+ db FLASH
+ db -1
+
+DisplayDepositWithdrawMenu:
+ coord hl, 9, 10
+ ld b, 6
+ ld c, 9
+ call TextBoxBorder
+ ld a, [wParentMenuItem]
+ and a ; was the Deposit or Withdraw item selected in the parent menu?
+ ld de, DepositPCText
+ jr nz, .next
+ ld de, WithdrawPCText
+.next
+ coord hl, 11, 12
+ call PlaceString
+ coord hl, 11, 14
+ ld de, StatsCancelPCText
+ call PlaceString
+ ld hl, wTopMenuItemY
+ ld a, 12
+ ld [hli], a ; wTopMenuItemY
+ ld a, 10
+ ld [hli], a ; wTopMenuItemX
+ xor a
+ ld [hli], a ; wCurrentMenuItem
+ inc hl
+ ld a, 2
+ ld [hli], a ; wMaxMenuItem
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hl], a ; wLastMenuItem
+ ld hl, wListScrollOffset
+ ld [hli], a ; wListScrollOffset
+ ld [hl], a ; wMenuWatchMovingOutOfBounds
+ ld [wPlayerMonNumber], a
+ ld [wPartyAndBillsPCSavedMenuItem], a
+.loop
+ call HandleMenuInput
+ bit 1, a ; pressed B?
+ jr nz, .exit
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .choseDepositWithdraw
+ dec a
+ jr z, .viewStats
+.exit
+ and a
+ ret
+.choseDepositWithdraw
+ scf
+ ret
+.viewStats
+ call SaveScreenTilesToBuffer1
+ ld a, [wParentMenuItem]
+ and a
+ ld a, PLAYER_PARTY_DATA
+ jr nz, .next2
+ ld a, BOX_DATA
+.next2
+ ld [wMonDataLocation], a
+ predef StatusScreen
+ predef StatusScreen2
+ call LoadScreenTilesFromBuffer1
+ call ReloadTilesetTilePatterns
+ call RunDefaultPaletteCommand
+ call LoadGBPal
+ jr .loop
+
+DepositPCText: db "DEPOSIT@"
+WithdrawPCText: db "WITHDRAW@"
+StatsCancelPCText:
+ db "STATS"
+ next "CANCEL@"
+
+SwitchOnText:
+ TX_FAR _SwitchOnText
+ db "@"
+
+WhatText:
+ TX_FAR _WhatText
+ db "@"
+
+DepositWhichMonText:
+ TX_FAR _DepositWhichMonText
+ db "@"
+
+MonWasStoredText:
+ TX_FAR _MonWasStoredText
+ db "@"
+
+CantDepositLastMonText:
+ TX_FAR _CantDepositLastMonText
+ db "@"
+
+BoxFullText:
+ TX_FAR _BoxFullText
+ db "@"
+
+MonIsTakenOutText:
+ TX_FAR _MonIsTakenOutText
+ db "@"
+
+NoMonText:
+ TX_FAR _NoMonText
+ db "@"
+
+CantTakeMonText:
+ TX_FAR _CantTakeMonText
+ db "@"
+
+ReleaseWhichMonText:
+ TX_FAR _ReleaseWhichMonText
+ db "@"
+
+OnceReleasedText:
+ TX_FAR _OnceReleasedText
+ db "@"
+
+MonWasReleasedText:
+ TX_FAR _MonWasReleasedText
+ db "@"
+
+CableClubLeftGameboy::
+ ld a, [hSerialConnectionStatus]
+ cp USING_EXTERNAL_CLOCK
+ ret z
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_RIGHT
+ ret nz
+ ld a, [wCurMap]
+ cp TRADE_CENTER
+ ld a, LINK_STATE_START_TRADE
+ jr z, .next
+ inc a ; LINK_STATE_START_BATTLE
+.next
+ ld [wLinkState], a
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump JustAMomentText
+
+CableClubRightGameboy::
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ ret z
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_LEFT
+ ret nz
+ ld a, [wCurMap]
+ cp TRADE_CENTER
+ ld a, LINK_STATE_START_TRADE
+ jr z, .next
+ inc a ; LINK_STATE_START_BATTLE
+.next
+ ld [wLinkState], a
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump JustAMomentText
+
+JustAMomentText::
+ TX_FAR _JustAMomentText
+ db "@"
+
+ ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump OpenBillsPCText
+
+OpenBillsPCText::
+ db $FD ; FuncTX_BillsPC
+
diff --git a/en/engine/menu/diploma.asm b/en/engine/menu/diploma.asm
new file mode 100755
index 00000000..09ba123e
--- /dev/null
+++ b/en/engine/menu/diploma.asm
@@ -0,0 +1,113 @@
+DisplayDiploma:
+ call SaveScreenTilesToBuffer2
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ ld hl, wd730
+ set 6, [hl]
+ call DisableLCD
+ ld hl, CircleTile
+ ld de, vChars2 + $700
+ ld bc, $0010
+ ld a, BANK(CircleTile)
+ call FarCopyData2
+ coord hl, 0, 0
+ lb bc, 16, 18
+ predef Diploma_TextBoxBorder
+ ld hl, DiplomaTextPointersAndCoords
+ ld c, $5
+.asm_56715
+ push bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ push hl
+ ld h, [hl]
+ ld l, a
+ call PlaceString
+ pop hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .asm_56715
+ coord hl, 10, 4
+ ld de, wPlayerName
+ call PlaceString
+ callba DrawPlayerCharacter
+
+; Move the player 33 pixels right and set the priority bit so he appears
+; behind the background layer.
+ ld hl, wOAMBuffer + $01
+ lb bc, $80, $28
+.adjustPlayerGfxLoop
+ ld a, [hl] ; X
+ add 33
+ ld [hli], a
+ inc hl
+ ld a, b
+ ld [hli], a ; attributes
+ inc hl
+ dec c
+ jr nz, .adjustPlayerGfxLoop
+
+ call EnableLCD
+ callba LoadTrainerInfoTextBoxTiles
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+ call Delay3
+ call GBPalNormal
+ ld a, $90
+ ld [rOBP0], a
+ call WaitForTextScrollButtonPress
+ ld hl, wd730
+ res 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call RestoreScreenTilesAndReloadTilePatterns
+ call Delay3
+ jp GBPalNormal
+
+UnusedPlayerNameLengthFunc:
+; Unused function that does a calculation involving the length of the player's
+; name.
+ ld hl, wPlayerName
+ ld bc, $ff00
+.loop
+ ld a, [hli]
+ cp "@"
+ ret z
+ dec c
+ jr .loop
+
+DiplomaTextPointersAndCoords:
+ dw DiplomaText
+ dwCoord 5, 2
+ dw DiplomaPlayer
+ dwCoord 3, 4
+ dw DiplomaEmptyText
+ dwCoord 15, 4
+ dw DiplomaCongrats
+ dwCoord 2, 6
+ dw DiplomaGameFreak
+ dwCoord 9, 16
+
+DiplomaText:
+ db $70,"Diploma",$70,"@"
+
+DiplomaPlayer:
+ db "Player@"
+
+DiplomaEmptyText:
+ db "@"
+
+DiplomaCongrats:
+ db "Congrats! This"
+ next "diploma certifies"
+ next "that you have"
+ next "completed your"
+ next "#DEX.@"
+
+DiplomaGameFreak:
+ db "GAME FREAK@"
diff --git a/en/engine/menu/draw_start_menu.asm b/en/engine/menu/draw_start_menu.asm
new file mode 100644
index 00000000..11777dc6
--- /dev/null
+++ b/en/engine/menu/draw_start_menu.asm
@@ -0,0 +1,89 @@
+; function that displays the start menu
+DrawStartMenu:
+ CheckEvent EVENT_GOT_POKEDEX
+; menu with pokedex
+ coord hl, 10, 0
+ ld b, $0e
+ ld c, $08
+ jr nz, .drawTextBoxBorder
+; shorter menu if the player doesn't have the pokedex
+ coord hl, 10, 0
+ ld b, $0c
+ ld c, $08
+.drawTextBoxBorder
+ call TextBoxBorder
+ ld a, D_DOWN | D_UP | START | B_BUTTON | A_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $02
+ ld [wTopMenuItemY], a ; Y position of first menu choice
+ ld a, $0b
+ ld [wTopMenuItemX], a ; X position of first menu choice
+ ld a, [wBattleAndStartSavedMenuItem] ; remembered menu selection from last time
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ xor a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld hl, wd730
+ set 6, [hl] ; no pauses between printing each letter
+ coord hl, 12, 2
+ CheckEvent EVENT_GOT_POKEDEX
+; case for not having pokedex
+ ld a, $06
+ jr z, .storeMenuItemCount
+; case for having pokedex
+ ld de, StartMenuPokedexText
+ call PrintStartMenuItem
+ ld a, $07
+.storeMenuItemCount
+ ld [wMaxMenuItem], a ; number of menu items
+ ld de, StartMenuPokemonText
+ call PrintStartMenuItem
+ ld de, StartMenuItemText
+ call PrintStartMenuItem
+ ld de, wPlayerName ; player's name
+ call PrintStartMenuItem
+ ld a, [wd72e]
+ bit 6, a ; is the player using the link feature?
+; case for not using link feature
+ ld de, StartMenuSaveText
+ jr z, .printSaveOrResetText
+; case for using link feature
+ ld de, StartMenuResetText
+.printSaveOrResetText
+ call PrintStartMenuItem
+ ld de, StartMenuOptionText
+ call PrintStartMenuItem
+ ld de, StartMenuExitText
+ call PlaceString
+ ld hl, wd730
+ res 6, [hl] ; turn pauses between printing letters back on
+ ret
+
+StartMenuPokedexText:
+ db "POKéDEX@"
+
+StartMenuPokemonText:
+ db "POKéMON@"
+
+StartMenuItemText:
+ db "ITEM@"
+
+StartMenuSaveText:
+ db "SAVE@"
+
+StartMenuResetText:
+ db "RESET@"
+
+StartMenuExitText:
+ db "EXIT@"
+
+StartMenuOptionText:
+ db "OPTION@"
+
+PrintStartMenuItem:
+ push hl
+ call PlaceString
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ ret
diff --git a/en/engine/menu/league_pc.asm b/en/engine/menu/league_pc.asm
new file mode 100755
index 00000000..170c0ef3
--- /dev/null
+++ b/en/engine/menu/league_pc.asm
@@ -0,0 +1,120 @@
+PKMNLeaguePC:
+ ld hl, AccessedHoFPCText
+ call PrintText
+ ld hl, wd730
+ set 6, [hl]
+ push hl
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ ld [wSpriteFlipped], a
+ ld [wUpdateSpritesEnabled], a
+ ld [wHoFTeamIndex2], a
+ ld [wHoFTeamNo], a
+ ld a, [wNumHoFTeams]
+ ld b, a
+ cp HOF_TEAM_CAPACITY + 1
+ jr c, .loop
+; If the total number of hall of fame teams is greater than the storage
+; capacity, then calculate the number of the first team that is still recorded.
+ ld b, HOF_TEAM_CAPACITY
+ sub b
+ ld [wHoFTeamNo], a
+.loop
+ ld hl, wHoFTeamNo
+ inc [hl]
+ push bc
+ ld a, [wHoFTeamIndex2]
+ ld [wHoFTeamIndex], a
+ callba LoadHallOfFameTeams
+ call LeaguePCShowTeam
+ pop bc
+ jr c, .doneShowingTeams
+ ld hl, wHoFTeamIndex2
+ inc [hl]
+ ld a, [hl]
+ cp b
+ jr nz, .loop
+.doneShowingTeams
+ pop af
+ ld [hTilesetType], a
+ pop af
+ ld [wUpdateSpritesEnabled], a
+ pop hl
+ res 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call RunDefaultPaletteCommand
+ jp GBPalNormal
+
+LeaguePCShowTeam:
+ ld c, PARTY_LENGTH
+.loop
+ push bc
+ call LeaguePCShowMon
+ call WaitForTextScrollButtonPress
+ ld a, [hJoyHeld]
+ bit 1, a
+ jr nz, .exit
+ ld hl, wHallOfFame + HOF_MON
+ ld de, wHallOfFame
+ ld bc, HOF_TEAM - HOF_MON
+ call CopyData
+ pop bc
+ ld a, [wHallOfFame + 0]
+ cp $ff
+ jr z, .done
+ dec c
+ jr nz, .loop
+.done
+ and a
+ ret
+.exit
+ pop bc
+ scf
+ ret
+
+LeaguePCShowMon:
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ ld hl, wHallOfFame
+ ld a, [hli]
+ ld [wHoFMonSpecies], a
+ ld [wcf91], a
+ ld [wd0b5], a
+ ld [wBattleMonSpecies2], a
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld a, [hli]
+ ld [wHoFMonLevel], a
+ ld de, wcd6d
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ ld c, 0
+ call RunPaletteCommand
+ coord hl, 12, 5
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ call GBPalNormal
+ coord hl, 0, 13
+ ld b, 2
+ ld c, $12
+ call TextBoxBorder
+ coord hl, 1, 15
+ ld de, HallOfFameNoText
+ call PlaceString
+ coord hl, 16, 15
+ ld de, wHoFTeamNo
+ lb bc, 1, 3
+ call PrintNumber
+ jpba HoFDisplayMonInfo
+
+HallOfFameNoText:
+ db "HALL OF FAME No @"
+
+AccessedHoFPCText:
+ TX_FAR _AccessedHoFPCText
+ db "@"
diff --git a/en/engine/menu/main_menu.asm b/en/engine/menu/main_menu.asm
new file mode 100755
index 00000000..da2e98e4
--- /dev/null
+++ b/en/engine/menu/main_menu.asm
@@ -0,0 +1,712 @@
+MainMenu:
+; Check save file
+ call InitOptions
+ xor a
+ ld [wOptionsInitialized], a
+ inc a
+ ld [wSaveFileStatus], a
+ call CheckForPlayerNameInSRAM
+ jr nc, .mainMenuLoop
+
+ predef LoadSAV
+
+.mainMenuLoop
+ ld c, 20
+ call DelayFrames
+ xor a ; LINK_STATE_NONE
+ ld [wLinkState], a
+ ld hl, wPartyAndBillsPCSavedMenuItem
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld [wDefaultMap], a
+ ld hl, wd72e
+ res 6, [hl]
+ call ClearScreen
+ call RunDefaultPaletteCommand
+ call LoadTextBoxTilePatterns
+ call LoadFontTilePatterns
+ ld hl, wd730
+ set 6, [hl]
+ ld a, [wSaveFileStatus]
+ cp 1
+ jr z, .noSaveFile
+; there's a save file
+ coord hl, 0, 0
+ ld b, 6
+ ld c, 13
+ call TextBoxBorder
+ coord hl, 2, 2
+ ld de, ContinueText
+ call PlaceString
+ jr .next2
+.noSaveFile
+ coord hl, 0, 0
+ ld b, 4
+ ld c, 13
+ call TextBoxBorder
+ coord hl, 2, 2
+ ld de, NewGameText
+ call PlaceString
+.next2
+ ld hl, wd730
+ res 6, [hl]
+ call UpdateSprites
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wMenuJoypadPollCount], a
+ inc a
+ ld [wTopMenuItemX], a
+ inc a
+ ld [wTopMenuItemY], a
+ ld a, A_BUTTON | B_BUTTON | START
+ ld [wMenuWatchedKeys], a
+ ld a, [wSaveFileStatus]
+ ld [wMaxMenuItem], a
+ call HandleMenuInput
+ bit 1, a ; pressed B?
+ jp nz, DisplayTitleScreen ; if so, go back to the title screen
+ ld c, 20
+ call DelayFrames
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, [wSaveFileStatus]
+ cp 2
+ jp z, .skipInc
+; If there's no save file, increment the current menu item so that the numbers
+; are the same whether or not there's a save file.
+ inc b
+.skipInc
+ ld a, b
+ and a
+ jr z, .choseContinue
+ cp 1
+ jp z, StartNewGame
+ call DisplayOptionMenu
+ ld a, 1
+ ld [wOptionsInitialized], a
+ jp .mainMenuLoop
+.choseContinue
+ call DisplayContinueGameInfo
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+.inputLoop
+ xor a
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
+ ld [hJoyHeld], a
+ call Joypad
+ ld a, [hJoyHeld]
+ bit 0, a
+ jr nz, .pressedA
+ bit 1, a
+ jp nz, .mainMenuLoop ; pressed B
+ jr .inputLoop
+.pressedA
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ ld a, PLAYER_DIR_DOWN
+ ld [wPlayerDirection], a
+ ld c, 10
+ call DelayFrames
+ ld a, [wNumHoFTeams]
+ and a
+ jp z, SpecialEnterMap
+ ld a, [wCurMap] ; map ID
+ cp HALL_OF_FAME
+ jp nz, SpecialEnterMap
+ xor a
+ ld [wDestinationMap], a
+ ld hl, wd732
+ set 2, [hl] ; fly warp or dungeon warp
+ call SpecialWarpIn
+ jp SpecialEnterMap
+
+InitOptions:
+ ld a, 1 ; no delay
+ ld [wLetterPrintingDelayFlags], a
+ ld a, 3 ; medium speed
+ ld [wOptions], a
+ ret
+
+LinkMenu:
+ xor a
+ ld [wLetterPrintingDelayFlags], a
+ ld hl, wd72e
+ set 6, [hl]
+ ld hl, TextTerminator_6b20
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ ld hl, WhereWouldYouLikeText
+ call PrintText
+ coord hl, 5, 5
+ ld b, $6
+ ld c, $d
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 7, 7
+ ld de, CableClubOptionsText
+ call PlaceString
+ xor a
+ ld [wUnusedCD37], a
+ ld [wd72d], a
+ ld hl, wTopMenuItemY
+ ld a, $7
+ ld [hli], a
+ ld a, $6
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $2
+ ld [hli], a
+ inc a
+ ; ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hl], a
+.waitForInputLoop
+ call HandleMenuInput
+ and A_BUTTON | B_BUTTON
+ add a
+ add a
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ add b
+ add $d0
+ ld [wLinkMenuSelectionSendBuffer], a
+ ld [wLinkMenuSelectionSendBuffer + 1], a
+.exchangeMenuSelectionLoop
+ call Serial_ExchangeLinkMenuSelection
+ ld a, [wLinkMenuSelectionReceiveBuffer]
+ ld b, a
+ and $f0
+ cp $d0
+ jr z, .asm_5c7d
+ ld a, [wLinkMenuSelectionReceiveBuffer + 1]
+ ld b, a
+ and $f0
+ cp $d0
+ jr nz, .exchangeMenuSelectionLoop
+.asm_5c7d
+ ld a, b
+ and $c ; did the enemy press A or B?
+ jr nz, .enemyPressedAOrB
+; the enemy didn't press A or B
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and $c ; did the player press A or B?
+ jr z, .waitForInputLoop ; if neither the player nor the enemy pressed A or B, try again
+ jr .doneChoosingMenuSelection ; if the player pressed A or B but the enemy didn't, use the player's selection
+.enemyPressedAOrB
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and $c ; did the player press A or B?
+ jr z, .useEnemyMenuSelection ; if the enemy pressed A or B but the player didn't, use the enemy's selection
+; the enemy and the player both pressed A or B
+; The gameboy that is clocking the connection wins.
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .doneChoosingMenuSelection
+.useEnemyMenuSelection
+ ld a, b
+ ld [wLinkMenuSelectionSendBuffer], a
+ and $3
+ ld [wCurrentMenuItem], a
+.doneChoosingMenuSelection
+ ld a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .skipStartingTransfer
+ call DelayFrame
+ call DelayFrame
+ ld a, START_TRANSFER_INTERNAL_CLOCK
+ ld [rSC], a
+.skipStartingTransfer
+ ld b, $7f
+ ld c, $7f
+ ld d, $ec
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and (B_BUTTON << 2) ; was B button pressed?
+ jr nz, .updateCursorPosition
+; A button was pressed
+ ld a, [wCurrentMenuItem]
+ cp $2
+ jr z, .updateCursorPosition
+ ld c, d
+ ld d, b
+ dec a
+ jr z, .updateCursorPosition
+ ld b, c
+ ld c, d
+.updateCursorPosition
+ ld a, b
+ Coorda 6, 7
+ ld a, c
+ Coorda 6, 9
+ ld a, d
+ Coorda 6, 11
+ ld c, 40
+ call DelayFrames
+ call LoadScreenTilesFromBuffer1
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and (B_BUTTON << 2) ; was B button pressed?
+ jr nz, .choseCancel ; cancel if B pressed
+ ld a, [wCurrentMenuItem]
+ cp $2
+ jr z, .choseCancel
+ xor a
+ ld [wWalkBikeSurfState], a ; start walking
+ ld a, [wCurrentMenuItem]
+ and a
+ ld a, COLOSSEUM
+ jr nz, .next
+ ld a, TRADE_CENTER
+.next
+ ld [wd72d], a
+ ld hl, PleaseWaitText
+ call PrintText
+ ld c, 50
+ call DelayFrames
+ ld hl, wd732
+ res 1, [hl]
+ ld a, [wDefaultMap]
+ ld [wDestinationMap], a
+ call SpecialWarpIn
+ ld c, 20
+ call DelayFrames
+ xor a
+ ld [wMenuJoypadPollCount], a
+ ld [wSerialExchangeNybbleSendData], a
+ inc a ; LINK_STATE_IN_CABLE_CLUB
+ ld [wLinkState], a
+ ld [wEnteringCableClub], a
+ jr SpecialEnterMap
+.choseCancel
+ xor a
+ ld [wMenuJoypadPollCount], a
+ call Delay3
+ call CloseLinkConnection
+ ld hl, LinkCanceledText
+ call PrintText
+ ld hl, wd72e
+ res 6, [hl]
+ ret
+
+WhereWouldYouLikeText:
+ TX_FAR _WhereWouldYouLikeText
+ db "@"
+
+PleaseWaitText:
+ TX_FAR _PleaseWaitText
+ db "@"
+
+LinkCanceledText:
+ TX_FAR _LinkCanceledText
+ db "@"
+
+StartNewGame:
+ ld hl, wd732
+ res 1, [hl]
+ call OakSpeech
+ ld c, 20
+ call DelayFrames
+
+; enter map after using a special warp or loading the game from the main menu
+SpecialEnterMap:
+ xor a
+ ld [hJoyPressed], a
+ ld [hJoyHeld], a
+ ld [hJoy5], a
+ ld [wd72d], a
+ ld hl, wd732
+ set 0, [hl] ; count play time
+ call ResetPlayerSpriteData
+ ld c, 20
+ call DelayFrames
+ ld a, [wEnteringCableClub]
+ and a
+ ret nz
+ jp EnterMap
+
+ContinueText:
+ db "CONTINUE", $4e
+
+NewGameText:
+ db "NEW GAME"
+ next "OPTION@"
+
+CableClubOptionsText:
+ db "TRADE CENTER"
+ next "COLOSSEUM"
+ next "CANCEL@"
+
+DisplayContinueGameInfo:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 4, 7
+ ld b, 8
+ ld c, 14
+ call TextBoxBorder
+ coord hl, 5, 9
+ ld de, SaveScreenInfoText
+ call PlaceString
+ coord hl, 12, 9
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 17, 11
+ call PrintNumBadges
+ coord hl, 16, 13
+ call PrintNumOwnedMons
+ coord hl, 13, 15
+ call PrintPlayTime
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld c, 30
+ jp DelayFrames
+
+PrintSaveScreenText:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 4, 0
+ ld b, $8
+ ld c, $e
+ call TextBoxBorder
+ call LoadTextBoxTilePatterns
+ call UpdateSprites
+ coord hl, 5, 2
+ ld de, SaveScreenInfoText
+ call PlaceString
+ coord hl, 12, 2
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 17, 4
+ call PrintNumBadges
+ coord hl, 16, 6
+ call PrintNumOwnedMons
+ coord hl, 13, 8
+ call PrintPlayTime
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld c, 30
+ jp DelayFrames
+
+PrintNumBadges:
+ push hl
+ ld hl, wObtainedBadges
+ ld b, $1
+ call CountSetBits
+ pop hl
+ ld de, wNumSetBits
+ lb bc, 1, 2
+ jp PrintNumber
+
+PrintNumOwnedMons:
+ push hl
+ ld hl, wPokedexOwned
+ ld b, wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ pop hl
+ ld de, wNumSetBits
+ lb bc, 1, 3
+ jp PrintNumber
+
+PrintPlayTime:
+ ld de, wPlayTimeHours
+ lb bc, 1, 3
+ call PrintNumber
+ ld [hl], $6d
+ inc hl
+ ld de, wPlayTimeMinutes
+ lb bc, LEADING_ZEROES | 1, 2
+ jp PrintNumber
+
+SaveScreenInfoText:
+ db "PLAYER"
+ next "BADGES "
+ next "#DEX "
+ next "TIME@"
+
+DisplayOptionMenu:
+ coord hl, 0, 0
+ ld b, 3
+ ld c, 18
+ call TextBoxBorder
+ coord hl, 0, 5
+ ld b, 3
+ ld c, 18
+ call TextBoxBorder
+ coord hl, 0, 10
+ ld b, 3
+ ld c, 18
+ call TextBoxBorder
+ coord hl, 1, 1
+ ld de, TextSpeedOptionText
+ call PlaceString
+ coord hl, 1, 6
+ ld de, BattleAnimationOptionText
+ call PlaceString
+ coord hl, 1, 11
+ ld de, BattleStyleOptionText
+ call PlaceString
+ coord hl, 2, 16
+ ld de, OptionMenuCancelText
+ call PlaceString
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ inc a
+ ld [wLetterPrintingDelayFlags], a
+ ld [wUnusedCD40], a
+ ld a, 3 ; text speed cursor Y coordinate
+ ld [wTopMenuItemY], a
+ call SetCursorPositionsFromOptions
+ ld a, [wOptionsTextSpeedCursorX] ; text speed cursor X coordinate
+ ld [wTopMenuItemX], a
+ ld a, $01
+ ld [H_AUTOBGTRANSFERENABLED], a ; enable auto background transfer
+ call Delay3
+.loop
+ call PlaceMenuCursor
+ call SetOptionsFromCursorPositions
+.getJoypadStateLoop
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ ld b, a
+ and A_BUTTON | B_BUTTON | START | D_RIGHT | D_LEFT | D_UP | D_DOWN ; any key besides select pressed?
+ jr z, .getJoypadStateLoop
+ bit 1, b ; B button pressed?
+ jr nz, .exitMenu
+ bit 3, b ; Start button pressed?
+ jr nz, .exitMenu
+ bit 0, b ; A button pressed?
+ jr z, .checkDirectionKeys
+ ld a, [wTopMenuItemY]
+ cp 16 ; is the cursor on Cancel?
+ jr nz, .loop
+.exitMenu
+ ld a, SFX_PRESS_AB
+ call PlaySound
+ ret
+.eraseOldMenuCursor
+ ld [wTopMenuItemX], a
+ call EraseMenuCursor
+ jp .loop
+.checkDirectionKeys
+ ld a, [wTopMenuItemY]
+ bit 7, b ; Down pressed?
+ jr nz, .downPressed
+ bit 6, b ; Up pressed?
+ jr nz, .upPressed
+ cp 8 ; cursor in Battle Animation section?
+ jr z, .cursorInBattleAnimation
+ cp 13 ; cursor in Battle Style section?
+ jr z, .cursorInBattleStyle
+ cp 16 ; cursor on Cancel?
+ jr z, .loop
+.cursorInTextSpeed
+ bit 5, b ; Left pressed?
+ jp nz, .pressedLeftInTextSpeed
+ jp .pressedRightInTextSpeed
+.downPressed
+ cp 16
+ ld b, -13
+ ld hl, wOptionsTextSpeedCursorX
+ jr z, .updateMenuVariables
+ ld b, 5
+ cp 3
+ inc hl
+ jr z, .updateMenuVariables
+ cp 8
+ inc hl
+ jr z, .updateMenuVariables
+ ld b, 3
+ inc hl
+ jr .updateMenuVariables
+.upPressed
+ cp 8
+ ld b, -5
+ ld hl, wOptionsTextSpeedCursorX
+ jr z, .updateMenuVariables
+ cp 13
+ inc hl
+ jr z, .updateMenuVariables
+ cp 16
+ ld b, -3
+ inc hl
+ jr z, .updateMenuVariables
+ ld b, 13
+ inc hl
+.updateMenuVariables
+ add b
+ ld [wTopMenuItemY], a
+ ld a, [hl]
+ ld [wTopMenuItemX], a
+ call PlaceUnfilledArrowMenuCursor
+ jp .loop
+.cursorInBattleAnimation
+ ld a, [wOptionsBattleAnimCursorX] ; battle animation cursor X coordinate
+ xor $0b ; toggle between 1 and 10
+ ld [wOptionsBattleAnimCursorX], a
+ jp .eraseOldMenuCursor
+.cursorInBattleStyle
+ ld a, [wOptionsBattleStyleCursorX] ; battle style cursor X coordinate
+ xor $0b ; toggle between 1 and 10
+ ld [wOptionsBattleStyleCursorX], a
+ jp .eraseOldMenuCursor
+.pressedLeftInTextSpeed
+ ld a, [wOptionsTextSpeedCursorX] ; text speed cursor X coordinate
+ cp 1
+ jr z, .updateTextSpeedXCoord
+ cp 7
+ jr nz, .fromSlowToMedium
+ sub 6
+ jr .updateTextSpeedXCoord
+.fromSlowToMedium
+ sub 7
+ jr .updateTextSpeedXCoord
+.pressedRightInTextSpeed
+ ld a, [wOptionsTextSpeedCursorX] ; text speed cursor X coordinate
+ cp 14
+ jr z, .updateTextSpeedXCoord
+ cp 7
+ jr nz, .fromFastToMedium
+ add 7
+ jr .updateTextSpeedXCoord
+.fromFastToMedium
+ add 6
+.updateTextSpeedXCoord
+ ld [wOptionsTextSpeedCursorX], a ; text speed cursor X coordinate
+ jp .eraseOldMenuCursor
+
+TextSpeedOptionText:
+ db "TEXT SPEED"
+ next " FAST MEDIUM SLOW@"
+
+BattleAnimationOptionText:
+ db "BATTLE ANIMATION"
+ next " ON OFF@"
+
+BattleStyleOptionText:
+ db "BATTLE STYLE"
+ next " SHIFT SET@"
+
+OptionMenuCancelText:
+ db "CANCEL@"
+
+; sets the options variable according to the current placement of the menu cursors in the options menu
+SetOptionsFromCursorPositions:
+ ld hl, TextSpeedOptionData
+ ld a, [wOptionsTextSpeedCursorX] ; text speed cursor X coordinate
+ ld c, a
+.loop
+ ld a, [hli]
+ cp c
+ jr z, .textSpeedMatchFound
+ inc hl
+ jr .loop
+.textSpeedMatchFound
+ ld a, [hl]
+ ld d, a
+ ld a, [wOptionsBattleAnimCursorX] ; battle animation cursor X coordinate
+ dec a
+ jr z, .battleAnimationOn
+.battleAnimationOff
+ set 7, d
+ jr .checkBattleStyle
+.battleAnimationOn
+ res 7, d
+.checkBattleStyle
+ ld a, [wOptionsBattleStyleCursorX] ; battle style cursor X coordinate
+ dec a
+ jr z, .battleStyleShift
+.battleStyleSet
+ set 6, d
+ jr .storeOptions
+.battleStyleShift
+ res 6, d
+.storeOptions
+ ld a, d
+ ld [wOptions], a
+ ret
+
+; reads the options variable and places menu cursors in the correct positions within the options menu
+SetCursorPositionsFromOptions:
+ ld hl, TextSpeedOptionData + 1
+ ld a, [wOptions]
+ ld c, a
+ and $3f
+ push bc
+ ld de, 2
+ call IsInArray
+ pop bc
+ dec hl
+ ld a, [hl]
+ ld [wOptionsTextSpeedCursorX], a ; text speed cursor X coordinate
+ coord hl, 0, 3
+ call .placeUnfilledRightArrow
+ sla c
+ ld a, 1 ; On
+ jr nc, .storeBattleAnimationCursorX
+ ld a, 10 ; Off
+.storeBattleAnimationCursorX
+ ld [wOptionsBattleAnimCursorX], a ; battle animation cursor X coordinate
+ coord hl, 0, 8
+ call .placeUnfilledRightArrow
+ sla c
+ ld a, 1
+ jr nc, .storeBattleStyleCursorX
+ ld a, 10
+.storeBattleStyleCursorX
+ ld [wOptionsBattleStyleCursorX], a ; battle style cursor X coordinate
+ coord hl, 0, 13
+ call .placeUnfilledRightArrow
+; cursor in front of Cancel
+ coord hl, 0, 16
+ ld a, 1
+.placeUnfilledRightArrow
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld [hl], $ec ; unfilled right arrow menu cursor
+ ret
+
+; table that indicates how the 3 text speed options affect frame delays
+; Format:
+; 00: X coordinate of menu cursor
+; 01: delay after printing a letter (in frames)
+TextSpeedOptionData:
+ db 14,5 ; Slow
+ db 7,3 ; Medium
+ db 1,1 ; Fast
+ db 7 ; default X coordinate (Medium)
+ db $ff ; terminator
+
+CheckForPlayerNameInSRAM:
+; Check if the player name data in SRAM has a string terminator character
+; (indicating that a name may have been saved there) and return whether it does
+; in carry.
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld b, NAME_LENGTH
+ ld hl, sPlayerName
+.loop
+ ld a, [hli]
+ cp "@"
+ jr z, .found
+ dec b
+ jr nz, .loop
+; not found
+ xor a
+ ld [MBC1SRamEnable], a
+ ld [MBC1SRamBankingMode], a
+ and a
+ ret
+.found
+ xor a
+ ld [MBC1SRamEnable], a
+ ld [MBC1SRamBankingMode], a
+ scf
+ ret
diff --git a/en/engine/menu/naming_screen.asm b/en/engine/menu/naming_screen.asm
new file mode 100755
index 00000000..4804d02a
--- /dev/null
+++ b/en/engine/menu/naming_screen.asm
@@ -0,0 +1,512 @@
+AskName:
+ call SaveScreenTilesToBuffer1
+ call GetPredefRegisters
+ push hl
+ ld a, [wIsInBattle]
+ dec a
+ coord hl, 0, 0
+ ld b, 4
+ ld c, 11
+ call z, ClearScreenArea ; only if in wild battle
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, DoYouWantToNicknameText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ pop hl
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .declinedNickname
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ push hl
+ ld a, NAME_MON_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .inBattle
+ call ReloadMapSpriteTilePatterns
+.inBattle
+ call LoadScreenTilesFromBuffer1
+ pop hl
+ pop af
+ ld [wUpdateSpritesEnabled], a
+ ld a, [wcf4b]
+ cp "@"
+ ret nz
+.declinedNickname
+ ld d, h
+ ld e, l
+ ld hl, wcd6d
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+DoYouWantToNicknameText:
+ TX_FAR _DoYouWantToNicknameText
+ db "@"
+
+DisplayNameRaterScreen:
+ ld hl, wBuffer
+ xor a
+ ld [wUpdateSpritesEnabled], a
+ ld a, NAME_MON_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ call GBPalWhiteOutWithDelay3
+ call RestoreScreenTilesAndReloadTilePatterns
+ call LoadGBPal
+ ld a, [wcf4b]
+ cp "@"
+ jr z, .playerCancelled
+ ld hl, wPartyMonNicks
+ ld bc, NAME_LENGTH
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ld hl, wBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ and a
+ ret
+.playerCancelled
+ scf
+ ret
+
+DisplayNamingScreen:
+ push hl
+ ld hl, wd730
+ set 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+ call LoadHpBarAndStatusTilePatterns
+ call LoadEDTile
+ callba LoadMonPartySpriteGfx
+ coord hl, 0, 4
+ ld b, 9
+ ld c, 18
+ call TextBoxBorder
+ call PrintNamingText
+ ld a, 3
+ ld [wTopMenuItemY], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+ ld [wLastMenuItem], a
+ ld [wCurrentMenuItem], a
+ ld a, $ff
+ ld [wMenuWatchedKeys], a
+ ld a, 7
+ ld [wMaxMenuItem], a
+ ld a, "@"
+ ld [wcf4b], a
+ xor a
+ ld hl, wNamingScreenSubmitName
+ ld [hli], a
+ ld [hli], a
+ ld [wAnimCounter], a
+.selectReturnPoint
+ call PrintAlphabet
+ call GBPalNormal
+.ABStartReturnPoint
+ ld a, [wNamingScreenSubmitName]
+ and a
+ jr nz, .submitNickname
+ call PrintNicknameAndUnderscores
+.dPadReturnPoint
+ call PlaceMenuCursor
+.inputLoop
+ ld a, [wCurrentMenuItem]
+ push af
+ callba AnimatePartyMon_ForceSpeed1
+ pop af
+ ld [wCurrentMenuItem], a
+ call JoypadLowSensitivity
+ ld a, [hJoyPressed]
+ and a
+ jr z, .inputLoop
+ ld hl, .namingScreenButtonFunctions
+.checkForPressedButton
+ sla a
+ jr c, .foundPressedButton
+ inc hl
+ inc hl
+ inc hl
+ inc hl
+ jr .checkForPressedButton
+.foundPressedButton
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push de
+ jp hl
+
+.submitNickname
+ pop de
+ ld hl, wcf4b
+ ld bc, NAME_LENGTH
+ call CopyData
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call ClearSprites
+ call RunDefaultPaletteCommand
+ call GBPalNormal
+ xor a
+ ld [wAnimCounter], a
+ ld hl, wd730
+ res 6, [hl]
+ ld a, [wIsInBattle]
+ and a
+ jp z, LoadTextBoxTilePatterns
+ jpab LoadHudTilePatterns
+
+.namingScreenButtonFunctions
+ dw .dPadReturnPoint
+ dw .pressedDown
+ dw .dPadReturnPoint
+ dw .pressedUp
+ dw .dPadReturnPoint
+ dw .pressedLeft
+ dw .dPadReturnPoint
+ dw .pressedRight
+ dw .ABStartReturnPoint
+ dw .pressedStart
+ dw .selectReturnPoint
+ dw .pressedSelect
+ dw .ABStartReturnPoint
+ dw .pressedB
+ dw .ABStartReturnPoint
+ dw .pressedA
+
+.pressedA_changedCase
+ pop de
+ ld de, .selectReturnPoint
+ push de
+.pressedSelect
+ ld a, [wAlphabetCase]
+ xor $1
+ ld [wAlphabetCase], a
+ ret
+
+.pressedStart
+ ld a, 1
+ ld [wNamingScreenSubmitName], a
+ ret
+
+.pressedA
+ ld a, [wCurrentMenuItem]
+ cp $5 ; "ED" row
+ jr nz, .didNotPressED
+ ld a, [wTopMenuItemX]
+ cp $11 ; "ED" column
+ jr z, .pressedStart
+.didNotPressED
+ ld a, [wCurrentMenuItem]
+ cp $6 ; case switch row
+ jr nz, .didNotPressCaseSwtich
+ ld a, [wTopMenuItemX]
+ cp $1 ; case switch column
+ jr z, .pressedA_changedCase
+.didNotPressCaseSwtich
+ ld hl, wMenuCursorLocation
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ ld a, [hl]
+ ld [wNamingScreenLetter], a
+ call CalcStringLength
+ ld a, [wNamingScreenLetter]
+ cp $e5
+ ld de, Dakutens
+ jr z, .dakutensAndHandakutens
+ cp $e4
+ ld de, Handakutens
+ jr z, .dakutensAndHandakutens
+ ld a, [wNamingScreenType]
+ cp NAME_MON_SCREEN
+ jr nc, .checkMonNameLength
+ ld a, [wNamingScreenNameLength]
+ cp $7 ; max length of player/rival names
+ jr .checkNameLength
+.checkMonNameLength
+ ld a, [wNamingScreenNameLength]
+ cp $a ; max length of pokemon nicknames
+.checkNameLength
+ jr c, .addLetter
+ ret
+
+.dakutensAndHandakutens
+ push hl
+ call DakutensAndHandakutens
+ pop hl
+ ret nc
+ dec hl
+.addLetter
+ ld a, [wNamingScreenLetter]
+ ld [hli], a
+ ld [hl], "@"
+ ld a, SFX_PRESS_AB
+ call PlaySound
+ ret
+.pressedB
+ ld a, [wNamingScreenNameLength]
+ and a
+ ret z
+ call CalcStringLength
+ dec hl
+ ld [hl], "@"
+ ret
+.pressedRight
+ ld a, [wCurrentMenuItem]
+ cp $6
+ ret z ; can't scroll right on bottom row
+ ld a, [wTopMenuItemX]
+ cp $11 ; max
+ jp z, .wrapToFirstColumn
+ inc a
+ inc a
+ jr .done
+.wrapToFirstColumn
+ ld a, $1
+ jr .done
+.pressedLeft
+ ld a, [wCurrentMenuItem]
+ cp $6
+ ret z ; can't scroll right on bottom row
+ ld a, [wTopMenuItemX]
+ dec a
+ jp z, .wrapToLastColumn
+ dec a
+ jr .done
+.wrapToLastColumn
+ ld a, $11 ; max
+ jr .done
+.pressedUp
+ ld a, [wCurrentMenuItem]
+ dec a
+ ld [wCurrentMenuItem], a
+ and a
+ ret nz
+ ld a, $6 ; wrap to bottom row
+ ld [wCurrentMenuItem], a
+ ld a, $1 ; force left column
+ jr .done
+.pressedDown
+ ld a, [wCurrentMenuItem]
+ inc a
+ ld [wCurrentMenuItem], a
+ cp $7
+ jr nz, .wrapToTopRow
+ ld a, $1
+ ld [wCurrentMenuItem], a
+ jr .done
+.wrapToTopRow
+ cp $6
+ ret nz
+ ld a, $1
+.done
+ ld [wTopMenuItemX], a
+ jp EraseMenuCursor
+
+LoadEDTile:
+ ld de, ED_Tile
+ ld hl, vFont + $700
+ ld bc, (ED_TileEnd - ED_Tile) / $8
+ ; to fix the graphical bug on poor emulators
+ ;lb bc, BANK(ED_Tile), (ED_TileEnd - ED_Tile) / $8
+ jp CopyVideoDataDouble
+
+ED_Tile:
+ binlang gfx/ED_tile.1bpp
+ED_TileEnd:
+
+PrintAlphabet:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, [wAlphabetCase]
+ and a
+ ld de, LowerCaseAlphabet
+ jr nz, .lowercase
+ ld de, UpperCaseAlphabet
+.lowercase
+ coord hl, 2, 5
+ lb bc, 5, 9 ; 5 rows, 9 columns
+.outerLoop
+ push bc
+.innerLoop
+ ld a, [de]
+ ld [hli], a
+ inc hl
+ inc de
+ dec c
+ jr nz, .innerLoop
+ ld bc, SCREEN_WIDTH + 2
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .outerLoop
+ call PlaceString
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ jp Delay3
+
+LowerCaseAlphabet:
+ db "abcdefghijklmnopqrstuvwxyz ×():;[]",$e1,$e2,"-?!♂♀/⠄,¥UPPER CASE@"
+
+UpperCaseAlphabet:
+ db "ABCDEFGHIJKLMNOPQRSTUVWXYZ ×():;[]",$e1,$e2,"-?!♂♀/⠄,¥lower case@"
+
+PrintNicknameAndUnderscores:
+ call CalcStringLength
+ ld a, c
+ ld [wNamingScreenNameLength], a
+ coord hl, 10, 2
+ lb bc, 1, 10
+ call ClearScreenArea
+ coord hl, 10, 2
+ ld de, wcf4b
+ call PlaceString
+ coord hl, 10, 3
+ ld a, [wNamingScreenType]
+ cp NAME_MON_SCREEN
+ jr nc, .pokemon1
+ ld b, 7 ; player or rival max name length
+ jr .playerOrRival1
+.pokemon1
+ ld b, 10 ; pokemon max name length
+.playerOrRival1
+ ld a, $76 ; underscore tile id
+.placeUnderscoreLoop
+ ld [hli], a
+ dec b
+ jr nz, .placeUnderscoreLoop
+ ld a, [wNamingScreenType]
+ cp NAME_MON_SCREEN
+ ld a, [wNamingScreenNameLength]
+ jr nc, .pokemon2
+ cp 7 ; player or rival max name length
+ jr .playerOrRival2
+.pokemon2
+ cp 10 ; pokemon max name length
+.playerOrRival2
+ jr nz, .emptySpacesRemaining
+ ; when all spaces are filled, force the cursor onto the ED tile
+ call EraseMenuCursor
+ ld a, $11 ; "ED" x coord
+ ld [wTopMenuItemX], a
+ ld a, $5 ; "ED" y coord
+ ld [wCurrentMenuItem], a
+ ld a, [wNamingScreenType]
+ cp NAME_MON_SCREEN
+ ld a, 9 ; keep the last underscore raised
+ jr nc, .pokemon3
+ ld a, 6 ; keep the last underscore raised
+.pokemon3
+.emptySpacesRemaining
+ ld c, a
+ ld b, $0
+ coord hl, 10, 3
+ add hl, bc
+ ld [hl], $77 ; raised underscore tile id
+ ret
+
+DakutensAndHandakutens:
+ push de
+ call CalcStringLength
+ dec hl
+ ld a, [hl]
+ pop hl
+ ld de, $2
+ call IsInArray
+ ret nc
+ inc hl
+ ld a, [hl]
+ ld [wNamingScreenLetter], a
+ ret
+
+Dakutens:
+ db "かが", "きぎ", "くぐ", "けげ", "こご"
+ db "さざ", "しじ", "すず", "せぜ", "そぞ"
+ db "ただ", "ちぢ", "つづ", "てで", "とど"
+ db "はば", "ひび", "ふぶ", "へべ", "ほぼ"
+ db "カガ", "キギ", "クグ", "ケゲ", "コゴ"
+ db "サザ", "シジ", "スズ", "セゼ", "ソゾ"
+ db "タダ", "チヂ", "ツヅ", "テデ", "トド"
+ db "ハバ", "ヒビ", "フブ", "へべ", "ホボ"
+ db $ff
+
+Handakutens:
+ db "はぱ", "ひぴ", "ふぷ", "へぺ", "ほぽ"
+ db "ハパ", "ヒピ", "フプ", "へぺ", "ホポ"
+ db $ff
+
+; calculates the length of the string at wcf4b and stores it in c
+CalcStringLength:
+ ld hl, wcf4b
+ ld c, $0
+.loop
+ ld a, [hl]
+ cp "@"
+ ret z
+ inc hl
+ inc c
+ jr .loop
+
+PrintNamingText:
+ coord hl, 0, 1
+ ld a, [wNamingScreenType]
+ ld de, YourTextString
+ and a
+ jr z, .notNickname
+ ld de, RivalsTextString
+ dec a
+ jr z, .notNickname
+ ld a, [wcf91]
+ ld [wMonPartySpriteSpecies], a
+ push af
+ callba WriteMonPartySpriteOAMBySpecies
+ pop af
+ ld [wd11e], a
+ call GetMonName
+ coord hl, 4, 1
+ call PlaceString
+ ld hl, $1
+ add hl, bc
+ ld [hl], $c9
+ coord hl, 1, 3
+ ld de, NicknameTextString
+ jr .placeString
+.notNickname
+ call PlaceString
+ ld l, c
+ ld h, b
+ ld de, NameTextString
+.placeString
+ jp PlaceString
+
+YourTextString:
+ db "YOUR @"
+
+RivalsTextString:
+ db "RIVAL's @"
+
+NameTextString:
+ db "NAME?@"
+
+NicknameTextString:
+ db "NICKNAME?@"
diff --git a/en/engine/menu/party_menu.asm b/en/engine/menu/party_menu.asm
new file mode 100755
index 00000000..8323d0eb
--- /dev/null
+++ b/en/engine/menu/party_menu.asm
@@ -0,0 +1,325 @@
+; [wPartyMenuTypeOrMessageID] = menu type / message ID
+; if less than $F0, it is a menu type
+; menu types:
+; 00: normal pokemon menu (e.g. Start menu)
+; 01: use healing item on pokemon menu
+; 02: in-battle switch pokemon menu
+; 03: learn TM/HM menu
+; 04: swap pokemon positions menu
+; 05: use evolution stone on pokemon menu
+; otherwise, it is a message ID
+; f0: poison healed
+; f1: burn healed
+; f2: freeze healed
+; f3: sleep healed
+; f4: paralysis healed
+; f5: HP healed
+; f6: health returned
+; f7: revitalized
+; f8: leveled up
+DrawPartyMenu_:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ call UpdateSprites
+ callba LoadMonPartySpriteGfxWithLCDDisabled ; load pokemon icon graphics
+
+RedrawPartyMenu_:
+ ld a, [wPartyMenuTypeOrMessageID]
+ cp SWAP_MONS_PARTY_MENU
+ jp z, .printMessage
+ call ErasePartyMenuCursors
+ callba InitPartyMenuBlkPacket
+ coord hl, 3, 0
+ ld de, wPartySpecies
+ xor a
+ ld c, a
+ ld [hPartyMonIndex], a
+ ld [wWhichPartyMenuHPBar], a
+.loop
+ ld a, [de]
+ cp $FF ; reached the terminator?
+ jp z, .afterDrawingMonEntries
+ push bc
+ push de
+ push hl
+ ld a, c
+ push hl
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ pop hl
+ call PlaceString ; print the pokemon's name
+ callba WriteMonPartySpriteOAMByPartyIndex ; place the appropriate pokemon icon
+ ld a, [hPartyMonIndex]
+ ld [wWhichPokemon], a
+ inc a
+ ld [hPartyMonIndex], a
+ call LoadMonData
+ pop hl
+ push hl
+ ld a, [wMenuItemToSwap]
+ and a ; is the player swapping pokemon positions?
+ jr z, .skipUnfilledRightArrow
+; if the player is swapping pokemon positions
+ dec a
+ ld b, a
+ ld a, [wWhichPokemon]
+ cp b ; is the player swapping the current pokemon in the list?
+ jr nz, .skipUnfilledRightArrow
+; the player is swapping the current pokemon in the list
+ dec hl
+ dec hl
+ dec hl
+ ld a, "▷" ; unfilled right arrow menu cursor
+ ld [hli], a ; place the cursor
+ inc hl
+ inc hl
+.skipUnfilledRightArrow
+ ld a, [wPartyMenuTypeOrMessageID] ; menu type
+ cp TMHM_PARTY_MENU
+ jr z, .teachMoveMenu
+ cp EVO_STONE_PARTY_MENU
+ jr z, .evolutionStoneMenu
+ push hl
+ ld bc, 14 ; 14 columns to the right
+ add hl, bc
+ ld de, wLoadedMonStatus
+ call PrintStatusCondition
+ pop hl
+ push hl
+ ld bc, SCREEN_WIDTH + 1 ; down 1 row and right 1 column
+ ld a, [hFlags_0xFFF6]
+ set 0, a
+ ld [hFlags_0xFFF6], a
+ add hl, bc
+ predef DrawHP2 ; draw HP bar and prints current / max HP
+ ld a, [hFlags_0xFFF6]
+ res 0, a
+ ld [hFlags_0xFFF6], a
+ call SetPartyMenuHPBarColor ; color the HP bar (on SGB)
+ pop hl
+ jr .printLevel
+.teachMoveMenu
+ push hl
+ predef CanLearnTM ; check if the pokemon can learn the move
+ pop hl
+ ld de, .ableToLearnMoveText
+ ld a, c
+ and a
+ jr nz, .placeMoveLearnabilityString
+ ld de, .notAbleToLearnMoveText
+.placeMoveLearnabilityString
+ ld bc, 20 + 9 ; down 1 row and right 9 columns
+ push hl
+ add hl, bc
+ call PlaceString
+ pop hl
+.printLevel
+ ld bc, 10 ; move 10 columns to the right
+ add hl, bc
+ call PrintLevel
+ pop hl
+ pop de
+ inc de
+ ld bc, 2 * 20
+ add hl, bc
+ pop bc
+ inc c
+ jp .loop
+.ableToLearnMoveText
+ db "ABLE@"
+.notAbleToLearnMoveText
+ db "NOT ABLE@"
+.evolutionStoneMenu
+ push hl
+ ld hl, EvosMovesPointerTable
+ ld b, 0
+ ld a, [wLoadedMonSpecies]
+ dec a
+ add a
+ rl b
+ ld c, a
+ add hl, bc
+ ld de, wEvosMoves
+ ld a, BANK(EvosMovesPointerTable)
+ ld bc, 2
+ call FarCopyData
+ ld hl, wEvosMoves
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wEvosMoves
+ ld a, BANK(EvosMovesPointerTable)
+ ld bc, wEvosMoves.end - wEvosMoves
+ call FarCopyData
+ ld hl, wEvosMoves
+ ld de, .notAbleToEvolveText
+; loop through the pokemon's evolution entries
+.checkEvolutionsLoop
+ ld a, [hli]
+ and a ; reached terminator?
+ jr z, .placeEvolutionStoneString ; if so, place the "NOT ABLE" string
+ inc hl
+ inc hl
+ cp EV_ITEM
+ jr nz, .checkEvolutionsLoop
+; if it's a stone evolution entry
+ dec hl
+ dec hl
+ ld b, [hl]
+ ld a, [wEvoStoneItemID] ; the stone the player used
+ inc hl
+ inc hl
+ inc hl
+ cp b ; does the player's stone match this evolution entry's stone?
+ jr nz, .checkEvolutionsLoop
+; if it does match
+ ld de, .ableToEvolveText
+.placeEvolutionStoneString
+ ld bc, 20 + 9 ; down 1 row and right 9 columns
+ pop hl
+ push hl
+ add hl, bc
+ call PlaceString
+ pop hl
+ jr .printLevel
+.ableToEvolveText
+ db "ABLE@"
+.notAbleToEvolveText
+ db "NOT ABLE@"
+.afterDrawingMonEntries
+ ld b, SET_PAL_PARTY_MENU
+ call RunPaletteCommand
+.printMessage
+ ld hl, wd730
+ ld a, [hl]
+ push af
+ push hl
+ set 6, [hl] ; turn off letter printing delay
+ ld a, [wPartyMenuTypeOrMessageID] ; message ID
+ cp $F0
+ jr nc, .printItemUseMessage
+ add a
+ ld hl, PartyMenuMessagePointers
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+.done
+ pop hl
+ pop af
+ ld [hl], a
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ jp GBPalNormal
+.printItemUseMessage
+ and $0F
+ ld hl, PartyMenuItemUseMessagePointers
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ ld a, [wUsedItemOnWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ pop hl
+ call PrintText
+ jr .done
+
+PartyMenuItemUseMessagePointers:
+ dw AntidoteText
+ dw BurnHealText
+ dw IceHealText
+ dw AwakeningText
+ dw ParlyzHealText
+ dw PotionText
+ dw FullHealText
+ dw ReviveText
+ dw RareCandyText
+
+PartyMenuMessagePointers:
+ dw PartyMenuNormalText
+ dw PartyMenuItemUseText
+ dw PartyMenuBattleText
+ dw PartyMenuUseTMText
+ dw PartyMenuSwapMonText
+ dw PartyMenuItemUseText
+
+PartyMenuNormalText:
+ TX_FAR _PartyMenuNormalText
+ db "@"
+
+PartyMenuItemUseText:
+ TX_FAR _PartyMenuItemUseText
+ db "@"
+
+PartyMenuBattleText:
+ TX_FAR _PartyMenuBattleText
+ db "@"
+
+PartyMenuUseTMText:
+ TX_FAR _PartyMenuUseTMText
+ db "@"
+
+PartyMenuSwapMonText:
+ TX_FAR _PartyMenuSwapMonText
+ db "@"
+
+PotionText:
+ TX_FAR _PotionText
+ db "@"
+
+AntidoteText:
+ TX_FAR _AntidoteText
+ db "@"
+
+ParlyzHealText:
+ TX_FAR _ParlyzHealText
+ db "@"
+
+BurnHealText:
+ TX_FAR _BurnHealText
+ db "@"
+
+IceHealText:
+ TX_FAR _IceHealText
+ db "@"
+
+AwakeningText:
+ TX_FAR _AwakeningText
+ db "@"
+
+FullHealText:
+ TX_FAR _FullHealText
+ db "@"
+
+ReviveText:
+ TX_FAR _ReviveText
+ db "@"
+
+RareCandyText:
+ TX_FAR _RareCandyText
+ TX_SFX_ITEM_1 ; probably supposed to play SFX_LEVEL_UP but the wrong music bank is loaded
+ TX_BLINK
+ db "@"
+
+SetPartyMenuHPBarColor:
+ ld hl, wPartyMenuHPBarColors
+ ld a, [wWhichPartyMenuHPBar]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ call GetHealthBarColor
+ ld b, UPDATE_PARTY_MENU_BLK_PACKET
+ call RunPaletteCommand
+ ld hl, wWhichPartyMenuHPBar
+ inc [hl]
+ ret
diff --git a/en/engine/menu/players_pc.asm b/en/engine/menu/players_pc.asm
new file mode 100755
index 00000000..bc2be4ef
--- /dev/null
+++ b/en/engine/menu/players_pc.asm
@@ -0,0 +1,303 @@
+PlayerPC:
+ ld hl, wd730
+ set 6, [hl]
+ ld a, ITEM_NAME
+ ld [wNameListType], a
+ call SaveScreenTilesToBuffer1
+ xor a
+ ld [wBagSavedMenuItem], a
+ ld [wParentMenuItem], a
+ ld a, [wFlags_0xcd60]
+ bit 3, a ; accessing player's PC through another PC?
+ jr nz, PlayerPCMenu
+; accessing it directly
+ ld a, SFX_TURN_ON_PC
+ call PlaySound
+ ld hl, TurnedOnPC2Text
+ call PrintText
+
+PlayerPCMenu:
+ ld a, [wParentMenuItem]
+ ld [wCurrentMenuItem], a
+ ld hl, wFlags_0xcd60
+ set 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ coord hl, 0, 0
+ ld b, $8
+ ld c, $e
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 2, 2
+ ld de, PlayersPCMenuEntries
+ call PlaceString
+ ld hl, wTopMenuItemY
+ ld a, 2
+ ld [hli], a ; wTopMenuItemY
+ dec a
+ ld [hli], a ; wTopMenuItemX
+ inc hl
+ inc hl
+ ld a, 3
+ ld [hli], a ; wMaxMenuItem
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; wMenuWatchedKeys
+ xor a
+ ld [hl], a
+ ld hl, wListScrollOffset
+ ld [hli], a ; wListScrollOffset
+ ld [hl], a ; wMenuWatchMovingOutOfBounds
+ ld [wPlayerMonNumber], a
+ ld hl, WhatDoYouWantText
+ call PrintText
+ call HandleMenuInput
+ bit 1, a
+ jp nz, ExitPlayerPC
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem]
+ ld [wParentMenuItem], a
+ and a
+ jp z, PlayerPCWithdraw
+ dec a
+ jp z, PlayerPCDeposit
+ dec a
+ jp z, PlayerPCToss
+
+ExitPlayerPC:
+ ld a, [wFlags_0xcd60]
+ bit 3, a ; accessing player's PC through another PC?
+ jr nz, .next
+; accessing it directly
+ ld a, SFX_TURN_OFF_PC
+ call PlaySound
+ call WaitForSoundToFinish
+.next
+ ld hl, wFlags_0xcd60
+ res 5, [hl]
+ call LoadScreenTilesFromBuffer2
+ xor a
+ ld [wListScrollOffset], a
+ ld [wBagSavedMenuItem], a
+ ld hl, wd730
+ res 6, [hl]
+ xor a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ret
+
+PlayerPCDeposit:
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wListScrollOffset], a
+ ld a, [wNumBagItems]
+ and a
+ jr nz, .loop
+ ld hl, NothingToDepositText
+ call PrintText
+ jp PlayerPCMenu
+.loop
+ ld hl, WhatToDepositText
+ call PrintText
+ ld hl, wNumBagItems
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ call DisplayListMenuID
+ jp c, PlayerPCMenu
+ call IsKeyItem
+ ld a, 1
+ ld [wItemQuantity], a
+ ld a, [wIsKeyItem]
+ and a
+ jr nz, .next
+; if it's not a key item, there can be more than one of the item
+ ld hl, DepositHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ cp $ff
+ jp z, .loop
+.next
+ ld hl, wNumBoxItems
+ call AddItemToInventory
+ jr c, .roomAvailable
+ ld hl, NoRoomToStoreText
+ call PrintText
+ jp .loop
+.roomAvailable
+ ld hl, wNumBagItems
+ call RemoveItemFromInventory
+ call WaitForSoundToFinish
+ ld a, SFX_WITHDRAW_DEPOSIT
+ call PlaySound
+ call WaitForSoundToFinish
+ ld hl, ItemWasStoredText
+ call PrintText
+ jp .loop
+
+PlayerPCWithdraw:
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wListScrollOffset], a
+ ld a, [wNumBoxItems]
+ and a
+ jr nz, .loop
+ ld hl, NothingStoredText
+ call PrintText
+ jp PlayerPCMenu
+.loop
+ ld hl, WhatToWithdrawText
+ call PrintText
+ ld hl, wNumBoxItems
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ call DisplayListMenuID
+ jp c, PlayerPCMenu
+ call IsKeyItem
+ ld a, 1
+ ld [wItemQuantity], a
+ ld a, [wIsKeyItem]
+ and a
+ jr nz, .next
+; if it's not a key item, there can be more than one of the item
+ ld hl, WithdrawHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ cp $ff
+ jp z, .loop
+.next
+ ld hl, wNumBagItems
+ call AddItemToInventory
+ jr c, .roomAvailable
+ ld hl, CantCarryMoreText
+ call PrintText
+ jp .loop
+.roomAvailable
+ ld hl, wNumBoxItems
+ call RemoveItemFromInventory
+ call WaitForSoundToFinish
+ ld a, SFX_WITHDRAW_DEPOSIT
+ call PlaySound
+ call WaitForSoundToFinish
+ ld hl, WithdrewItemText
+ call PrintText
+ jp .loop
+
+PlayerPCToss:
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wListScrollOffset], a
+ ld a, [wNumBoxItems]
+ and a
+ jr nz, .loop
+ ld hl, NothingStoredText
+ call PrintText
+ jp PlayerPCMenu
+.loop
+ ld hl, WhatToTossText
+ call PrintText
+ ld hl, wNumBoxItems
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ push hl
+ call DisplayListMenuID
+ pop hl
+ jp c, PlayerPCMenu
+ push hl
+ call IsKeyItem
+ pop hl
+ ld a, 1
+ ld [wItemQuantity], a
+ ld a, [wIsKeyItem]
+ and a
+ jr nz, .next
+ ld a, [wcf91]
+ call IsItemHM
+ jr c, .next
+; if it's not a key item, there can be more than one of the item
+ push hl
+ ld hl, TossHowManyText
+ call PrintText
+ call DisplayChooseQuantityMenu
+ pop hl
+ cp $ff
+ jp z, .loop
+.next
+ call TossItem ; disallows tossing key items
+ jp .loop
+
+PlayersPCMenuEntries:
+ db "WITHDRAW ITEM"
+ next "DEPOSIT ITEM"
+ next "TOSS ITEM"
+ next "LOG OFF@"
+
+TurnedOnPC2Text:
+ TX_FAR _TurnedOnPC2Text
+ db "@"
+
+WhatDoYouWantText:
+ TX_FAR _WhatDoYouWantText
+ db "@"
+
+WhatToDepositText:
+ TX_FAR _WhatToDepositText
+ db "@"
+
+DepositHowManyText:
+ TX_FAR _DepositHowManyText
+ db "@"
+
+ItemWasStoredText:
+ TX_FAR _ItemWasStoredText
+ db "@"
+
+NothingToDepositText:
+ TX_FAR _NothingToDepositText
+ db "@"
+
+NoRoomToStoreText:
+ TX_FAR _NoRoomToStoreText
+ db "@"
+
+WhatToWithdrawText:
+ TX_FAR _WhatToWithdrawText
+ db "@"
+
+WithdrawHowManyText:
+ TX_FAR _WithdrawHowManyText
+ db "@"
+
+WithdrewItemText:
+ TX_FAR _WithdrewItemText
+ db "@"
+
+NothingStoredText:
+ TX_FAR _NothingStoredText
+ db "@"
+
+CantCarryMoreText:
+ TX_FAR _CantCarryMoreText
+ db "@"
+
+WhatToTossText:
+ TX_FAR _WhatToTossText
+ db "@"
+
+TossHowManyText:
+ TX_FAR _TossHowManyText
+ db "@"
diff --git a/en/engine/menu/pokedex.asm b/en/engine/menu/pokedex.asm
new file mode 100755
index 00000000..6a3ea959
--- /dev/null
+++ b/en/engine/menu/pokedex.asm
@@ -0,0 +1,665 @@
+ShowPokedexMenu:
+ call GBPalWhiteOut
+ call ClearScreen
+ call UpdateSprites
+ ld a, [wListScrollOffset]
+ push af
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wListScrollOffset], a
+ ld [wLastMenuItem], a
+ inc a
+ ld [wd11e], a
+ ld [hJoy7], a
+.setUpGraphics
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+ callab LoadPokedexTilePatterns
+.doPokemonListMenu
+ ld hl, wTopMenuItemY
+ ld a, 3
+ ld [hli], a ; top menu item Y
+ xor a
+ ld [hli], a ; top menu item X
+ inc a
+ ld [wMenuWatchMovingOutOfBounds], a
+ inc hl
+ inc hl
+ ld a, 6
+ ld [hli], a ; max menu item ID
+ ld [hl], D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON
+ call HandlePokedexListMenu
+ jr c, .goToSideMenu ; if the player chose a pokemon from the list
+.exitPokedex
+ xor a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [hJoy7], a
+ ld [wWastedByteCD3A], a
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ pop af
+ ld [wListScrollOffset], a
+ call GBPalWhiteOutWithDelay3
+ call RunDefaultPaletteCommand
+ jp ReloadMapData
+.goToSideMenu
+ call HandlePokedexSideMenu
+ dec b
+ jr z, .exitPokedex ; if the player chose Quit
+ dec b
+ jr z, .doPokemonListMenu ; if pokemon not seen or player pressed B button
+ jp .setUpGraphics ; if pokemon data or area was shown
+
+; handles the menu on the lower right in the pokedex screen
+; OUTPUT:
+; b = reason for exiting menu
+; 00: showed pokemon data or area
+; 01: the player chose Quit
+; 02: the pokemon has not been seen yet or the player pressed the B button
+HandlePokedexSideMenu:
+ call PlaceUnfilledArrowMenuCursor
+ ld a, [wCurrentMenuItem]
+ push af
+ ld b, a
+ ld a, [wLastMenuItem]
+ push af
+ ld a, [wListScrollOffset]
+ push af
+ add b
+ inc a
+ ld [wd11e], a
+ ld a, [wd11e]
+ push af
+ ld a, [wDexMaxSeenMon]
+ push af ; this doesn't need to be preserved
+ ld hl, wPokedexSeen
+ call IsPokemonBitSet
+ ld b, 2
+ jr z, .exitSideMenu
+ call PokedexToIndex
+ ld hl, wTopMenuItemY
+ ld a, 10
+ ld [hli], a ; top menu item Y
+ ld a, 15
+ ld [hli], a ; top menu item X
+ xor a
+ ld [hli], a ; current menu item ID
+ inc hl
+ ld a, 3
+ ld [hli], a ; max menu item ID
+ ;ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; menu watched keys (A button and B button)
+ xor a
+ ld [hli], a ; old menu item ID
+ ld [wMenuWatchMovingOutOfBounds], a
+.handleMenuInput
+ call HandleMenuInput
+ bit 1, a ; was the B button pressed?
+ ld b, 2
+ jr nz, .buttonBPressed
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .choseData
+ dec a
+ jr z, .choseCry
+ dec a
+ jr z, .choseArea
+.choseQuit
+ ld b, 1
+.exitSideMenu
+ pop af
+ ld [wDexMaxSeenMon], a
+ pop af
+ ld [wd11e], a
+ pop af
+ ld [wListScrollOffset], a
+ pop af
+ ld [wLastMenuItem], a
+ pop af
+ ld [wCurrentMenuItem], a
+ push bc
+ coord hl, 0, 3
+ ld de, 20
+ lb bc, " ", 13
+ call DrawTileLine ; cover up the menu cursor in the pokemon list
+ pop bc
+ ret
+
+.buttonBPressed
+ push bc
+ coord hl, 15, 10
+ ld de, 20
+ lb bc, " ", 7
+ call DrawTileLine ; cover up the menu cursor in the side menu
+ pop bc
+ jr .exitSideMenu
+
+.choseData
+ call ShowPokedexDataInternal
+ ld b, 0
+ jr .exitSideMenu
+
+; play pokemon cry
+.choseCry
+ ld a, [wd11e]
+ call GetCryData
+ call PlaySound
+ jr .handleMenuInput
+
+.choseArea
+ predef LoadTownMap_Nest ; display pokemon areas
+ ld b, 0
+ jr .exitSideMenu
+
+; handles the list of pokemon on the left of the pokedex screen
+; sets carry flag if player presses A, unsets carry flag if player presses B
+HandlePokedexListMenu:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+; draw the horizontal line separating the seen and owned amounts from the menu
+ coord hl, 15, 8
+ ld a, "─"
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ coord hl, 14, 0
+ ld [hl], $71 ; vertical line tile
+ coord hl, 14, 1
+ call DrawPokedexVerticalLine
+ coord hl, 14, 9
+ call DrawPokedexVerticalLine
+ ld hl, wPokedexSeen
+ ld b, wPokedexSeenEnd - wPokedexSeen
+ call CountSetBits
+ ld de, wNumSetBits
+ coord hl, 16, 3
+ lb bc, 1, 3
+ call PrintNumber ; print number of seen pokemon
+ ld hl, wPokedexOwned
+ ld b, wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ ld de, wNumSetBits
+ coord hl, 16, 6
+ lb bc, 1, 3
+ call PrintNumber ; print number of owned pokemon
+ coord hl, 16, 2
+ ld de, PokedexSeenText
+ call PlaceString
+ coord hl, 16, 5
+ ld de, PokedexOwnText
+ call PlaceString
+ coord hl, 1, 1
+ ld de, PokedexContentsText
+ call PlaceString
+ coord hl, 16, 10
+ ld de, PokedexMenuItemsText
+ call PlaceString
+; find the highest pokedex number among the pokemon the player has seen
+ ld hl, wPokedexSeenEnd - 1
+ ld b, (wPokedexSeenEnd - wPokedexSeen) * 8 + 1
+.maxSeenPokemonLoop
+ ld a, [hld]
+ ld c, 8
+.maxSeenPokemonInnerLoop
+ dec b
+ sla a
+ jr c, .storeMaxSeenPokemon
+ dec c
+ jr nz, .maxSeenPokemonInnerLoop
+ jr .maxSeenPokemonLoop
+
+.storeMaxSeenPokemon
+ ld a, b
+ ld [wDexMaxSeenMon], a
+.loop
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 4, 2
+ lb bc, 14, 10
+ call ClearScreenArea
+ coord hl, 1, 3
+ ld a, [wListScrollOffset]
+ ld [wd11e], a
+ ld d, 7
+ ld a, [wDexMaxSeenMon]
+ cp 7
+ jr nc, .printPokemonLoop
+ ld d, a
+ dec a
+ ld [wMaxMenuItem], a
+; loop to print pokemon pokedex numbers and names
+; if the player has owned the pokemon, it puts a pokeball beside the name
+.printPokemonLoop
+ ld a, [wd11e]
+ inc a
+ ld [wd11e], a
+ push af
+ push de
+ push hl
+ ld de, -SCREEN_WIDTH
+ add hl, de
+ ld de, wd11e
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber ; print the pokedex number
+ ld de, SCREEN_WIDTH
+ add hl, de
+ dec hl
+ push hl
+ ld hl, wPokedexOwned
+ call IsPokemonBitSet
+ pop hl
+ ld a, " "
+ jr z, .writeTile
+ ld a, $72 ; pokeball tile
+.writeTile
+ ld [hl], a ; put a pokeball next to pokemon that the player has owned
+ push hl
+ ld hl, wPokedexSeen
+ call IsPokemonBitSet
+ jr nz, .getPokemonName ; if the player has seen the pokemon
+ ld de, .dashedLine ; print a dashed line in place of the name if the player hasn't seen the pokemon
+ jr .skipGettingName
+.dashedLine ; for unseen pokemon in the list
+ db "----------@"
+.getPokemonName
+ call PokedexToIndex
+ call GetMonName
+.skipGettingName
+ pop hl
+ inc hl
+ call PlaceString
+ pop hl
+ ld bc, 2 * SCREEN_WIDTH
+ add hl, bc
+ pop de
+ pop af
+ ld [wd11e], a
+ dec d
+ jr nz, .printPokemonLoop
+ ld a, 01
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ call GBPalNormal
+ call HandleMenuInput
+ bit 1, a ; was the B button pressed?
+ jp nz, .buttonBPressed
+.checkIfUpPressed
+ bit 6, a ; was Up pressed?
+ jr z, .checkIfDownPressed
+.upPressed ; scroll up one row
+ ld a, [wListScrollOffset]
+ and a
+ jp z, .loop
+ dec a
+ ld [wListScrollOffset], a
+ jp .loop
+.checkIfDownPressed
+ bit 7, a ; was Down pressed?
+ jr z, .checkIfRightPressed
+.downPressed ; scroll down one row
+ ld a, [wDexMaxSeenMon]
+ cp 7
+ jp c, .loop ; can't if the list is shorter than 7
+ sub 7
+ ld b, a
+ ld a, [wListScrollOffset]
+ cp b
+ jp z, .loop
+ inc a
+ ld [wListScrollOffset], a
+ jp .loop
+.checkIfRightPressed
+ bit 4, a ; was Right pressed?
+ jr z, .checkIfLeftPressed
+.rightPressed ; scroll down 7 rows
+ ld a, [wDexMaxSeenMon]
+ cp 7
+ jp c, .loop ; can't if the list is shorter than 7
+ sub 6
+ ld b, a
+ ld a, [wListScrollOffset]
+ add 7
+ ld [wListScrollOffset], a
+ cp b
+ jp c, .loop
+ dec b
+ ld a, b
+ ld [wListScrollOffset], a
+ jp .loop
+.checkIfLeftPressed ; scroll up 7 rows
+ bit 5, a ; was Left pressed?
+ jr z, .buttonAPressed
+.leftPressed
+ ld a, [wListScrollOffset]
+ sub 7
+ ld [wListScrollOffset], a
+ jp nc, .loop
+ xor a
+ ld [wListScrollOffset], a
+ jp .loop
+.buttonAPressed
+ scf
+ ret
+.buttonBPressed
+ and a
+ ret
+
+DrawPokedexVerticalLine:
+ ld c, 9 ; height of line
+ ld de, SCREEN_WIDTH
+ ld a, $71 ; vertical line tile
+.loop
+ ld [hl], a
+ add hl, de
+ xor 1 ; toggle between vertical line tile and box tile
+ dec c
+ jr nz, .loop
+ ret
+
+PokedexSeenText:
+ db "SEEN@"
+
+PokedexOwnText:
+ db "OWN@"
+
+PokedexContentsText:
+ db "CONTENTS@"
+
+PokedexMenuItemsText:
+ db "DATA"
+ next "CRY"
+ next "AREA"
+ next "QUIT@"
+
+; tests if a pokemon's bit is set in the seen or owned pokemon bit fields
+; INPUT:
+; [wd11e] = pokedex number
+; hl = address of bit field
+IsPokemonBitSet:
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, FLAG_TEST
+ predef FlagActionPredef
+ ld a, c
+ and a
+ ret
+
+; function to display pokedex data from outside the pokedex
+ShowPokedexData:
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ callab LoadPokedexTilePatterns ; load pokedex tiles
+
+; function to display pokedex data from inside the pokedex
+ShowPokedexDataInternal:
+ ld hl, wd72c
+ set 1, [hl]
+ ld a, $33 ; 3/7 volume
+ ld [rNR50], a
+ call GBPalWhiteOut ; zero all palettes
+ call ClearScreen
+ ld a, [wd11e] ; pokemon ID
+ ld [wcf91], a
+ push af
+ ld b, SET_PAL_POKEDEX
+ call RunPaletteCommand
+ pop af
+ ld [wd11e], a
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+
+ coord hl, 0, 0
+ ld de, 1
+ lb bc, $64, SCREEN_WIDTH
+ call DrawTileLine ; draw top border
+
+ coord hl, 0, 17
+ ld b, $6f
+ call DrawTileLine ; draw bottom border
+
+ coord hl, 0, 1
+ ld de, 20
+ lb bc, $66, $10
+ call DrawTileLine ; draw left border
+
+ coord hl, 19, 1
+ ld b, $67
+ call DrawTileLine ; draw right border
+
+ ld a, $63 ; upper left corner tile
+ Coorda 0, 0
+ ld a, $65 ; upper right corner tile
+ Coorda 19, 0
+ ld a, $6c ; lower left corner tile
+ Coorda 0, 17
+ ld a, $6e ; lower right corner tile
+ Coorda 19, 17
+
+ coord hl, 0, 9
+ ld de, PokedexDataDividerLine
+ call PlaceString ; draw horizontal divider line
+
+ coord hl, 9, 6
+ ld de, HeightWeightText
+ call PlaceString
+
+ call GetMonName
+ coord hl, 9, 2
+ call PlaceString
+
+ ld hl, PokedexEntryPointers
+ ld a, [wd11e]
+ dec a
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld d, [hl] ; de = address of pokedex entry
+
+ coord hl, 9, 4
+ call PlaceString ; print species name
+
+ ld h, b
+ ld l, c
+ push de
+ ld a, [wd11e]
+ push af
+ call IndexToPokedex
+
+ coord hl, 2, 8
+ ld a, "№"
+ ld [hli], a
+ ld a, "⠄"
+ ld [hli], a
+ ld de, wd11e
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber ; print pokedex number
+
+ ld hl, wPokedexOwned
+ call IsPokemonBitSet
+ pop af
+ ld [wd11e], a
+ ld a, [wcf91]
+ ld [wd0b5], a
+ pop de
+
+ push af
+ push bc
+ push de
+ push hl
+
+ call Delay3
+ call GBPalNormal
+ call GetMonHeader ; load pokemon picture location
+ coord hl, 1, 1
+ call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
+ ld a, [wcf91]
+ call PlayCry ; play pokemon cry
+
+ pop hl
+ pop de
+ pop bc
+ pop af
+
+ ld a, c
+ and a
+ jp z, .waitForButtonPress ; if the pokemon has not been owned, don't print the height, weight, or description
+ inc de ; de = address of feet (height)
+ ld a, [de] ; reads feet, but a is overwritten without being used
+ coord hl, 12, 6
+ lb bc, 1, 2
+ call PrintNumber ; print feet (height)
+ ld a, $60 ; feet symbol tile (one tick)
+ ld [hl], a
+ inc de
+ inc de ; de = address of inches (height)
+ coord hl, 15, 6
+ lb bc, LEADING_ZEROES | 1, 2
+ call PrintNumber ; print inches (height)
+ ld a, $61 ; inches symbol tile (two ticks)
+ ld [hl], a
+; now print the weight (note that weight is stored in tenths of pounds internally)
+ inc de
+ inc de
+ inc de ; de = address of upper byte of weight
+ push de
+; put weight in big-endian order at hDexWeight
+ ld hl, hDexWeight
+ ld a, [hl] ; save existing value of [hDexWeight]
+ push af
+ ld a, [de] ; a = upper byte of weight
+ ld [hli], a ; store upper byte of weight in [hDexWeight]
+ ld a, [hl] ; save existing value of [hDexWeight + 1]
+ push af
+ dec de
+ ld a, [de] ; a = lower byte of weight
+ ld [hl], a ; store lower byte of weight in [hDexWeight + 1]
+ ld de, hDexWeight
+ coord hl, 11, 8
+ lb bc, 2, 5 ; 2 bytes, 5 digits
+ call PrintNumber ; print weight
+ coord hl, 14, 8
+ ld a, [hDexWeight + 1]
+ sub 10
+ ld a, [hDexWeight]
+ sbc 0
+ jr nc, .next
+ ld [hl], "0" ; if the weight is less than 10, put a 0 before the decimal point
+.next
+ inc hl
+ ld a, [hli]
+ ld [hld], a ; make space for the decimal point by moving the last digit forward one tile
+ ld [hl], "⠄" ; decimal point tile
+ pop af
+ ld [hDexWeight + 1], a ; restore original value of [hDexWeight + 1]
+ pop af
+ ld [hDexWeight], a ; restore original value of [hDexWeight]
+ pop hl
+ inc hl ; hl = address of pokedex description text
+ coord bc, 1, 11
+ ld a, 2
+ ld [$fff4], a
+ call TextCommandProcessor ; print pokedex description text
+ xor a
+ ld [$fff4], a
+.waitForButtonPress
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ and A_BUTTON | B_BUTTON
+ jr z, .waitForButtonPress
+ pop af
+ ld [hTilesetType], a
+ call GBPalWhiteOut
+ call ClearScreen
+ call RunDefaultPaletteCommand
+ call LoadTextBoxTilePatterns
+ call GBPalNormal
+ ld hl, wd72c
+ res 1, [hl]
+ ld a, $77 ; max volume
+ ld [rNR50], a
+ ret
+
+HeightWeightText:
+ db "HT ?",$60,"??",$61
+ next "WT ???lb@"
+
+; XXX does anything point to this?
+PokeText:
+ db "#@"
+
+; horizontal line that divides the pokedex text description from the rest of the data
+PokedexDataDividerLine:
+ db $68,$69,$6B,$69,$6B
+ db $69,$6B,$69,$6B,$6B
+ db $6B,$6B,$69,$6B,$69
+ db $6B,$69,$6B,$69,$6A
+ db "@"
+
+; draws a line of tiles
+; INPUT:
+; b = tile ID
+; c = number of tile ID's to write
+; de = amount to destination address after each tile (1 for horizontal, 20 for vertical)
+; hl = destination address
+DrawTileLine:
+ push bc
+ push de
+.loop
+ ld [hl], b
+ add hl, de
+ dec c
+ jr nz, .loop
+ pop de
+ pop bc
+ ret
+
+ inclang data/pokedex_entries.asm
+
+PokedexToIndex:
+ ; converts the Pokédex number at wd11e to an index
+ push bc
+ push hl
+ ld a, [wd11e]
+ ld b, a
+ ld c, 0
+ ld hl, PokedexOrder
+
+.loop ; go through the list until we find an entry with a matching dex number
+ inc c
+ ld a, [hli]
+ cp b
+ jr nz, .loop
+
+ ld a, c
+ ld [wd11e], a
+ pop hl
+ pop bc
+ ret
+
+IndexToPokedex:
+ ; converts the index number at wd11e to a Pokédex number
+ push bc
+ push hl
+ ld a, [wd11e]
+ dec a
+ ld hl, PokedexOrder
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wd11e], a
+ pop hl
+ pop bc
+ ret
+
+INCLUDE "data/pokedex_order.asm"
diff --git a/en/engine/menu/prize_menu.asm b/en/engine/menu/prize_menu.asm
new file mode 100755
index 00000000..86ebb6a8
--- /dev/null
+++ b/en/engine/menu/prize_menu.asm
@@ -0,0 +1,306 @@
+CeladonPrizeMenu:
+ ld b, COIN_CASE
+ call IsItemInBag
+ jr nz, .havingCoinCase
+ ld hl, RequireCoinCaseTextPtr
+ jp PrintText
+.havingCoinCase
+ ld hl, wd730
+ set 6, [hl] ; disable letter-printing delay
+ ld hl, ExchangeCoinsForPrizesTextPtr
+ call PrintText
+; the following are the menu settings
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $03
+ ld [wMaxMenuItem], a
+ ld a, $04
+ ld [wTopMenuItemY], a
+ ld a, $01
+ ld [wTopMenuItemX], a
+ call PrintPrizePrice
+ coord hl, 0, 2
+ ld b, 8
+ ld c, 16
+ call TextBoxBorder
+ call GetPrizeMenuId
+ call UpdateSprites
+ ld hl, WhichPrizeTextPtr
+ call PrintText
+ call HandleMenuInput ; menu choice handler
+ bit 1, a ; keypress = B (Cancel)
+ jr nz, .noChoice
+ ld a, [wCurrentMenuItem]
+ cp 3 ; "NO,THANKS" choice
+ jr z, .noChoice
+ call HandlePrizeChoice
+.noChoice
+ ld hl, wd730
+ res 6, [hl]
+ ret
+
+RequireCoinCaseTextPtr:
+ TX_FAR _RequireCoinCaseText
+ TX_WAIT
+ db "@"
+
+ExchangeCoinsForPrizesTextPtr:
+ TX_FAR _ExchangeCoinsForPrizesText
+ db "@"
+
+WhichPrizeTextPtr:
+ TX_FAR _WhichPrizeText
+ db "@"
+
+GetPrizeMenuId:
+; determine which one among the three
+; prize-texts has been selected
+; using the text ID (stored in [hSpriteIndexOrTextID])
+; load the three prizes at wd13d-wd13f
+; load the three prices at wd141-wd146
+; display the three prizes' names
+; (distinguishing between Pokemon names
+; and Items (specifically TMs) names)
+ ld a, [hSpriteIndexOrTextID]
+ sub 3 ; prize-texts' id are 3, 4 and 5
+ ld [wWhichPrizeWindow], a ; prize-texts' id (relative, i.e. 0, 1 or 2)
+ add a
+ add a
+ ld d, 0
+ ld e, a
+ ld hl, PrizeDifferentMenuPtrs
+ add hl, de
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+ inc hl
+ push hl
+ ld hl, wPrize1
+ call CopyString
+ pop hl
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wPrize1Price
+ ld bc, 6
+ call CopyData
+ ld a, [wWhichPrizeWindow]
+ cp 2 ;is TM_menu?
+ jr nz, .putMonName
+ ld a, [wPrize1]
+ ld [wd11e], a
+ call GetItemName
+ coord hl, 2, 4
+ call PlaceString
+ ld a, [wPrize2]
+ ld [wd11e], a
+ call GetItemName
+ coord hl, 2, 6
+ call PlaceString
+ ld a, [wPrize3]
+ ld [wd11e], a
+ call GetItemName
+ coord hl, 2, 8
+ call PlaceString
+ jr .putNoThanksText
+.putMonName
+ ld a, [wPrize1]
+ ld [wd11e], a
+ call GetMonName
+ coord hl, 2, 4
+ call PlaceString
+ ld a, [wPrize2]
+ ld [wd11e], a
+ call GetMonName
+ coord hl, 2, 6
+ call PlaceString
+ ld a, [wPrize3]
+ ld [wd11e], a
+ call GetMonName
+ coord hl, 2, 8
+ call PlaceString
+.putNoThanksText
+ coord hl, 2, 10
+ ld de, NoThanksText
+ call PlaceString
+; put prices on the right side of the textbox
+ ld de, wPrize1Price
+ coord hl, 13, 5
+; reg. c:
+; [low nybble] number of bytes
+; [bit 765 = %100] space-padding (not zero-padding)
+ ld c, (1 << 7 | 2)
+; Function $15CD displays BCD value (same routine
+; used by text-command $02)
+ call PrintBCDNumber
+ ld de, wPrize2Price
+ coord hl, 13, 7
+ ld c, (1 << 7 | 2)
+ call PrintBCDNumber
+ ld de, wPrize3Price
+ coord hl, 13, 9
+ ld c, (1 << 7 | 2)
+ jp PrintBCDNumber
+
+ inclang data/prizes.asm
+
+PrintPrizePrice:
+ coord hl, 11, 0
+ ld b, 1
+ ld c, 7
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 12, 0
+ ld de, .CoinString
+ call PlaceString
+ coord hl, 13, 1
+ ld de, .SixSpacesString
+ call PlaceString
+ coord hl, 13, 1
+ ld de, wPlayerCoins
+ ld c, %10000010
+ call PrintBCDNumber
+ ret
+
+.CoinString:
+ db "COIN@"
+
+.SixSpacesString:
+ db " @"
+
+LoadCoinsToSubtract:
+ ld a, [wWhichPrize]
+ add a
+ ld d, 0
+ ld e, a
+ ld hl, wPrize1Price
+ add hl, de ; get selected prize's price
+ xor a
+ ld [hUnusedCoinsByte], a
+ ld a, [hli]
+ ld [hCoins], a
+ ld a, [hl]
+ ld [hCoins + 1], a
+ ret
+
+HandlePrizeChoice:
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPrize], a
+ ld d, 0
+ ld e, a
+ ld hl, wPrize1
+ add hl, de
+ ld a, [hl]
+ ld [wd11e], a
+ ld a, [wWhichPrizeWindow]
+ cp 2 ; is prize a TM?
+ jr nz, .getMonName
+ call GetItemName
+ jr .givePrize
+.getMonName
+ call GetMonName
+.givePrize
+ ld hl, SoYouWantPrizeTextPtr
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem] ; yes/no answer (Y=0, N=1)
+ and a
+ jr nz, .printOhFineThen
+ call LoadCoinsToSubtract
+ call HasEnoughCoins
+ jr c, .notEnoughCoins
+ ld a, [wWhichPrizeWindow]
+ cp $02
+ jr nz, .giveMon
+ ld a, [wd11e]
+ ld b, a
+ ld a, 1
+ ld c, a
+ call GiveItem
+ jr nc, .bagFull
+ jr .subtractCoins
+.giveMon
+ ld a, [wd11e]
+ ld [wcf91], a
+ push af
+ call GetPrizeMonLevel
+ ld c, a
+ pop af
+ ld b, a
+ call GivePokemon
+
+; If either the party or box was full, wait after displaying message.
+ push af
+ ld a, [wAddedToParty]
+ and a
+ call z, WaitForTextScrollButtonPress
+ pop af
+
+; If the mon couldn't be given to the player (because both the party and box
+; were full), return without subtracting coins.
+ ret nc
+
+.subtractCoins
+ call LoadCoinsToSubtract
+ ld hl, hCoins + 1
+ ld de, wPlayerCoins + 1
+ ld c, $02 ; how many bytes
+ predef SubBCDPredef
+ jp PrintPrizePrice
+.bagFull
+ ld hl, PrizeRoomBagIsFullTextPtr
+ jp PrintText
+.notEnoughCoins
+ ld hl, SorryNeedMoreCoinsText
+ jp PrintText
+.printOhFineThen
+ ld hl, OhFineThenTextPtr
+ jp PrintText
+
+UnknownPrizeData:
+; XXX what's this?
+ db $00,$01,$00,$01,$00,$01,$00,$00,$01
+
+HereYouGoTextPtr:
+ TX_FAR _HereYouGoText
+ TX_WAIT
+ db "@"
+
+SoYouWantPrizeTextPtr:
+ TX_FAR _SoYouWantPrizeText
+ db "@"
+
+SorryNeedMoreCoinsText:
+ TX_FAR _SorryNeedMoreCoinsText
+ TX_WAIT
+ db "@"
+
+PrizeRoomBagIsFullTextPtr:
+ TX_FAR _OopsYouDontHaveEnoughRoomText
+ TX_WAIT
+ db "@"
+
+OhFineThenTextPtr:
+ TX_FAR _OhFineThenText
+ TX_WAIT
+ db "@"
+
+GetPrizeMonLevel:
+ ld a, [wcf91]
+ ld b, a
+ ld hl, PrizeMonLevelDictionary
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .matchFound
+ inc hl
+ jr .loop
+.matchFound
+ ld a, [hl]
+ ld [wCurEnemyLVL], a
+ ret
+
+INCLUDE "data/prize_mon_levels.asm"
diff --git a/en/engine/menu/start_sub_menus.asm b/en/engine/menu/start_sub_menus.asm
new file mode 100755
index 00000000..947837e3
--- /dev/null
+++ b/en/engine/menu/start_sub_menus.asm
@@ -0,0 +1,854 @@
+StartMenu_Pokedex:
+ predef ShowPokedexMenu
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call Delay3
+ call LoadGBPal
+ call UpdateSprites
+ jp RedisplayStartMenu
+
+StartMenu_Pokemon:
+ ld a, [wPartyCount]
+ and a
+ jp z, RedisplayStartMenu
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ ld [wUpdateSpritesEnabled], a
+ call DisplayPartyMenu
+ jr .checkIfPokemonChosen
+.loop
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ call GoBackToPartyMenu
+.checkIfPokemonChosen
+ jr nc, .chosePokemon
+.exitMenu
+ call GBPalWhiteOutWithDelay3
+ call RestoreScreenTilesAndReloadTilePatterns
+ call LoadGBPal
+ jp RedisplayStartMenu
+.chosePokemon
+ call SaveScreenTilesToBuffer1
+ ld a, FIELD_MOVE_MON_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; display pokemon menu options
+ ld hl, wFieldMoves
+ lb bc, 2, 12 ; max menu item ID, top menu item Y
+ ld e, 5
+.adjustMenuVariablesLoop
+ dec e
+ jr z, .storeMenuVariables
+ ld a, [hli]
+ and a ; end of field moves?
+ jr z, .storeMenuVariables
+ inc b
+ dec c
+ dec c
+ jr .adjustMenuVariablesLoop
+.storeMenuVariables
+ ld hl, wTopMenuItemY
+ ld a, c
+ ld [hli], a ; top menu item Y
+ ld a, [hFieldMoveMonMenuTopMenuItemX]
+ ld [hli], a ; top menu item X
+ xor a
+ ld [hli], a ; current menu item ID
+ inc hl
+ ld a, b
+ ld [hli], a ; max menu item ID
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; menu watched keys
+ xor a
+ ld [hl], a
+ call HandleMenuInput
+ push af
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ pop af
+ bit 1, a ; was the B button pressed?
+ jp nz, .loop
+; if the B button wasn't pressed
+ ld a, [wMaxMenuItem]
+ ld b, a
+ ld a, [wCurrentMenuItem] ; menu selection
+ cp b
+ jp z, .exitMenu ; if the player chose Cancel
+ dec b
+ cp b
+ jr z, .choseSwitch
+ dec b
+ cp b
+ jp z, .choseStats
+ ld c, a
+ ld b, 0
+ ld hl, wFieldMoves
+ add hl, bc
+ jp .choseOutOfBattleMove
+.choseSwitch
+ ld a, [wPartyCount]
+ cp 2 ; is there more than one pokemon in the party?
+ jp c, StartMenu_Pokemon ; if not, no switching
+ call SwitchPartyMon_InitVarOrSwapData ; init [wMenuItemToSwap]
+ ld a, SWAP_MONS_PARTY_MENU
+ ld [wPartyMenuTypeOrMessageID], a
+ call GoBackToPartyMenu
+ jp .checkIfPokemonChosen
+.choseStats
+ call ClearSprites
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ predef StatusScreen
+ predef StatusScreen2
+ call ReloadMapData
+ jp StartMenu_Pokemon
+.choseOutOfBattleMove
+ push hl
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ pop hl
+ ld a, [hl]
+ dec a
+ add a
+ ld b, 0
+ ld c, a
+ ld hl, .outOfBattleMovePointers
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wObtainedBadges] ; badges obtained
+ jp hl
+.outOfBattleMovePointers
+ dw .cut
+ dw .fly
+ dw .surf
+ dw .surf
+ dw .strength
+ dw .flash
+ dw .dig
+ dw .teleport
+ dw .softboiled
+.fly
+ bit 2, a ; does the player have the Thunder Badge?
+ jp z, .newBadgeRequired
+ call CheckIfInOutsideMap
+ jr z, .canFly
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ ld hl, .cannotFlyHereText
+ call PrintText
+ jp .loop
+.canFly
+ call ChooseFlyDestination
+ ld a, [wd732]
+ bit 3, a ; did the player decide to fly?
+ jp nz, .goBackToMap
+ call LoadFontTilePatterns
+ ld hl, wd72e
+ set 1, [hl]
+ jp StartMenu_Pokemon
+.cut
+ bit 1, a ; does the player have the Cascade Badge?
+ jp z, .newBadgeRequired
+ predef UsedCut
+ ld a, [wActionResultOrTookBattleTurn]
+ and a
+ jp z, .loop
+ jp CloseTextDisplay
+.surf
+ bit 4, a ; does the player have the Soul Badge?
+ jp z, .newBadgeRequired
+ callba IsSurfingAllowed
+ ld hl, wd728
+ bit 1, [hl]
+ res 1, [hl]
+ jp z, .loop
+ ld a, SURFBOARD
+ ld [wcf91], a
+ ld [wPseudoItemID], a
+ call UseItem
+ ld a, [wActionResultOrTookBattleTurn]
+ and a
+ jp z, .loop
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.strength
+ bit 3, a ; does the player have the Rainbow Badge?
+ jp z, .newBadgeRequired
+ predef PrintStrengthTxt
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.flash
+ bit 0, a ; does the player have the Boulder Badge?
+ jp z, .newBadgeRequired
+ xor a
+ ld [wMapPalOffset], a
+ ld hl, .flashLightsAreaText
+ call PrintText
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.flashLightsAreaText
+ TX_FAR _FlashLightsAreaText
+ db "@"
+.dig
+ ld a, ESCAPE_ROPE
+ ld [wcf91], a
+ ld [wPseudoItemID], a
+ call UseItem
+ ld a, [wActionResultOrTookBattleTurn]
+ and a
+ jp z, .loop
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.teleport
+ call CheckIfInOutsideMap
+ jr z, .canTeleport
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ ld hl, .cannotUseTeleportNowText
+ call PrintText
+ jp .loop
+.canTeleport
+ ld hl, .warpToLastPokemonCenterText
+ call PrintText
+ ld hl, wd732
+ set 3, [hl]
+ set 6, [hl]
+ ld hl, wd72e
+ set 1, [hl]
+ res 4, [hl]
+ ld c, 60
+ call DelayFrames
+ call GBPalWhiteOutWithDelay3
+ jp .goBackToMap
+.warpToLastPokemonCenterText
+ TX_FAR _WarpToLastPokemonCenterText
+ db "@"
+.cannotUseTeleportNowText
+ TX_FAR _CannotUseTeleportNowText
+ db "@"
+.cannotFlyHereText
+ TX_FAR _CannotFlyHereText
+ db "@"
+.softboiled
+ ld hl, wPartyMon1MaxHP
+ ld a, [wWhichPokemon]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld a, [hli]
+ ld [H_DIVIDEND], a
+ ld a, [hl]
+ ld [H_DIVIDEND + 1], a
+ ld a, 5
+ ld [H_DIVISOR], a
+ ld b, 2 ; number of bytes
+ call Divide
+ ld bc, wPartyMon1HP - wPartyMon1MaxHP
+ add hl, bc
+ ld a, [hld]
+ ld b, a
+ ld a, [H_QUOTIENT + 3]
+ sub b
+ ld b, [hl]
+ ld a, [H_QUOTIENT + 2]
+ sbc b
+ jp nc, .notHealthyEnough
+ ld a, [wPartyAndBillsPCSavedMenuItem]
+ push af
+ ld a, POTION
+ ld [wcf91], a
+ ld [wPseudoItemID], a
+ call UseItem
+ pop af
+ ld [wPartyAndBillsPCSavedMenuItem], a
+ jp .loop
+.notHealthyEnough ; if current HP is less than 1/5 of max HP
+ ld hl, .notHealthyEnoughText
+ call PrintText
+ jp .loop
+.notHealthyEnoughText
+ TX_FAR _NotHealthyEnoughText
+ db "@"
+.goBackToMap
+ call RestoreScreenTilesAndReloadTilePatterns
+ jp CloseTextDisplay
+.newBadgeRequired
+ ld hl, .newBadgeRequiredText
+ call PrintText
+ jp .loop
+.newBadgeRequiredText
+ TX_FAR _NewBadgeRequiredText
+ db "@"
+
+; writes a blank tile to all possible menu cursor positions on the party menu
+ErasePartyMenuCursors:
+ coord hl, 0, 1
+ ld bc, 2 * 20 ; menu cursor positions are 2 rows apart
+ ld a, 6 ; 6 menu cursor positions
+.loop
+ ld [hl], " "
+ add hl, bc
+ dec a
+ jr nz, .loop
+ ret
+
+ItemMenuLoop:
+ call LoadScreenTilesFromBuffer2DisableBGTransfer ; restore saved screen
+ call RunDefaultPaletteCommand
+
+StartMenu_Item:
+ ld a, [wLinkState]
+ dec a ; is the player in the Colosseum or Trade Centre?
+ jr nz, .notInCableClubRoom
+ ld hl, CannotUseItemsHereText
+ call PrintText
+ jr .exitMenu
+.notInCableClubRoom
+ ld bc, wNumBagItems
+ ld hl, wListPointer
+ ld a, c
+ ld [hli], a
+ ld [hl], b ; store item bag pointer in wListPointer (for DisplayListMenuID)
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ ld a, [wBagSavedMenuItem]
+ ld [wCurrentMenuItem], a
+ call DisplayListMenuID
+ ld a, [wCurrentMenuItem]
+ ld [wBagSavedMenuItem], a
+ jr nc, .choseItem
+.exitMenu
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call LoadTextBoxTilePatterns
+ call UpdateSprites
+ jp RedisplayStartMenu
+.choseItem
+; erase menu cursor (blank each tile in front of an item name)
+ ld a, " "
+ Coorda 5, 4
+ Coorda 5, 6
+ Coorda 5, 8
+ Coorda 5, 10
+ call PlaceUnfilledArrowMenuCursor
+ xor a
+ ld [wMenuItemToSwap], a
+ ld a, [wcf91]
+ cp BICYCLE
+ jp z, .useOrTossItem
+.notBicycle1
+ ld a, USE_TOSS_MENU_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld hl, wTopMenuItemY
+ ld a, 11
+ ld [hli], a ; top menu item Y
+ ld a, 14
+ ld [hli], a ; top menu item X
+ xor a
+ ld [hli], a ; current menu item ID
+ inc hl
+ inc a ; a = 1
+ ld [hli], a ; max menu item ID
+ ld a, A_BUTTON | B_BUTTON
+ ld [hli], a ; menu watched keys
+ xor a
+ ld [hl], a ; old menu item id
+ call HandleMenuInput
+ call PlaceUnfilledArrowMenuCursor
+ bit 1, a ; was the B button pressed?
+ jr z, .useOrTossItem
+ jp ItemMenuLoop
+.useOrTossItem ; if the player made the choice to use or toss the item
+ ld a, [wcf91]
+ ld [wd11e], a
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld a, [wcf91]
+ cp BICYCLE
+ jr nz, .notBicycle2
+ ld a, [wd732]
+ bit 5, a
+ jr z, .useItem_closeMenu
+ ld hl, CannotGetOffHereText
+ call PrintText
+ jp ItemMenuLoop
+.notBicycle2
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .tossItem
+; use item
+ ld [wPseudoItemID], a ; a must be 0 due to above conditional jump
+ ld a, [wcf91]
+ cp HM_01
+ jr nc, .useItem_partyMenu
+ ld hl, UsableItems_CloseMenu
+ ld de, 1
+ call IsInArray
+ jr c, .useItem_closeMenu
+ ld a, [wcf91]
+ ld hl, UsableItems_PartyMenu
+ ld de, 1
+ call IsInArray
+ jr c, .useItem_partyMenu
+ call UseItem
+ jp ItemMenuLoop
+.useItem_closeMenu
+ xor a
+ ld [wPseudoItemID], a
+ call UseItem
+ ld a, [wActionResultOrTookBattleTurn]
+ and a
+ jp z, ItemMenuLoop
+ jp CloseStartMenu
+.useItem_partyMenu
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ call UseItem
+ ld a, [wActionResultOrTookBattleTurn]
+ cp $02
+ jp z, .partyMenuNotDisplayed
+ call GBPalWhiteOutWithDelay3
+ call RestoreScreenTilesAndReloadTilePatterns
+ pop af
+ ld [wUpdateSpritesEnabled], a
+ jp StartMenu_Item
+.partyMenuNotDisplayed
+ pop af
+ ld [wUpdateSpritesEnabled], a
+ jp ItemMenuLoop
+.tossItem
+ call IsKeyItem
+ ld a, [wIsKeyItem]
+ and a
+ jr nz, .skipAskingQuantity
+ ld a, [wcf91]
+ call IsItemHM
+ jr c, .skipAskingQuantity
+ call DisplayChooseQuantityMenu
+ inc a
+ jr z, .tossZeroItems
+.skipAskingQuantity
+ ld hl, wNumBagItems
+ call TossItem
+.tossZeroItems
+ jp ItemMenuLoop
+
+CannotUseItemsHereText:
+ TX_FAR _CannotUseItemsHereText
+ db "@"
+
+CannotGetOffHereText:
+ TX_FAR _CannotGetOffHereText
+ db "@"
+
+; items which bring up the party menu when used
+UsableItems_PartyMenu:
+ db MOON_STONE
+ db ANTIDOTE
+ db BURN_HEAL
+ db ICE_HEAL
+ db AWAKENING
+ db PARLYZ_HEAL
+ db FULL_RESTORE
+ db MAX_POTION
+ db HYPER_POTION
+ db SUPER_POTION
+ db POTION
+ db FIRE_STONE
+ db THUNDER_STONE
+ db WATER_STONE
+ db HP_UP
+ db PROTEIN
+ db IRON
+ db CARBOS
+ db CALCIUM
+ db RARE_CANDY
+ db LEAF_STONE
+ db FULL_HEAL
+ db REVIVE
+ db MAX_REVIVE
+ db FRESH_WATER
+ db SODA_POP
+ db LEMONADE
+ db X_ATTACK
+ db X_DEFEND
+ db X_SPEED
+ db X_SPECIAL
+ db PP_UP
+ db ETHER
+ db MAX_ETHER
+ db ELIXER
+ db MAX_ELIXER
+ db $ff
+
+; items which close the item menu when used
+UsableItems_CloseMenu:
+ db ESCAPE_ROPE
+ db ITEMFINDER
+ db POKE_FLUTE
+ db OLD_ROD
+ db GOOD_ROD
+ db SUPER_ROD
+ db $ff
+
+StartMenu_TrainerInfo:
+ call GBPalWhiteOut
+ call ClearScreen
+ call UpdateSprites
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ call DrawTrainerInfo
+ predef DrawBadges ; draw badges
+ ld b, SET_PAL_TRAINER_CARD
+ call RunPaletteCommand
+ call GBPalNormal
+ call WaitForTextScrollButtonPress ; wait for button press
+ call GBPalWhiteOut
+ call LoadFontTilePatterns
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call RunDefaultPaletteCommand
+ call ReloadMapData
+ call LoadGBPal
+ pop af
+ ld [hTilesetType], a
+ jp RedisplayStartMenu
+
+; loads tile patterns and draws everything except for gym leader faces / badges
+DrawTrainerInfo:
+ ld de, RedPicFront
+ lb bc, BANK(RedPicFront), $01
+ predef DisplayPicCenteredOrUpperRight
+ call DisableLCD
+ coord hl, 0, 2
+ ld a, " "
+ call TrainerInfo_DrawVerticalLine
+ coord hl, 1, 2
+ call TrainerInfo_DrawVerticalLine
+ ld hl, vChars2 + $70
+ ld de, vChars2
+ ld bc, $70 * 4
+ call CopyData
+ ld hl, TrainerInfoTextBoxTileGraphics ; trainer info text box tile patterns
+ ld de, vChars2 + $770
+ ld bc, $0080
+ push bc
+ call TrainerInfo_FarCopyData
+ ld hl, BlankLeaderNames
+ ld de, vChars2 + $600
+ ld bc, $0170
+ call TrainerInfo_FarCopyData
+ pop bc
+ ld hl, BadgeNumbersTileGraphics ; badge number tile patterns
+ ld de, vChars1 + $580
+ call TrainerInfo_FarCopyData
+ ld hl, GymLeaderFaceAndBadgeTileGraphics ; gym leader face and badge tile patterns
+ ld de, vChars2 + $200
+ ld bc, $0400
+ ld a, $03
+ call FarCopyData2
+ ld hl, TextBoxGraphics
+ ld de, $00d0
+ add hl, de ; hl = colon tile pattern
+ ld de, vChars1 + $560
+ ld bc, $0010
+ ld a, $04
+ push bc
+ call FarCopyData2
+ pop bc
+ ld hl, TrainerInfoTextBoxTileGraphics + $80 ; background tile pattern
+ ld de, vChars1 + $570
+ call TrainerInfo_FarCopyData
+ call EnableLCD
+ ld hl, wTrainerInfoTextBoxWidthPlus1
+ ld a, 18 + 1
+ ld [hli], a
+ dec a
+ ld [hli], a
+ ld [hl], 1
+ coord hl, 0, 0
+ call TrainerInfo_DrawTextBox
+ ld hl, wTrainerInfoTextBoxWidthPlus1
+ ld a, 16 + 1
+ ld [hli], a
+ dec a
+ ld [hli], a
+ ld [hl], 3
+ coord hl, 1, 10
+ call TrainerInfo_DrawTextBox
+ coord hl, 0, 10
+ ld a, $d7
+ call TrainerInfo_DrawVerticalLine
+ coord hl, 19, 10
+ call TrainerInfo_DrawVerticalLine
+ coord hl, 6, 9
+ ld de, TrainerInfo_BadgesText
+ call PlaceString
+ coord hl, 2, 2
+ ld de, TrainerInfo_NameMoneyTimeText
+ call PlaceString
+ coord hl, 7, 2
+ ld de, wPlayerName
+ call PlaceString
+ coord hl, 8, 4
+ ld de, wPlayerMoney
+ ld c, $e3
+ call PrintBCDNumber
+ coord hl, 9, 6
+ ld de, wPlayTimeHours ; hours
+ lb bc, LEFT_ALIGN | 1, 3
+ call PrintNumber
+ ld [hl], $d6 ; colon tile ID
+ inc hl
+ ld de, wPlayTimeMinutes ; minutes
+ lb bc, LEADING_ZEROES | 1, 2
+ jp PrintNumber
+
+TrainerInfo_FarCopyData:
+ ld a, BANK(TrainerInfoTextBoxTileGraphics)
+ jp FarCopyData2
+
+TrainerInfo_NameMoneyTimeText:
+ db "NAME/"
+ next "MONEY/"
+ next "TIME/@"
+
+; $76 is a circle tile
+TrainerInfo_BadgesText:
+ db $76,"BADGES",$76,"@"
+
+; draws a text box on the trainer info screen
+; height is always 6
+; INPUT:
+; hl = destination address
+; [wTrainerInfoTextBoxWidthPlus1] = width
+; [wTrainerInfoTextBoxWidth] = width - 1
+; [wTrainerInfoTextBoxNextRowOffset] = distance from the end of a text box row to the start of the next
+TrainerInfo_DrawTextBox:
+ ld a, $79 ; upper left corner tile ID
+ lb de, $7a, $7b ; top edge and upper right corner tile ID's
+ call TrainerInfo_DrawHorizontalEdge ; draw top edge
+ call TrainerInfo_NextTextBoxRow
+ ld a, [wTrainerInfoTextBoxWidthPlus1]
+ ld e, a
+ ld d, 0
+ ld c, 6 ; height of the text box
+.loop
+ ld [hl], $7c ; left edge tile ID
+ add hl, de
+ ld [hl], $78 ; right edge tile ID
+ call TrainerInfo_NextTextBoxRow
+ dec c
+ jr nz, .loop
+ ld a, $7d ; lower left corner tile ID
+ lb de, $77, $7e ; bottom edge and lower right corner tile ID's
+
+TrainerInfo_DrawHorizontalEdge:
+ ld [hli], a ; place left corner tile
+ ld a, [wTrainerInfoTextBoxWidth]
+ ld c, a
+ ld a, d
+.loop
+ ld [hli], a ; place edge tile
+ dec c
+ jr nz, .loop
+ ld a, e
+ ld [hl], a ; place right corner tile
+ ret
+
+TrainerInfo_NextTextBoxRow:
+ ld a, [wTrainerInfoTextBoxNextRowOffset] ; distance to the start of the next row
+.loop
+ inc hl
+ dec a
+ jr nz, .loop
+ ret
+
+; draws a vertical line
+; INPUT:
+; hl = address of top tile in the line
+; a = tile ID
+TrainerInfo_DrawVerticalLine:
+ ld de, SCREEN_WIDTH
+ ld c, 8
+.loop
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+StartMenu_SaveReset:
+ ld a, [wd72e]
+ bit 6, a ; is the player using the link feature?
+ jp nz, Init
+ predef SaveSAV ; save the game
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ jp HoldTextDisplayOpen
+
+StartMenu_Option:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ call UpdateSprites
+ callab DisplayOptionMenu
+ call LoadScreenTilesFromBuffer2 ; restore saved screen
+ call LoadTextBoxTilePatterns
+ call UpdateSprites
+ jp RedisplayStartMenu
+
+SwitchPartyMon:
+ call SwitchPartyMon_InitVarOrSwapData ; swap data
+ ld a, [wSwappedMenuItem]
+ call SwitchPartyMon_ClearGfx
+ ld a, [wCurrentMenuItem]
+ call SwitchPartyMon_ClearGfx
+ jp RedrawPartyMenu_
+
+SwitchPartyMon_ClearGfx:
+ push af
+ coord hl, 0, 0
+ ld bc, SCREEN_WIDTH * 2
+ call AddNTimes
+ ld c, SCREEN_WIDTH * 2
+ ld a, " "
+.clearMonBGLoop ; clear the mon's row in the party menu
+ ld [hli], a
+ dec c
+ jr nz, .clearMonBGLoop
+ pop af
+ ld hl, wOAMBuffer
+ ld bc, $10
+ call AddNTimes
+ ld de, $4
+ ld c, e
+.clearMonOAMLoop
+ ld [hl], $a0
+ add hl, de
+ dec c
+ jr nz, .clearMonOAMLoop
+ call WaitForSoundToFinish
+ ld a, SFX_SWAP
+ jp PlaySound
+
+SwitchPartyMon_InitVarOrSwapData:
+; This is used to initialise [wMenuItemToSwap] and to actually swap the data.
+ ld a, [wMenuItemToSwap]
+ and a ; has [wMenuItemToSwap] been initialised yet?
+ jr nz, .pickedMonsToSwap
+; If not, initialise [wMenuItemToSwap] so that it matches the current mon.
+ ld a, [wWhichPokemon]
+ inc a ; [wMenuItemToSwap] counts from 1
+ ld [wMenuItemToSwap], a
+ ret
+.pickedMonsToSwap
+ xor a
+ ld [wPartyMenuTypeOrMessageID], a
+ ld a, [wMenuItemToSwap]
+ dec a
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ ld [wSwappedMenuItem], a
+ cp b ; swapping a mon with itself?
+ jr nz, .swappingDifferentMons
+; can't swap a mon with itself
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ ret
+.swappingDifferentMons
+ ld a, b
+ ld [wMenuItemToSwap], a
+ push hl
+ push de
+ ld hl, wPartySpecies
+ ld d, h
+ ld e, l
+ ld a, [wCurrentMenuItem]
+ add l
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld a, [wMenuItemToSwap]
+ add e
+ ld e, a
+ jr nc, .noCarry2
+ inc d
+.noCarry2
+ ld a, [hl]
+ ld [hSwapTemp], a
+ ld a, [de]
+ ld [hl], a
+ ld a, [hSwapTemp]
+ ld [de], a
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wCurrentMenuItem]
+ call AddNTimes
+ push hl
+ ld de, wSwitchPartyMonTempBuffer
+ ld bc, wPartyMon2 - wPartyMon1
+ call CopyData
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wMenuItemToSwap]
+ call AddNTimes
+ pop de
+ push hl
+ ld bc, wPartyMon2 - wPartyMon1
+ call CopyData
+ pop de
+ ld hl, wSwitchPartyMonTempBuffer
+ ld bc, wPartyMon2 - wPartyMon1
+ call CopyData
+ ld hl, wPartyMonOT
+ ld a, [wCurrentMenuItem]
+ call SkipFixedLengthTextEntries
+ push hl
+ ld de, wSwitchPartyMonTempBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wPartyMonOT
+ ld a, [wMenuItemToSwap]
+ call SkipFixedLengthTextEntries
+ pop de
+ push hl
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop de
+ ld hl, wSwitchPartyMonTempBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wPartyMonNicks
+ ld a, [wCurrentMenuItem]
+ call SkipFixedLengthTextEntries
+ push hl
+ ld de, wSwitchPartyMonTempBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wPartyMonNicks
+ ld a, [wMenuItemToSwap]
+ call SkipFixedLengthTextEntries
+ pop de
+ push hl
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop de
+ ld hl, wSwitchPartyMonTempBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wMenuItemToSwap]
+ ld [wSwappedMenuItem], a
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ pop de
+ pop hl
+ ret
diff --git a/en/engine/menu/status_screen.asm b/en/engine/menu/status_screen.asm
new file mode 100755
index 00000000..ef94f13c
--- /dev/null
+++ b/en/engine/menu/status_screen.asm
@@ -0,0 +1,481 @@
+DrawHP:
+; Draws the HP bar in the stats screen
+ call GetPredefRegisters
+ ld a, $1
+ jr DrawHP_
+
+DrawHP2:
+; Draws the HP bar in the party screen
+ call GetPredefRegisters
+ ld a, $2
+
+DrawHP_:
+ ld [wHPBarType], a
+ push hl
+ ld a, [wLoadedMonHP]
+ ld b, a
+ ld a, [wLoadedMonHP + 1]
+ ld c, a
+ or b
+ jr nz, .nonzeroHP
+ xor a
+ ld c, a
+ ld e, a
+ ld a, $6
+ ld d, a
+ jp .drawHPBarAndPrintFraction
+.nonzeroHP
+ ld a, [wLoadedMonMaxHP]
+ ld d, a
+ ld a, [wLoadedMonMaxHP + 1]
+ ld e, a
+ predef HPBarLength
+ ld a, $6
+ ld d, a
+ ld c, a
+.drawHPBarAndPrintFraction
+ pop hl
+ push de
+ push hl
+ push hl
+ call DrawHPBar
+ pop hl
+ ld a, [hFlags_0xFFF6]
+ bit 0, a
+ jr z, .printFractionBelowBar
+ ld bc, $9 ; right of bar
+ jr .printFraction
+.printFractionBelowBar
+ ld bc, SCREEN_WIDTH + 1 ; below bar
+.printFraction
+ add hl, bc
+ ld de, wLoadedMonHP
+ lb bc, 2, 3
+ call PrintNumber
+ ld a, "/"
+ ld [hli], a
+ ld de, wLoadedMonMaxHP
+ lb bc, 2, 3
+ call PrintNumber
+ pop hl
+ pop de
+ ret
+
+
+; Predef 0x37
+StatusScreen:
+ call LoadMonData
+ ld a, [wMonDataLocation]
+ cp BOX_DATA
+ jr c, .DontRecalculate
+; mon is in a box or daycare
+ ld a, [wLoadedMonBoxLevel]
+ ld [wLoadedMonLevel], a
+ ld [wCurEnemyLVL], a
+ ld hl, wLoadedMonHPExp - 1
+ ld de, wLoadedMonStats
+ ld b, $1
+ call CalcStats ; Recalculate stats
+.DontRecalculate
+ ld hl, wd72c
+ set 1, [hl]
+ ld a, $33
+ ld [rNR50], a ; Reduce the volume
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ call LoadHpBarAndStatusTilePatterns
+ ld de, BattleHudTiles1 ; source
+ ld hl, vChars2 + $6d0 ; dest
+ lb bc, BANK(BattleHudTiles1), $03
+ call CopyVideoDataDouble ; ·│ :L and halfarrow line end
+ ld de, BattleHudTiles2
+ ld hl, vChars2 + $780
+ lb bc, BANK(BattleHudTiles2), $01
+ call CopyVideoDataDouble ; │
+ ld de, BattleHudTiles3
+ ld hl, vChars2 + $760
+ lb bc, BANK(BattleHudTiles3), $02
+ call CopyVideoDataDouble ; ─┘
+ ld de, PTile
+ ld hl, vChars2 + $720
+ lb bc, BANK(PTile), (PTileEnd - PTile) / $8
+ call CopyVideoDataDouble ; P (for PP), inline
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ coord hl, 19, 1
+ lb bc, 6, 10
+ call DrawLineBox ; Draws the box around name, HP and status
+ ld de, -6
+ add hl, de
+ ld [hl], "⠄" ; . after No ("." is a different one)
+ dec hl
+ ld [hl], "№"
+ coord hl, 19, 9
+ lb bc, 8, 6
+ call DrawLineBox ; Draws the box around types, ID No. and OT
+ coord hl, 10, 9
+ ld de, Type1Text
+ call PlaceString ; "TYPE1/"
+ coord hl, 11, 3
+ predef DrawHP
+ ld hl, wStatusScreenHPBarColor
+ call GetHealthBarColor
+ ld b, SET_PAL_STATUS_SCREEN
+ call RunPaletteCommand
+ coord hl, 16, 6
+ ld de, wLoadedMonStatus
+ call PrintStatusCondition
+ jr nz, .StatusWritten
+ coord hl, 16, 6
+ ld de, OKText
+ call PlaceString ; "OK"
+.StatusWritten
+ coord hl, 9, 6
+ ld de, StatusText
+ call PlaceString ; "STATUS/"
+ coord hl, 14, 2
+ call PrintLevel ; Pokémon level
+ ld a, [wMonHIndex]
+ ld [wd11e], a
+ ld [wd0b5], a
+ predef IndexToPokedex
+ coord hl, 3, 7
+ ld de, wd11e
+ lb bc, LEADING_ZEROES | 1, 3
+ call PrintNumber ; Pokémon no.
+ coord hl, 11, 10
+ predef PrintMonType
+ ld hl, NamePointers2
+ call .GetStringPointer
+ ld d, h
+ ld e, l
+ coord hl, 9, 1
+ call PlaceString ; Pokémon name
+ ld hl, OTPointers
+ call .GetStringPointer
+ ld d, h
+ ld e, l
+ coord hl, 12, 16
+ call PlaceString ; OT
+ coord hl, 12, 14
+ ld de, wLoadedMonOTID
+ lb bc, LEADING_ZEROES | 2, 5
+ call PrintNumber ; ID Number
+ ld d, $0
+ call PrintStatsBox
+ call Delay3
+ call GBPalNormal
+ coord hl, 1, 0
+ call LoadFlippedFrontSpriteByMonIndex ; draw Pokémon picture
+ ld a, [wcf91]
+ call PlayCry ; play Pokémon cry
+ call WaitForTextScrollButtonPress ; wait for button
+ pop af
+ ld [hTilesetType], a
+ ret
+
+.GetStringPointer
+ ld a, [wMonDataLocation]
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wMonDataLocation]
+ cp DAYCARE_DATA
+ ret z
+ ld a, [wWhichPokemon]
+ jp SkipFixedLengthTextEntries
+
+OTPointers:
+ dw wPartyMonOT
+ dw wEnemyMonOT
+ dw wBoxMonOT
+ dw wDayCareMonOT
+
+NamePointers2:
+ dw wPartyMonNicks
+ dw wEnemyMonNicks
+ dw wBoxMonNicks
+ dw wDayCareMonName
+
+Type1Text:
+ db "TYPE1/", $4e
+
+Type2Text:
+ db "TYPE2/", $4e
+
+IDNoText:
+ db $73, "№/", $4e
+
+OTText:
+ db "OT/"
+ next "@"
+
+StatusText:
+ db "STATUS/@"
+
+OKText:
+ db "OK@"
+
+; Draws a line starting from hl high b and wide c
+DrawLineBox:
+ ld de, SCREEN_WIDTH ; New line
+.PrintVerticalLine
+ ld [hl], $78 ; │
+ add hl, de
+ dec b
+ jr nz, .PrintVerticalLine
+ ld [hl], $77 ; ┘
+ dec hl
+.PrintHorizLine
+ ld [hl], $76 ; ─
+ dec hl
+ dec c
+ jr nz, .PrintHorizLine
+ ld [hl], $6f ; ← (halfarrow ending)
+ ret
+
+PTile: ; This is a single 1bpp "P" tile
+ INCBIN "gfx/p_tile.1bpp"
+PTileEnd:
+
+PrintStatsBox:
+ ld a, d
+ and a ; a is 0 from the status screen
+ jr nz, .DifferentBox
+ coord hl, 0, 8
+ ld b, 8
+ ld c, 8
+ call TextBoxBorder ; Draws the box
+ coord hl, 1, 9 ; Start printing stats from here
+ ld bc, $0019 ; Number offset
+ jr .PrintStats
+.DifferentBox
+ coord hl, 9, 2
+ ld b, 8
+ ld c, 9
+ call TextBoxBorder
+ coord hl, 11, 3
+ ld bc, $0018
+.PrintStats
+ push bc
+ push hl
+ ld de, StatsText
+ call PlaceString
+ pop hl
+ pop bc
+ add hl, bc
+ ld de, wLoadedMonAttack
+ lb bc, 2, 3
+ call PrintStat
+ ld de, wLoadedMonDefense
+ call PrintStat
+ ld de, wLoadedMonSpeed
+ call PrintStat
+ ld de, wLoadedMonSpecial
+ jp PrintNumber
+PrintStat:
+ push hl
+ call PrintNumber
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ ret
+
+StatsText:
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPEED"
+ next "SPECIAL@"
+
+StatusScreen2:
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld bc, NUM_MOVES + 1
+ ld hl, wMoves
+ call FillMemory
+ ld hl, wLoadedMonMoves
+ ld de, wMoves
+ ld bc, NUM_MOVES
+ call CopyData
+ callab FormatMovesString
+ coord hl, 9, 2
+ lb bc, 5, 10
+ call ClearScreenArea ; Clear under name
+ coord hl, 19, 3
+ ld [hl], $78
+ coord hl, 0, 8
+ ld b, 8
+ ld c, 18
+ call TextBoxBorder ; Draw move container
+ coord hl, 2, 9
+ ld de, wMovesString
+ call PlaceString ; Print moves
+ ld a, [wNumMovesMinusOne]
+ inc a
+ ld c, a
+ ld a, $4
+ sub c
+ ld b, a ; Number of moves ?
+ coord hl, 11, 10
+ ld de, SCREEN_WIDTH * 2
+ ld a, $72 ; special P tile id
+ call StatusScreen_PrintPP ; Print "PP"
+ ld a, b
+ and a
+ jr z, .InitPP
+ ld c, a
+ ld a, "-"
+ call StatusScreen_PrintPP ; Fill the rest with --
+.InitPP
+ ld hl, wLoadedMonMoves
+ coord de, 14, 10
+ ld b, 0
+.PrintPP
+ ld a, [hli]
+ and a
+ jr z, .PPDone
+ push bc
+ push hl
+ push de
+ ld hl, wCurrentMenuItem
+ ld a, [hl]
+ push af
+ ld a, b
+ ld [hl], a
+ push hl
+ callab GetMaxPP
+ pop hl
+ pop af
+ ld [hl], a
+ pop de
+ pop hl
+ push hl
+ ld bc, wPartyMon1PP - wPartyMon1Moves - 1
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [wStatusScreenCurrentPP], a
+ ld h, d
+ ld l, e
+ push hl
+ ld de, wStatusScreenCurrentPP
+ lb bc, 1, 2
+ call PrintNumber
+ ld a, "/"
+ ld [hli], a
+ ld de, wMaxPP
+ lb bc, 1, 2
+ call PrintNumber
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ inc b
+ ld a, b
+ cp $4
+ jr nz, .PrintPP
+.PPDone
+ coord hl, 9, 3
+ ld de, StatusScreenExpText
+ call PlaceString
+ ld a, [wLoadedMonLevel]
+ push af
+ cp MAX_LEVEL
+ jr z, .Level100
+ inc a
+ ld [wLoadedMonLevel], a ; Increase temporarily if not 100
+.Level100
+ coord hl, 14, 6
+ ld [hl], $70 ; 1-tile "to"
+ inc hl
+ inc hl
+ call PrintLevel
+ pop af
+ ld [wLoadedMonLevel], a
+ ld de, wLoadedMonExp
+ coord hl, 12, 4
+ lb bc, 3, 7
+ call PrintNumber ; exp
+ call CalcExpToLevelUp
+ ld de, wLoadedMonExp
+ coord hl, 7, 6
+ lb bc, 3, 7
+ call PrintNumber ; exp needed to level up
+ coord hl, 9, 0
+ call StatusScreen_ClearName
+ coord hl, 9, 1
+ call StatusScreen_ClearName
+ ld a, [wMonHIndex]
+ ld [wd11e], a
+ call GetMonName
+ coord hl, 9, 1
+ call PlaceString
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ call WaitForTextScrollButtonPress ; wait for button
+ pop af
+ ld [hTilesetType], a
+ ld hl, wd72c
+ res 1, [hl]
+ ld a, $77
+ ld [rNR50], a
+ call GBPalWhiteOut
+ jp ClearScreen
+
+CalcExpToLevelUp:
+ ld a, [wLoadedMonLevel]
+ cp MAX_LEVEL
+ jr z, .atMaxLevel
+ inc a
+ ld d, a
+ callab CalcExperience
+ ld hl, wLoadedMonExp + 2
+ ld a, [hExperience + 2]
+ sub [hl]
+ ld [hld], a
+ ld a, [hExperience + 1]
+ sbc [hl]
+ ld [hld], a
+ ld a, [hExperience]
+ sbc [hl]
+ ld [hld], a
+ ret
+.atMaxLevel
+ ld hl, wLoadedMonExp
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+StatusScreenExpText:
+ db "EXP POINTS"
+ next "LEVEL UP@"
+
+StatusScreen_ClearName:
+ ld bc, 10
+ ld a, " "
+ jp FillMemory
+
+StatusScreen_PrintPP:
+; print PP or -- c times, going down two rows each time
+ ld [hli], a
+ ld [hld], a
+ add hl, de
+ dec c
+ jr nz, StatusScreen_PrintPP
+ ret
diff --git a/en/engine/menu/text_box.asm b/en/engine/menu/text_box.asm
new file mode 100644
index 00000000..b9a36652
--- /dev/null
+++ b/en/engine/menu/text_box.asm
@@ -0,0 +1,767 @@
+; function to draw various text boxes
+DisplayTextBoxID_:
+ ld a, [wTextBoxID]
+ cp TWO_OPTION_MENU
+ jp z, DisplayTwoOptionMenu
+ ld c, a
+ ld hl, TextBoxFunctionTable
+ ld de, 3
+ call SearchTextBoxTable
+ jr c, .functionTableMatch
+ ld hl, TextBoxCoordTable
+ ld de, 5
+ call SearchTextBoxTable
+ jr c, .coordTableMatch
+ ld hl, TextBoxTextAndCoordTable
+ ld de, 9
+ call SearchTextBoxTable
+ jr c, .textAndCoordTableMatch
+.done
+ ret
+.functionTableMatch
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; hl = address of function
+ ld de, .done
+ push de
+ jp hl ; jump to the function
+.coordTableMatch
+ call GetTextBoxIDCoords
+ call GetAddressOfScreenCoords
+ call TextBoxBorder
+ ret
+.textAndCoordTableMatch
+ call GetTextBoxIDCoords
+ push hl
+ call GetAddressOfScreenCoords
+ call TextBoxBorder
+ pop hl
+ call GetTextBoxIDText
+ ld a, [wd730]
+ push af
+ ld a, [wd730]
+ set 6, a ; no pauses between printing each letter
+ ld [wd730], a
+ call PlaceString
+ pop af
+ ld [wd730], a
+ call UpdateSprites
+ ret
+
+; function to search a table terminated with $ff for a byte matching c in increments of de
+; sets carry flag if a match is found and clears carry flag if not
+SearchTextBoxTable:
+ dec de
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .notFound
+ cp c
+ jr z, .found
+ add hl, de
+ jr .loop
+.found
+ scf
+.notFound
+ ret
+
+; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable
+; INPUT:
+; hl = address of coordinates
+; OUTPUT:
+; b = height
+; c = width
+; d = row of upper left corner
+; e = column of upper left corner
+GetTextBoxIDCoords:
+ ld a, [hli] ; column of upper left corner
+ ld e, a
+ ld a, [hli] ; row of upper left corner
+ ld d, a
+ ld a, [hli] ; column of lower right corner
+ sub e
+ dec a
+ ld c, a ; c = width
+ ld a, [hli] ; row of lower right corner
+ sub d
+ dec a
+ ld b, a ; b = height
+ ret
+
+; function to load a text address and text coordinates from the TextBoxTextAndCoordTable
+GetTextBoxIDText:
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a ; de = address of text
+ push de ; save text address
+ ld a, [hli]
+ ld e, a ; column of upper left corner of text
+ ld a, [hl]
+ ld d, a ; row of upper left corner of text
+ call GetAddressOfScreenCoords
+ pop de ; restore text address
+ ret
+
+; function to point hl to the screen coordinates
+; INPUT:
+; d = row
+; e = column
+; OUTPUT:
+; hl = address of upper left corner of text box
+GetAddressOfScreenCoords:
+ push bc
+ coord hl, 0, 0
+ ld bc, 20
+.loop ; loop to add d rows to the base address
+ ld a, d
+ and a
+ jr z, .addedRows
+ add hl, bc
+ dec d
+ jr .loop
+.addedRows
+ pop bc
+ add hl, de
+ ret
+
+; Format:
+; 00: text box ID
+; 01-02: function address
+TextBoxFunctionTable:
+ dbw MONEY_BOX, DisplayMoneyBox
+ dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu
+ dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu
+ db $ff ; terminator
+
+; Format:
+; 00: text box ID
+; 01: column of upper left corner
+; 02: row of upper left corner
+; 03: column of lower right corner
+; 04: row of lower right corner
+TextBoxCoordTable:
+ db MESSAGE_BOX, 0, 12, 19, 17
+ db $03, 0, 0, 19, 14
+ db $07, 0, 0, 11, 6
+ db LIST_MENU_BOX, 4, 2, 19, 12
+ db $10, 7, 0, 19, 17
+ db MON_SPRITE_POPUP, 6, 4, 14, 13
+ db $ff ; terminator
+
+; Format:
+; 00: text box ID
+; 01: column of upper left corner
+; 02: row of upper left corner
+; 03: column of lower right corner
+; 04: row of lower right corner
+; 05-06: address of text
+; 07: column of beginning of text
+; 08: row of beginning of text
+; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row]
+TextBoxTextAndCoordTable:
+ db JP_MOCHIMONO_MENU_TEMPLATE
+ db 0,0,14,17 ; text box coordinates
+ dw JapaneseMochimonoText
+ db 3,0 ; text coordinates
+
+ db USE_TOSS_MENU_TEMPLATE
+ db 13,10,19,14 ; text box coordinates
+ dw UseTossText
+ db 15,11 ; text coordinates
+
+ db JP_SAVE_MESSAGE_MENU_TEMPLATE
+ db 0,0,7,5 ; text box coordinates
+ dw JapaneseSaveMessageText
+ db 2,2 ; text coordinates
+
+ db JP_SPEED_OPTIONS_MENU_TEMPLATE
+ db 0,6,5,10 ; text box coordinates
+ dw JapaneseSpeedOptionsText
+ db 2,7 ; text coordinates
+
+ db BATTLE_MENU_TEMPLATE
+ db 8,12,19,17 ; text box coordinates
+ dw BattleMenuText
+ db 10,14 ; text coordinates
+
+ db SAFARI_BATTLE_MENU_TEMPLATE
+ db 0,12,19,17 ; text box coordinates
+ dw SafariZoneBattleMenuText
+ db 2,14 ; text coordinates
+
+ db SWITCH_STATS_CANCEL_MENU_TEMPLATE
+ db 11,11,19,17 ; text box coordinates
+ dw SwitchStatsCancelText
+ db 13,12 ; text coordinates
+
+ db BUY_SELL_QUIT_MENU_TEMPLATE
+ db 0,0,10,6 ; text box coordinates
+ dw BuySellQuitText
+ db 2,1 ; text coordinates
+
+ db MONEY_BOX_TEMPLATE
+ db 11,0,19,2 ; text box coordinates
+ dw MoneyText
+ db 13,0 ; text coordinates
+
+ db JP_AH_MENU_TEMPLATE
+ db 7,6,11,10 ; text box coordinates
+ dw JapaneseAhText
+ db 8,8 ; text coordinates
+
+ db JP_POKEDEX_MENU_TEMPLATE
+ db 11,8,19,17 ; text box coordinates
+ dw JapanesePokedexMenu
+ db 12,10 ; text coordinates
+
+; note that there is no terminator
+
+BuySellQuitText:
+ db "BUY"
+ next "SELL"
+ next "QUIT@@"
+
+UseTossText:
+ db "USE"
+ next "TOSS@"
+
+JapaneseSaveMessageText:
+ db "きろく"
+ next "メッセージ@"
+
+JapaneseSpeedOptionsText:
+ db "はやい"
+ next "おそい@"
+
+MoneyText:
+ db "MONEY@"
+
+JapaneseMochimonoText:
+ db "もちもの@"
+
+JapaneseMainMenuText:
+ db "つづきから"
+ next "さいしょから@"
+
+BattleMenuText:
+ db "FIGHT ",$E1,$E2
+ next "ITEM RUN@"
+
+SafariZoneBattleMenuText:
+ db "BALL× BAIT"
+ next "THROW ROCK RUN@"
+
+SwitchStatsCancelText:
+ db "SWITCH"
+ next "STATS"
+ next "CANCEL@"
+
+JapaneseAhText:
+ db "アッ!@"
+
+JapanesePokedexMenu:
+ db "データをみる"
+ next "なきごえ"
+ next "ぶんぷをみる"
+ next "キャンセル@"
+
+DisplayMoneyBox:
+ ld hl, wd730
+ set 6, [hl]
+ ld a, MONEY_BOX_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ coord hl, 13, 1
+ ld b, 1
+ ld c, 6
+ call ClearScreenArea
+ coord hl, 12, 1
+ ld de, wPlayerMoney
+ ld c, $a3
+ call PrintBCDNumber
+ ld hl, wd730
+ res 6, [hl]
+ ret
+
+CurrencyString:
+ db " ¥@"
+
+DoBuySellQuitMenu:
+ ld a, [wd730]
+ set 6, a ; no printing delay
+ ld [wd730], a
+ xor a
+ ld [wChosenMenuItem], a
+ ld a, BUY_SELL_QUIT_MENU_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $2
+ ld [wMaxMenuItem], a
+ ld a, $1
+ ld [wTopMenuItemY], a
+ ld a, $1
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld a, [wd730]
+ res 6, a ; turn on the printing delay
+ ld [wd730], a
+ call HandleMenuInput
+ call PlaceUnfilledArrowMenuCursor
+ bit 0, a ; was A pressed?
+ jr nz, .pressedA
+ bit 1, a ; was B pressed? (always true since only A/B are watched)
+ jr z, .pressedA
+ ld a, CANCELLED_MENU
+ ld [wMenuExitMethod], a
+ jr .quit
+.pressedA
+ ld a, CHOSE_MENU_ITEM
+ ld [wMenuExitMethod], a
+ ld a, [wCurrentMenuItem]
+ ld [wChosenMenuItem], a
+ ld b, a
+ ld a, [wMaxMenuItem]
+ cp b
+ jr z, .quit
+ ret
+.quit
+ ld a, CANCELLED_MENU
+ ld [wMenuExitMethod], a
+ ld a, [wCurrentMenuItem]
+ ld [wChosenMenuItem], a
+ scf
+ ret
+
+; displays a menu with two options to choose from
+; b = Y of upper left corner of text region
+; c = X of upper left corner of text region
+; hl = address where the text box border should be drawn
+DisplayTwoOptionMenu:
+ push hl
+ ld a, [wd730]
+ set 6, a ; no printing delay
+ ld [wd730], a
+
+; pointless because both values are overwritten before they are read
+ xor a
+ ld [wChosenMenuItem], a
+ ld [wMenuExitMethod], a
+
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $1
+ ld [wMaxMenuItem], a
+ ld a, b
+ ld [wTopMenuItemY], a
+ ld a, c
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wLastMenuItem], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ push hl
+ ld hl, wTwoOptionMenuID
+ bit 7, [hl] ; select second menu item by default?
+ res 7, [hl]
+ jr z, .storeCurrentMenuItem
+ inc a
+.storeCurrentMenuItem
+ ld [wCurrentMenuItem], a
+ pop hl
+ push hl
+ push hl
+ call TwoOptionMenu_SaveScreenTiles
+ ld a, [wTwoOptionMenuID]
+ ld hl, TwoOptionMenuStrings
+ ld e, a
+ ld d, $0
+ ld a, $5
+.menuStringLoop
+ add hl, de
+ dec a
+ jr nz, .menuStringLoop
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ ld e, l
+ ld d, h
+ pop hl
+ push de
+ ld a, [wTwoOptionMenuID]
+ cp TRADE_CANCEL_MENU
+ jr nz, .notTradeCancelMenu
+ call CableClub_TextBoxBorder
+ jr .afterTextBoxBorder
+.notTradeCancelMenu
+ call TextBoxBorder
+.afterTextBoxBorder
+ call UpdateSprites
+ pop hl
+ ld a, [hli]
+ and a ; put blank line before first menu item?
+ ld bc, 20 + 2
+ jr z, .noBlankLine
+ ld bc, 2 * 20 + 2
+.noBlankLine
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ pop hl
+ add hl, bc
+ call PlaceString
+ ld hl, wd730
+ res 6, [hl] ; turn on the printing delay
+ ld a, [wTwoOptionMenuID]
+ cp NO_YES_MENU
+ jr nz, .notNoYesMenu
+; No/Yes menu
+; this menu type ignores the B button
+; it only seems to be used when confirming the deletion of a save file
+ xor a
+ ld [wTwoOptionMenuID], a
+ ld a, [wFlags_0xcd60]
+ push af
+ push hl
+ ld hl, wFlags_0xcd60
+ bit 5, [hl]
+ set 5, [hl] ; don't play sound when A or B is pressed in menu
+ pop hl
+.noYesMenuInputLoop
+ call HandleMenuInput
+ bit 1, a ; A button pressed?
+ jr nz, .noYesMenuInputLoop ; try again if A was not pressed
+ pop af
+ pop hl
+ ld [wFlags_0xcd60], a
+ ld a, SFX_PRESS_AB
+ call PlaySound
+ jr .pressedAButton
+.notNoYesMenu
+ xor a
+ ld [wTwoOptionMenuID], a
+ call HandleMenuInput
+ pop hl
+ bit 1, a ; A button pressed?
+ jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed
+.pressedAButton
+ ld a, [wCurrentMenuItem]
+ ld [wChosenMenuItem], a
+ and a
+ jr nz, .choseSecondMenuItem
+; chose first menu item
+ ld a, CHOSE_FIRST_ITEM
+ ld [wMenuExitMethod], a
+ ld c, 15
+ call DelayFrames
+ call TwoOptionMenu_RestoreScreenTiles
+ and a
+ ret
+.choseSecondMenuItem
+ ld a, 1
+ ld [wCurrentMenuItem], a
+ ld [wChosenMenuItem], a
+ ld a, CHOSE_SECOND_ITEM
+ ld [wMenuExitMethod], a
+ ld c, 15
+ call DelayFrames
+ call TwoOptionMenu_RestoreScreenTiles
+ scf
+ ret
+
+; Some of the wider/taller two option menus will not have the screen areas
+; they cover be fully saved/restored by the two functions below.
+; The bottom and right edges of the menu may remain after the function returns.
+
+TwoOptionMenu_SaveScreenTiles:
+ ld de, wBuffer
+ lb bc, 5, 6
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .loop
+ push bc
+ ld bc, SCREEN_WIDTH - 6
+ add hl, bc
+ pop bc
+ ld c, $6
+ dec b
+ jr nz, .loop
+ ret
+
+TwoOptionMenu_RestoreScreenTiles:
+ ld de, wBuffer
+ lb bc, 5, 6
+.loop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ push bc
+ ld bc, SCREEN_WIDTH - 6
+ add hl, bc
+ pop bc
+ ld c, 6
+ dec b
+ jr nz, .loop
+ call UpdateSprites
+ ret
+
+; Format:
+; 00: byte width
+; 01: byte height
+; 02: byte put blank line before first menu item
+; 03: word text pointer
+TwoOptionMenuStrings:
+ db 4,3,0
+ dw .YesNoMenu
+ db 6,3,0
+ dw .NorthWestMenu
+ db 6,3,0
+ dw .SouthEastMenu
+ db 6,3,0
+ dw .YesNoMenu
+ db 6,3,0
+ dw .NorthEastMenu
+ db 7,3,0
+ dw .TradeCancelMenu
+ db 7,4,1
+ dw .HealCancelMenu
+ db 4,3,0
+ dw .NoYesMenu
+
+.NoYesMenu
+ db "NO"
+ next "YES@"
+.YesNoMenu
+ db "YES"
+ next "NO@"
+.NorthWestMenu
+ db "NORTH"
+ next "WEST@"
+.SouthEastMenu
+ db "SOUTH"
+ next "EAST@"
+.NorthEastMenu
+ db "NORTH"
+ next "EAST@"
+.TradeCancelMenu
+ db "TRADE"
+ next "CANCEL@"
+.HealCancelMenu
+ db "HEAL"
+ next "CANCEL@"
+
+DisplayFieldMoveMonMenu:
+ xor a
+ ld hl, wFieldMoves
+ ld [hli], a ; wFieldMoves
+ ld [hli], a ; wFieldMoves + 1
+ ld [hli], a ; wFieldMoves + 2
+ ld [hli], a ; wFieldMoves + 3
+ ld [hli], a ; wNumFieldMoves
+ ld [hl], 12 ; wFieldMovesLeftmostXCoord
+ call GetMonFieldMoves
+ ld a, [wNumFieldMoves]
+ and a
+ jr nz, .fieldMovesExist
+
+; no field moves
+ coord hl, 11, 11
+ ld b, 5
+ ld c, 7
+ call TextBoxBorder
+ call UpdateSprites
+ ld a, 12
+ ld [hFieldMoveMonMenuTopMenuItemX], a
+ coord hl, 13, 12
+ ld de, PokemonMenuEntries
+ jp PlaceString
+
+.fieldMovesExist
+ push af
+
+; Calculate the text box position and dimensions based on the leftmost X coord
+; of the field move names before adjusting for the number of field moves.
+ coord hl, 0, 11
+ ld a, [wFieldMovesLeftmostXCoord]
+ dec a
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld b, 5
+ ld a, 18
+ sub e
+ ld c, a
+ pop af
+
+; For each field move, move the top of the text box up 2 rows while the leaving
+; the bottom of the text box at the bottom of the screen.
+ ld de, -SCREEN_WIDTH * 2
+.textBoxHeightLoop
+ add hl, de
+ inc b
+ inc b
+ dec a
+ jr nz, .textBoxHeightLoop
+
+; Make space for an extra blank row above the top field move.
+ ld de, -SCREEN_WIDTH
+ add hl, de
+ inc b
+
+ call TextBoxBorder
+ call UpdateSprites
+
+; Calculate the position of the first field move name to print.
+ coord hl, 0, 12
+ ld a, [wFieldMovesLeftmostXCoord]
+ inc a
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld de, -SCREEN_WIDTH * 2
+ ld a, [wNumFieldMoves]
+.calcFirstFieldMoveYLoop
+ add hl, de
+ dec a
+ jr nz, .calcFirstFieldMoveYLoop
+
+ xor a
+ ld [wNumFieldMoves], a
+ ld de, wFieldMoves
+.printNamesLoop
+ push hl
+ ld hl, FieldMoveNames
+ ld a, [de]
+ and a
+ jr z, .donePrintingNames
+ inc de
+ ld b, a ; index of name
+.skipNamesLoop ; skip past names before the name we want
+ dec b
+ jr z, .reachedName
+.skipNameLoop ; skip past current name
+ ld a, [hli]
+ cp "@"
+ jr nz, .skipNameLoop
+ jr .skipNamesLoop
+.reachedName
+ ld b, h
+ ld c, l
+ pop hl
+ push de
+ ld d, b
+ ld e, c
+ call PlaceString
+ ld bc, SCREEN_WIDTH * 2
+ add hl, bc
+ pop de
+ jr .printNamesLoop
+
+.donePrintingNames
+ pop hl
+ ld a, [wFieldMovesLeftmostXCoord]
+ ld [hFieldMoveMonMenuTopMenuItemX], a
+ coord hl, 0, 12
+ ld a, [wFieldMovesLeftmostXCoord]
+ inc a
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld de, PokemonMenuEntries
+ jp PlaceString
+
+FieldMoveNames:
+ db "CUT@"
+ db "FLY@"
+ db "@"
+ db "SURF@"
+ db "STRENGTH@"
+ db "FLASH@"
+ db "DIG@"
+ db "TELEPORT@"
+ db "SOFTBOILED@"
+
+PokemonMenuEntries:
+ db "STATS"
+ next "SWITCH"
+ next "CANCEL@"
+
+GetMonFieldMoves:
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1Moves
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld c, NUM_MOVES + 1
+ ld hl, wFieldMoves
+.loop
+ push hl
+.nextMove
+ dec c
+ jr z, .done
+ ld a, [de] ; move ID
+ and a
+ jr z, .done
+ ld b, a
+ inc de
+ ld hl, FieldMoveDisplayData
+.fieldMoveLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .nextMove ; if the move is not a field move
+ cp b
+ jr z, .foundFieldMove
+ inc hl
+ inc hl
+ jr .fieldMoveLoop
+.foundFieldMove
+ ld a, b
+ ld [wLastFieldMoveID], a
+ ld a, [hli] ; field move name index
+ ld b, [hl] ; field move leftmost X coordinate
+ pop hl
+ ld [hli], a ; store name index in wFieldMoves
+ ld a, [wNumFieldMoves]
+ inc a
+ ld [wNumFieldMoves], a
+ ld a, [wFieldMovesLeftmostXCoord]
+ cp b
+ jr c, .skipUpdatingLeftmostXCoord
+ ld a, b
+ ld [wFieldMovesLeftmostXCoord], a
+.skipUpdatingLeftmostXCoord
+ ld a, [wLastFieldMoveID]
+ ld b, a
+ jr .loop
+.done
+ pop hl
+ ret
+
+; Format: [Move id], [name index], [leftmost tile]
+; Move id = id of move
+; Name index = index of name in FieldMoveNames
+; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed
+; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C
+FieldMoveDisplayData:
+ db CUT, $01, $0C
+ db FLY, $02, $0C
+ db $B4, $03, $0C ; unused field move
+ db SURF, $04, $0C
+ db STRENGTH, $05, $0A
+ db FLASH, $06, $0C
+ db DIG, $07, $0C
+ db TELEPORT, $08, $0A
+ db SOFTBOILED, $09, $08
+ db $ff ; list terminator
diff --git a/en/engine/menu/vending_machine.asm b/en/engine/menu/vending_machine.asm
new file mode 100755
index 00000000..aab4adf4
--- /dev/null
+++ b/en/engine/menu/vending_machine.asm
@@ -0,0 +1,139 @@
+VendingMachineMenu:
+ ld hl, VendingMachineText1
+ call PrintText
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 3
+ ld [wMaxMenuItem], a
+ ld a, 5
+ ld [wTopMenuItemY], a
+ ld a, 1
+ ld [wTopMenuItemX], a
+ ld hl, wd730
+ set 6, [hl]
+ coord hl, 0, 3
+ ld b, 8
+ ld c, 12
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 2, 5
+ ld de, DrinkText
+ call PlaceString
+ coord hl, 9, 6
+ ld de, DrinkPriceText
+ call PlaceString
+ ld hl, wd730
+ res 6, [hl]
+ call HandleMenuInput
+ bit 1, a ; pressed B?
+ jr nz, .notThirsty
+ ld a, [wCurrentMenuItem]
+ cp 3 ; chose Cancel?
+ jr z, .notThirsty
+ xor a
+ ld [hMoney], a
+ ld [hMoney + 2], a
+ ld a, $2
+ ld [hMoney + 1], a
+ call HasEnoughMoney
+ jr nc, .enoughMoney
+ ld hl, VendingMachineText4
+ jp PrintText
+.enoughMoney
+ call LoadVendingMachineItem
+ ld a, [hVendingMachineItem]
+ ld b, a
+ ld c, 1
+ call GiveItem
+ jr nc, .BagFull
+
+ ld b, 60 ; number of times to play the "brrrrr" sound
+.playDeliverySound
+ ld c, 2
+ call DelayFrames
+ push bc
+ ld a, SFX_PUSH_BOULDER
+ call PlaySound
+ pop bc
+ dec b
+ jr nz, .playDeliverySound
+
+ ld hl, VendingMachineText5
+ call PrintText
+ ld hl, hVendingMachinePrice + 2
+ ld de, wPlayerMoney + 2
+ ld c, $3
+ predef SubBCDPredef
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ jp DisplayTextBoxID
+.BagFull
+ ld hl, VendingMachineText6
+ jp PrintText
+.notThirsty
+ ld hl, VendingMachineText7
+ jp PrintText
+
+VendingMachineText1:
+ TX_FAR _VendingMachineText1
+ db "@"
+
+DrinkText:
+ db "FRESH WATER"
+ next "SODA POP"
+ next "LEMONADE"
+ next "CANCEL@"
+
+DrinkPriceText:
+ db "¥200"
+ next "¥300"
+ next "¥350"
+ next "@"
+
+VendingMachineText4:
+ TX_FAR _VendingMachineText4
+ db "@"
+
+VendingMachineText5:
+ TX_FAR _VendingMachineText5
+ db "@"
+
+VendingMachineText6:
+ TX_FAR _VendingMachineText6
+ db "@"
+
+VendingMachineText7:
+ TX_FAR _VendingMachineText7
+ db "@"
+
+LoadVendingMachineItem:
+ ld hl, VendingPrices
+ ld a, [wCurrentMenuItem]
+ add a
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ ld [hVendingMachineItem], a
+ ld a, [hli]
+ ld [hVendingMachinePrice], a
+ ld a, [hli]
+ ld [hVendingMachinePrice + 1], a
+ ld a, [hl]
+ ld [hVendingMachinePrice + 2], a
+ ret
+
+VendingPrices:
+ db FRESH_WATER
+ money 200
+ db SODA_POP
+ money 300
+ db LEMONADE
+ money 350
diff --git a/en/engine/oak_speech2.asm b/en/engine/oak_speech2.asm
new file mode 100755
index 00000000..1258c59b
--- /dev/null
+++ b/en/engine/oak_speech2.asm
@@ -0,0 +1,272 @@
+ChoosePlayerName:
+ call OakSpeechSlidePicRight
+ ld de, DefaultNamesPlayer
+ call DisplayIntroNameTextBox
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .customName
+ ld hl, DefaultNamesPlayerList
+ call GetDefaultName
+ ld de, wPlayerName
+ call OakSpeechSlidePicLeft
+ jr .done
+.customName
+ ld hl, wPlayerName
+ xor a ; NAME_PLAYER_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ ld a, [wcf4b]
+ cp "@"
+ jr z, .customName
+ call ClearScreen
+ call Delay3
+ ld de, RedPicFront
+ ld b, BANK(RedPicFront)
+ call IntroDisplayPicCenteredOrUpperRight
+.done
+ ld hl, YourNameIsText
+ jp PrintText
+
+YourNameIsText:
+ TX_FAR _YourNameIsText
+ db "@"
+
+ChooseRivalName:
+ call OakSpeechSlidePicRight
+ ld de, DefaultNamesRival
+ call DisplayIntroNameTextBox
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .customName
+ ld hl, DefaultNamesRivalList
+ call GetDefaultName
+ ld de, wRivalName
+ call OakSpeechSlidePicLeft
+ jr .done
+.customName
+ ld hl, wRivalName
+ ld a, NAME_RIVAL_SCREEN
+ ld [wNamingScreenType], a
+ call DisplayNamingScreen
+ ld a, [wcf4b]
+ cp "@"
+ jr z, .customName
+ call ClearScreen
+ call Delay3
+ ld de, Rival1Pic
+ ld b, $13
+ call IntroDisplayPicCenteredOrUpperRight
+.done
+ ld hl, HisNameIsText
+ jp PrintText
+
+HisNameIsText:
+ TX_FAR _HisNameIsText
+ db "@"
+
+OakSpeechSlidePicLeft:
+ push de
+ coord hl, 0, 0
+ lb bc, 12, 11
+ call ClearScreenArea ; clear the name list text box
+ ld c, 10
+ call DelayFrames
+ pop de
+ ld hl, wcd6d
+ ld bc, NAME_LENGTH
+ call CopyData
+ call Delay3
+ coord hl, 12, 4
+ lb de, 6, 6 * SCREEN_WIDTH + 5
+ ld a, $ff
+ jr OakSpeechSlidePicCommon
+
+OakSpeechSlidePicRight:
+ coord hl, 5, 4
+ lb de, 6, 6 * SCREEN_WIDTH + 5
+ xor a
+
+OakSpeechSlidePicCommon:
+ push hl
+ push de
+ push bc
+ ld [hSlideDirection], a
+ ld a, d
+ ld [hSlideAmount], a
+ ld a, e
+ ld [hSlidingRegionSize], a
+ ld c, a
+ ld a, [hSlideDirection]
+ and a
+ jr nz, .next
+; If sliding right, point hl to the end of the pic's tiles.
+ ld d, 0
+ add hl, de
+.next
+ ld d, h
+ ld e, l
+.loop
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, [hSlideDirection]
+ and a
+ jr nz, .slideLeft
+; sliding right
+ ld a, [hli]
+ ld [hld], a
+ dec hl
+ jr .next2
+.slideLeft
+ ld a, [hld]
+ ld [hli], a
+ inc hl
+.next2
+ dec c
+ jr nz, .loop
+ ld a, [hSlideDirection]
+ and a
+ jr z, .next3
+; If sliding left, we need to zero the last tile in the pic (there is no need
+; to take a corresponding action when sliding right because hl initially points
+; to a 0 tile in that case).
+ xor a
+ dec hl
+ ld [hl], a
+.next3
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ ld a, [hSlidingRegionSize]
+ ld c, a
+ ld h, d
+ ld l, e
+ ld a, [hSlideDirection]
+ and a
+ jr nz, .slideLeft2
+ inc hl
+ jr .next4
+.slideLeft2
+ dec hl
+.next4
+ ld d, h
+ ld e, l
+ ld a, [hSlideAmount]
+ dec a
+ ld [hSlideAmount], a
+ jr nz, .loop
+ pop bc
+ pop de
+ pop hl
+ ret
+
+DisplayIntroNameTextBox:
+ push de
+ coord hl, 0, 0
+ ld b, $a
+ ld c, $9
+ call TextBoxBorder
+ coord hl, 3, 0
+ ld de, .namestring
+ call PlaceString
+ pop de
+ coord hl, 2, 2
+ call PlaceString
+ call UpdateSprites
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ inc a
+ ld [wTopMenuItemX], a
+ ld [wMenuWatchedKeys], a ; A_BUTTON
+ inc a
+ ld [wTopMenuItemY], a
+ inc a
+ ld [wMaxMenuItem], a
+ jp HandleMenuInput
+
+.namestring
+ db "NAME@"
+
+IF DEF(_RED)
+DefaultNamesPlayer:
+ db "NEW NAME"
+ next "RED"
+ next "ASH"
+ next "JACK"
+ db "@"
+
+DefaultNamesRival:
+ db "NEW NAME"
+ next "BLUE"
+ next "GARY"
+ next "JOHN"
+ db "@"
+ENDC
+
+IF DEF(_BLUE)
+DefaultNamesPlayer:
+ db "NEW NAME"
+ next "BLUE"
+ next "GARY"
+ next "JOHN"
+ db "@"
+
+DefaultNamesRival:
+ db "NEW NAME"
+ next "RED"
+ next "ASH"
+ next "JACK"
+ db "@"
+ENDC
+
+GetDefaultName:
+; a = name index
+; hl = name list
+ ld b, a
+ ld c, 0
+.loop
+ ld d, h
+ ld e, l
+.innerLoop
+ ld a, [hli]
+ cp "@"
+ jr nz, .innerLoop
+ ld a, b
+ cp c
+ jr z, .foundName
+ inc c
+ jr .loop
+.foundName
+ ld h, d
+ ld l, e
+ ld de, wcd6d
+ ld bc, $14
+ jp CopyData
+
+IF DEF(_RED)
+DefaultNamesPlayerList:
+ db "NEW NAME@"
+ db "RED@"
+ db "ASH@"
+ db "JACK@"
+DefaultNamesRivalList:
+ db "NEW NAME@"
+ db "BLUE@"
+ db "GARY@"
+ db "JOHN@"
+ENDC
+IF DEF(_BLUE)
+DefaultNamesPlayerList:
+ db "NEW NAME@"
+ db "BLUE@"
+ db "GARY@"
+ db "JOHN@"
+DefaultNamesRivalList:
+ db "NEW NAME@"
+ db "RED@"
+ db "ASH@"
+ db "JACK@"
+ENDC
+
+TextTerminator_6b20:
+ db "@"
diff --git a/en/engine/overworld/movement.asm b/en/engine/overworld/movement.asm
new file mode 100644
index 00000000..bbfbbc39
--- /dev/null
+++ b/en/engine/overworld/movement.asm
@@ -0,0 +1,880 @@
+UpdatePlayerSprite:
+ ld a, [wSpriteStateData2]
+ and a
+ jr z, .checkIfTextBoxInFrontOfSprite
+ cp $ff
+ jr z, .disableSprite
+ dec a
+ ld [wSpriteStateData2], a
+ jr .disableSprite
+; check if a text box is in front of the sprite by checking if the lower left
+; background tile the sprite is standing on is greater than $5F, which is
+; the maximum number for map tiles
+.checkIfTextBoxInFrontOfSprite
+ aCoord 8, 9
+ ld [hTilePlayerStandingOn], a
+ cp $60
+ jr c, .lowerLeftTileIsMapTile
+.disableSprite
+ ld a, $ff
+ ld [wSpriteStateData1 + 2], a
+ ret
+.lowerLeftTileIsMapTile
+ call DetectCollisionBetweenSprites
+ ld h, wSpriteStateData1 / $100
+ ld a, [wWalkCounter]
+ and a
+ jr nz, .moving
+ ld a, [wPlayerMovingDirection]
+; check if down
+ bit PLAYER_DIR_BIT_DOWN, a
+ jr z, .checkIfUp
+ xor a ; ld a, SPRITE_FACING_DOWN
+ jr .next
+.checkIfUp
+ bit PLAYER_DIR_BIT_UP, a
+ jr z, .checkIfLeft
+ ld a, SPRITE_FACING_UP
+ jr .next
+.checkIfLeft
+ bit PLAYER_DIR_BIT_LEFT, a
+ jr z, .checkIfRight
+ ld a, SPRITE_FACING_LEFT
+ jr .next
+.checkIfRight
+ bit PLAYER_DIR_BIT_RIGHT, a
+ jr z, .notMoving
+ ld a, SPRITE_FACING_RIGHT
+ jr .next
+.notMoving
+; zero the animation counters
+ xor a
+ ld [wSpriteStateData1 + 7], a
+ ld [wSpriteStateData1 + 8], a
+ jr .calcImageIndex
+.next
+ ld [wSpriteStateData1 + 9], a ; facing direction
+ ld a, [wFontLoaded]
+ bit 0, a
+ jr nz, .notMoving
+.moving
+ ld a, [wd736]
+ bit 7, a ; is the player sprite spinning due to a spin tile?
+ jr nz, .skipSpriteAnim
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl]
+ inc a
+ ld [hl], a
+ cp 4
+ jr nz, .calcImageIndex
+ xor a
+ ld [hl], a
+ inc hl
+ ld a, [hl]
+ inc a
+ and $3
+ ld [hl], a
+.calcImageIndex
+ ld a, [wSpriteStateData1 + 8]
+ ld b, a
+ ld a, [wSpriteStateData1 + 9]
+ add b
+ ld [wSpriteStateData1 + 2], a
+.skipSpriteAnim
+; If the player is standing on a grass tile, make the player's sprite have
+; lower priority than the background so that it's partially obscured by the
+; grass. Only the lower half of the sprite is permitted to have the priority
+; bit set by later logic.
+ ld a, [hTilePlayerStandingOn]
+ ld c, a
+ ld a, [wGrassTile]
+ cp c
+ ld a, $0
+ jr nz, .next2
+ ld a, $80
+.next2
+ ld [wSpriteStateData2 + 7], a
+ ret
+
+UnusedReadSpriteDataFunction:
+ push bc
+ push af
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld c, a
+ pop af
+ add c
+ ld l, a
+ pop bc
+ ret
+
+UpdateNPCSprite:
+ ld a, [H_CURRENTSPRITEOFFSET]
+ swap a
+ dec a
+ add a
+ ld hl, wMapSpriteData
+ add l
+ ld l, a
+ ld a, [hl] ; read movement byte 2
+ ld [wCurSpriteMovement2], a
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc l
+ ld a, [hl] ; c1x1
+ and a
+ jp z, InitializeSpriteStatus
+ call CheckSpriteAvailability
+ ret c ; if sprite is invisible, on tile >=$60, in grass or player is currently walking
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc l
+ ld a, [hl] ; c1x1
+ bit 7, a ; is the face player flag set?
+ jp nz, MakeNPCFacePlayer
+ ld b, a
+ ld a, [wFontLoaded]
+ bit 0, a
+ jp nz, notYetMoving
+ ld a, b
+ cp $2
+ jp z, UpdateSpriteMovementDelay ; c1x1 == 2
+ cp $3
+ jp z, UpdateSpriteInWalkingAnimation ; c1x1 == 3
+ ld a, [wWalkCounter]
+ and a
+ ret nz ; don't do anything yet if player is currently moving (redundant, already tested in CheckSpriteAvailability)
+ call InitializeSpriteScreenPosition
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ inc a
+ jr z, .randomMovement ; value $FF
+ inc a
+ jr z, .randomMovement ; value $FE
+; scripted movement
+ dec a
+ ld [hl], a ; increment movement byte 1 (movement data index)
+ dec a
+ push hl
+ ld hl, wNPCNumScriptedSteps
+ dec [hl] ; decrement wNPCNumScriptedSteps
+ pop hl
+ ld de, wNPCMovementDirections
+ call LoadDEPlusA ; a = [wNPCMovementDirections + movement byte 1]
+ cp $e0
+ jp z, ChangeFacingDirection
+ cp STAY
+ jr nz, .next
+; reached end of wNPCMovementDirections list
+ ld [hl], a ; store $ff in movement byte 1, disabling scripted movement
+ ld hl, wd730
+ res 0, [hl]
+ xor a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wWastedByteCD3A], a
+ ret
+.next
+ cp WALK
+ jr nz, .determineDirection
+; current NPC movement data is $fe. this seems buggy
+ ld [hl], $1 ; set movement byte 1 to $1
+ ld de, wNPCMovementDirections
+ call LoadDEPlusA ; a = [wNPCMovementDirections + $fe] (?)
+ jr .determineDirection
+.randomMovement
+ call GetTileSpriteStandsOn
+ call Random
+.determineDirection
+ ld b, a
+ ld a, [wCurSpriteMovement2]
+ cp $d0
+ jr z, .moveDown ; movement byte 2 = $d0 forces down
+ cp $d1
+ jr z, .moveUp ; movement byte 2 = $d1 forces up
+ cp $d2
+ jr z, .moveLeft ; movement byte 2 = $d2 forces left
+ cp $d3
+ jr z, .moveRight ; movement byte 2 = $d3 forces right
+ ld a, b
+ cp $40 ; a < $40: down (or left)
+ jr nc, .notDown
+ ld a, [wCurSpriteMovement2]
+ cp $2
+ jr z, .moveLeft ; movement byte 2 = $2 only allows left or right
+.moveDown
+ ld de, 2*SCREEN_WIDTH
+ add hl, de ; move tile pointer two rows down
+ lb de, 1, 0
+ lb bc, 4, SPRITE_FACING_DOWN
+ jr TryWalking
+.notDown
+ cp $80 ; $40 <= a < $80: up (or right)
+ jr nc, .notUp
+ ld a, [wCurSpriteMovement2]
+ cp $2
+ jr z, .moveRight ; movement byte 2 = $2 only allows left or right
+.moveUp
+ ld de, -2*SCREEN_WIDTH
+ add hl, de ; move tile pointer two rows up
+ lb de, -1, 0
+ lb bc, 8, SPRITE_FACING_UP
+ jr TryWalking
+.notUp
+ cp $c0 ; $80 <= a < $c0: left (or up)
+ jr nc, .notLeft
+ ld a, [wCurSpriteMovement2]
+ cp $1
+ jr z, .moveUp ; movement byte 2 = $1 only allows up or down
+.moveLeft
+ dec hl
+ dec hl ; move tile pointer two columns left
+ lb de, 0, -1
+ lb bc, 2, SPRITE_FACING_LEFT
+ jr TryWalking
+.notLeft ; $c0 <= a: right (or down)
+ ld a, [wCurSpriteMovement2]
+ cp $1
+ jr z, .moveDown ; movement byte 2 = $1 only allows up or down
+.moveRight
+ inc hl
+ inc hl ; move tile pointer two columns right
+ lb de, 0, 1
+ lb bc, 1, SPRITE_FACING_RIGHT
+ jr TryWalking
+
+; changes facing direction by zeroing the movement delta and calling TryWalking
+ChangeFacingDirection:
+ ld de, $0
+ ; fall through
+
+; b: direction (1,2,4 or 8)
+; c: new facing direction (0,4,8 or $c)
+; d: Y movement delta (-1, 0 or 1)
+; e: X movement delta (-1, 0 or 1)
+; hl: pointer to tile the sprite would walk onto
+; set carry on failure, clears carry on success
+TryWalking:
+ push hl
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld [hl], c ; c1x9 (update facing direction)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $3
+ ld l, a
+ ld [hl], d ; c1x3 (update Y movement delta)
+ inc l
+ inc l
+ ld [hl], e ; c1x5 (update X movement delta)
+ pop hl
+ push de
+ ld c, [hl] ; read tile to walk onto
+ call CanWalkOntoTile
+ pop de
+ ret c ; cannot walk there (reinitialization of delay values already done)
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hl] ; c2x4: Y position
+ add d
+ ld [hli], a ; update Y position
+ ld a, [hl] ; c2x5: X position
+ add e
+ ld [hl], a ; update X position
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ ld [hl], $10 ; c2x0=16: walk animation counter
+ dec h
+ inc l
+ ld [hl], $3 ; c1x1: set movement status to walking
+ jp UpdateSpriteImage
+
+; update the walking animation parameters for a sprite that is currently walking
+UpdateSpriteInWalkingAnimation:
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl] ; c1x7 (counter until next walk animation frame)
+ inc a
+ ld [hl], a ; c1x7 += 1
+ cp $4
+ jr nz, .noNextAnimationFrame
+ xor a
+ ld [hl], a ; c1x7 = 0
+ inc l
+ ld a, [hl] ; c1x8 (walk animation frame)
+ inc a
+ and $3
+ ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
+.noNextAnimationFrame
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $3
+ ld l, a
+ ld a, [hli] ; c1x3 (movement Y delta)
+ ld b, a
+ ld a, [hl] ; c1x4 (screen Y position)
+ add b
+ ld [hli], a ; update screen Y position
+ ld a, [hli] ; c1x5 (movement X delta)
+ ld b, a
+ ld a, [hl] ; c1x6 (screen X position)
+ add b
+ ld [hl], a ; update screen X position
+ ld a, [H_CURRENTSPRITEOFFSET]
+ ld l, a
+ inc h
+ ld a, [hl] ; c2x0 (walk animation counter)
+ dec a
+ ld [hl], a ; update walk animation counter
+ ret nz
+ ld a, $6 ; walking finished, update state
+ add l
+ ld l, a
+ ld a, [hl] ; c2x6 (movement byte 1)
+ cp $fe
+ jr nc, .initNextMovementCounter ; values $fe and $ff
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ dec h
+ ld [hl], $1 ; c1x1 = 1 (movement status ready)
+ ret
+.initNextMovementCounter
+ call Random
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld a, [hRandomAdd]
+ and $7f
+ ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f]
+ dec h ; note that value 0 actually makes the delay $100 (bug?)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $2 ; c1x1 = 2 (movement status)
+ inc l
+ inc l
+ xor a
+ ld b, [hl] ; c1x3 (movement Y delta)
+ ld [hli], a ; reset movement Y delta
+ inc l
+ ld c, [hl] ; c1x5 (movement X delta)
+ ld [hl], a ; reset movement X delta
+ ret
+
+; update delay value (c2x8) for sprites in the delayed state (c1x1)
+UpdateSpriteMovementDelay:
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ inc l
+ inc l
+ cp $fe
+ jr nc, .tickMoveCounter ; values $fe or $ff
+ ld [hl], $0
+ jr .moving
+.tickMoveCounter
+ dec [hl] ; c2x8: frame counter until next movement
+ jr nz, notYetMoving
+.moving
+ dec h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $1 ; c1x1 = 1 (mark as ready to move)
+notYetMoving:
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld [hl], $0 ; c1x8 = 0 (walk animation frame)
+ jp UpdateSpriteImage
+
+MakeNPCFacePlayer:
+; Make an NPC face the player if the player has spoken to him or her.
+
+; Check if the behaviour of the NPC facing the player when spoken to is
+; disabled. This is only done when rubbing the S.S. Anne captain's back.
+ ld a, [wd72d]
+ bit 5, a
+ jr nz, notYetMoving
+ res 7, [hl]
+ ld a, [wPlayerDirection]
+ bit PLAYER_DIR_BIT_UP, a
+ jr z, .notFacingDown
+ ld c, SPRITE_FACING_DOWN
+ jr .facingDirectionDetermined
+.notFacingDown
+ bit PLAYER_DIR_BIT_DOWN, a
+ jr z, .notFacingUp
+ ld c, SPRITE_FACING_UP
+ jr .facingDirectionDetermined
+.notFacingUp
+ bit PLAYER_DIR_BIT_LEFT, a
+ jr z, .notFacingRight
+ ld c, SPRITE_FACING_RIGHT
+ jr .facingDirectionDetermined
+.notFacingRight
+ ld c, SPRITE_FACING_LEFT
+.facingDirectionDetermined
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld [hl], c ; c1x9: set facing direction
+ jr notYetMoving
+
+InitializeSpriteStatus:
+ ld [hl], $1 ; $c1x1: set movement status to ready
+ inc l
+ ld [hl], $ff ; $c1x2: set sprite image to $ff (invisible/off screen)
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, $8
+ ld [hli], a ; $c2x2: set Y displacement to 8
+ ld [hl], a ; $c2x3: set X displacement to 8
+ ret
+
+; calculates the sprite's screen position form its map position and the player position
+InitializeSpriteScreenPosition:
+ ld h, wSpriteStateData2 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [wYCoord]
+ ld b, a
+ ld a, [hl] ; c2x4 (Y position + 4)
+ sub b ; relative to player position
+ swap a ; * 16
+ sub $4 ; - 4
+ dec h
+ ld [hli], a ; c1x4 (screen Y position)
+ inc h
+ ld a, [wXCoord]
+ ld b, a
+ ld a, [hli] ; c2x6 (X position + 4)
+ sub b ; relative to player position
+ swap a ; * 16
+ dec h
+ ld [hl], a ; c1x6 (screen X position)
+ ret
+
+; tests if sprite is off screen or otherwise unable to do anything
+CheckSpriteAvailability:
+ predef IsObjectHidden
+ ld a, [$ffe5]
+ and a
+ jp nz, .spriteInvisible
+ ld h, wSpriteStateData2 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6: movement byte 1
+ cp $fe
+ jr c, .skipXVisibilityTest ; movement byte 1 < $fe (i.e. the sprite's movement is scripted)
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld b, [hl] ; c2x4: Y pos (+4)
+ ld a, [wYCoord]
+ cp b
+ jr z, .skipYVisibilityTest
+ jr nc, .spriteInvisible ; above screen region
+ add $8 ; screen is 9 tiles high
+ cp b
+ jr c, .spriteInvisible ; below screen region
+.skipYVisibilityTest
+ inc l
+ ld b, [hl] ; c2x5: X pos (+4)
+ ld a, [wXCoord]
+ cp b
+ jr z, .skipXVisibilityTest
+ jr nc, .spriteInvisible ; left of screen region
+ add $9 ; screen is 10 tiles wide
+ cp b
+ jr c, .spriteInvisible ; right of screen region
+.skipXVisibilityTest
+; make the sprite invisible if a text box is in front of it
+; $5F is the maximum number for map tiles
+ call GetTileSpriteStandsOn
+ ld d, $60
+ ld a, [hli]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom left tile)
+ ld a, [hld]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom right tile)
+ ld bc, -20
+ add hl, bc ; go back one row of tiles
+ ld a, [hli]
+ cp d
+ jr nc, .spriteInvisible ; standing on tile with ID >=$60 (top left tile)
+ ld a, [hl]
+ cp d
+ jr c, .spriteVisible ; standing on tile with ID >=$60 (top right tile)
+.spriteInvisible
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld [hl], $ff ; c1x2
+ scf
+ jr .done
+.spriteVisible
+ ld c, a
+ ld a, [wWalkCounter]
+ and a
+ jr nz, .done ; if player is currently walking, we're done
+ call UpdateSpriteImage
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [wGrassTile]
+ cp c
+ ld a, $0
+ jr nz, .notInGrass
+ ld a, $80
+.notInGrass
+ ld [hl], a ; c2x7
+ and a
+.done
+ ret
+
+UpdateSpriteImage:
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ ld a, [hli] ; c1x8: walk animation frame
+ ld b, a
+ ld a, [hl] ; c1x9: facing direction
+ add b
+ ld b, a
+ ld a, [$ff93] ; current sprite offset
+ add b
+ ld b, a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld [hl], b ; c1x2: sprite to display
+ ret
+
+; tests if sprite can walk the specified direction
+; b: direction (1,2,4 or 8)
+; c: ID of tile the sprite would walk onto
+; d: Y movement delta (-1, 0 or 1)
+; e: X movement delta (-1, 0 or 1)
+; set carry on failure, clears carry on success
+CanWalkOntoTile:
+ ld h, wSpriteStateData2 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; c2x6 (movement byte 1)
+ cp $fe
+ jr nc, .notScripted ; values $fe and $ff
+; always allow walking if the movement is scripted
+ and a
+ ret
+.notScripted
+ ld a, [wTilesetCollisionPtr]
+ ld l, a
+ ld a, [wTilesetCollisionPtr+1]
+ ld h, a
+.tilePassableLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .impassable
+ cp c
+ jr nz, .tilePassableLoop
+ ld h, $c2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $6
+ ld l, a
+ ld a, [hl] ; $c2x6 (movement byte 1)
+ inc a
+ jr z, .impassable ; if $ff, no movement allowed (however, changing direction is)
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hli] ; c1x4 (screen Y pos)
+ add $4 ; align to blocks (Y pos is always 4 pixels off)
+ add d ; add Y delta
+ cp $80 ; if value is >$80, the destination is off screen (either $81 or $FF underflow)
+ jr nc, .impassable ; don't walk off screen
+ inc l
+ ld a, [hl] ; c1x6 (screen X pos)
+ add e ; add X delta
+ cp $90 ; if value is >$90, the destination is off screen (either $91 or $FF underflow)
+ jr nc, .impassable ; don't walk off screen
+ push de
+ push bc
+ call DetectCollisionBetweenSprites
+ pop bc
+ pop de
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $c
+ ld l, a
+ ld a, [hl] ; c1xc (directions in which sprite collision would occur)
+ and b ; check against chosen direction (1,2,4 or 8)
+ jr nz, .impassable ; collision between sprites, don't go there
+ ld h, wSpriteStateData2 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, [hli] ; c2x2 (sprite Y displacement, initialized at $8, keep track of where a sprite did go)
+ bit 7, d ; check if going upwards (d=$ff)
+ jr nz, .upwards
+ add d
+ cp $5
+ jr c, .impassable ; if c2x2+d < 5, don't go ;bug: this tests probably were supposed to prevent sprites
+ jr .checkHorizontal ; from walking out too far, but this line makes sprites get stuck
+.upwards ; whenever they walked upwards 5 steps
+ sub $1 ; on the other hand, the amount a sprite can walk out to the
+ jr c, .impassable ; if d2x2 == 0, don't go ; right of bottom is not limited (until the counter overflows)
+.checkHorizontal
+ ld d, a
+ ld a, [hl] ; c2x3 (sprite X displacement, initialized at $8, keep track of where a sprite did go)
+ bit 7, e ; check if going left (e=$ff)
+ jr nz, .left
+ add e
+ cp $5 ; compare, but no conditional jump like in the vertical check above (bug?)
+ jr .passable
+.left
+ sub $1
+ jr c, .impassable ; if d2x3 == 0, don't go
+.passable
+ ld [hld], a ; update c2x3
+ ld [hl], d ; update c2x2
+ and a ; clear carry (marking success)
+ ret
+.impassable
+ ld h, $c1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ inc a
+ ld l, a
+ ld [hl], $2 ; c1x1 = 2 (set movement status to delayed)
+ inc l
+ inc l
+ xor a
+ ld [hli], a ; c1x3 = 0 (clear Y movement delta)
+ inc l
+ ld [hl], a ; c1x5 = 0 (clear X movement delta)
+ inc h
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $8
+ ld l, a
+ call Random
+ ld a, [hRandomAdd]
+ and $7f
+ ld [hl], a ; c2x8: set next movement delay to a random value in [0,$7f] (again with delay $100 if value is 0)
+ scf ; set carry (marking failure to walk)
+ ret
+
+; calculates the tile pointer pointing to the tile the current sprite stands on
+; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to
+; hl: output pointer
+GetTileSpriteStandsOn:
+ ld h, wSpriteStateData1 / $100
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $4
+ ld l, a
+ ld a, [hli] ; c1x4: screen Y position
+ add $4 ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
+ and $f0 ; in case object is currently moving
+ srl a ; screen Y tile * 4
+ ld c, a
+ ld b, $0
+ inc l
+ ld a, [hl] ; c1x6: screen Y position
+ srl a
+ srl a
+ srl a ; screen X tile
+ add SCREEN_WIDTH ; screen X tile + 20
+ ld d, $0
+ ld e, a
+ coord hl, 0, 0
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ add hl, de ; wTileMap + 20*(screen Y tile + 1) + screen X tile
+ ret
+
+; loads [de+a] into a
+LoadDEPlusA:
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d
+.noCarry
+ ld a, [de]
+ ret
+
+DoScriptedNPCMovement:
+; This is an alternative method of scripting an NPC's movement and is only used
+; a few times in the game. It is used when the NPC and player must walk together
+; in sync, such as when the player is following the NPC somewhere. An NPC can't
+; be moved in sync with the player using the other method.
+ ld a, [wd730]
+ bit 7, a
+ ret z
+ ld hl, wd72e
+ bit 7, [hl]
+ set 7, [hl]
+ jp z, InitScriptedNPCMovement
+ ld hl, wNPCMovementDirections2
+ ld a, [wNPCMovementDirections2Index]
+ add l
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld a, [hl]
+; check if moving up
+ cp NPC_MOVEMENT_UP
+ jr nz, .checkIfMovingDown
+ call GetSpriteScreenYPointer
+ ld c, SPRITE_FACING_UP
+ ld a, -2
+ jr .move
+.checkIfMovingDown
+ cp NPC_MOVEMENT_DOWN
+ jr nz, .checkIfMovingLeft
+ call GetSpriteScreenYPointer
+ ld c, SPRITE_FACING_DOWN
+ ld a, 2
+ jr .move
+.checkIfMovingLeft
+ cp NPC_MOVEMENT_LEFT
+ jr nz, .checkIfMovingRight
+ call GetSpriteScreenXPointer
+ ld c, SPRITE_FACING_LEFT
+ ld a, -2
+ jr .move
+.checkIfMovingRight
+ cp NPC_MOVEMENT_RIGHT
+ jr nz, .noMatch
+ call GetSpriteScreenXPointer
+ ld c, SPRITE_FACING_RIGHT
+ ld a, 2
+ jr .move
+.noMatch
+ cp $ff
+ ret
+.move
+ ld b, a
+ ld a, [hl]
+ add b
+ ld [hl], a
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld a, c
+ ld [hl], a ; facing direction
+ call AnimScriptedNPCMovement
+ ld hl, wScriptedNPCWalkCounter
+ dec [hl]
+ ret nz
+ ld a, 8
+ ld [wScriptedNPCWalkCounter], a
+ ld hl, wNPCMovementDirections2Index
+ inc [hl]
+ ret
+
+InitScriptedNPCMovement:
+ xor a
+ ld [wNPCMovementDirections2Index], a
+ ld a, 8
+ ld [wScriptedNPCWalkCounter], a
+ jp AnimScriptedNPCMovement
+
+GetSpriteScreenYPointer:
+ ld a, $4
+ ld b, a
+ jr GetSpriteScreenXYPointerCommon
+
+GetSpriteScreenXPointer:
+ ld a, $6
+ ld b, a
+
+GetSpriteScreenXYPointerCommon:
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add l
+ add b
+ ld l, a
+ ret
+
+AnimScriptedNPCMovement:
+ ld hl, wSpriteStateData2
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $e
+ ld l, a
+ ld a, [hl] ; VRAM slot
+ dec a
+ swap a
+ ld b, a
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $9
+ ld l, a
+ ld a, [hl] ; facing direction
+ cp SPRITE_FACING_DOWN
+ jr z, .anim
+ cp SPRITE_FACING_UP
+ jr z, .anim
+ cp SPRITE_FACING_LEFT
+ jr z, .anim
+ cp SPRITE_FACING_RIGHT
+ jr z, .anim
+ ret
+.anim
+ add b
+ ld b, a
+ ld [hSpriteVRAMSlotAndFacing], a
+ call AdvanceScriptedNPCAnimFrameCounter
+ ld hl, wSpriteStateData1
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $2
+ ld l, a
+ ld a, [hSpriteVRAMSlotAndFacing]
+ ld b, a
+ ld a, [hSpriteAnimFrameCounter]
+ add b
+ ld [hl], a
+ ret
+
+AdvanceScriptedNPCAnimFrameCounter:
+ ld a, [H_CURRENTSPRITEOFFSET]
+ add $7
+ ld l, a
+ ld a, [hl] ; intra-animation frame counter
+ inc a
+ ld [hl], a
+ cp 4
+ ret nz
+ xor a
+ ld [hl], a ; reset intra-animation frame counter
+ inc l
+ ld a, [hl] ; animation frame counter
+ inc a
+ and $3
+ ld [hl], a
+ ld [hSpriteAnimFrameCounter], a
+ ret
diff --git a/en/engine/overworld/pokemart.asm b/en/engine/overworld/pokemart.asm
new file mode 100755
index 00000000..dc5b29b5
--- /dev/null
+++ b/en/engine/overworld/pokemart.asm
@@ -0,0 +1,272 @@
+DisplayPokemartDialogue_:
+ ld a, [wListScrollOffset]
+ ld [wSavedListScrollOffset], a
+ call UpdateSprites
+ xor a
+ ld [wBoughtOrSoldItemInMart], a
+.loop
+ xor a
+ ld [wListScrollOffset], a
+ ld [wCurrentMenuItem], a
+ ld [wPlayerMonNumber], a
+ inc a
+ ld [wPrintItemPrices], a
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, BUY_SELL_QUIT_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+
+; This code is useless. It copies the address of the pokemart's inventory to hl,
+; but the address is never used.
+ ld hl, wItemListPointer
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a
+
+ ld a, [wMenuExitMethod]
+ cp CANCELLED_MENU
+ jp z, .done
+ ld a, [wChosenMenuItem]
+ and a ; buying?
+ jp z, .buyMenu
+ dec a ; selling?
+ jp z, .sellMenu
+ dec a ; quitting?
+ jp z, .done
+.sellMenu
+
+; the same variables are set again below, so this code has no effect
+ xor a
+ ld [wPrintItemPrices], a
+ ld a, INIT_BAG_ITEM_LIST
+ ld [wInitListType], a
+ callab InitList
+
+ ld a, [wNumBagItems]
+ and a
+ jp z, .bagEmpty
+ ld hl, PokemonSellingGreetingText
+ call PrintText
+ call SaveScreenTilesToBuffer1 ; save screen
+.sellMenuLoop
+ call LoadScreenTilesFromBuffer1 ; restore saved screen
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; draw money text box
+ ld hl, wNumBagItems
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wPrintItemPrices], a
+ ld [wCurrentMenuItem], a
+ ld a, ITEMLISTMENU
+ ld [wListMenuID], a
+ call DisplayListMenuID
+ jp c, .returnToMainPokemartMenu ; if the player closed the menu
+.confirmItemSale ; if the player is trying to sell a specific item
+ call IsKeyItem
+ ld a, [wIsKeyItem]
+ and a
+ jr nz, .unsellableItem
+ ld a, [wcf91]
+ call IsItemHM
+ jr c, .unsellableItem
+ ld a, PRICEDITEMLISTMENU
+ ld [wListMenuID], a
+ ld [hHalveItemPrices], a ; halve prices when selling
+ call DisplayChooseQuantityMenu
+ inc a
+ jr z, .sellMenuLoop ; if the player closed the choose quantity menu with the B button
+ ld hl, PokemartTellSellPriceText
+ lb bc, 14, 1 ; location that PrintText always prints to, this is useless
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wMenuExitMethod]
+ cp CHOSE_SECOND_ITEM
+ jr z, .sellMenuLoop ; if the player chose No or pressed the B button
+
+; The following code is supposed to check if the player chose No, but the above
+; check already catches it.
+ ld a, [wChosenMenuItem]
+ dec a
+ jr z, .sellMenuLoop
+
+.sellItem
+ ld a, [wBoughtOrSoldItemInMart]
+ and a
+ jr nz, .skipSettingFlag1
+ inc a
+ ld [wBoughtOrSoldItemInMart], a
+.skipSettingFlag1
+ call AddAmountSoldToMoney
+ ld hl, wNumBagItems
+ call RemoveItemFromInventory
+ jp .sellMenuLoop
+.unsellableItem
+ ld hl, PokemartUnsellableItemText
+ call PrintText
+ jp .returnToMainPokemartMenu
+.bagEmpty
+ ld hl, PokemartItemBagEmptyText
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ jp .returnToMainPokemartMenu
+.buyMenu
+
+; the same variables are set again below, so this code has no effect
+ ld a, 1
+ ld [wPrintItemPrices], a
+ ld a, INIT_OTHER_ITEM_LIST
+ ld [wInitListType], a
+ callab InitList
+
+ ld hl, PokemartBuyingGreetingText
+ call PrintText
+ call SaveScreenTilesToBuffer1
+.buyMenuLoop
+ call LoadScreenTilesFromBuffer1
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld hl, wItemList
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ xor a
+ ld [wCurrentMenuItem], a
+ inc a
+ ld [wPrintItemPrices], a
+ inc a ; a = 2 (PRICEDITEMLISTMENU)
+ ld [wListMenuID], a
+ call DisplayListMenuID
+ jr c, .returnToMainPokemartMenu ; if the player closed the menu
+ ld a, 99
+ ld [wMaxItemQuantity], a
+ xor a
+ ld [hHalveItemPrices], a ; don't halve item prices when buying
+ call DisplayChooseQuantityMenu
+ inc a
+ jr z, .buyMenuLoop ; if the player closed the choose quantity menu with the B button
+ ld a, [wcf91] ; item ID
+ ld [wd11e], a ; store item ID for GetItemName
+ call GetItemName
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld hl, PokemartTellBuyPriceText
+ call PrintText
+ coord hl, 14, 7
+ lb bc, 8, 15
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wMenuExitMethod]
+ cp CHOSE_SECOND_ITEM
+ jp z, .buyMenuLoop ; if the player chose No or pressed the B button
+
+; The following code is supposed to check if the player chose No, but the above
+; check already catches it.
+ ld a, [wChosenMenuItem]
+ dec a
+ jr z, .buyMenuLoop
+
+.buyItem
+ call .isThereEnoughMoney
+ jr c, .notEnoughMoney
+ ld hl, wNumBagItems
+ call AddItemToInventory
+ jr nc, .bagFull
+ call SubtractAmountPaidFromMoney
+ ld a, [wBoughtOrSoldItemInMart]
+ and a
+ jr nz, .skipSettingFlag2
+ ld a, 1
+ ld [wBoughtOrSoldItemInMart], a
+.skipSettingFlag2
+ ld a, SFX_PURCHASE
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ ld hl, PokemartBoughtItemText
+ call PrintText
+ jp .buyMenuLoop
+.returnToMainPokemartMenu
+ call LoadScreenTilesFromBuffer1
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld hl, PokemartAnythingElseText
+ call PrintText
+ jp .loop
+.isThereEnoughMoney
+ ld de, wPlayerMoney
+ ld hl, hMoney
+ ld c, 3 ; length of money in bytes
+ jp StringCmp
+.notEnoughMoney
+ ld hl, PokemartNotEnoughMoneyText
+ call PrintText
+ jr .returnToMainPokemartMenu
+.bagFull
+ ld hl, PokemartItemBagFullText
+ call PrintText
+ jr .returnToMainPokemartMenu
+.done
+ ld hl, PokemartThankYouText
+ call PrintText
+ ld a, 1
+ ld [wUpdateSpritesEnabled], a
+ call UpdateSprites
+ ld a, [wSavedListScrollOffset]
+ ld [wListScrollOffset], a
+ ret
+
+PokemartBuyingGreetingText:
+ TX_FAR _PokemartBuyingGreetingText
+ db "@"
+
+PokemartTellBuyPriceText:
+ TX_FAR _PokemartTellBuyPriceText
+ db "@"
+
+PokemartBoughtItemText:
+ TX_FAR _PokemartBoughtItemText
+ db "@"
+
+PokemartNotEnoughMoneyText:
+ TX_FAR _PokemartNotEnoughMoneyText
+ db "@"
+
+PokemartItemBagFullText:
+ TX_FAR _PokemartItemBagFullText
+ db "@"
+
+PokemonSellingGreetingText:
+ TX_FAR _PokemonSellingGreetingText
+ db "@"
+
+PokemartTellSellPriceText:
+ TX_FAR _PokemartTellSellPriceText
+ db "@"
+
+PokemartItemBagEmptyText:
+ TX_FAR _PokemartItemBagEmptyText
+ db "@"
+
+PokemartUnsellableItemText:
+ TX_FAR _PokemartUnsellableItemText
+ db "@"
+
+PokemartThankYouText:
+ TX_FAR _PokemartThankYouText
+ db "@"
+
+PokemartAnythingElseText:
+ TX_FAR _PokemartAnythingElseText
+ db "@"
diff --git a/en/engine/print_waiting_text.asm b/en/engine/print_waiting_text.asm
new file mode 100644
index 00000000..7a95da2a
--- /dev/null
+++ b/en/engine/print_waiting_text.asm
@@ -0,0 +1,20 @@
+PrintWaitingText:
+ coord hl, 3, 10
+ ld b, $1
+ ld c, $b
+ ld a, [wIsInBattle]
+ and a
+ jr z, .asm_4c17
+ call TextBoxBorder
+ jr .asm_4c1a
+.asm_4c17
+ call CableClub_TextBoxBorder
+.asm_4c1a
+ coord hl, 4, 11
+ ld de, WaitingText
+ call PlaceString
+ ld c, 50
+ jp DelayFrames
+
+WaitingText:
+ db "Waiting...!@"
diff --git a/en/engine/save.asm b/en/engine/save.asm
new file mode 100755
index 00000000..97935dbb
--- /dev/null
+++ b/en/engine/save.asm
@@ -0,0 +1,708 @@
+LoadSAV:
+;(if carry -> write
+;"the file data is destroyed")
+ call ClearScreen
+ call LoadFontTilePatterns
+ call LoadTextBoxTilePatterns
+ call LoadSAV0
+ jr c, .badsum
+ call LoadSAV1
+ jr c, .badsum
+ call LoadSAV2
+ jr c, .badsum
+ ld a, $2 ; good checksum
+ jr .goodsum
+.badsum
+ ld hl, wd730
+ push hl
+ set 6, [hl]
+ ld hl, FileDataDestroyedText
+ call PrintText
+ ld c, 100
+ call DelayFrames
+ pop hl
+ res 6, [hl]
+ ld a, $1 ; bad checksum
+.goodsum
+ ld [wSaveFileStatus], a
+ ret
+
+FileDataDestroyedText:
+ TX_FAR _FileDataDestroyedText
+ db "@"
+
+LoadSAV0:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, sPlayerName ; hero name located in SRAM
+ ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
+ call SAVCheckSum
+ ld c, a
+ ld a, [sMainDataCheckSum] ; SAV's checksum
+ cp c
+ jp z, .checkSumsMatched
+
+; If the computed checksum didn't match the saved on, try again.
+ ld hl, sPlayerName
+ ld bc, sMainDataCheckSum - sPlayerName
+ call SAVCheckSum
+ ld c, a
+ ld a, [sMainDataCheckSum] ; SAV's checksum
+ cp c
+ jp nz, SAVBadCheckSum
+
+.checkSumsMatched
+ ld hl, sPlayerName
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, sMainData
+ ld de, wMainDataStart
+ ld bc, wMainDataEnd - wMainDataStart
+ call CopyData
+ ld hl, wCurMapTileset
+ set 7, [hl]
+ ld hl, sSpriteData
+ ld de, wSpriteDataStart
+ ld bc, wSpriteDataEnd - wSpriteDataStart
+ call CopyData
+ ld a, [sTilesetType]
+ ld [hTilesetType], a
+ ld hl, sCurBoxData
+ ld de, wBoxDataStart
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call CopyData
+ and a
+ jp SAVGoodChecksum
+
+LoadSAV1:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, sPlayerName ; hero name located in SRAM
+ ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
+ call SAVCheckSum
+ ld c, a
+ ld a, [sMainDataCheckSum] ; SAV's checksum
+ cp c
+ jr nz, SAVBadCheckSum
+ ld hl, sCurBoxData
+ ld de, wBoxDataStart
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call CopyData
+ and a
+ jp SAVGoodChecksum
+
+LoadSAV2:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, sPlayerName ; hero name located in SRAM
+ ld bc, sMainDataCheckSum - sPlayerName ; but here checks the full SAV
+ call SAVCheckSum
+ ld c, a
+ ld a, [sMainDataCheckSum] ; SAV's checksum
+ cp c
+ jp nz, SAVBadCheckSum
+ ld hl, sPartyData
+ ld de, wPartyDataStart
+ ld bc, wPartyDataEnd - wPartyDataStart
+ call CopyData
+ ld hl, sMainData
+ ld de, wPokedexOwned
+ ld bc, wPokedexSeenEnd - wPokedexOwned
+ call CopyData
+ and a
+ jp SAVGoodChecksum
+
+SAVBadCheckSum:
+ scf
+
+SAVGoodChecksum:
+ ld a, $0
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+LoadSAVIgnoreBadCheckSum:
+; unused function that loads save data and ignores bad checksums
+ call LoadSAV0
+ call LoadSAV1
+ jp LoadSAV2
+
+SaveSAV:
+ callba PrintSaveScreenText
+ ld hl, WouldYouLikeToSaveText
+ call SaveSAVConfirm
+ and a ;|0 = Yes|1 = No|
+ ret nz
+ ld a, [wSaveFileStatus]
+ dec a
+ jr z, .save
+ call SAVCheckRandomID
+ jr z, .save
+ ld hl, OlderFileWillBeErasedText
+ call SaveSAVConfirm
+ and a
+ ret nz
+.save
+ call SaveSAVtoSRAM
+ coord hl, 1, 13
+ lb bc, 4, 18
+ call ClearScreenArea
+ coord hl, 1, 14
+ ld de, NowSavingString
+ call PlaceString
+ ld c, 120
+ call DelayFrames
+ ld hl, GameSavedText
+ call PrintText
+ ld a, SFX_SAVE
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ ld c, 30
+ jp DelayFrames
+
+NowSavingString:
+ db "Now saving...@"
+
+SaveSAVConfirm:
+ call PrintText
+ coord hl, 0, 7
+ lb bc, 8, 1
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; yes/no menu
+ ld a, [wCurrentMenuItem]
+ ret
+
+WouldYouLikeToSaveText:
+ TX_FAR _WouldYouLikeToSaveText
+ db "@"
+
+GameSavedText:
+ TX_FAR _GameSavedText
+ db "@"
+
+OlderFileWillBeErasedText:
+ TX_FAR _OlderFileWillBeErasedText
+ db "@"
+
+SaveSAVtoSRAM0:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, wPlayerName
+ ld de, sPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wMainDataStart
+ ld de, sMainData
+ ld bc, wMainDataEnd - wMainDataStart
+ call CopyData
+ ld hl, wSpriteDataStart
+ ld de, sSpriteData
+ ld bc, wSpriteDataEnd - wSpriteDataStart
+ call CopyData
+ ld hl, wBoxDataStart
+ ld de, sCurBoxData
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call CopyData
+ ld a, [hTilesetType]
+ ld [sTilesetType], a
+ ld hl, sPlayerName
+ ld bc, sMainDataCheckSum - sPlayerName
+ call SAVCheckSum
+ ld [sMainDataCheckSum], a
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+SaveSAVtoSRAM1:
+; stored pokémon
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, wBoxDataStart
+ ld de, sCurBoxData
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call CopyData
+ ld hl, sPlayerName
+ ld bc, sMainDataCheckSum - sPlayerName
+ call SAVCheckSum
+ ld [sMainDataCheckSum], a
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+SaveSAVtoSRAM2:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld hl, wPartyDataStart
+ ld de, sPartyData
+ ld bc, wPartyDataEnd - wPartyDataStart
+ call CopyData
+ ld hl, wPokedexOwned ; pokédex only
+ ld de, sMainData
+ ld bc, wPokedexSeenEnd - wPokedexOwned
+ call CopyData
+ ld hl, sPlayerName
+ ld bc, sMainDataCheckSum - sPlayerName
+ call SAVCheckSum
+ ld [sMainDataCheckSum], a
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+SaveSAVtoSRAM:
+ ld a, $2
+ ld [wSaveFileStatus], a
+ call SaveSAVtoSRAM0
+ call SaveSAVtoSRAM1
+ jp SaveSAVtoSRAM2
+
+SAVCheckSum:
+;Check Sum (result[1 byte] is complemented)
+ ld d, 0
+.loop
+ ld a, [hli]
+ add d
+ ld d, a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ ld a, d
+ cpl
+ ret
+
+CalcIndividualBoxCheckSums:
+ ld hl, sBox1 ; sBox7
+ ld de, sBank2IndividualBoxChecksums ; sBank3IndividualBoxChecksums
+ ld b, NUM_BOXES / 2
+.loop
+ push bc
+ push de
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call SAVCheckSum
+ pop de
+ ld [de], a
+ inc de
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+GetBoxSRAMLocation:
+; in: a = box num
+; out: b = box SRAM bank, hl = pointer to start of box
+ ld hl, BoxSRAMPointerTable
+ ld a, [wCurrentBoxNum]
+ and $7f
+ cp NUM_BOXES / 2
+ ld b, 2
+ jr c, .next
+ inc b
+ sub NUM_BOXES / 2
+.next
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+BoxSRAMPointerTable:
+ dw sBox1 ; sBox7
+ dw sBox2 ; sBox8
+ dw sBox3 ; sBox9
+ dw sBox4 ; sBox10
+ dw sBox5 ; sBox11
+ dw sBox6 ; sBox12
+
+ChangeBox::
+ ld hl, WhenYouChangeBoxText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ ret nz ; return if No was chosen
+ ld hl, wCurrentBoxNum
+ bit 7, [hl] ; is it the first time player is changing the box?
+ call z, EmptyAllSRAMBoxes ; if so, empty all boxes in SRAM
+ call DisplayChangeBoxMenu
+ call UpdateSprites
+ ld hl, hFlags_0xFFF6
+ set 1, [hl]
+ call HandleMenuInput
+ ld hl, hFlags_0xFFF6
+ res 1, [hl]
+ bit 1, a ; pressed b
+ ret nz
+ call GetBoxSRAMLocation
+ ld e, l
+ ld d, h
+ ld hl, wBoxDataStart
+ call CopyBoxToOrFromSRAM ; copy old box from WRAM to SRAM
+ ld a, [wCurrentMenuItem]
+ set 7, a
+ ld [wCurrentBoxNum], a
+ call GetBoxSRAMLocation
+ ld de, wBoxDataStart
+ call CopyBoxToOrFromSRAM ; copy new box from SRAM to WRAM
+ ld hl, wMapTextPtr
+ ld de, wChangeBoxSavedMapTextPointer
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ call RestoreMapTextPointer
+ call SaveSAVtoSRAM
+ ld hl, wChangeBoxSavedMapTextPointer
+ call SetMapTextPointer
+ ld a, SFX_SAVE
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ ret
+
+WhenYouChangeBoxText:
+ TX_FAR _WhenYouChangeBoxText
+ db "@"
+
+CopyBoxToOrFromSRAM:
+; copy an entire box from hl to de with b as the SRAM bank
+ push hl
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld a, b
+ ld [MBC1SRamBank], a
+ ld bc, wBoxDataEnd - wBoxDataStart
+ call CopyData
+ pop hl
+
+; mark the memory that the box was copied from as am empty box
+ xor a
+ ld [hli], a
+ dec a
+ ld [hl], a
+
+ ld hl, sBox1 ; sBox7
+ ld bc, sBank2AllBoxesChecksum - sBox1
+ call SAVCheckSum
+ ld [sBank2AllBoxesChecksum], a ; sBank3AllBoxesChecksum
+ call CalcIndividualBoxCheckSums
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+DisplayChangeBoxMenu:
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 11
+ ld [wMaxMenuItem], a
+ ld a, 1
+ ld [wTopMenuItemY], a
+ ld a, 12
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld a, [wCurrentBoxNum]
+ and $7f
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ coord hl, 0, 0
+ ld b, 2
+ ld c, 9
+ call TextBoxBorder
+ ld hl, ChooseABoxText
+ call PrintText
+ coord hl, 11, 0
+ ld b, 12
+ ld c, 7
+ call TextBoxBorder
+ ld hl, hFlags_0xFFF6
+ set 2, [hl]
+ ld de, BoxNames
+ coord hl, 13, 1
+ call PlaceString
+ ld hl, hFlags_0xFFF6
+ res 2, [hl]
+ ld a, [wCurrentBoxNum]
+ and $7f
+ cp 9
+ jr c, .singleDigitBoxNum
+ sub 9
+ coord hl, 8, 2
+ ld [hl], "1"
+ add "0"
+ jr .next
+.singleDigitBoxNum
+ add "1"
+.next
+ Coorda 9, 2
+ coord hl, 1, 2
+ ld de, BoxNoText
+ call PlaceString
+ call GetMonCountsForAllBoxes
+ coord hl, 18, 1
+ ld de, wBoxMonCounts
+ ld bc, SCREEN_WIDTH
+ ld a, $c
+.loop
+ push af
+ ld a, [de]
+ and a ; is the box empty?
+ jr z, .skipPlacingPokeball
+ ld [hl], $78 ; place pokeball tile next to box name if box not empty
+.skipPlacingPokeball
+ add hl, bc
+ inc de
+ pop af
+ dec a
+ jr nz, .loop
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+ChooseABoxText:
+ TX_FAR _ChooseABoxText
+ db "@"
+
+BoxNames:
+ db "BOX 1"
+ next "BOX 2"
+ next "BOX 3"
+ next "BOX 4"
+ next "BOX 5"
+ next "BOX 6"
+ next "BOX 7"
+ next "BOX 8"
+ next "BOX 9"
+ next "BOX10"
+ next "BOX11"
+ next "BOX12@"
+
+BoxNoText:
+ db "BOX No.@"
+
+EmptyAllSRAMBoxes:
+; marks all boxes in SRAM as empty (initialisation for the first time the
+; player changes the box)
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld a, 2
+ ld [MBC1SRamBank], a
+ call EmptySRAMBoxesInBank
+ ld a, 3
+ ld [MBC1SRamBank], a
+ call EmptySRAMBoxesInBank
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+EmptySRAMBoxesInBank:
+; marks every box in the current SRAM bank as empty
+ ld hl, sBox1 ; sBox7
+ call EmptySRAMBox
+ ld hl, sBox2 ; sBox8
+ call EmptySRAMBox
+ ld hl, sBox3 ; sBox9
+ call EmptySRAMBox
+ ld hl, sBox4 ; sBox10
+ call EmptySRAMBox
+ ld hl, sBox5 ; sBox11
+ call EmptySRAMBox
+ ld hl, sBox6 ; sBox12
+ call EmptySRAMBox
+ ld hl, sBox1 ; sBox7
+ ld bc, sBank2AllBoxesChecksum - sBox1
+ call SAVCheckSum
+ ld [sBank2AllBoxesChecksum], a ; sBank3AllBoxesChecksum
+ call CalcIndividualBoxCheckSums
+ ret
+
+EmptySRAMBox:
+ xor a
+ ld [hli], a
+ dec a
+ ld [hl], a
+ ret
+
+GetMonCountsForAllBoxes:
+ ld hl, wBoxMonCounts
+ push hl
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ ld a, $2
+ ld [MBC1SRamBank], a
+ call GetMonCountsForBoxesInBank
+ ld a, $3
+ ld [MBC1SRamBank], a
+ call GetMonCountsForBoxesInBank
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ pop hl
+
+; copy the count for the current box from WRAM
+ ld a, [wCurrentBoxNum]
+ and $7f
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [wNumInBox]
+ ld [hl], a
+
+ ret
+
+GetMonCountsForBoxesInBank:
+ ld a, [sBox1] ; sBox7
+ ld [hli], a
+ ld a, [sBox2] ; sBox8
+ ld [hli], a
+ ld a, [sBox3] ; sBox9
+ ld [hli], a
+ ld a, [sBox4] ; sBox10
+ ld [hli], a
+ ld a, [sBox5] ; sBox11
+ ld [hli], a
+ ld a, [sBox6] ; sBox12
+ ld [hli], a
+ ret
+
+SAVCheckRandomID:
+;checks if Sav file is the same by checking player's name 1st letter ($a598)
+; and the two random numbers generated at game beginning
+;(which are stored at wPlayerID)s
+ ld a, $0a
+ ld [MBC1SRamEnable], a
+ ld a, $01
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamBank], a
+ ld a, [sPlayerName]
+ and a
+ jr z, .next
+ ld hl, sPlayerName
+ ld bc, sMainDataCheckSum - sPlayerName
+ call SAVCheckSum
+ ld c, a
+ ld a, [sMainDataCheckSum]
+ cp c
+ jr nz, .next
+ ld hl, sMainData + (wPlayerID - wMainDataStart) ; player ID
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wPlayerID]
+ cp l
+ jr nz, .next
+ ld a, [wPlayerID + 1]
+ cp h
+.next
+ ld a, $00
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+SaveHallOfFameTeams:
+ ld a, [wNumHoFTeams]
+ dec a
+ cp HOF_TEAM_CAPACITY
+ jr nc, .shiftHOFTeams
+ ld hl, sHallOfFame
+ ld bc, HOF_TEAM
+ call AddNTimes
+ ld e, l
+ ld d, h
+ ld hl, wHallOfFame
+ ld bc, HOF_TEAM
+ jr HallOfFame_Copy
+
+.shiftHOFTeams
+; if the space designated for HOF teams is full, then shift all HOF teams to the next slot, making space for the new HOF team
+; this deletes the last HOF team though
+ ld hl, sHallOfFame + HOF_TEAM
+ ld de, sHallOfFame
+ ld bc, HOF_TEAM * (HOF_TEAM_CAPACITY - 1)
+ call HallOfFame_Copy
+ ld hl, wHallOfFame
+ ld de, sHallOfFame + HOF_TEAM * (HOF_TEAM_CAPACITY - 1)
+ ld bc, HOF_TEAM
+ jr HallOfFame_Copy
+
+LoadHallOfFameTeams:
+ ld hl, sHallOfFame
+ ld bc, HOF_TEAM
+ ld a, [wHoFTeamIndex]
+ call AddNTimes
+ ld de, wHallOfFame
+ ld bc, HOF_TEAM
+ ; fallthrough
+
+HallOfFame_Copy:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ xor a
+ ld [MBC1SRamBank], a
+ call CopyData
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+ClearSAV:
+ ld a, SRAM_ENABLE
+ ld [MBC1SRamEnable], a
+ ld a, $1
+ ld [MBC1SRamBankingMode], a
+ xor a
+ call PadSRAM_FF
+ ld a, $1
+ call PadSRAM_FF
+ ld a, $2
+ call PadSRAM_FF
+ ld a, $3
+ call PadSRAM_FF
+ xor a
+ ld [MBC1SRamBankingMode], a
+ ld [MBC1SRamEnable], a
+ ret
+
+PadSRAM_FF:
+ ld [MBC1SRamBank], a
+ ld hl, $a000
+ ld bc, $2000
+ ld a, $ff
+ jp FillMemory
diff --git a/en/engine/slot_machine.asm b/en/engine/slot_machine.asm
new file mode 100755
index 00000000..cb9a3bfb
--- /dev/null
+++ b/en/engine/slot_machine.asm
@@ -0,0 +1,892 @@
+PromptUserToPlaySlots:
+ call SaveScreenTilesToBuffer2
+ ld a, BANK(DisplayTextIDInit)
+ ld [wAutoTextBoxDrawingControl], a
+ ld b, a
+ ld hl, DisplayTextIDInit
+ call Bankswitch
+ ld hl, PlaySlotMachineText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .done ; if player chose No
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ ld hl, wSlotMachineRerollCounter
+ xor a
+ ld [hli], a
+ ld [hl], SMILE_BUBBLE
+ predef EmotionBubble
+ call GBPalWhiteOutWithDelay3
+ call LoadSlotMachineTiles
+ call LoadFontTilePatterns
+ ld b, SET_PAL_SLOTS
+ call RunPaletteCommand
+ call GBPalNormal
+ ld a, $e4
+ ld [rOBP0], a
+ ld hl, wd730
+ set 6, [hl]
+ xor a
+ ld [wSlotMachineAllowMatchesCounter], a
+ ld hl, wStoppingWhichSlotMachineWheel
+ ld bc, $0014
+ call FillMemory
+ call MainSlotMachineLoop
+ ld hl, wd730
+ res 6, [hl]
+ xor a
+ ld [wSlotMachineAllowMatchesCounter], a
+ call GBPalWhiteOutWithDelay3
+ ld a, $1
+ ld [wUpdateSpritesEnabled], a
+ call RunDefaultPaletteCommand
+ call ReloadMapSpriteTilePatterns
+ call ReloadTilesetTilePatterns
+.done
+ call LoadScreenTilesFromBuffer2
+ call Delay3
+ call GBPalNormal
+ ld a, [wSlotMachineSavedROMBank]
+ push af
+ jp CloseTextDisplay
+
+PlaySlotMachineText:
+ TX_FAR _PlaySlotMachineText
+ db "@"
+
+MainSlotMachineLoop:
+ call SlotMachine_PrintCreditCoins
+ xor a
+ ld hl, wPayoutCoins
+ ld [hli], a
+ ld [hl], a
+ call SlotMachine_PrintPayoutCoins
+ ld hl, BetHowManySlotMachineText
+ call PrintText
+ call SaveScreenTilesToBuffer1
+.loop
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, 2
+ ld [wMaxMenuItem], a
+ ld a, 12
+ ld [wTopMenuItemY], a
+ ld a, 15
+ ld [wTopMenuItemX], a
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ coord hl, 14, 11
+ ld b, 5
+ ld c, 4
+ call TextBoxBorder
+ coord hl, 16, 12
+ ld de, CoinMultiplierSlotMachineText
+ call PlaceString
+ call HandleMenuInput
+ and B_BUTTON
+ jp nz, LoadScreenTilesFromBuffer1
+ ld a, [wCurrentMenuItem]
+ ld b, a
+ ld a, 3
+ sub b
+ ld [wSlotMachineBet], a
+ ld hl, wPlayerCoins
+ ld c, a
+ ld a, [hli]
+ and a
+ jr nz, .skip1
+ ld a, [hl]
+ cp c
+ jr nc, .skip1
+ ld hl, NotEnoughCoinsSlotMachineText
+ call PrintText
+ jr .loop
+.skip1
+ call LoadScreenTilesFromBuffer1
+ call SlotMachine_SubtractBetFromPlayerCoins
+ call SlotMachine_LightBalls
+ call SlotMachine_SetFlags
+ ld a, 4
+ ld hl, wSlotMachineWheel1SlipCounter
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ call WaitForSoundToFinish
+ ld a, SFX_SLOTS_NEW_SPIN
+ call PlaySound
+ ld hl, StartSlotMachineText
+ call PrintText
+ call SlotMachine_SpinWheels
+ call SlotMachine_CheckForMatches
+ ld hl, wPlayerCoins
+ ld a, [hli]
+ or [hl]
+ jr nz, .skip2
+ ld hl, OutOfCoinsSlotMachineText
+ call PrintText
+ ld c, 60
+ jp DelayFrames
+.skip2
+ ld hl, OneMoreGoSlotMachineText
+ call PrintText
+ coord hl, 14, 12
+ lb bc, 13, 15
+ xor a ; YES_NO_MENU
+ ld [wTwoOptionMenuID], a
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ ld a, [wCurrentMenuItem]
+ and a
+ ret nz
+ call SlotMachine_PutOutLitBalls
+ jp MainSlotMachineLoop
+
+CoinMultiplierSlotMachineText:
+ db "×3"
+ next "×2"
+ next "×1@"
+
+OutOfCoinsSlotMachineText:
+ TX_FAR _OutOfCoinsSlotMachineText
+ db "@"
+
+BetHowManySlotMachineText:
+ TX_FAR _BetHowManySlotMachineText
+ db "@"
+
+StartSlotMachineText:
+ TX_FAR _StartSlotMachineText
+ db "@"
+
+NotEnoughCoinsSlotMachineText:
+ TX_FAR _NotEnoughCoinsSlotMachineText
+ db "@"
+
+OneMoreGoSlotMachineText:
+ TX_FAR _OneMoreGoSlotMachineText
+ db "@"
+
+SlotMachine_SetFlags:
+ ld hl, wSlotMachineFlags
+ bit 7, [hl]
+ ret nz
+ ld a, [wSlotMachineAllowMatchesCounter]
+ and a
+ jr nz, .allowMatches
+ call Random
+ and a
+ jr z, .setAllowMatchesCounter ; 1/256 (~0.4%) chance
+ ld b, a
+ ld a, [wSlotMachineSevenAndBarModeChance]
+ cp b
+ jr c, .allowSevenAndBarMatches
+ ld a, 210
+ cp b
+ jr c, .allowMatches ; 55/256 (~21.5%) chance
+ ld [hl], 0
+ ret
+.allowMatches
+ set 6, [hl]
+ ret
+.setAllowMatchesCounter
+ ld a, 60
+ ld [wSlotMachineAllowMatchesCounter], a
+ ret
+.allowSevenAndBarMatches
+ set 7, [hl]
+ ret
+
+SlotMachine_SpinWheels:
+ ld c, 20
+.loop1
+ push bc
+ call SlotMachine_AnimWheel1
+ call SlotMachine_AnimWheel2
+ call SlotMachine_AnimWheel3
+ ld c, 2
+ call DelayFrames
+ pop bc
+ dec c
+ jr nz, .loop1
+ xor a
+ ld [wStoppingWhichSlotMachineWheel], a
+.loop2
+ call SlotMachine_HandleInputWhileWheelsSpin
+ call SlotMachine_StopOrAnimWheel1
+ call SlotMachine_StopOrAnimWheel2
+ call SlotMachine_StopOrAnimWheel3
+ ret c
+ ld a, [wOnSGB]
+ xor $1
+ inc a
+ ld c, a
+ call DelayFrames
+ jr .loop2
+
+; Note that the wheels can only stop when a symbol is centred in the wheel
+; and thus 3 full symbols rather than 2 full symbols and 2 half symbols are
+; visible. The 3 functions below ensure this by checking if the wheel offset
+; is even before stopping the wheel.
+
+SlotMachine_StopOrAnimWheel1:
+ ld a, [wStoppingWhichSlotMachineWheel]
+ cp 1
+ jr c, .animWheel
+ ld de, wSlotMachineWheel1Offset
+ ld a, [de]
+ rra
+ jr nc, .animWheel ; check that a symbol is centred in the wheel
+ ld hl, wSlotMachineWheel1SlipCounter
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ call SlotMachine_StopWheel1Early
+ ret nz
+.animWheel
+ jp SlotMachine_AnimWheel1
+
+SlotMachine_StopOrAnimWheel2:
+ ld a, [wStoppingWhichSlotMachineWheel]
+ cp 2
+ jr c, .animWheel
+ ld de, wSlotMachineWheel2Offset
+ ld a, [de]
+ rra
+ jr nc, .animWheel ; check that a symbol is centred in the wheel
+ ld hl, wSlotMachineWheel2SlipCounter
+ ld a, [hl]
+ and a
+ ret z
+ dec [hl]
+ call SlotMachine_StopWheel2Early
+ ret z
+.animWheel
+ jp SlotMachine_AnimWheel2
+
+SlotMachine_StopOrAnimWheel3:
+ ld a, [wStoppingWhichSlotMachineWheel]
+ cp 3
+ jr c, .animWheel
+ ld de, wSlotMachineWheel3Offset
+ ld a, [de]
+ rra
+ jr nc, .animWheel ; check that a symbol is centred in the wheel
+; wheel 3 stops as soon as possible
+ scf
+ ret
+.animWheel
+ call SlotMachine_AnimWheel3
+ and a
+ ret
+
+SlotMachine_StopWheel1Early:
+ call SlotMachine_GetWheel1Tiles
+ ld hl, wSlotMachineWheel1BottomTile
+ ld a, [wSlotMachineFlags]
+ and $80
+ jr nz, .sevenAndBarMode
+; Stop early if the middle symbol is not a cherry.
+ inc hl
+ ld a, [hl]
+ cp SLOTSCHERRY >> 8
+ jr nz, .stopWheel
+ ret
+; It looks like this was intended to make the wheel stop when a 7 symbol was
+; visible, but it has a bug and so the wheel stops randomly.
+.sevenAndBarMode
+ ld c, $3
+.loop
+ ld a, [hli]
+ cp SLOTS7 >> 8
+ jr c, .stopWheel ; condition never true
+ dec c
+ jr nz, .loop
+ ret
+.stopWheel
+ inc a
+ ld hl, wSlotMachineWheel1SlipCounter
+ ld [hl], 0
+ ret
+
+SlotMachine_StopWheel2Early:
+ call SlotMachine_GetWheel2Tiles
+ ld a, [wSlotMachineFlags]
+ and $80
+ jr nz, .sevenAndBarMode
+; Stop early if any symbols are lined up in the first two wheels.
+ call SlotMachine_FindWheel1Wheel2Matches
+ ret nz
+ jr .stopWheel
+; Stop early if two 7 symbols or two bar symbols are lined up in the first two
+; wheels OR if no symbols are lined up and the bottom symbol in wheel 2 is a
+; 7 symbol or bar symbol. The second part could be a bug or a way to reduce the
+; player's odds.
+.sevenAndBarMode
+ call SlotMachine_FindWheel1Wheel2Matches
+ ld a, [de]
+ cp (SLOTSBAR >> 8) + 1
+ ret nc
+.stopWheel
+ xor a
+ ld [wSlotMachineWheel2SlipCounter], a
+ ret
+
+SlotMachine_FindWheel1Wheel2Matches:
+; return whether wheel 1 and wheel 2's current positions allow a match (given
+; that wheel 3 stops in a good position) in Z
+ ld hl, wSlotMachineWheel1BottomTile
+ ld de, wSlotMachineWheel2BottomTile
+ ld a, [de]
+ cp [hl] ; wheel 1 bottom, wheel 2 bottom
+ ret z
+ inc de
+ ld a, [de]
+ cp [hl] ; wheel 1 bottom, wheel 2 middle
+ ret z
+ inc hl
+ cp [hl] ; wheel 1 middle, wheel 2 middle
+ ret z
+ inc hl
+ cp [hl] ; wheel 1 top, wheel 2 middle
+ ret z
+ inc de
+ ld a, [de]
+ cp [hl] ; wheel 1 top, wheel 2 top
+ ret z
+ dec de
+ dec de
+ ret
+
+SlotMachine_CheckForMatches:
+ call SlotMachine_GetWheel3Tiles
+ ld a, [wSlotMachineBet]
+ cp 2
+ jr z, .checkMatchesFor2CoinBet
+ cp 1
+ jr z, .checkMatchFor1CoinBet
+; 3 coin bet allows diagonal matches (plus the matches for 1/2 coin bets)
+ ld hl, wSlotMachineWheel1BottomTile
+ ld de, wSlotMachineWheel2MiddleTile
+ ld bc, wSlotMachineWheel3TopTile
+ call SlotMachine_CheckForMatch
+ jp z, .foundMatch
+ ld hl, wSlotMachineWheel1TopTile
+ ld de, wSlotMachineWheel2MiddleTile
+ ld bc, wSlotMachineWheel3BottomTile
+ call SlotMachine_CheckForMatch
+ jr z, .foundMatch
+; 2 coin bet allows top/bottom horizontal matches (plus the match for a 1 coin bet)
+.checkMatchesFor2CoinBet
+ ld hl, wSlotMachineWheel1TopTile
+ ld de, wSlotMachineWheel2TopTile
+ ld bc, wSlotMachineWheel3TopTile
+ call SlotMachine_CheckForMatch
+ jr z, .foundMatch
+ ld hl, wSlotMachineWheel1BottomTile
+ ld de, wSlotMachineWheel2BottomTile
+ ld bc, wSlotMachineWheel3BottomTile
+ call SlotMachine_CheckForMatch
+ jr z, .foundMatch
+; 1 coin bet only allows a middle horizontal match
+.checkMatchFor1CoinBet
+ ld hl, wSlotMachineWheel1MiddleTile
+ ld de, wSlotMachineWheel2MiddleTile
+ ld bc, wSlotMachineWheel3MiddleTile
+ call SlotMachine_CheckForMatch
+ jr z, .foundMatch
+ ld a, [wSlotMachineFlags]
+ and $c0
+ jr z, .noMatch
+ ld hl, wSlotMachineRerollCounter
+ dec [hl]
+ jr nz, .rollWheel3DownByOneSymbol
+.noMatch
+ ld hl, NotThisTimeText
+ call PrintText
+.done
+ xor a
+ ld [wMuteAudioAndPauseMusic], a
+ ret
+.rollWheel3DownByOneSymbol
+ call SlotMachine_AnimWheel3
+ call DelayFrame
+ call SlotMachine_AnimWheel3
+ call DelayFrame
+ jp SlotMachine_CheckForMatches
+.foundMatch
+ ld a, [wSlotMachineFlags]
+ and $c0
+ jr z, .rollWheel3DownByOneSymbol ; roll wheel if player isn't allowed to win
+ and $80
+ jr nz, .acceptMatch
+; if 7/bar matches aren't enabled and the match was a 7/bar symbol, roll wheel
+ ld a, [hl]
+ cp (SLOTSBAR >> 8) + 1
+ jr c, .rollWheel3DownByOneSymbol
+.acceptMatch
+ ld a, [hl]
+ sub $2
+ ld [wSlotMachineWinningSymbol], a
+ ld hl, SlotRewardPointers
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ push de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wcf4b
+ ld bc, 4
+ call CopyData
+ pop hl
+ ld de, .flashScreenLoop
+ push de
+ jp hl
+
+.flashScreenLoop
+ ld a, [rBGP]
+ xor $40
+ ld [rBGP], a
+ ld c, 5
+ call DelayFrames
+ dec b
+ jr nz, .flashScreenLoop
+ ld hl, wPayoutCoins
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ call SlotMachine_PrintPayoutCoins
+ ld hl, SymbolLinedUpSlotMachineText
+ call PrintText
+ call WaitForTextScrollButtonPress
+ call SlotMachine_PayCoinsToPlayer
+ call SlotMachine_PrintPayoutCoins
+ ld a, $e4
+ ld [rOBP0], a
+ jp .done
+
+SymbolLinedUpSlotMachineText:
+ TX_ASM
+ push bc
+ call SlotMachine_PrintWinningSymbol
+ ld hl, LinedUpText
+ pop bc
+ inc bc
+ inc bc
+ inc bc
+ inc bc
+ ret
+
+LinedUpText:
+ TX_FAR _LinedUpText
+ db "@"
+
+SlotRewardPointers:
+ dw SlotReward300Func
+ dw SlotReward300Text
+ dw SlotReward100Func
+ dw SlotReward100Text
+ dw SlotReward8Func
+ dw SlotReward8Text
+ dw SlotReward15Func
+ dw SlotReward15Text
+ dw SlotReward15Func
+ dw SlotReward15Text
+ dw SlotReward15Func
+ dw SlotReward15Text
+
+SlotReward300Text:
+ db "300@"
+
+SlotReward100Text:
+ db "100@"
+
+SlotReward8Text:
+ db "8@"
+
+SlotReward15Text:
+ db "15@"
+
+NotThisTimeText:
+ TX_FAR _NotThisTimeText
+ db "@"
+
+; compares the slot machine tiles at bc, de, and hl
+SlotMachine_CheckForMatch:
+ ld a, [de]
+ cp [hl]
+ ret nz
+ ld a, [bc]
+ cp [hl]
+ ret
+
+SlotMachine_GetWheel3Tiles:
+ ld de, wSlotMachineWheel3BottomTile
+ ld hl, SlotMachineWheel3
+ ld a, [wSlotMachineWheel3Offset]
+ call SlotMachine_GetWheelTiles
+
+SlotMachine_GetWheel2Tiles:
+ ld de, wSlotMachineWheel2BottomTile
+ ld hl, SlotMachineWheel2
+ ld a, [wSlotMachineWheel2Offset]
+ call SlotMachine_GetWheelTiles
+
+SlotMachine_GetWheel1Tiles:
+ ld de, wSlotMachineWheel1BottomTile
+ ld hl, SlotMachineWheel1
+ ld a, [wSlotMachineWheel1Offset]
+
+SlotMachine_GetWheelTiles:
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld c, 3
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+
+SlotReward8Func:
+ ld hl, wSlotMachineAllowMatchesCounter
+ ld a, [hl]
+ and a
+ jr z, .skip
+ dec [hl]
+.skip
+ ld b, $2
+ ld de, 8
+ ret
+
+SlotReward15Func:
+ ld hl, wSlotMachineAllowMatchesCounter
+ ld a, [hl]
+ and a
+ jr z, .skip
+ dec [hl]
+.skip
+ ld b, $4
+ ld de, 15
+ ret
+
+SlotReward100Func:
+ ld a, SFX_GET_KEY_ITEM
+ call PlaySound
+ xor a
+ ld [wSlotMachineFlags], a
+ ld b, $8
+ ld de, 100
+ ret
+
+SlotReward300Func:
+ ld hl, YeahText
+ call PrintText
+ ld a, SFX_GET_ITEM_2
+ call PlaySound
+ call Random
+ cp $80
+ ld a, $0
+ jr c, .skip
+ ld [wSlotMachineFlags], a
+.skip
+ ld [wSlotMachineAllowMatchesCounter], a
+ ld b, $14
+ ld de, 300
+ ret
+
+YeahText:
+ TX_FAR _YeahText
+ TX_DELAY
+ db "@"
+
+SlotMachine_PrintWinningSymbol:
+; prints winning symbol and down arrow in text box
+ coord hl, 2, 14
+ ld a, [wSlotMachineWinningSymbol]
+ add $25
+ ld [hli], a
+ inc a
+ ld [hld], a
+ inc a
+ ld de, -SCREEN_WIDTH
+ add hl, de
+ ld [hli], a
+ inc a
+ ld [hl], a
+ coord hl, 18, 16
+ ld [hl], "▼"
+ ret
+
+SlotMachine_SubtractBetFromPlayerCoins:
+ ld hl, wTempCoins2 + 1
+ ld a, [wSlotMachineBet]
+ ld [hld], a
+ xor a
+ ld [hli], a
+ ld de, wPlayerCoins + 1
+ ld c, $2
+ predef SubBCDPredef
+
+SlotMachine_PrintCreditCoins:
+ coord hl, 5, 1
+ ld de, wPlayerCoins
+ ld c, $2
+ jp PrintBCDNumber
+
+SlotMachine_PrintPayoutCoins:
+ coord hl, 11, 1
+ ld de, wPayoutCoins
+ lb bc, LEADING_ZEROES | 2, 4 ; 2 bytes, 4 digits
+ jp PrintNumber
+
+SlotMachine_PayCoinsToPlayer:
+ ld a, $1
+ ld [wMuteAudioAndPauseMusic], a
+ call WaitForSoundToFinish
+
+; Put 1 in the temp coins variable. This value is added to the player's coins
+; repeatedly so the player can watch the value go up 1 coin at a time.
+ ld hl, wTempCoins1
+ xor a
+ ld [hli], a
+ inc a
+ ld [hl], a
+
+ ld a, 5
+ ld [wAnimCounter], a
+
+; Subtract 1 from the payout amount and add 1 to the player's coins each
+; iteration until the payout amount reaches 0.
+.loop
+ ld a, [wPayoutCoins + 1]
+ ld l, a
+ ld a, [wPayoutCoins]
+ ld h, a
+ or l
+ ret z
+ ld de, -1
+ add hl, de
+ ld a, l
+ ld [wPayoutCoins + 1], a
+ ld a, h
+ ld [wPayoutCoins], a
+ ld hl, wTempCoins1 + 1
+ ld de, wPlayerCoins + 1
+ ld c, $2
+ predef AddBCDPredef
+ call SlotMachine_PrintCreditCoins
+ call SlotMachine_PrintPayoutCoins
+ ld a, SFX_SLOTS_REWARD
+ call PlaySound
+ ld a, [wAnimCounter]
+ dec a
+ jr nz, .skip1
+ ld a, [rOBP0]
+ xor $40 ; make the slot wheel symbols flash
+ ld [rOBP0], a
+ ld a, 5
+.skip1
+ ld [wAnimCounter], a
+ ld a, [wSlotMachineWinningSymbol]
+ cp (SLOTSBAR >> 8) + 1
+ ld c, 8
+ jr nc, .skip2
+ srl c ; c = 4 (make the the coins transfer faster if the symbol was 7 or bar)
+.skip2
+ call DelayFrames
+ jr .loop
+
+SlotMachine_PutOutLitBalls:
+ ld a, $23
+ ld [wNewSlotMachineBallTile], a
+ jr SlotMachine_UpdateThreeCoinBallTiles
+
+SlotMachine_LightBalls:
+ ld a, $14
+ ld [wNewSlotMachineBallTile], a
+ ld a, [wSlotMachineBet]
+ dec a
+ jr z, SlotMachine_UpdateOneCoinBallTiles
+ dec a
+ jr z, SlotMachine_UpdateTwoCoinBallTiles
+
+SlotMachine_UpdateThreeCoinBallTiles:
+ coord hl, 3, 2
+ call SlotMachine_UpdateBallTiles
+ coord hl, 3, 10
+ call SlotMachine_UpdateBallTiles
+
+SlotMachine_UpdateTwoCoinBallTiles:
+ coord hl, 3, 4
+ call SlotMachine_UpdateBallTiles
+ coord hl, 3, 8
+ call SlotMachine_UpdateBallTiles
+
+SlotMachine_UpdateOneCoinBallTiles:
+ coord hl, 3, 6
+
+SlotMachine_UpdateBallTiles:
+ ld a, [wNewSlotMachineBallTile]
+ ld [hl], a
+ ld bc, 13
+ add hl, bc
+ ld [hl], a
+ ld bc, 7
+ add hl, bc
+ inc a
+ ld [hl], a
+ ld bc, 13
+ add hl, bc
+ ld [hl], a
+ ret
+
+SlotMachine_AnimWheel1:
+ ld bc, SlotMachineWheel1
+ ld de, wSlotMachineWheel1Offset
+ ld hl, wOAMBuffer
+ ld a, $30
+ ld [wBaseCoordX], a
+ jr SlotMachine_AnimWheel
+
+SlotMachine_AnimWheel2:
+ ld bc, SlotMachineWheel2
+ ld de, wSlotMachineWheel2Offset
+ ld hl, wOAMBuffer + $30
+ ld a, $50
+ ld [wBaseCoordX], a
+ jr SlotMachine_AnimWheel
+
+SlotMachine_AnimWheel3:
+ ld bc, SlotMachineWheel3
+ ld de, wSlotMachineWheel3Offset
+ ld hl, wOAMBuffer + $60
+ ld a, $70
+ ld [wBaseCoordX], a
+
+SlotMachine_AnimWheel:
+ ld a, $58
+ ld [wBaseCoordY], a
+ push de
+ ld a, [de]
+ ld d, b
+ add c
+ ld e, a
+ jr nc, .loop
+ inc d
+.loop
+ ld a, [wBaseCoordY]
+ ld [hli], a
+ ld a, [wBaseCoordX]
+ ld [hli], a
+ ld a, [de]
+ ld [hli], a
+ ld a, $80
+ ld [hli], a
+ ld a, [wBaseCoordY]
+ ld [hli], a
+ ld a, [wBaseCoordX]
+ add $8
+ ld [hli], a
+ ld a, [de]
+ inc a
+ ld [hli], a
+ ld a, $80
+ ld [hli], a
+ inc de
+ ld a, [wBaseCoordY]
+ sub $8
+ ld [wBaseCoordY], a
+ cp $28
+ jr nz, .loop
+ pop de
+ ld a, [de]
+ inc a ; advance the offset so that the wheel animates
+ cp 30
+ jr nz, .skip
+ xor a ; wrap around to 0 when the offset reaches 30
+.skip
+ ld [de], a
+ ret
+
+SlotMachine_HandleInputWhileWheelsSpin:
+ call DelayFrame
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ and A_BUTTON
+ ret z
+ ld hl, wStoppingWhichSlotMachineWheel
+ ld a, [hl]
+ dec a
+ ld de, wSlotMachineWheel1SlipCounter
+ jr z, .skip
+ dec a
+ ld de, wSlotMachineWheel2SlipCounter
+ jr z, .skip
+.loop
+ inc [hl]
+ ld a, SFX_SLOTS_STOP_WHEEL
+ jp PlaySound
+.skip
+ ld a, [de]
+ and a
+ ret nz
+ jr .loop
+
+LoadSlotMachineTiles:
+ call DisableLCD
+ ld hl, SlotMachineTiles2
+ ld de, vChars0
+ ld bc, $1c0
+ ld a, BANK(SlotMachineTiles2)
+ call FarCopyData2
+ ld hl, SlotMachineTiles1
+ ld de, vChars2
+ ld bc, $250
+ ld a, BANK(SlotMachineTiles1)
+ call FarCopyData2
+ ld hl, SlotMachineTiles2
+ ld de, vChars2 + $250
+ ld bc, $1c0
+ ld a, BANK(SlotMachineTiles2)
+ call FarCopyData2
+ ld hl, SlotMachineMap
+ coord de, 0, 0
+ ld bc, SlotMachineMapEnd - SlotMachineMap
+ call CopyData
+ call EnableLCD
+ ld hl, wSlotMachineWheel1Offset
+ ld a, $1c
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ call SlotMachine_AnimWheel1
+ call SlotMachine_AnimWheel2
+ jp SlotMachine_AnimWheel3
+
+SlotMachineMap:
+ INCBIN "gfx/tilemaps/slotmachine.map"
+SlotMachineMapEnd:
+
+INCLUDE "data/slot_machine_wheels.asm"
+
+SlotMachineTiles1:
+IF DEF(_RED)
+ binlang gfx/red/slotmachine1.2bpp
+ENDC
+IF DEF(_BLUE)
+ binlang gfx/blue/slotmachine1.2bpp
+ENDC
diff --git a/en/engine/status_ailments.asm b/en/engine/status_ailments.asm
new file mode 100755
index 00000000..787533c4
--- /dev/null
+++ b/en/engine/status_ailments.asm
@@ -0,0 +1,46 @@
+PrintStatusAilment:
+ ld a, [de]
+ bit PSN, a
+ jr nz, .psn
+ bit BRN, a
+ jr nz, .brn
+ bit FRZ, a
+ jr nz, .frz
+ bit PAR, a
+ jr nz, .par
+ and SLP
+ ret z
+ ld a, "S"
+ ld [hli], a
+ ld a, "L"
+ ld [hli], a
+ ld [hl], "P"
+ ret
+.psn
+ ld a, "P"
+ ld [hli], a
+ ld a, "S"
+ ld [hli], a
+ ld [hl], "N"
+ ret
+.brn
+ ld a, "B"
+ ld [hli], a
+ ld a, "R"
+ ld [hli], a
+ ld [hl], "N"
+ ret
+.frz
+ ld a, "F"
+ ld [hli], a
+ ld a, "R"
+ ld [hli], a
+ ld [hl], "Z"
+ ret
+.par
+ ld a, "P"
+ ld [hli], a
+ ld a, "A"
+ ld [hli], a
+ ld [hl], "R"
+ ret
diff --git a/en/engine/titlescreen.asm b/en/engine/titlescreen.asm
new file mode 100755
index 00000000..03a5832d
--- /dev/null
+++ b/en/engine/titlescreen.asm
@@ -0,0 +1,403 @@
+; copy text of fixed length NAME_LENGTH (like player name, rival name, mon names, ...)
+CopyFixedLengthText:
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+SetDefaultNamesBeforeTitlescreen:
+ ld hl, NintenText
+ ld de, wPlayerName
+ call CopyFixedLengthText
+ ld hl, SonyText
+ ld de, wRivalName
+ call CopyFixedLengthText
+ xor a
+ ld [hWY], a
+ ld [wLetterPrintingDelayFlags], a
+ ld hl, wd732
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld a, BANK(Music_TitleScreen)
+ ld [wAudioROMBank], a
+ ld [wAudioSavedROMBank], a
+
+DisplayTitleScreen:
+ call GBPalWhiteOut
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ xor a
+ ld [hTilesetType], a
+ ld [hSCX], a
+ ld a, $40
+ ld [hSCY], a
+ ld a, $90
+ ld [hWY], a
+ call ClearScreen
+ call DisableLCD
+ call LoadFontTilePatterns
+ ld hl, NintendoCopyrightLogoGraphics
+ ld de, vTitleLogo2 + $100
+ ld bc, $50
+ ld a, BANK(NintendoCopyrightLogoGraphics)
+ call FarCopyData2
+ ld hl, GamefreakLogoGraphics
+ ld de, vTitleLogo2 + $100 + $50
+ ld bc, $90
+ ld a, BANK(GamefreakLogoGraphics)
+ call FarCopyData2
+ ld hl, PokemonLogoGraphics
+ ld de, vTitleLogo
+ ld bc, $600
+ ld a, BANK(PokemonLogoGraphics)
+ call FarCopyData2 ; first chunk
+ ld hl, PokemonLogoGraphics+$600
+ ld de, vTitleLogo2
+ ld bc, $100
+ ld a, BANK(PokemonLogoGraphics)
+ call FarCopyData2 ; second chunk
+ ld hl, Version_GFX
+ ld de, vChars2 + $600 - (Version_GFXEnd - Version_GFX - $50)
+ ld bc, Version_GFXEnd - Version_GFX
+ ld a, BANK(Version_GFX)
+ call FarCopyDataDouble
+ call ClearBothBGMaps
+
+; place tiles for pokemon logo (except for the last row)
+ coord hl, 2, 1
+ ld a, $80
+ ld de, SCREEN_WIDTH
+ ld c, 6
+.pokemonLogoTileLoop
+ ld b, $10
+ push hl
+.pokemonLogoTileRowLoop ; place tiles for one row
+ ld [hli], a
+ inc a
+ dec b
+ jr nz, .pokemonLogoTileRowLoop
+ pop hl
+ add hl, de
+ dec c
+ jr nz, .pokemonLogoTileLoop
+
+; place tiles for the last row of the pokemon logo
+ coord hl, 2, 7
+ ld a, $31
+ ld b, $10
+.pokemonLogoLastTileRowLoop
+ ld [hli], a
+ inc a
+ dec b
+ jr nz, .pokemonLogoLastTileRowLoop
+
+ call DrawPlayerCharacter
+
+; put a pokeball in the player's hand
+ ld hl, wOAMBuffer + $28
+ ld a, $74
+ ld [hl], a
+
+; place tiles for title screen copyright
+ coord hl, 2, 17
+ ld de, .tileScreenCopyrightTiles
+ ld b, $10
+.tileScreenCopyrightTilesLoop
+ ld a, [de]
+ ld [hli], a
+ inc de
+ dec b
+ jr nz, .tileScreenCopyrightTilesLoop
+
+ jr .next
+
+.tileScreenCopyrightTiles
+ db $41,$42,$43,$42,$44,$42,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E ; ©'95.'96.'98 GAME FREAK inc.
+
+.next
+ call SaveScreenTilesToBuffer2
+ call LoadScreenTilesFromBuffer2
+ call EnableLCD
+IF DEF(_RED)
+ ld a, CHARMANDER ; which Pokemon to show first on the title screen
+ENDC
+IF DEF(_BLUE)
+ ld a, SQUIRTLE ; which Pokemon to show first on the title screen
+ENDC
+
+ ld [wTitleMonSpecies], a
+ call LoadTitleMonSprite
+ ld a, (vBGMap0 + $300) / $100
+ call TitleScreenCopyTileMapToVRAM
+ call SaveScreenTilesToBuffer1
+ ld a, $40
+ ld [hWY], a
+ call LoadScreenTilesFromBuffer2
+ ld a, vBGMap0 / $100
+ call TitleScreenCopyTileMapToVRAM
+ ld b, SET_PAL_TITLE_SCREEN
+ call RunPaletteCommand
+ call GBPalNormal
+ ld a, %11100100
+ ld [rOBP0], a
+
+; make pokemon logo bounce up and down
+ ld bc, hSCY ; background scroll Y
+ ld hl, .TitleScreenPokemonLogoYScrolls
+.bouncePokemonLogoLoop
+ ld a, [hli]
+ and a
+ jr z, .finishedBouncingPokemonLogo
+ ld d, a
+ cp -3
+ jr nz, .skipPlayingSound
+ ld a, SFX_INTRO_CRASH
+ call PlaySound
+.skipPlayingSound
+ ld a, [hli]
+ ld e, a
+ call .ScrollTitleScreenPokemonLogo
+ jr .bouncePokemonLogoLoop
+
+.TitleScreenPokemonLogoYScrolls:
+; Controls the bouncing effect of the Pokemon logo on the title screen
+ db -4,16 ; y scroll amount, number of times to scroll
+ db 3,4
+ db -3,4
+ db 2,2
+ db -2,2
+ db 1,2
+ db -1,2
+ db 0 ; terminate list with 0
+
+.ScrollTitleScreenPokemonLogo:
+; Scrolls the Pokemon logo on the title screen to create the bouncing effect
+; Scrolls d pixels e times
+ call DelayFrame
+ ld a, [bc] ; background scroll Y
+ add d
+ ld [bc], a
+ dec e
+ jr nz, .ScrollTitleScreenPokemonLogo
+ ret
+
+.finishedBouncingPokemonLogo
+ call LoadScreenTilesFromBuffer1
+ ld c, 36
+ call DelayFrames
+ ld a, SFX_INTRO_WHOOSH
+ call PlaySound
+
+; scroll game version in from the right
+ call PrintGameVersionOnTitleScreen
+ ld a, SCREEN_HEIGHT_PIXELS
+ ld [hWY], a
+ ld d, 144
+.scrollTitleScreenGameVersionLoop
+ ld h, d
+ ld l, 64
+ call ScrollTitleScreenGameVersion
+ ld h, 0
+ ld l, 80
+ call ScrollTitleScreenGameVersion
+ ld a, d
+ add 4
+ ld d, a
+ and a
+ jr nz, .scrollTitleScreenGameVersionLoop
+
+ ld a, vBGMap1 / $100
+ call TitleScreenCopyTileMapToVRAM
+ call LoadScreenTilesFromBuffer2
+ call PrintGameVersionOnTitleScreen
+ call Delay3
+ call WaitForSoundToFinish
+ ld a, MUSIC_TITLE_SCREEN
+ ld [wNewSoundID], a
+ call PlaySound
+ xor a
+ ld [wUnusedCC5B], a
+
+; Keep scrolling in new mons indefinitely until the user performs input.
+.awaitUserInterruptionLoop
+ ld c, 200
+ call CheckForUserInterruption
+ jr c, .finishedWaiting
+ call TitleScreenScrollInMon
+ ld c, 1
+ call CheckForUserInterruption
+ jr c, .finishedWaiting
+ callba TitleScreenAnimateBallIfStarterOut
+ call TitleScreenPickNewMon
+ jr .awaitUserInterruptionLoop
+
+.finishedWaiting
+ ld a, [wTitleMonSpecies]
+ call PlayCry
+ call WaitForSoundToFinish
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ xor a
+ ld [hWY], a
+ inc a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ ld a, vBGMap0 / $100
+ call TitleScreenCopyTileMapToVRAM
+ ld a, vBGMap1 / $100
+ call TitleScreenCopyTileMapToVRAM
+ call Delay3
+ call LoadGBPal
+ ld a, [hJoyHeld]
+ ld b, a
+ and D_UP | SELECT | B_BUTTON
+ cp D_UP | SELECT | B_BUTTON
+ jp z, .doClearSaveDialogue
+ jp MainMenu
+
+.doClearSaveDialogue
+ jpba DoClearSaveDialogue
+
+TitleScreenPickNewMon:
+ ld a, vBGMap0 / $100
+ call TitleScreenCopyTileMapToVRAM
+
+.loop
+; Keep looping until a mon different from the current one is picked.
+ call Random
+ and $f
+ ld c, a
+ ld b, 0
+ ld hl, TitleMons
+ add hl, bc
+ ld a, [hl]
+ ld hl, wTitleMonSpecies
+
+; Can't be the same as before.
+ cp [hl]
+ jr z, .loop
+
+ ld [hl], a
+ call LoadTitleMonSprite
+
+ ld a, $90
+ ld [hWY], a
+ ld d, 1 ; scroll out
+ callba TitleScroll
+ ret
+
+TitleScreenScrollInMon:
+ ld d, 0 ; scroll in
+ callba TitleScroll
+ xor a
+ ld [hWY], a
+ ret
+
+ScrollTitleScreenGameVersion:
+.wait
+ ld a, [rLY]
+ cp l
+ jr nz, .wait
+
+ ld a, h
+ ld [rSCX], a
+
+.wait2
+ ld a, [rLY]
+ cp h
+ jr z, .wait2
+ ret
+
+DrawPlayerCharacter:
+ ld hl, PlayerCharacterTitleGraphics
+ ld de, vSprites
+ ld bc, PlayerCharacterTitleGraphicsEnd - PlayerCharacterTitleGraphics
+ ld a, BANK(PlayerCharacterTitleGraphics)
+ call FarCopyData2
+ call ClearSprites
+ xor a
+ ld [wPlayerCharacterOAMTile], a
+ ld hl, wOAMBuffer
+ ld de, $605a
+ ld b, 7
+.loop
+ push de
+ ld c, 5
+.innerLoop
+ ld a, d
+ ld [hli], a ; Y
+ ld a, e
+ ld [hli], a ; X
+ add 8
+ ld e, a
+ ld a, [wPlayerCharacterOAMTile]
+ ld [hli], a ; tile
+ inc a
+ ld [wPlayerCharacterOAMTile], a
+ inc hl
+ dec c
+ jr nz, .innerLoop
+ pop de
+ ld a, 8
+ add d
+ ld d, a
+ dec b
+ jr nz, .loop
+ ret
+
+ClearBothBGMaps:
+ ld hl, vBGMap0
+ ld bc, $400 * 2
+ ld a, " "
+ jp FillMemory
+
+LoadTitleMonSprite:
+ ld [wcf91], a
+ ld [wd0b5], a
+ coord hl, 5, 10
+ call GetMonHeader
+ jp LoadFrontSpriteByMonIndex
+
+TitleScreenCopyTileMapToVRAM:
+ ld [H_AUTOBGTRANSFERDEST + 1], a
+ jp Delay3
+
+LoadCopyrightAndTextBoxTiles:
+ xor a
+ ld [hWY], a
+ call ClearScreen
+ call LoadTextBoxTilePatterns
+
+LoadCopyrightTiles:
+ ld de, NintendoCopyrightLogoGraphics
+ ld hl, vChars2 + $600
+ lb bc, BANK(NintendoCopyrightLogoGraphics), (GamefreakLogoGraphicsEnd - NintendoCopyrightLogoGraphics) / $10
+ call CopyVideoData
+ coord hl, 2, 7
+ ld de, CopyrightTextString
+ jp PlaceString
+
+CopyrightTextString:
+ db $60,$61,$62,$61,$63,$61,$64,$7F,$65,$66,$67,$68,$69,$6A ; ©'95.'96.'98 Nintendo
+ next $60,$61,$62,$61,$63,$61,$64,$7F,$6B,$6C,$6D,$6E,$6F,$70,$71,$72 ; ©'95.'96.'98 Creatures inc.
+ next $60,$61,$62,$61,$63,$61,$64,$7F,$73,$74,$75,$76,$77,$78,$79,$7A,$7B ; ©'95.'96.'98 GAME FREAK inc.
+ db "@"
+
+INCLUDE "data/title_mons.asm"
+
+; prints version text (red, blue)
+PrintGameVersionOnTitleScreen:
+ coord hl, 7, 8
+ ld de, VersionOnTitleScreenText
+ jp PlaceString
+
+; these point to special tiles specifically loaded for that purpose and are not usual text
+VersionOnTitleScreenText:
+IF DEF(_RED)
+ db $60,$61,$7F,$65,$66,$67,$68,$69,"@" ; "Red Version"
+ENDC
+IF DEF(_BLUE)
+ db $61,$62,$63,$64,$65,$66,$67,$68,"@" ; "Blue Version"
+ENDC
+
+NintenText: db "NINTEN@"
+SonyText: db "SONY@"
diff --git a/en/engine/town_map.asm b/en/engine/town_map.asm
new file mode 100755
index 00000000..62fba431
--- /dev/null
+++ b/en/engine/town_map.asm
@@ -0,0 +1,619 @@
+DisplayTownMap:
+ call LoadTownMap
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ ld a, $1
+ ld [hJoy7], a
+ ld a, [wCurMap]
+ push af
+ ld b, $0
+ call DrawPlayerOrBirdSprite ; player sprite
+ coord hl, 1, 0
+ ld de, wcd6d
+ call PlaceString
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $10
+ call CopyData
+ ld hl, vSprites + $40
+ ld de, TownMapCursor
+ lb bc, BANK(TownMapCursor), (TownMapCursorEnd - TownMapCursor) / $8
+ call CopyVideoDataDouble
+ xor a
+ ld [wWhichTownMapLocation], a
+ pop af
+ jr .enterLoop
+
+.townMapLoop
+ coord hl, 0, 0
+ lb bc, 1, 20
+ call ClearScreenArea
+ ld hl, TownMapOrder
+ ld a, [wWhichTownMapLocation]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+.enterLoop
+ ld de, wTownMapCoords
+ call LoadTownMapEntry
+ ld a, [de]
+ push hl
+ call TownMapCoordsToOAMCoords
+ ld a, $4
+ ld [wOAMBaseTile], a
+ ld hl, wOAMBuffer + $10
+ call WriteTownMapSpriteOAM ; town map cursor sprite
+ pop hl
+ ld de, wcd6d
+.copyMapName
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $50
+ jr nz, .copyMapName
+ coord hl, 1, 0
+ ld de, wcd6d
+ call PlaceString
+ ld hl, wOAMBuffer + $10
+ ld de, wTileMapBackup + 16
+ ld bc, $10
+ call CopyData
+.inputLoop
+ call TownMapSpriteBlinkingAnimation
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ ld b, a
+ and A_BUTTON | B_BUTTON | D_UP | D_DOWN
+ jr z, .inputLoop
+ ld a, SFX_TINK
+ call PlaySound
+ bit 6, b
+ jr nz, .pressedUp
+ bit 7, b
+ jr nz, .pressedDown
+ xor a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ ld [hJoy7], a
+ ld [wAnimCounter], a
+ call ExitTownMap
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+.pressedUp
+ ld a, [wWhichTownMapLocation]
+ inc a
+ cp TownMapOrderEnd - TownMapOrder ; number of list items + 1
+ jr nz, .noOverflow
+ xor a
+.noOverflow
+ ld [wWhichTownMapLocation], a
+ jp .townMapLoop
+.pressedDown
+ ld a, [wWhichTownMapLocation]
+ dec a
+ cp -1
+ jr nz, .noUnderflow
+ ld a, TownMapOrderEnd - TownMapOrder - 1 ; number of list items
+.noUnderflow
+ ld [wWhichTownMapLocation], a
+ jp .townMapLoop
+
+INCLUDE "data/town_map_order.asm"
+
+TownMapCursor:
+ INCBIN "gfx/town_map_cursor.1bpp"
+TownMapCursorEnd:
+
+LoadTownMap_Nest:
+ call LoadTownMap
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ call DisplayWildLocations
+ call GetMonName
+ coord hl, 1, 0
+ call PlaceString
+ ld h, b
+ ld l, c
+ ld de, MonsNestText
+ call PlaceString
+ call WaitForTextScrollButtonPress
+ call ExitTownMap
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+
+MonsNestText:
+ db "'s NEST@"
+
+LoadTownMap_Fly:
+ call ClearSprites
+ call LoadTownMap
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ ld de, BirdSprite
+ ld hl, vSprites + $40
+ lb bc, BANK(BirdSprite), $c
+ call CopyVideoData
+ ld de, TownMapUpArrow
+ ld hl, vChars1 + $6d0
+ lb bc, BANK(TownMapUpArrow), (TownMapUpArrowEnd - TownMapUpArrow) / $8
+ call CopyVideoDataDouble
+ call BuildFlyLocationsList
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ coord hl, 0, 0
+ ld de, ToText
+ call PlaceString
+ ld a, [wCurMap]
+ ld b, $0
+ call DrawPlayerOrBirdSprite
+ ld hl, wFlyLocationsList
+ coord de, 18, 0
+.townMapFlyLoop
+ ld a, " "
+ ld [de], a
+ push hl
+ push hl
+ coord hl, 3, 0
+ lb bc, 1, 15
+ call ClearScreenArea
+ pop hl
+ ld a, [hl]
+ ld b, $4
+ call DrawPlayerOrBirdSprite ; draw bird sprite
+ coord hl, 3, 0
+ ld de, wcd6d
+ call PlaceString
+ ld c, 15
+ call DelayFrames
+ coord hl, 18, 0
+ ld [hl], "▲"
+ coord hl, 19, 0
+ ld [hl], "▼"
+ pop hl
+.inputLoop
+ push hl
+ call DelayFrame
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ ld b, a
+ pop hl
+ and A_BUTTON | B_BUTTON | D_UP | D_DOWN
+ jr z, .inputLoop
+ bit 0, b
+ jr nz, .pressedA
+ ld a, SFX_TINK
+ call PlaySound
+ bit 6, b
+ jr nz, .pressedUp
+ bit 7, b
+ jr nz, .pressedDown
+ jr .pressedB
+.pressedA
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ ld a, [hl]
+ ld [wDestinationMap], a
+ ld hl, wd732
+ set 3, [hl]
+ inc hl
+ set 7, [hl]
+.pressedB
+ xor a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ call GBPalWhiteOutWithDelay3
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+.pressedUp
+ coord de, 18, 0
+ inc hl
+ ld a, [hl]
+ cp $ff
+ jr z, .wrapToStartOfList
+ cp $fe
+ jr z, .pressedUp ; skip past unvisited towns
+ jp .townMapFlyLoop
+.wrapToStartOfList
+ ld hl, wFlyLocationsList
+ jp .townMapFlyLoop
+.pressedDown
+ coord de, 19, 0
+ dec hl
+ ld a, [hl]
+ cp $ff
+ jr z, .wrapToEndOfList
+ cp $fe
+ jr z, .pressedDown ; skip past unvisited towns
+ jp .townMapFlyLoop
+.wrapToEndOfList
+ ld hl, wFlyLocationsList + 11
+ jr .pressedDown
+
+ToText:
+ db "To@"
+
+BuildFlyLocationsList:
+ ld hl, wFlyLocationsList - 1
+ ld [hl], $ff
+ inc hl
+ ld a, [wTownVisitedFlag]
+ ld e, a
+ ld a, [wTownVisitedFlag + 1]
+ ld d, a
+ ld bc, SAFFRON_CITY + 1
+.loop
+ srl d
+ rr e
+ ld a, $fe ; store $fe if the town hasn't been visited
+ jr nc, .notVisited
+ ld a, b ; store the map number of the town if it has been visited
+.notVisited
+ ld [hl], a
+ inc hl
+ inc b
+ dec c
+ jr nz, .loop
+ ld [hl], $ff
+ ret
+
+TownMapUpArrow:
+ INCBIN "gfx/up_arrow.1bpp"
+TownMapUpArrowEnd:
+
+LoadTownMap:
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ coord hl, 0, 0
+ ld b, $12
+ ld c, $12
+ call TextBoxBorder
+ call DisableLCD
+ ld hl, WorldMapTileGraphics
+ ld de, vChars2 + $600
+ ld bc, WorldMapTileGraphicsEnd - WorldMapTileGraphics
+ ld a, BANK(WorldMapTileGraphics)
+ call FarCopyData2
+ ld hl, MonNestIcon
+ ld de, vSprites + $40
+ ld bc, MonNestIconEnd - MonNestIcon
+ ld a, BANK(MonNestIcon)
+ call FarCopyDataDouble
+ coord hl, 0, 0
+ ld de, CompressedMap
+.nextTile
+ ld a, [de]
+ and a
+ jr z, .done
+ ld b, a
+ and $f
+ ld c, a
+ ld a, b
+ swap a
+ and $f
+ add $60
+.writeRunLoop
+ ld [hli], a
+ dec c
+ jr nz, .writeRunLoop
+ inc de
+ jr .nextTile
+.done
+ call EnableLCD
+ ld b, SET_PAL_TOWN_MAP
+ call RunPaletteCommand
+ call Delay3
+ call GBPalNormal
+ xor a
+ ld [wAnimCounter], a
+ inc a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ ret
+
+CompressedMap:
+; you can decompress this file with the redrle program in the extras/ dir
+ INCBIN "gfx/town_map.rle"
+
+ExitTownMap:
+; clear town map graphics data and load usual graphics data
+ xor a
+ ld [wTownMapSpriteBlinkingEnabled], a
+ call GBPalWhiteOut
+ call ClearScreen
+ call ClearSprites
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ call UpdateSprites
+ jp RunDefaultPaletteCommand
+
+DrawPlayerOrBirdSprite:
+; a = map number
+; b = OAM base tile
+ push af
+ ld a, b
+ ld [wOAMBaseTile], a
+ pop af
+ ld de, wTownMapCoords
+ call LoadTownMapEntry
+ ld a, [de]
+ push hl
+ call TownMapCoordsToOAMCoords
+ call WritePlayerOrBirdSpriteOAM
+ pop hl
+ ld de, wcd6d
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp "@"
+ jr nz, .loop
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $a0
+ jp CopyData
+
+DisplayWildLocations:
+ callba FindWildLocationsOfMon
+ call ZeroOutDuplicatesInList
+ ld hl, wOAMBuffer
+ ld de, wTownMapCoords
+.loop
+ ld a, [de]
+ cp $ff
+ jr z, .exitLoop
+ and a
+ jr z, .nextEntry
+ push hl
+ call LoadTownMapEntry
+ pop hl
+ ld a, [de]
+ cp $19 ; Cerulean Cave's coordinates
+ jr z, .nextEntry ; skip Cerulean Cave
+ call TownMapCoordsToOAMCoords
+ ld a, $4 ; nest icon tile no.
+ ld [hli], a
+ xor a
+ ld [hli], a
+.nextEntry
+ inc de
+ jr .loop
+.exitLoop
+ ld a, l
+ and a ; were any OAM entries written?
+ jr nz, .drawPlayerSprite
+; if no OAM entries were written, print area unknown text
+ coord hl, 1, 7
+ ld b, 2
+ ld c, 15
+ call TextBoxBorder
+ coord hl, 2, 9
+ ld de, AreaUnknownText
+ call PlaceString
+ jr .done
+.drawPlayerSprite
+ ld a, [wCurMap]
+ ld b, $0
+ call DrawPlayerOrBirdSprite
+.done
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $a0
+ jp CopyData
+
+AreaUnknownText:
+ db " AREA UNKNOWN@"
+
+TownMapCoordsToOAMCoords:
+; in: lower nybble of a = x, upper nybble of a = y
+; out: b and [hl] = (y * 8) + 24, c and [hl+1] = (x * 8) + 24
+ push af
+ and $f0
+ srl a
+ add 24
+ ld b, a
+ ld [hli], a
+ pop af
+ and $f
+ swap a
+ srl a
+ add 24
+ ld c, a
+ ld [hli], a
+ ret
+
+WritePlayerOrBirdSpriteOAM:
+ ld a, [wOAMBaseTile]
+ and a
+ ld hl, wOAMBuffer + $90 ; for player sprite
+ jr z, WriteTownMapSpriteOAM
+ ld hl, wOAMBuffer + $80 ; for bird sprite
+
+WriteTownMapSpriteOAM:
+ push hl
+
+; Subtract 4 from c (X coord) and 4 from b (Y coord). However, the carry from c
+; is added to b, so the net result is that only 3 is subtracted from b.
+ lb hl, -4, -4
+ add hl, bc
+
+ ld b, h
+ ld c, l
+ pop hl
+
+WriteAsymmetricMonPartySpriteOAM:
+; Writes 4 OAM blocks for a helix mon party sprite, since it does not have
+; a vertical line of symmetry.
+ lb de, 2, 2
+.loop
+ push de
+ push bc
+.innerLoop
+ ld a, b
+ ld [hli], a
+ ld a, c
+ ld [hli], a
+ ld a, [wOAMBaseTile]
+ ld [hli], a
+ inc a
+ ld [wOAMBaseTile], a
+ xor a
+ ld [hli], a
+ inc d
+ ld a, 8
+ add c
+ ld c, a
+ dec e
+ jr nz, .innerLoop
+ pop bc
+ pop de
+ ld a, 8
+ add b
+ ld b, a
+ dec d
+ jr nz, .loop
+ ret
+
+WriteSymmetricMonPartySpriteOAM:
+; Writes 4 OAM blocks for a mon party sprite other than a helix. All the
+; sprites other than the helix one have a vertical line of symmetry which allows
+; the X-flip OAM bit to be used so that only 2 rather than 4 tile patterns are
+; needed.
+ xor a
+ ld [wSymmetricSpriteOAMAttributes], a
+ lb de, 2, 2
+.loop
+ push de
+ push bc
+.innerLoop
+ ld a, b
+ ld [hli], a ; Y
+ ld a, c
+ ld [hli], a ; X
+ ld a, [wOAMBaseTile]
+ ld [hli], a ; tile
+ ld a, [wSymmetricSpriteOAMAttributes]
+ ld [hli], a ; attributes
+ xor (1 << OAM_X_FLIP)
+ ld [wSymmetricSpriteOAMAttributes], a
+ inc d
+ ld a, 8
+ add c
+ ld c, a
+ dec e
+ jr nz, .innerLoop
+ pop bc
+ pop de
+ push hl
+ ld hl, wOAMBaseTile
+ inc [hl]
+ inc [hl]
+ pop hl
+ ld a, 8
+ add b
+ ld b, a
+ dec d
+ jr nz, .loop
+ ret
+
+ZeroOutDuplicatesInList:
+; replace duplicate bytes in the list of wild pokemon locations with 0
+ ld de, wBuffer
+.loop
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ ld c, a
+ ld l, e
+ ld h, d
+.zeroDuplicatesLoop
+ ld a, [hl]
+ cp $ff
+ jr z, .loop
+ cp c
+ jr nz, .skipZeroing
+ xor a
+ ld [hl], a
+.skipZeroing
+ inc hl
+ jr .zeroDuplicatesLoop
+
+LoadTownMapEntry:
+; in: a = map number
+; out: lower nybble of [de] = x, upper nybble of [de] = y, hl = address of name
+ cp REDS_HOUSE_1F
+ jr c, .external
+ ld bc, 4
+ ld hl, InternalMapEntries
+.loop
+ cp [hl]
+ jr c, .foundEntry
+ add hl, bc
+ jr .loop
+.foundEntry
+ inc hl
+ jr .readEntry
+.external
+ ld hl, ExternalMapEntries
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ add hl, bc
+.readEntry
+ ld a, [hli]
+ ld [de], a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+INCLUDE "data/town_map_entries.asm"
+
+ inclang text/map_names.asm
+
+MonNestIcon:
+ INCBIN "gfx/mon_nest_icon.1bpp"
+MonNestIconEnd:
+
+TownMapSpriteBlinkingAnimation:
+ ld a, [wAnimCounter]
+ inc a
+ cp 25
+ jr z, .hideSprites
+ cp 50
+ jr nz, .done
+; show sprites when the counter reaches 50
+ ld hl, wTileMapBackup
+ ld de, wOAMBuffer
+ ld bc, $90
+ call CopyData
+ xor a
+ jr .done
+.hideSprites
+ ld hl, wOAMBuffer
+ ld b, $24
+ ld de, $4
+.hideSpritesLoop
+ ld [hl], $a0
+ add hl, de
+ dec b
+ jr nz, .hideSpritesLoop
+ ld a, 25
+.done
+ ld [wAnimCounter], a
+ jp DelayFrame
diff --git a/en/engine/trade.asm b/en/engine/trade.asm
new file mode 100755
index 00000000..8bc8e3bc
--- /dev/null
+++ b/en/engine/trade.asm
@@ -0,0 +1,853 @@
+InternalClockTradeAnim:
+; Do the trading animation with the player's gameboy on the left.
+; In-game trades and internally clocked link cable trades use this.
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wLeftGBMonSpecies], a
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wRightGBMonSpecies], a
+ ld de, InternalClockTradeFuncSequence
+ jr TradeAnimCommon
+
+ExternalClockTradeAnim:
+; Do the trading animation with the player's gameboy on the right.
+; Externally clocked link cable trades use this.
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wLeftGBMonSpecies], a
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wRightGBMonSpecies], a
+ ld de, ExternalClockTradeFuncSequence
+
+TradeAnimCommon:
+ ld a, [wOptions]
+ push af
+ ld a, [hSCY]
+ push af
+ ld a, [hSCX]
+ push af
+ xor a
+ ld [wOptions], a
+ ld [hSCY], a
+ ld [hSCX], a
+ push de
+.loop
+ pop de
+ ld a, [de]
+ cp $ff
+ jr z, .done
+ inc de
+ push de
+ ld hl, TradeFuncPointerTable
+ add a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .loop
+ push de
+ jp hl ; call trade func, which will return to the top of the loop
+.done
+ pop af
+ ld [hSCX], a
+ pop af
+ ld [hSCY], a
+ pop af
+ ld [wOptions], a
+ ret
+
+addtradefunc: MACRO
+\1TradeFunc::
+ dw \1
+ ENDM
+
+tradefunc: MACRO
+ db (\1TradeFunc - TradeFuncPointerTable) / 2
+ ENDM
+
+; The functions in the sequences below are executed in order by TradeFuncCommon.
+; They are from opposite perspectives. The external clock one makes use of
+; Trade_SwapNames to swap the player and enemy names for some functions.
+
+InternalClockTradeFuncSequence:
+ tradefunc LoadTradingGFXAndMonNames
+ tradefunc Trade_ShowPlayerMon
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_AnimateBallEnteringLinkCable
+ tradefunc Trade_AnimLeftToRight
+ tradefunc Trade_Delay100
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWentToText
+ tradefunc PrintTradeForSendsText
+ tradefunc PrintTradeFarewellText
+ tradefunc Trade_AnimRightToLeft
+ tradefunc Trade_ShowClearedWindow
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_ShowEnemyMon
+ tradefunc Trade_Delay100
+ tradefunc Trade_Cleanup
+ db $FF
+
+ExternalClockTradeFuncSequence:
+ tradefunc LoadTradingGFXAndMonNames
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWillTradeText
+ tradefunc PrintTradeFarewellText
+ tradefunc Trade_SwapNames
+ tradefunc Trade_AnimLeftToRight
+ tradefunc Trade_SwapNames
+ tradefunc Trade_ShowClearedWindow
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_ShowEnemyMon
+ tradefunc Trade_SlideTextBoxOffScreen
+ tradefunc Trade_ShowPlayerMon
+ tradefunc Trade_DrawOpenEndOfLinkCable
+ tradefunc Trade_AnimateBallEnteringLinkCable
+ tradefunc Trade_SwapNames
+ tradefunc Trade_AnimRightToLeft
+ tradefunc Trade_SwapNames
+ tradefunc Trade_Delay100
+ tradefunc Trade_ShowClearedWindow
+ tradefunc PrintTradeWentToText
+ tradefunc Trade_Cleanup
+ db $FF
+
+TradeFuncPointerTable:
+ addtradefunc LoadTradingGFXAndMonNames
+ addtradefunc Trade_ShowPlayerMon
+ addtradefunc Trade_DrawOpenEndOfLinkCable
+ addtradefunc Trade_AnimateBallEnteringLinkCable
+ addtradefunc Trade_ShowEnemyMon
+ addtradefunc Trade_AnimLeftToRight
+ addtradefunc Trade_AnimRightToLeft
+ addtradefunc Trade_Delay100
+ addtradefunc Trade_ShowClearedWindow
+ addtradefunc PrintTradeWentToText
+ addtradefunc PrintTradeForSendsText
+ addtradefunc PrintTradeFarewellText
+ addtradefunc PrintTradeTakeCareText
+ addtradefunc PrintTradeWillTradeText
+ addtradefunc Trade_Cleanup
+ addtradefunc Trade_SlideTextBoxOffScreen
+ addtradefunc Trade_SwapNames
+
+Trade_Delay100:
+ ld c, 100
+ jp DelayFrames
+
+Trade_CopyTileMapToVRAM:
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+Trade_Delay80:
+ ld c, 80
+ jp DelayFrames
+
+Trade_ClearTileMap:
+ coord hl, 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, " "
+ jp FillMemory
+
+LoadTradingGFXAndMonNames:
+ call Trade_ClearTileMap
+ call DisableLCD
+ ld hl, TradingAnimationGraphics
+ ld de, vChars2 + $310
+ ld bc, TradingAnimationGraphicsEnd - TradingAnimationGraphics
+ ld a, BANK(TradingAnimationGraphics)
+ call FarCopyData2
+ ld hl, TradingAnimationGraphics2
+ ld de, vSprites + $7c0
+ ld bc, TradingAnimationGraphics2End - TradingAnimationGraphics2
+ ld a, BANK(TradingAnimationGraphics2)
+ call FarCopyData2
+ ld hl, vBGMap0
+ ld bc, $800
+ ld a, " "
+ call FillMemory
+ call ClearSprites
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ ld hl, wd730
+ set 6, [hl] ; turn on instant text printing
+ ld a, [wOnSGB]
+ and a
+ ld a, $e4 ; non-SGB OBP0
+ jr z, .next
+ ld a, $f0 ; SGB OBP0
+.next
+ ld [rOBP0], a
+ call EnableLCD
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, [wTradedPlayerMonSpecies]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wcd6d
+ ld de, wcf4b
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wTradedEnemyMonSpecies]
+ ld [wd11e], a
+ jp GetMonName
+
+Trade_LoadMonPartySpriteGfx:
+ ld a, %11010000
+ ld [rOBP1], a
+ jpba LoadMonPartySpriteGfx
+
+Trade_SwapNames:
+ ld hl, wPlayerName
+ ld de, wBuffer
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wLinkEnemyTrainerName
+ ld de, wPlayerName
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld hl, wBuffer
+ ld de, wLinkEnemyTrainerName
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+Trade_Cleanup:
+ xor a
+ call LoadGBPal
+ ld hl, wd730
+ res 6, [hl] ; turn off instant text printing
+ ret
+
+Trade_ShowPlayerMon:
+ ld a, %10101011
+ ld [rLCDC], a
+ ld a, $50
+ ld [hWY], a
+ ld a, $86
+ ld [rWX], a
+ ld [hSCX], a
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ coord hl, 4, 0
+ ld b, 6
+ ld c, 10
+ call TextBoxBorder
+ call Trade_PrintPlayerMonInfoText
+ ld b, vBGMap0 / $100
+ call CopyScreenTileBufferToVRAM
+ call ClearScreen
+ ld a, [wTradedPlayerMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, $7e
+.slideScreenLoop
+ push af
+ call DelayFrame
+ pop af
+ ld [rWX], a
+ ld [hSCX], a
+ dec a
+ dec a
+ and a
+ jr nz, .slideScreenLoop
+ call Trade_Delay80
+ ld a, TRADE_BALL_POOF_ANIM
+ call Trade_ShowAnimation
+ ld a, TRADE_BALL_DROP_ANIM
+ call Trade_ShowAnimation ; clears mon pic
+ ld a, [wTradedPlayerMonSpecies]
+ call PlayCry
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+Trade_DrawOpenEndOfLinkCable:
+ call Trade_ClearTileMap
+ ld b, vBGMap0 / $100
+ call CopyScreenTileBufferToVRAM
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+
+; This function call is pointless. It just copies blank tiles to VRAM that was
+; already filled with blank tiles.
+ ld hl, vBGMap1 + $8c
+ call Trade_CopyCableTilesOffScreen
+
+ ld a, $a0
+ ld [hSCX], a
+ call DelayFrame
+ ld a, %10001011
+ ld [rLCDC], a
+ coord hl, 6, 2
+ ld b, $7 ; open end of link cable tile ID list index
+ call CopyTileIDsFromList_ZeroBaseTileID
+ call Trade_CopyTileMapToVRAM
+ ld a, SFX_HEAL_HP
+ call PlaySound
+ ld c, 20
+.loop
+ ld a, [hSCX]
+ add 4
+ ld [hSCX], a
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_AnimateBallEnteringLinkCable:
+ ld a, TRADE_BALL_SHAKE_ANIM
+ call Trade_ShowAnimation
+ ld c, 10
+ call DelayFrames
+ ld a, %11100100
+ ld [rOBP0], a
+ xor a
+ ld [wLinkCableAnimBulgeToggle], a
+ lb bc, $20, $60
+.moveBallInsideLinkCableLoop
+ push bc
+ xor a
+ ld de, Trade_BallInsideLinkCableOAM
+ call WriteOAMBlock
+ ld a, [wLinkCableAnimBulgeToggle]
+ xor $1
+ ld [wLinkCableAnimBulgeToggle], a
+ add $7e
+ ld hl, wOAMBuffer + $02
+ ld de, 4
+ ld c, e
+.cycleLinkCableBulgeTile
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .cycleLinkCableBulgeTile
+ call Delay3
+ pop bc
+ ld a, c
+ add $4
+ ld c, a
+ cp $a0
+ jr nc, .ballSpriteReachedEdgeOfScreen
+ ld a, SFX_TINK
+ call PlaySound
+ jr .moveBallInsideLinkCableLoop
+.ballSpriteReachedEdgeOfScreen
+ call ClearSprites
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ ld b, $98
+ call CopyScreenTileBufferToVRAM
+ call Delay3
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+Trade_BallInsideLinkCableOAM:
+ db $7E,$00,$7E,$20
+ db $7E,$40,$7E,$60
+
+Trade_ShowEnemyMon:
+ ld a, TRADE_BALL_TILT_ANIM
+ call Trade_ShowAnimation
+ call Trade_ShowClearedWindow
+ coord hl, 4, 10
+ ld b, 6
+ ld c, 10
+ call TextBoxBorder
+ call Trade_PrintEnemyMonInfoText
+ call Trade_CopyTileMapToVRAM
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, [wTradedEnemyMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, TRADE_BALL_POOF_ANIM
+ call Trade_ShowAnimation
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld a, [wTradedEnemyMonSpecies]
+ call PlayCry
+ call Trade_Delay100
+ coord hl, 4, 10
+ lb bc, 8, 12
+ call ClearScreenArea
+ jp PrintTradeTakeCareText
+
+Trade_AnimLeftToRight:
+; Animates the mon moving from the left GB to the right one.
+ call Trade_InitGameboyTransferGfx
+ ld a, $1
+ ld [wTradedMonMovingRight], a
+ ld a, %11100100
+ ld [rOBP0], a
+ ld a, $54
+ ld [wBaseCoordX], a
+ ld a, $1c
+ ld [wBaseCoordY], a
+ ld a, [wLeftGBMonSpecies]
+ ld [wMonPartySpriteSpecies], a
+ call Trade_WriteCircledMonOAM
+ call Trade_DrawLeftGameboy
+ call Trade_CopyTileMapToVRAM
+ call Trade_DrawCableAcrossScreen
+ ld hl, vBGMap1 + $8c
+ call Trade_CopyCableTilesOffScreen
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawRightGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Trade_AnimMonMoveVertical
+ jp ClearSprites
+
+Trade_AnimRightToLeft:
+; Animates the mon moving from the right GB to the left one.
+ call Trade_InitGameboyTransferGfx
+ xor a
+ ld [wTradedMonMovingRight], a
+ ld a, $64
+ ld [wBaseCoordX], a
+ ld a, $44
+ ld [wBaseCoordY], a
+ ld a, [wRightGBMonSpecies]
+ ld [wMonPartySpriteSpecies], a
+ call Trade_WriteCircledMonOAM
+ call Trade_DrawRightGameboy
+ call Trade_CopyTileMapToVRAM
+ call Trade_DrawCableAcrossScreen
+ ld hl, vBGMap1 + $94
+ call Trade_CopyCableTilesOffScreen
+ call Trade_AnimMonMoveVertical
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawLeftGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ jp ClearSprites
+
+Trade_InitGameboyTransferGfx:
+; Initialises the graphics for showing a mon moving between gameboys.
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call Trade_LoadMonPartySpriteGfx
+ call DelayFrame
+ ld a, %10101011
+ ld [rLCDC], a
+ xor a
+ ld [hSCX], a
+ ld a, $90
+ ld [hWY], a
+ ret
+
+Trade_DrawLeftGameboy:
+ call Trade_ClearTileMap
+
+; draw link cable
+ coord hl, 11, 4
+ ld a, $5d
+ ld [hli], a
+ ld a, $5e
+ ld c, 8
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+
+; draw gameboy pic
+ coord hl, 5, 3
+ ld b, $6
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with player name below gameboy pic
+ coord hl, 4, 12
+ ld b, 2
+ ld c, 7
+ call TextBoxBorder
+ coord hl, 5, 14
+ ld de, wPlayerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawRightGameboy:
+ call Trade_ClearTileMap
+
+; draw horizontal segment of link cable
+ coord hl, 0, 4
+ ld a, $5e
+ ld c, $e
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+
+; draw vertical segment of link cable
+ ld a, $5f
+ ld [hl], a
+ ld de, SCREEN_WIDTH
+ add hl, de
+ ld a, $61
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld [hl], a
+ add hl, de
+ ld a, $60
+ ld [hld], a
+ ld a, $5d
+ ld [hl], a
+
+; draw gameboy pic
+ coord hl, 7, 8
+ ld b, $6
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with enemy name above link cable
+ coord hl, 6, 0
+ ld b, 2
+ ld c, 7
+ call TextBoxBorder
+ coord hl, 7, 2
+ ld de, wLinkEnemyTrainerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawCableAcrossScreen:
+; Draws the link cable across the screen.
+ call Trade_ClearTileMap
+ coord hl, 0, 4
+ ld a, $5e
+ ld c, SCREEN_WIDTH
+.loop
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_CopyCableTilesOffScreen:
+; This is used to copy the link cable tiles off screen so that the cable
+; continues when the screen is scrolled.
+ push hl
+ coord hl, 0, 4
+ call CopyToRedrawRowOrColumnSrcTiles
+ pop hl
+ ld a, h
+ ld [hRedrawRowOrColumnDest + 1], a
+ ld a, l
+ ld [hRedrawRowOrColumnDest], a
+ ld a, REDRAW_ROW
+ ld [hRedrawRowOrColumnMode], a
+ ld c, 10
+ jp DelayFrames
+
+Trade_AnimMonMoveHorizontal:
+; Animates the mon going through the link cable horizontally over a distance of
+; b 16-pixel units.
+ ld a, [wTradedMonMovingRight]
+ ld e, a
+ ld d, $8
+.scrollLoop
+ ld a, e
+ dec a
+ jr z, .movingRight
+; moving left
+ ld a, [hSCX]
+ sub $2
+ jr .next
+.movingRight
+ ld a, [hSCX]
+ add $2
+.next
+ ld [hSCX], a
+ call DelayFrame
+ dec d
+ jr nz, .scrollLoop
+ call Trade_AnimCircledMon
+ dec b
+ jr nz, Trade_AnimMonMoveHorizontal
+ ret
+
+Trade_AnimCircledMon:
+; Cycles between the two animation frames of the mon party sprite, cycles
+; between a circle and an oval around the mon sprite, and makes the cable flash.
+ push de
+ push bc
+ push hl
+ ld a, [rBGP]
+ xor $3c ; make link cable flash
+ ld [rBGP], a
+ ld hl, wOAMBuffer + $02
+ ld de, $4
+ ld c, $14
+.loop
+ ld a, [hl]
+ xor $40
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ pop hl
+ pop bc
+ pop de
+ ret
+
+Trade_WriteCircledMonOAM:
+ callba WriteMonPartySpriteOAMBySpecies
+ call Trade_WriteCircleOAM
+
+Trade_AddOffsetsToOAMCoords:
+ ld hl, wOAMBuffer
+ ld c, $14
+.loop
+ ld a, [wBaseCoordY]
+ add [hl]
+ ld [hli], a
+ ld a, [wBaseCoordX]
+ add [hl]
+ ld [hli], a
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_AnimMonMoveVertical:
+; Animates the mon going through the link cable vertically as well as
+; horizontally for a bit. The last bit of horizontal movement (when moving
+; right) or the first bit of horizontal movement (when moving left) are done
+; here instead of Trade_AnimMonMoveHorizontal because this function moves the
+; sprite itself rather than scrolling the screen around the sprite. Moving the
+; sprite itself is necessary because the vertical segment of the link cable is
+; to the right of the screen position that the mon sprite has when
+; Trade_AnimMonMoveHorizontal is executing.
+ ld a, [wTradedMonMovingRight]
+ and a
+ jr z, .movingLeft
+; moving right
+ lb bc, 4, 0 ; move right
+ call .doAnim
+ lb bc, 0, 10 ; move down
+ jr .doAnim
+.movingLeft
+ lb bc, 0, -10 ; move up
+ call .doAnim
+ lb bc, -4, 0 ; move left
+.doAnim
+ ld a, b
+ ld [wBaseCoordX], a
+ ld a, c
+ ld [wBaseCoordY], a
+ ld d, $4
+.loop
+ call Trade_AddOffsetsToOAMCoords
+ call Trade_AnimCircledMon
+ ld c, 8
+ call DelayFrames
+ dec d
+ jr nz, .loop
+ ret
+
+Trade_WriteCircleOAM:
+; Writes the OAM blocks for the circle around the traded mon as it passes
+; the link cable.
+ ld hl, Trade_CircleOAMPointers
+ ld c, $4
+ xor a
+.loop
+ push bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ inc hl
+ push hl
+ inc a
+ push af
+ call WriteOAMBlock
+ pop af
+ pop hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+Trade_CircleOAMPointers:
+ dw Trade_CircleOAM0
+ db $08,$08
+ dw Trade_CircleOAM1
+ db $18,$08
+ dw Trade_CircleOAM2
+ db $08,$18
+ dw Trade_CircleOAM3
+ db $18,$18
+
+Trade_CircleOAM0:
+ db $38,$10,$39,$10
+ db $3A,$10,$3B,$10
+
+Trade_CircleOAM1:
+ db $39,$30,$38,$30
+ db $3B,$30,$3A,$30
+
+Trade_CircleOAM2:
+ db $3A,$50,$3B,$50
+ db $38,$50,$39,$50
+
+Trade_CircleOAM3:
+ db $3B,$70,$3A,$70
+ db $39,$70,$38,$70
+
+; a = species
+Trade_LoadMonSprite:
+ ld [wcf91], a
+ ld [wd0b5], a
+ ld [wWholeScreenPaletteMonSpecies], a
+ ld b, SET_PAL_POKEMON_WHOLE_SCREEN
+ ld c, 0
+ call RunPaletteCommand
+ ld a, [H_AUTOBGTRANSFERENABLED]
+ xor $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call GetMonHeader
+ coord hl, 7, 2
+ call LoadFlippedFrontSpriteByMonIndex
+ ld c, 10
+ jp DelayFrames
+
+Trade_ShowClearedWindow:
+; clears the window and covers the BG entirely with the window
+ ld a, $1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ call ClearScreen
+ ld a, %11100011
+ ld [rLCDC], a
+ ld a, $7
+ ld [rWX], a
+ xor a
+ ld [hWY], a
+ ld a, $90
+ ld [hSCX], a
+ ret
+
+Trade_SlideTextBoxOffScreen:
+; Slides the window right until it's off screen. The window usually just has
+; a text box at the bottom when this is called. However, when this is called
+; after Trade_ShowEnemyMon in the external clock sequence, there is a mon pic
+; above the text box and it is also scrolled off the screen.
+ ld c, 50
+ call DelayFrames
+.loop
+ call DelayFrame
+ ld a, [rWX]
+ inc a
+ inc a
+ ld [rWX], a
+ cp $a1
+ jr nz, .loop
+ call Trade_ClearTileMap
+ ld c, 10
+ call DelayFrames
+ ld a, $7
+ ld [rWX], a
+ ret
+
+PrintTradeWentToText:
+ ld hl, TradeWentToText
+ call PrintText
+ ld c, 200
+ call DelayFrames
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWentToText:
+ TX_FAR _TradeWentToText
+ db "@"
+
+PrintTradeForSendsText:
+ ld hl, TradeForText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeSendsText
+ call PrintText
+ jp Trade_Delay80
+
+TradeForText:
+ TX_FAR _TradeForText
+ db "@"
+
+TradeSendsText:
+ TX_FAR _TradeSendsText
+ db "@"
+
+PrintTradeFarewellText:
+ ld hl, TradeWavesFarewellText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeTransferredText
+ call PrintText
+ call Trade_Delay80
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWavesFarewellText:
+ TX_FAR _TradeWavesFarewellText
+ db "@"
+
+TradeTransferredText:
+ TX_FAR _TradeTransferredText
+ db "@"
+
+PrintTradeTakeCareText:
+ ld hl, TradeTakeCareText
+ call PrintText
+ jp Trade_Delay80
+
+TradeTakeCareText:
+ TX_FAR _TradeTakeCareText
+ db "@"
+
+PrintTradeWillTradeText:
+ ld hl, TradeWillTradeText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeforText
+ call PrintText
+ jp Trade_Delay80
+
+TradeWillTradeText:
+ TX_FAR _TradeWillTradeText
+ db "@"
+
+TradeforText:
+ TX_FAR _TradeforText
+ db "@"
+
+Trade_ShowAnimation:
+ ld [wAnimationID], a
+ xor a
+ ld [wAnimationType], a
+ predef_jump MoveAnimation
diff --git a/en/gfx/ED_tile.png b/en/gfx/ED_tile.png
new file mode 100644
index 00000000..352489d6
--- /dev/null
+++ b/en/gfx/ED_tile.png
Binary files differ
diff --git a/en/gfx/battle_hud1.png b/en/gfx/battle_hud1.png
new file mode 100644
index 00000000..74e6361f
--- /dev/null
+++ b/en/gfx/battle_hud1.png
Binary files differ
diff --git a/en/gfx/blue/blueversion.png b/en/gfx/blue/blueversion.png
new file mode 100644
index 00000000..a9c87be8
--- /dev/null
+++ b/en/gfx/blue/blueversion.png
Binary files differ
diff --git a/en/gfx/blue/sgbborder.png b/en/gfx/blue/sgbborder.png
new file mode 100644
index 00000000..098df2b6
--- /dev/null
+++ b/en/gfx/blue/sgbborder.png
Binary files differ
diff --git a/en/gfx/blue/slotmachine1.png b/en/gfx/blue/slotmachine1.png
new file mode 100644
index 00000000..41ebfdea
--- /dev/null
+++ b/en/gfx/blue/slotmachine1.png
Binary files differ
diff --git a/en/gfx/copyright.png b/en/gfx/copyright.png
new file mode 100644
index 00000000..49174349
--- /dev/null
+++ b/en/gfx/copyright.png
Binary files differ
diff --git a/en/gfx/font.png b/en/gfx/font.png
new file mode 100644
index 00000000..34e86b4a
--- /dev/null
+++ b/en/gfx/font.png
Binary files differ
diff --git a/en/gfx/hp_bar_and_status.png b/en/gfx/hp_bar_and_status.png
new file mode 100644
index 00000000..1a832831
--- /dev/null
+++ b/en/gfx/hp_bar_and_status.png
Binary files differ
diff --git a/en/gfx/overworld.png b/en/gfx/overworld.png
new file mode 100644
index 00000000..c7533e40
--- /dev/null
+++ b/en/gfx/overworld.png
Binary files differ
diff --git a/en/gfx/pokedex.png b/en/gfx/pokedex.png
new file mode 100644
index 00000000..0a2c89ea
--- /dev/null
+++ b/en/gfx/pokedex.png
Binary files differ
diff --git a/en/gfx/red/redgreenversion.png b/en/gfx/red/redgreenversion.png
new file mode 100644
index 00000000..e41b4295
--- /dev/null
+++ b/en/gfx/red/redgreenversion.png
Binary files differ
diff --git a/en/gfx/red/sgbborder.png b/en/gfx/red/sgbborder.png
new file mode 100644
index 00000000..7549bb47
--- /dev/null
+++ b/en/gfx/red/sgbborder.png
Binary files differ
diff --git a/en/gfx/red/slotmachine1.png b/en/gfx/red/slotmachine1.png
new file mode 100644
index 00000000..785c74f9
--- /dev/null
+++ b/en/gfx/red/slotmachine1.png
Binary files differ
diff --git a/en/gfx/town_map.png b/en/gfx/town_map.png
new file mode 100644
index 00000000..23e52130
--- /dev/null
+++ b/en/gfx/town_map.png
Binary files differ
diff --git a/en/home.asm b/en/home.asm
new file mode 100644
index 00000000..28699042
--- /dev/null
+++ b/en/home.asm
@@ -0,0 +1,4721 @@
+
+; The rst vectors are unused.
+SECTION "rst 00", ROM0 [$00]
+ rst $38
+SECTION "rst 08", ROM0 [$08]
+ rst $38
+SECTION "rst 10", ROM0 [$10]
+ rst $38
+SECTION "rst 18", ROM0 [$18]
+ rst $38
+SECTION "rst 20", ROM0 [$20]
+ rst $38
+SECTION "rst 28", ROM0 [$28]
+ rst $38
+SECTION "rst 30", ROM0 [$30]
+ rst $38
+SECTION "rst 38", ROM0 [$38]
+ rst $38
+
+; Hardware interrupts
+SECTION "vblank", ROM0 [$40]
+ jp VBlank
+SECTION "hblank", ROM0 [$48]
+ rst $38
+SECTION "timer", ROM0 [$50]
+ jp Timer
+SECTION "serial", ROM0 [$58]
+ jp Serial
+SECTION "joypad", ROM0 [$60]
+ reti
+
+
+SECTION "Home", ROM0
+
+DisableLCD::
+ xor a
+ ld [rIF], a
+ ld a, [rIE]
+ ld b, a
+ res 0, a
+ ld [rIE], a
+
+.wait
+ ld a, [rLY]
+ cp LY_VBLANK
+ jr nz, .wait
+
+ ld a, [rLCDC]
+ and $ff ^ rLCDC_ENABLE_MASK
+ ld [rLCDC], a
+ ld a, b
+ ld [rIE], a
+ ret
+
+EnableLCD::
+ ld a, [rLCDC]
+ set rLCDC_ENABLE, a
+ ld [rLCDC], a
+ ret
+
+ClearSprites::
+ xor a
+ ld hl, wOAMBuffer
+ ld b, 40 * 4
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+HideSprites::
+ ld a, 160
+ ld hl, wOAMBuffer
+ ld de, 4
+ ld b, 40
+.loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ ret
+
+INCLUDE "home/copy.asm"
+
+
+
+SECTION "Entry", ROM0 [$100]
+
+ nop
+ jp Start
+
+
+SECTION "Header", ROM0 [$104]
+
+ ; The header is generated by rgbfix.
+ ; The space here is allocated to prevent code from being overwritten.
+
+ ds $150 - $104
+
+
+
+SECTION "Main", ROM0
+
+Start::
+ cp GBC
+ jr z, .gbc
+ xor a
+ jr .ok
+.gbc
+ ld a, 0
+.ok
+ ld [wGBC], a
+ jp Init
+
+
+INCLUDE "home/joypad.asm"
+INCLUDE "data/map_header_pointers.asm"
+INCLUDE "home/overworld.asm"
+
+CheckForUserInterruption::
+; Return carry if Up+Select+B, Start or A are pressed in c frames.
+; Used only in the intro and title screen.
+ call DelayFrame
+
+ push bc
+ call JoypadLowSensitivity
+ pop bc
+
+ ld a, [hJoyHeld]
+ cp D_UP + SELECT + B_BUTTON
+ jr z, .input
+
+ ld a, [hJoy5]
+ and START | A_BUTTON
+ jr nz, .input
+
+ dec c
+ jr nz, CheckForUserInterruption
+
+ and a
+ ret
+
+.input
+ scf
+ ret
+
+; function to load position data for destination warp when switching maps
+; INPUT:
+; a = ID of destination warp within destination map
+LoadDestinationWarpPosition::
+ ld b, a
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wPredefParentBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld a, b
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld bc, 4
+ ld de, wCurrentTileBlockMapViewPointer
+ call CopyData
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+
+DrawHPBar::
+; Draw an HP bar d tiles long, and fill it to e pixels.
+; If c is nonzero, show at least a sliver regardless.
+; The right end of the bar changes with [wHPBarType].
+
+ push hl
+ push de
+ push bc
+
+ ; Left
+ ld a, $71 ; "HP:"
+ ld [hli], a
+ ld a, $62
+ ld [hli], a
+
+ push hl
+
+ ; Middle
+ ld a, $63 ; empty
+.draw
+ ld [hli], a
+ dec d
+ jr nz, .draw
+
+ ; Right
+ ld a, [wHPBarType]
+ dec a
+ ld a, $6d ; status screen and battle
+ jr z, .ok
+ dec a ; pokemon menu
+.ok
+ ld [hl], a
+
+ pop hl
+
+ ld a, e
+ and a
+ jr nz, .fill
+
+ ; If c is nonzero, draw a pixel anyway.
+ ld a, c
+ and a
+ jr z, .done
+ ld e, 1
+
+.fill
+ ld a, e
+ sub 8
+ jr c, .partial
+ ld e, a
+ ld a, $6b ; full
+ ld [hli], a
+ ld a, e
+ and a
+ jr z, .done
+ jr .fill
+
+.partial
+ ; Fill remaining pixels at the end if necessary.
+ ld a, $63 ; empty
+ add e
+ ld [hl], a
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+; loads pokemon data from one of multiple sources to wLoadedMon
+; loads base stats to wMonHeader
+; INPUT:
+; [wWhichPokemon] = index of pokemon within party/box
+; [wMonDataLocation] = source
+; 00: player's party
+; 01: enemy's party
+; 02: current box
+; 03: daycare
+; OUTPUT:
+; [wcf91] = pokemon ID
+; wLoadedMon = base address of pokemon data
+; wMonHeader = base address of base stats
+LoadMonData::
+ jpab LoadMonData_
+
+OverwritewMoves::
+; Write c to [wMoves + b]. Unused.
+ ld hl, wMoves
+ ld e, b
+ ld d, 0
+ add hl, de
+ ld a, c
+ ld [hl], a
+ ret
+
+LoadFlippedFrontSpriteByMonIndex::
+ ld a, 1
+ ld [wSpriteFlipped], a
+
+LoadFrontSpriteByMonIndex::
+ push hl
+ ld a, [wd11e]
+ push af
+ ld a, [wcf91]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld hl, wd11e
+ ld a, [hl]
+ pop bc
+ ld [hl], b
+ and a
+ pop hl
+ jr z, .invalidDexNumber ; dex #0 invalid
+ cp NUM_POKEMON + 1
+ jr c, .validDexNumber ; dex >#151 invalid
+.invalidDexNumber
+ ld a, RHYDON ; $1
+ ld [wcf91], a
+ ret
+.validDexNumber
+ push hl
+ ld de, vFrontPic
+ call LoadMonFrontSprite
+ pop hl
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(CopyUncompressedPicToHL)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ xor a
+ ld [hStartTileID], a
+ call CopyUncompressedPicToHL
+ xor a
+ ld [wSpriteFlipped], a
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+
+PlayCry::
+; Play monster a's cry.
+ call GetCryData
+ call PlaySound
+ jp WaitForSoundToFinish
+
+GetCryData::
+; Load cry data for monster a.
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, CryData
+ add hl, bc
+ add hl, bc
+ add hl, bc
+
+ ld a, BANK(CryData)
+ call BankswitchHome
+ ld a, [hli]
+ ld b, a ; cry id
+ ld a, [hli]
+ ld [wFrequencyModifier], a
+ ld a, [hl]
+ ld [wTempoModifier], a
+ call BankswitchBack
+
+ ; Cry headers have 3 channels,
+ ; and start from index $14,
+ ; so add 3 times the cry id.
+ ld a, b
+ ld c, $14
+ rlca ; * 2
+ add b
+ add c
+ ret
+
+DisplayPartyMenu::
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ call PartyMenuInit
+ call DrawPartyMenu
+ jp HandlePartyMenuInput
+
+GoBackToPartyMenu::
+ ld a, [hTilesetType]
+ push af
+ xor a
+ ld [hTilesetType], a
+ call PartyMenuInit
+ call RedrawPartyMenu
+ jp HandlePartyMenuInput
+
+PartyMenuInit::
+ ld a, 1 ; hardcoded bank
+ call BankswitchHome
+ call LoadHpBarAndStatusTilePatterns
+ ld hl, wd730
+ set 6, [hl] ; turn off letter printing delay
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld hl, wTopMenuItemY
+ inc a
+ ld [hli], a ; top menu item Y
+ xor a
+ ld [hli], a ; top menu item X
+ ld a, [wPartyAndBillsPCSavedMenuItem]
+ push af
+ ld [hli], a ; current menu item ID
+ inc hl
+ ld a, [wPartyCount]
+ and a ; are there more than 0 pokemon in the party?
+ jr z, .storeMaxMenuItemID
+ dec a
+; if party is not empty, the max menu item ID is ([wPartyCount] - 1)
+; otherwise, it is 0
+.storeMaxMenuItemID
+ ld [hli], a ; max menu item ID
+ ld a, [wForcePlayerToChooseMon]
+ and a
+ ld a, A_BUTTON | B_BUTTON
+ jr z, .next
+ xor a
+ ld [wForcePlayerToChooseMon], a
+ inc a ; a = A_BUTTON
+.next
+ ld [hli], a ; menu watched keys
+ pop af
+ ld [hl], a ; old menu item ID
+ ret
+
+HandlePartyMenuInput::
+ ld a, 1
+ ld [wMenuWrappingEnabled], a
+ ld a, $40
+ ld [wPartyMenuAnimMonEnabled], a
+ call HandleMenuInput_
+ call PlaceUnfilledArrowMenuCursor
+ ld b, a
+ xor a
+ ld [wPartyMenuAnimMonEnabled], a
+ ld a, [wCurrentMenuItem]
+ ld [wPartyAndBillsPCSavedMenuItem], a
+ ld hl, wd730
+ res 6, [hl] ; turn on letter printing delay
+ ld a, [wMenuItemToSwap]
+ and a
+ jp nz, .swappingPokemon
+ pop af
+ ld [hTilesetType], a
+ bit 1, b
+ jr nz, .noPokemonChosen
+ ld a, [wPartyCount]
+ and a
+ jr z, .noPokemonChosen
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPokemon], a
+ ld hl, wPartySpecies
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wcf91], a
+ ld [wBattleMonSpecies2], a
+ call BankswitchBack
+ and a
+ ret
+.noPokemonChosen
+ call BankswitchBack
+ scf
+ ret
+.swappingPokemon
+ bit 1, b ; was the B button pressed?
+ jr z, .handleSwap ; if not, handle swapping the pokemon
+.cancelSwap ; if the B button was pressed
+ callba ErasePartyMenuCursors
+ xor a
+ ld [wMenuItemToSwap], a
+ ld [wPartyMenuTypeOrMessageID], a
+ call RedrawPartyMenu
+ jr HandlePartyMenuInput
+.handleSwap
+ ld a, [wCurrentMenuItem]
+ ld [wWhichPokemon], a
+ callba SwitchPartyMon
+ jr HandlePartyMenuInput
+
+DrawPartyMenu::
+ ld hl, DrawPartyMenu_
+ jr DrawPartyMenuCommon
+
+RedrawPartyMenu::
+ ld hl, RedrawPartyMenu_
+
+DrawPartyMenuCommon::
+ ld b, BANK(RedrawPartyMenu_)
+ jp Bankswitch
+
+; prints a pokemon's status condition
+; INPUT:
+; de = address of status condition
+; hl = destination address
+PrintStatusCondition::
+ push de
+ dec de
+ dec de ; de = address of current HP
+ ld a, [de]
+ ld b, a
+ dec de
+ ld a, [de]
+ or b ; is the pokemon's HP zero?
+ pop de
+ jr nz, PrintStatusConditionNotFainted
+; if the pokemon's HP is 0, print "FNT"
+ ld a, "F"
+ ld [hli], a
+ ld a, "N"
+ ld [hli], a
+ ld [hl], "T"
+ and a
+ ret
+
+PrintStatusConditionNotFainted:
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(PrintStatusAilment)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call PrintStatusAilment ; print status condition
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; function to print pokemon level, leaving off the ":L" if the level is at least 100
+; INPUT:
+; hl = destination address
+; [wLoadedMonLevel] = level
+PrintLevel::
+ ld a, $6e ; ":L" tile ID
+ ld [hli], a
+ ld c, 2 ; number of digits
+ ld a, [wLoadedMonLevel] ; level
+ cp 100
+ jr c, PrintLevelCommon
+; if level at least 100, write over the ":L" tile
+ dec hl
+ inc c ; increment number of digits to 3
+ jr PrintLevelCommon
+
+; prints the level without leaving off ":L" regardless of level
+; INPUT:
+; hl = destination address
+; [wLoadedMonLevel] = level
+PrintLevelFull::
+ ld a, $6e ; ":L" tile ID
+ ld [hli], a
+ ld c, 3 ; number of digits
+ ld a, [wLoadedMonLevel] ; level
+
+PrintLevelCommon::
+ ld [wd11e], a
+ ld de, wd11e
+ ld b, LEFT_ALIGN | 1 ; 1 byte
+ jp PrintNumber
+
+GetwMoves::
+; Unused. Returns the move at index a from wMoves in a
+ ld hl, wMoves
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ret
+
+; copies the base stat data of a pokemon to wMonHeader
+; INPUT:
+; [wd0b5] = pokemon ID
+GetMonHeader::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(BaseStats)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ push bc
+ push de
+ push hl
+ ld a, [wd11e]
+ push af
+ ld a, [wd0b5]
+ ld [wd11e], a
+ ld de, FossilKabutopsPic
+ ld b, $66 ; size of Kabutops fossil and Ghost sprites
+ cp FOSSIL_KABUTOPS ; Kabutops fossil
+ jr z, .specialID
+ ld de, GhostPic
+ cp MON_GHOST ; Ghost
+ jr z, .specialID
+ ld de, FossilAerodactylPic
+ ld b, $77 ; size of Aerodactyl fossil sprite
+ cp FOSSIL_AERODACTYL ; Aerodactyl fossil
+ jr z, .specialID
+ cp MEW
+ jr z, .mew
+ predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
+ ld a, [wd11e]
+ dec a
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ ld hl, BaseStats
+ call AddNTimes
+ ld de, wMonHeader
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ call CopyData
+ jr .done
+.specialID
+ ld hl, wMonHSpriteDim
+ ld [hl], b ; write sprite dimensions
+ inc hl
+ ld [hl], e ; write front sprite pointer
+ inc hl
+ ld [hl], d
+ jr .done
+.mew
+ ld hl, MewBaseStats
+ ld de, wMonHeader
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ ld a, BANK(MewBaseStats)
+ call FarCopyData
+.done
+ ld a, [wd0b5]
+ ld [wMonHIndex], a
+ pop af
+ ld [wd11e], a
+ pop hl
+ pop de
+ pop bc
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; copy party pokemon's name to wcd6d
+GetPartyMonName2::
+ ld a, [wWhichPokemon] ; index within party
+ ld hl, wPartyMonNicks
+
+; this is called more often
+GetPartyMonName::
+ push hl
+ push bc
+ call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times
+ ld de, wcd6d
+ push de
+ ld bc, NAME_LENGTH
+ call CopyData
+ pop de
+ pop bc
+ pop hl
+ ret
+
+; function to print a BCD (Binary-coded decimal) number
+; de = address of BCD number
+; hl = destination address
+; c = flags and length
+; bit 7: if set, do not print leading zeroes
+; if unset, print leading zeroes
+; bit 6: if set, left-align the string (do not pad empty digits with spaces)
+; if unset, right-align the string
+; bit 5: if set, print currency symbol at the beginning of the string
+; if unset, do not print the currency symbol
+; bits 0-4: length of BCD number in bytes
+; Note that bits 5 and 7 are modified during execution. The above reflects
+; their meaning at the beginning of the functions's execution.
+PrintBCDNumber::
+ ld b, c ; save flags in b
+ res 7, c
+ res 6, c
+ res 5, c ; c now holds the length
+ bit 5, b
+ jr z, .loop
+ bit 7, b
+ jr nz, .loop
+ ld [hl], "¥"
+ inc hl
+.loop
+ ld a, [de]
+ swap a
+ call PrintBCDDigit ; print upper digit
+ ld a, [de]
+ call PrintBCDDigit ; print lower digit
+ inc de
+ dec c
+ jr nz, .loop
+ bit 7, b ; were any non-zero digits printed?
+ jr z, .done ; if so, we are done
+.numberEqualsZero ; if every digit of the BCD number is zero
+ bit 6, b ; left or right alignment?
+ jr nz, .skipRightAlignmentAdjustment
+ dec hl ; if the string is right-aligned, it needs to be moved back one space
+.skipRightAlignmentAdjustment
+ bit 5, b
+ jr z, .skipCurrencySymbol
+ ld [hl], "¥"
+ inc hl
+.skipCurrencySymbol
+ ld [hl], "0"
+ call PrintLetterDelay
+ inc hl
+.done
+ ret
+
+PrintBCDDigit::
+ and $f
+ and a
+ jr z, .zeroDigit
+.nonzeroDigit
+ bit 7, b ; have any non-space characters been printed?
+ jr z, .outputDigit
+; if bit 7 is set, then no numbers have been printed yet
+ bit 5, b ; print the currency symbol?
+ jr z, .skipCurrencySymbol
+ ld [hl], "¥"
+ inc hl
+ res 5, b
+.skipCurrencySymbol
+ res 7, b ; unset 7 to indicate that a nonzero digit has been reached
+.outputDigit
+ add "0"
+ ld [hli], a
+ jp PrintLetterDelay
+.zeroDigit
+ bit 7, b ; either printing leading zeroes or already reached a nonzero digit?
+ jr z, .outputDigit ; if so, print a zero digit
+ bit 6, b ; left or right alignment?
+ ret nz
+ inc hl ; if right-aligned, "print" a space by advancing the pointer
+ ret
+
+; uncompresses the front or back sprite of the specified mon
+; assumes the corresponding mon header is already loaded
+; hl contains offset to sprite pointer ($b for front or $d for back)
+UncompressMonSprite::
+ ld bc, wMonHeader
+ add hl, bc
+ ld a, [hli]
+ ld [wSpriteInputPtr], a ; fetch sprite input pointer
+ ld a, [hl]
+ ld [wSpriteInputPtr+1], a
+; define (by index number) the bank that a pokemon's image is in
+; index = Mew, bank 1
+; index = Kabutops fossil, bank $B
+; index < $1F, bank 9
+; $1F ≤ index < $4A, bank $A
+; $4A ≤ index < $74, bank $B
+; $74 ≤ index < $99, bank $C
+; $99 ≤ index, bank $D
+ ld a, [wcf91] ; XXX name for this ram location
+ ld b, a
+ cp MEW
+ ld a, BANK(MewPicFront)
+ jr z, .GotBank
+ ld a, b
+ cp FOSSIL_KABUTOPS
+ ld a, BANK(FossilKabutopsPic)
+ jr z, .GotBank
+ ld a, b
+ cp TANGELA + 1
+ ld a, BANK(TangelaPicFront)
+ jr c, .GotBank
+ ld a, b
+ cp MOLTRES + 1
+ ld a, BANK(MoltresPicFront)
+ jr c, .GotBank
+ ld a, b
+ cp BEEDRILL + 2
+ ld a, BANK(BeedrillPicFront)
+ jr c, .GotBank
+ ld a, b
+ cp STARMIE + 1
+ ld a, BANK(StarmiePicFront)
+ jr c, .GotBank
+ ld a, BANK(VictreebelPicFront)
+.GotBank
+ jp UncompressSpriteData
+
+; de: destination location
+LoadMonFrontSprite::
+ push de
+ ld hl, wMonHFrontSprite - wMonHeader
+ call UncompressMonSprite
+ ld hl, wMonHSpriteDim
+ ld a, [hli]
+ ld c, a
+ pop de
+ ; fall through
+
+; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram
+; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers
+; de: destination location
+; a,c: sprite dimensions (in tiles of 8x8 each)
+LoadUncompressedSpriteData::
+ push de
+ and $f
+ ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width
+ ld b, a
+ ld a, $7
+ sub b ; 7-w
+ inc a ; 8-w
+ srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up)
+ ld b, a
+ add a
+ add a
+ add a
+ sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles)
+ ld [H_SPRITEOFFSET], a
+ ld a, c
+ swap a
+ and $f
+ ld b, a
+ add a
+ add a
+ add a ; 8*tiles is height in bytes
+ ld [H_SPRITEHEIGHT], a
+ ld a, $7
+ sub b ; 7-h ; skip for vertical center (in tiles, relative to current column)
+ ld b, a
+ ld a, [H_SPRITEOFFSET]
+ add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles)
+ add a
+ add a
+ add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes)
+ ld [H_SPRITEOFFSET], a
+ xor a
+ ld [$4000], a
+ ld hl, sSpriteBuffer0
+ call ZeroSpriteBuffer ; zero buffer 0
+ ld de, sSpriteBuffer1
+ ld hl, sSpriteBuffer0
+ call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
+ ld hl, sSpriteBuffer1
+ call ZeroSpriteBuffer ; zero buffer 1
+ ld de, sSpriteBuffer2
+ ld hl, sSpriteBuffer1
+ call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
+ pop de
+ jp InterlaceMergeSpriteBuffers
+
+; copies and aligns the sprite data properly inside the sprite buffer
+; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area
+AlignSpriteDataCentered::
+ ld a, [H_SPRITEOFFSET]
+ ld b, $0
+ ld c, a
+ add hl, bc
+ ld a, [H_SPRITEWIDTH]
+.columnLoop
+ push af
+ push hl
+ ld a, [H_SPRITEHEIGHT]
+ ld c, a
+.columnInnerLoop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec c
+ jr nz, .columnInnerLoop
+ pop hl
+ ld bc, 7*8 ; 7 tiles
+ add hl, bc ; advance one full column
+ pop af
+ dec a
+ jr nz, .columnLoop
+ ret
+
+; fills the sprite buffer (pointed to in hl) with zeros
+ZeroSpriteBuffer::
+ ld bc, SPRITEBUFFERSIZE
+.nextByteLoop
+ xor a
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .nextByteLoop
+ ret
+
+; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2
+; in the resulting sprite, the rows of the two source sprites are interlaced
+; de: output address
+InterlaceMergeSpriteBuffers::
+ xor a
+ ld [$4000], a
+ push de
+ ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2
+ ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1
+ ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0
+ ld a, SPRITEBUFFERSIZE/2 ; $c4
+ ld [H_SPRITEINTERLACECOUNTER], a
+.interlaceLoop
+ ld a, [de]
+ dec de
+ ld [hld], a ; write byte of source 2
+ ld a, [bc]
+ dec bc
+ ld [hld], a ; write byte of source 1
+ ld a, [de]
+ dec de
+ ld [hld], a ; write byte of source 2
+ ld a, [bc]
+ dec bc
+ ld [hld], a ; write byte of source 1
+ ld a, [H_SPRITEINTERLACECOUNTER]
+ dec a
+ ld [H_SPRITEINTERLACECOUNTER], a
+ jr nz, .interlaceLoop
+ ld a, [wSpriteFlipped]
+ and a
+ jr z, .notFlipped
+ ld bc, 2*SPRITEBUFFERSIZE
+ ld hl, sSpriteBuffer1
+.swapLoop
+ swap [hl] ; if flipped swap nybbles in all bytes
+ inc hl
+ dec bc
+ ld a, b
+ or c
+ jr nz, .swapLoop
+.notFlipped
+ pop hl
+ ld de, sSpriteBuffer1
+ ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
+ ld a, [H_LOADEDROMBANK]
+ ld b, a
+ jp CopyVideoData
+
+
+INCLUDE "data/collision.asm"
+INCLUDE "home/copy2.asm"
+ inclang home/text.asm
+INCLUDE "home/vcopy.asm"
+INCLUDE "home/init.asm"
+INCLUDE "home/vblank.asm"
+INCLUDE "home/fade.asm"
+INCLUDE "home/serial.asm"
+INCLUDE "home/timer.asm"
+INCLUDE "home/audio.asm"
+
+
+UpdateSprites::
+ ld a, [wUpdateSpritesEnabled]
+ dec a
+ ret nz
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(_UpdateSprites)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call _UpdateSprites
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+INCLUDE "data/mart_inventories.asm"
+
+TextScriptEndingChar::
+ db "@"
+TextScriptEnd::
+ ld hl, TextScriptEndingChar
+ ret
+
+ExclamationText::
+ TX_FAR _ExclamationText
+ db "@"
+
+GroundRoseText::
+ TX_FAR _GroundRoseText
+ db "@"
+
+BoulderText::
+ TX_FAR _BoulderText
+ db "@"
+
+MartSignText::
+ TX_FAR _MartSignText
+ db "@"
+
+PokeCenterSignText::
+ TX_FAR _PokeCenterSignText
+ db "@"
+
+PickUpItemText::
+ TX_ASM
+ predef PickUpItem
+ jp TextScriptEnd
+
+
+INCLUDE "home/pic.asm"
+
+
+ResetPlayerSpriteData::
+ ld hl, wSpriteStateData1
+ call ResetPlayerSpriteData_ClearSpriteData
+ ld hl, wSpriteStateData2
+ call ResetPlayerSpriteData_ClearSpriteData
+ ld a, $1
+ ld [wSpriteStateData1], a
+ ld [wSpriteStateData2 + $0e], a
+ ld hl, wSpriteStateData1 + 4
+ ld [hl], $3c ; set Y screen pos
+ inc hl
+ inc hl
+ ld [hl], $40 ; set X screen pos
+ ret
+
+; overwrites sprite data with zeroes
+ResetPlayerSpriteData_ClearSpriteData::
+ ld bc, $10
+ xor a
+ jp FillMemory
+
+FadeOutAudio::
+ ld a, [wAudioFadeOutControl]
+ and a ; currently fading out audio?
+ jr nz, .fadingOut
+ ld a, [wd72c]
+ bit 1, a
+ ret nz
+ ld a, $77
+ ld [rNR50], a
+ ret
+.fadingOut
+ ld a, [wAudioFadeOutCounter]
+ and a
+ jr z, .counterReachedZero
+ dec a
+ ld [wAudioFadeOutCounter], a
+ ret
+.counterReachedZero
+ ld a, [wAudioFadeOutCounterReloadValue]
+ ld [wAudioFadeOutCounter], a
+ ld a, [rNR50]
+ and a ; has the volume reached 0?
+ jr z, .fadeOutComplete
+ ld b, a
+ and $f
+ dec a
+ ld c, a
+ ld a, b
+ and $f0
+ swap a
+ dec a
+ swap a
+ or c
+ ld [rNR50], a
+ ret
+.fadeOutComplete
+ ld a, [wAudioFadeOutControl]
+ ld b, a
+ xor a
+ ld [wAudioFadeOutControl], a
+ ld a, $ff
+ ld [wNewSoundID], a
+ call PlaySound
+ ld a, [wAudioSavedROMBank]
+ ld [wAudioROMBank], a
+ ld a, b
+ ld [wNewSoundID], a
+ jp PlaySound
+
+; this function is used to display sign messages, sprite dialog, etc.
+; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID
+DisplayTextID::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ callba DisplayTextIDInit ; initialization
+ ld hl, wTextPredefFlag
+ bit 0, [hl]
+ res 0, [hl]
+ jr nz, .skipSwitchToMapBank
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+.skipSwitchToMapBank
+ ld a, 30 ; half a second
+ ld [H_FRAMECOUNTER], a ; used as joypad poll timer
+ ld hl, wMapTextPtr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; hl = map text pointer
+ ld d, $00
+ ld a, [hSpriteIndexOrTextID] ; text ID
+ ld [wSpriteIndex], a
+ and a
+ jp z, DisplayStartMenu
+ cp TEXT_SAFARI_GAME_OVER
+ jp z, DisplaySafariGameOverText
+ cp TEXT_MON_FAINTED
+ jp z, DisplayPokemonFaintedText
+ cp TEXT_BLACKED_OUT
+ jp z, DisplayPlayerBlackedOutText
+ cp TEXT_REPEL_WORE_OFF
+ jp z, DisplayRepelWoreOffText
+ ld a, [wNumSprites]
+ ld e, a
+ ld a, [hSpriteIndexOrTextID] ; sprite ID
+ cp e
+ jr z, .spriteHandling
+ jr nc, .skipSpriteHandling
+.spriteHandling
+; get the text ID of the sprite
+ push hl
+ push de
+ push bc
+ callba UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction)
+ pop bc
+ pop de
+ ld hl, wMapSpriteData ; NPC text entries
+ ld a, [hSpriteIndexOrTextID]
+ dec a
+ add a
+ add l
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ inc hl
+ ld a, [hl] ; a = text ID of the sprite
+ pop hl
+.skipSpriteHandling
+; look up the address of the text in the map's text entries
+ dec a
+ ld e, a
+ sla e
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; hl = address of the text
+ ld a, [hl] ; a = first byte of text
+; check first byte of text for special cases
+ cp $fe ; Pokemart NPC
+ jp z, DisplayPokemartDialogue
+ cp $ff ; Pokemon Center NPC
+ jp z, DisplayPokemonCenterDialogue
+ cp $fc ; Item Storage PC
+ jp z, FuncTX_ItemStoragePC
+ cp $fd ; Bill's PC
+ jp z, FuncTX_BillsPC
+ cp $f9 ; Pokemon Center PC
+ jp z, FuncTX_PokemonCenterPC
+ cp $f5 ; Vending Machine
+ jr nz, .notVendingMachine
+ callba VendingMachineMenu ; jump banks to vending machine routine
+ jr AfterDisplayingTextID
+.notVendingMachine
+ cp $f7 ; prize menu
+ jp z, FuncTX_GameCornerPrizeMenu
+ cp $f6 ; cable connection NPC in Pokemon Center
+ jr nz, .notSpecialCase
+ callab CableClubNPC
+ jr AfterDisplayingTextID
+.notSpecialCase
+ call PrintText_NoCreatingTextBox ; display the text
+ ld a, [wDoNotWaitForButtonPressAfterDisplayingText]
+ and a
+ jr nz, HoldTextDisplayOpen
+
+AfterDisplayingTextID::
+ ld a, [wEnteringCableClub]
+ and a
+ jr nz, HoldTextDisplayOpen
+ call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text
+
+; loop to hold the dialogue box open as long as the player keeps holding down the A button
+HoldTextDisplayOpen::
+ call Joypad
+ ld a, [hJoyHeld]
+ bit 0, a ; is the A button being pressed?
+ jr nz, HoldTextDisplayOpen
+
+CloseTextDisplay::
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+ ld a, $90
+ ld [hWY], a ; move the window off the screen
+ call DelayFrame
+ call LoadGBPal
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; disable continuous WRAM to VRAM transfer each V-blank
+; loop to make sprites face the directions they originally faced before the dialogue
+ ld hl, wSpriteStateData2 + $19
+ ld c, $0f
+ ld de, $0010
+.restoreSpriteFacingDirectionLoop
+ ld a, [hl]
+ dec h
+ ld [hl], a
+ inc h
+ add hl, de
+ dec c
+ jr nz, .restoreSpriteFacingDirectionLoop
+ ld a, BANK(InitMapSprites)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
+ ld hl, wFontLoaded
+ res 0, [hl]
+ ld a, [wd732]
+ bit 3, a ; used fly warp
+ call z, LoadPlayerSpriteGraphics
+ call LoadCurrentMapView
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ jp UpdateSprites
+
+DisplayPokemartDialogue::
+ push hl
+ ld hl, PokemartGreetingText
+ call PrintText
+ pop hl
+ inc hl
+ call LoadItemList
+ ld a, PRICEDITEMLISTMENU
+ ld [wListMenuID], a
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(DisplayPokemartDialogue_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call DisplayPokemartDialogue_
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ jp AfterDisplayingTextID
+
+PokemartGreetingText::
+ TX_FAR _PokemartGreetingText
+ db "@"
+
+LoadItemList::
+ ld a, 1
+ ld [wUpdateSpritesEnabled], a
+ ld a, h
+ ld [wItemListPointer], a
+ ld a, l
+ ld [wItemListPointer + 1], a
+ ld de, wItemList
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr nz, .loop
+ ret
+
+DisplayPokemonCenterDialogue::
+; zeroing these doesn't appear to serve any purpose
+ xor a
+ ld [$ff8b], a
+ ld [$ff8c], a
+ ld [$ff8d], a
+
+ inc hl
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(DisplayPokemonCenterDialogue_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call DisplayPokemonCenterDialogue_
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ jp AfterDisplayingTextID
+
+DisplaySafariGameOverText::
+ callab PrintSafariGameOverText
+ jp AfterDisplayingTextID
+
+DisplayPokemonFaintedText::
+ ld hl, PokemonFaintedText
+ call PrintText
+ jp AfterDisplayingTextID
+
+PokemonFaintedText::
+ TX_FAR _PokemonFaintedText
+ db "@"
+
+DisplayPlayerBlackedOutText::
+ ld hl, PlayerBlackedOutText
+ call PrintText
+ ld a, [wd732]
+ res 5, a ; reset forced to use bike bit
+ ld [wd732], a
+ jp HoldTextDisplayOpen
+
+PlayerBlackedOutText::
+ TX_FAR _PlayerBlackedOutText
+ db "@"
+
+DisplayRepelWoreOffText::
+ ld hl, RepelWoreOffText
+ call PrintText
+ jp AfterDisplayingTextID
+
+RepelWoreOffText::
+ TX_FAR _RepelWoreOffText
+ db "@"
+
+INCLUDE "engine/menu/start_menu.asm"
+
+; function to count how many bits are set in a string of bytes
+; INPUT:
+; hl = address of string of bytes
+; b = length of string of bytes
+; OUTPUT:
+; [wNumSetBits] = number of set bits
+CountSetBits::
+ ld c, 0
+.loop
+ ld a, [hli]
+ ld e, a
+ ld d, 8
+.innerLoop ; count how many bits are set in the current byte
+ srl e
+ ld a, 0
+ adc c
+ ld c, a
+ dec d
+ jr nz, .innerLoop
+ dec b
+ jr nz, .loop
+ ld a, c
+ ld [wNumSetBits], a
+ ret
+
+; subtracts the amount the player paid from their money
+; sets carry flag if there is enough money and unsets carry flag if not
+SubtractAmountPaidFromMoney::
+ jpba SubtractAmountPaidFromMoney_
+
+; adds the amount the player sold to their money
+AddAmountSoldToMoney::
+ ld de, wPlayerMoney + 2
+ ld hl, $ffa1 ; total price of items
+ ld c, 3 ; length of money in bytes
+ predef AddBCDPredef ; add total price to money
+ ld a, MONEY_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; redraw money text box
+ ld a, SFX_PURCHASE
+ call PlaySoundWaitForCurrent
+ jp WaitForSoundToFinish
+
+; function to remove an item (in varying quantities) from the player's bag or PC box
+; INPUT:
+; HL = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wWhichPokemon] = index (within the inventory) of the item to remove
+; [wItemQuantity] = quantity to remove
+RemoveItemFromInventory::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(RemoveItemFromInventory_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call RemoveItemFromInventory_
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; function to add an item (in varying quantities) to the player's bag or PC box
+; INPUT:
+; HL = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wItemQuantity] = item quantity
+; sets carry flag if successful, unsets carry flag if unsuccessful
+AddItemToInventory::
+ push bc
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(AddItemToInventory_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call AddItemToInventory_
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ pop bc
+ ret
+
+; INPUT:
+; [wListMenuID] = list menu ID
+; [wListPointer] = address of the list (2 bytes)
+DisplayListMenuID::
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; disable auto-transfer
+ ld a, 1
+ ld [hJoy7], a ; joypad state update flag
+ ld a, [wBattleType]
+ and a ; is it the Old Man battle?
+ jr nz, .specialBattleType
+ ld a, $01 ; hardcoded bank
+ jr .bankswitch
+.specialBattleType ; Old Man battle
+ ld a, BANK(DisplayBattleMenu)
+.bankswitch
+ call BankswitchHome
+ ld hl, wd730
+ set 6, [hl] ; turn off letter printing delay
+ xor a
+ ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
+ ld [wListCount], a
+ ld a, [wListPointer]
+ ld l, a
+ ld a, [wListPointer + 1]
+ ld h, a ; hl = address of the list
+ ld a, [hl] ; the first byte is the number of entries in the list
+ ld [wListCount], a
+ ld a, LIST_MENU_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID ; draw the menu text box
+ call UpdateSprites ; disable sprites behind the text box
+; the code up to .skipMovingSprites appears to be useless
+ coord hl, 4, 2 ; coordinates of upper left corner of menu text box
+ lb de, 9, 14 ; height and width of menu text box
+ ld a, [wListMenuID]
+ and a ; is it a PC pokemon list?
+ jr nz, .skipMovingSprites
+ call UpdateSprites
+.skipMovingSprites
+ ld a, 1 ; max menu item ID is 1 if the list has less than 2 entries
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld a, [wListCount]
+ cp 2 ; does the list have less than 2 entries?
+ jr c, .setMenuVariables
+ ld a, 2 ; max menu item ID is 2 if the list has at least 2 entries
+.setMenuVariables
+ ld [wMaxMenuItem], a
+ ld a, 4
+ ld [wTopMenuItemY], a
+ ld a, 5
+ ld [wTopMenuItemX], a
+ ld a, A_BUTTON | B_BUTTON | SELECT
+ ld [wMenuWatchedKeys], a
+ ld c, 10
+ call DelayFrames
+
+DisplayListMenuIDLoop::
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a ; disable transfer
+ call PrintListMenuEntries
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a ; enable transfer
+ call Delay3
+ ld a, [wBattleType]
+ and a ; is it the Old Man battle?
+ jr z, .notOldManBattle
+.oldManBattle
+ ld a, "▶"
+ Coorda 5, 4 ; place menu cursor in front of first menu entry
+ ld c, 80
+ call DelayFrames
+ xor a
+ ld [wCurrentMenuItem], a
+ coord hl, 5, 4
+ ld a, l
+ ld [wMenuCursorLocation], a
+ ld a, h
+ ld [wMenuCursorLocation + 1], a
+ jr .buttonAPressed
+.notOldManBattle
+ call LoadGBPal
+ call HandleMenuInput
+ push af
+ call PlaceMenuCursor
+ pop af
+ bit 0, a ; was the A button pressed?
+ jp z, .checkOtherKeys
+.buttonAPressed
+ ld a, [wCurrentMenuItem]
+ call PlaceUnfilledArrowMenuCursor
+
+; pointless because both values are overwritten before they are read
+ ld a, $01
+ ld [wMenuExitMethod], a
+ ld [wChosenMenuItem], a
+
+ xor a
+ ld [wMenuWatchMovingOutOfBounds], a
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld a, [wListScrollOffset]
+ add c
+ ld c, a
+ ld a, [wListCount]
+ and a ; is the list empty?
+ jp z, ExitListMenu ; if so, exit the menu
+ dec a
+ cp c ; did the player select Cancel?
+ jp c, ExitListMenu ; if so, exit the menu
+ ld a, c
+ ld [wWhichPokemon], a
+ ld a, [wListMenuID]
+ cp ITEMLISTMENU
+ jr nz, .skipMultiplying
+; if it's an item menu
+ sla c ; item entries are 2 bytes long, so multiply by 2
+.skipMultiplying
+ ld a, [wListPointer]
+ ld l, a
+ ld a, [wListPointer + 1]
+ ld h, a
+ inc hl ; hl = beginning of list entries
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ ld [wcf91], a
+ ld a, [wListMenuID]
+ and a ; is it a PC pokemon list?
+ jr z, .pokemonList
+ push hl
+ call GetItemPrice
+ pop hl
+ ld a, [wListMenuID]
+ cp ITEMLISTMENU
+ jr nz, .skipGettingQuantity
+; if it's an item menu
+ inc hl
+ ld a, [hl] ; a = item quantity
+ ld [wMaxItemQuantity], a
+.skipGettingQuantity
+ ld a, [wcf91]
+ ld [wd0b5], a
+ ld a, BANK(ItemNames)
+ ld [wPredefBank], a
+ call GetName
+ jr .storeChosenEntry
+.pokemonList
+ ld hl, wPartyCount
+ ld a, [wListPointer]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld hl, wPartyMonNicks
+ jr z, .getPokemonName
+ ld hl, wBoxMonNicks ; box pokemon names
+.getPokemonName
+ ld a, [wWhichPokemon]
+ call GetPartyMonName
+.storeChosenEntry ; store the menu entry that the player chose and return
+ ld de, wcd6d
+ call CopyStringToCF4B ; copy name to wcf4b
+ ld a, CHOSE_MENU_ITEM
+ ld [wMenuExitMethod], a
+ ld a, [wCurrentMenuItem]
+ ld [wChosenMenuItem], a
+ xor a
+ ld [hJoy7], a ; joypad state update flag
+ ld hl, wd730
+ res 6, [hl] ; turn on letter printing delay
+ jp BankswitchBack
+.checkOtherKeys ; check B, SELECT, Up, and Down keys
+ bit 1, a ; was the B button pressed?
+ jp nz, ExitListMenu ; if so, exit the menu
+ bit 2, a ; was the select button pressed?
+ jp nz, HandleItemListSwapping ; if so, allow the player to swap menu entries
+ ld b, a
+ bit 7, b ; was Down pressed?
+ ld hl, wListScrollOffset
+ jr z, .upPressed
+.downPressed
+ ld a, [hl]
+ add 3
+ ld b, a
+ ld a, [wListCount]
+ cp b ; will going down scroll past the Cancel button?
+ jp c, DisplayListMenuIDLoop
+ inc [hl] ; if not, go down
+ jp DisplayListMenuIDLoop
+.upPressed
+ ld a, [hl]
+ and a
+ jp z, DisplayListMenuIDLoop
+ dec [hl]
+ jp DisplayListMenuIDLoop
+
+DisplayChooseQuantityMenu::
+; text box dimensions/coordinates for just quantity
+ coord hl, 15, 9
+ ld b, 1 ; height
+ ld c, 3 ; width
+ ld a, [wListMenuID]
+ cp PRICEDITEMLISTMENU
+ jr nz, .drawTextBox
+; text box dimensions/coordinates for quantity and price
+ coord hl, 7, 9
+ ld b, 1 ; height
+ ld c, 11 ; width
+.drawTextBox
+ call TextBoxBorder
+ coord hl, 16, 10
+ ld a, [wListMenuID]
+ cp PRICEDITEMLISTMENU
+ jr nz, .printInitialQuantity
+ coord hl, 8, 10
+.printInitialQuantity
+ ld de, InitialQuantityText
+ call PlaceString
+ xor a
+ ld [wItemQuantity], a ; initialize current quantity to 0
+ jp .incrementQuantity
+.waitForKeyPressLoop
+ call JoypadLowSensitivity
+ ld a, [hJoyPressed] ; newly pressed buttons
+ bit 0, a ; was the A button pressed?
+ jp nz, .buttonAPressed
+ bit 1, a ; was the B button pressed?
+ jp nz, .buttonBPressed
+ bit 6, a ; was Up pressed?
+ jr nz, .incrementQuantity
+ bit 7, a ; was Down pressed?
+ jr nz, .decrementQuantity
+ jr .waitForKeyPressLoop
+.incrementQuantity
+ ld a, [wMaxItemQuantity]
+ inc a
+ ld b, a
+ ld hl, wItemQuantity ; current quantity
+ inc [hl]
+ ld a, [hl]
+ cp b
+ jr nz, .handleNewQuantity
+; wrap to 1 if the player goes above the max quantity
+ ld a, 1
+ ld [hl], a
+ jr .handleNewQuantity
+.decrementQuantity
+ ld hl, wItemQuantity ; current quantity
+ dec [hl]
+ jr nz, .handleNewQuantity
+; wrap to the max quantity if the player goes below 1
+ ld a, [wMaxItemQuantity]
+ ld [hl], a
+.handleNewQuantity
+ coord hl, 17, 10
+ ld a, [wListMenuID]
+ cp PRICEDITEMLISTMENU
+ jr nz, .printQuantity
+.printPrice
+ ld c, $03
+ ld a, [wItemQuantity]
+ ld b, a
+ ld hl, hMoney ; total price
+; initialize total price to 0
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+.addLoop ; loop to multiply the individual price by the quantity to get the total price
+ ld de, hMoney + 2
+ ld hl, hItemPrice + 2
+ push bc
+ predef AddBCDPredef ; add the individual price to the current sum
+ pop bc
+ dec b
+ jr nz, .addLoop
+ ld a, [hHalveItemPrices]
+ and a ; should the price be halved (for selling items)?
+ jr z, .skipHalvingPrice
+ xor a
+ ld [hDivideBCDDivisor], a
+ ld [hDivideBCDDivisor + 1], a
+ ld a, $02
+ ld [hDivideBCDDivisor + 2], a
+ predef DivideBCDPredef3 ; halves the price
+; store the halved price
+ ld a, [hDivideBCDQuotient]
+ ld [hMoney], a
+ ld a, [hDivideBCDQuotient + 1]
+ ld [hMoney + 1], a
+ ld a, [hDivideBCDQuotient + 2]
+ ld [hMoney + 2], a
+.skipHalvingPrice
+ coord hl, 12, 10
+ ld de, SpacesBetweenQuantityAndPriceText
+ call PlaceString
+ ld de, hMoney ; total price
+ ld c, $a3
+ call PrintBCDNumber
+ coord hl, 9, 10
+.printQuantity
+ ld de, wItemQuantity ; current quantity
+ lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits
+ call PrintNumber
+ jp .waitForKeyPressLoop
+.buttonAPressed ; the player chose to make the transaction
+ xor a
+ ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
+ ret
+.buttonBPressed ; the player chose to cancel the transaction
+ xor a
+ ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
+ ld a, $ff
+ ret
+
+InitialQuantityText::
+ db "×01@"
+
+SpacesBetweenQuantityAndPriceText::
+ db " @"
+
+ExitListMenu::
+ ld a, [wCurrentMenuItem]
+ ld [wChosenMenuItem], a
+ ld a, CANCELLED_MENU
+ ld [wMenuExitMethod], a
+ ld [wMenuWatchMovingOutOfBounds], a
+ xor a
+ ld [hJoy7], a
+ ld hl, wd730
+ res 6, [hl]
+ call BankswitchBack
+ xor a
+ ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
+ scf
+ ret
+
+PrintListMenuEntries::
+ coord hl, 5, 3
+ ld b, 9
+ ld c, 14
+ call ClearScreenArea
+ ld a, [wListPointer]
+ ld e, a
+ ld a, [wListPointer + 1]
+ ld d, a
+ inc de ; de = beginning of list entries
+ ld a, [wListScrollOffset]
+ ld c, a
+ ld a, [wListMenuID]
+ cp ITEMLISTMENU
+ ld a, c
+ jr nz, .skipMultiplying
+; if it's an item menu
+; item entries are 2 bytes long, so multiply by 2
+ sla a
+ sla c
+.skipMultiplying
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d
+.noCarry
+ coord hl, 6, 4 ; coordinates of first list entry name
+ ld b, 4 ; print 4 names
+.loop
+ ld a, b
+ ld [wWhichPokemon], a
+ ld a, [de]
+ ld [wd11e], a
+ cp $ff
+ jp z, .printCancelMenuItem
+ push bc
+ push de
+ push hl
+ push hl
+ push de
+ ld a, [wListMenuID]
+ and a
+ jr z, .pokemonPCMenu
+ cp MOVESLISTMENU
+ jr z, .movesMenu
+.itemMenu
+ call GetItemName
+ jr .placeNameString
+.pokemonPCMenu
+ push hl
+ ld hl, wPartyCount
+ ld a, [wListPointer]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld hl, wPartyMonNicks
+ jr z, .getPokemonName
+ ld hl, wBoxMonNicks ; box pokemon names
+.getPokemonName
+ ld a, [wWhichPokemon]
+ ld b, a
+ ld a, 4
+ sub b
+ ld b, a
+ ld a, [wListScrollOffset]
+ add b
+ call GetPartyMonName
+ pop hl
+ jr .placeNameString
+.movesMenu
+ call GetMoveName
+.placeNameString
+ call PlaceString
+ pop de
+ pop hl
+ ld a, [wPrintItemPrices]
+ and a ; should prices be printed?
+ jr z, .skipPrintingItemPrice
+.printItemPrice
+ push hl
+ ld a, [de]
+ ld de, ItemPrices
+ ld [wcf91], a
+ call GetItemPrice ; get price
+ pop hl
+ ld bc, SCREEN_WIDTH + 5 ; 1 row down and 5 columns right
+ add hl, bc
+ ld c, $a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
+ call PrintBCDNumber
+.skipPrintingItemPrice
+ ld a, [wListMenuID]
+ and a
+ jr nz, .skipPrintingPokemonLevel
+.printPokemonLevel
+ ld a, [wd11e]
+ push af
+ push hl
+ ld hl, wPartyCount
+ ld a, [wListPointer]
+ cp l ; is it a list of party pokemon or box pokemon?
+ ld a, PLAYER_PARTY_DATA
+ jr z, .next
+ ld a, BOX_DATA
+.next
+ ld [wMonDataLocation], a
+ ld hl, wWhichPokemon
+ ld a, [hl]
+ ld b, a
+ ld a, $04
+ sub b
+ ld b, a
+ ld a, [wListScrollOffset]
+ add b
+ ld [hl], a
+ call LoadMonData
+ ld a, [wMonDataLocation]
+ and a ; is it a list of party pokemon or box pokemon?
+ jr z, .skipCopyingLevel
+.copyLevel
+ ld a, [wLoadedMonBoxLevel]
+ ld [wLoadedMonLevel], a
+.skipCopyingLevel
+ pop hl
+ ld bc, $001c
+ add hl, bc
+ call PrintLevel
+ pop af
+ ld [wd11e], a
+.skipPrintingPokemonLevel
+ pop hl
+ pop de
+ inc de
+ ld a, [wListMenuID]
+ cp ITEMLISTMENU
+ jr nz, .nextListEntry
+.printItemQuantity
+ ld a, [wd11e]
+ ld [wcf91], a
+ call IsKeyItem ; check if item is unsellable
+ ld a, [wIsKeyItem]
+ and a ; is the item unsellable?
+ jr nz, .skipPrintingItemQuantity ; if so, don't print the quantity
+ push hl
+ ld bc, SCREEN_WIDTH + 8 ; 1 row down and 8 columns right
+ add hl, bc
+ ld a, "×"
+ ld [hli], a
+ ld a, [wd11e]
+ push af
+ ld a, [de]
+ ld [wMaxItemQuantity], a
+ push de
+ ld de, wd11e
+ ld [de], a
+ lb bc, 1, 2
+ call PrintNumber
+ pop de
+ pop af
+ ld [wd11e], a
+ pop hl
+.skipPrintingItemQuantity
+ inc de
+ pop bc
+ inc c
+ push bc
+ inc c
+ ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
+ and a ; is an item being swapped?
+ jr z, .nextListEntry
+ sla a
+ cp c ; is it this item?
+ jr nz, .nextListEntry
+ dec hl
+ ld a, $ec ; unfilled right arrow menu cursor to indicate an item being swapped
+ ld [hli], a
+.nextListEntry
+ ld bc, 2 * SCREEN_WIDTH ; 2 rows
+ add hl, bc
+ pop bc
+ inc c
+ dec b
+ jp nz, .loop
+ ld bc, -8
+ add hl, bc
+ ld a, "▼"
+ ld [hl], a
+ ret
+.printCancelMenuItem
+ ld de, ListMenuCancelText
+ jp PlaceString
+
+ListMenuCancelText::
+ db "CANCEL@"
+
+GetMonName::
+ push hl
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(MonsterNames)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld a, [wd11e]
+ dec a
+ ld hl, MonsterNames
+ ld c, 10
+ ld b, 0
+ call AddNTimes
+ ld de, wcd6d
+ push de
+ ld bc, 10
+ call CopyData
+ ld hl, wcd6d + 10
+ ld [hl], "@"
+ pop de
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ pop hl
+ ret
+
+GetItemName::
+; given an item ID at [wd11e], store the name of the item into a string
+; starting at wcd6d
+ push hl
+ push bc
+ ld a, [wd11e]
+ cp HM_01 ; is this a TM/HM?
+ jr nc, .Machine
+
+ ld [wd0b5], a
+ ld a, ITEM_NAME
+ ld [wNameListType], a
+ ld a, BANK(ItemNames)
+ ld [wPredefBank], a
+ call GetName
+ jr .Finish
+
+.Machine
+ call GetMachineName
+.Finish
+ ld de, wcd6d ; pointer to where item name is stored in RAM
+ pop bc
+ pop hl
+ ret
+
+GetMachineName::
+; copies the name of the TM/HM in [wd11e] to wcd6d
+ push hl
+ push de
+ push bc
+ ld a, [wd11e]
+ push af
+ cp TM_01 ; is this a TM? [not HM]
+ jr nc, .WriteTM
+; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
+; TM printing code
+ add 5
+ ld [wd11e], a
+ ld hl, HiddenPrefix ; points to "HM"
+ ld bc, 2
+ jr .WriteMachinePrefix
+.WriteTM
+ ld hl, TechnicalPrefix ; points to "TM"
+ ld bc, 2
+.WriteMachinePrefix
+ ld de, wcd6d
+ call CopyData
+
+; now get the machine number and convert it to text
+ ld a, [wd11e]
+ sub TM_01 - 1
+ ld b, "0"
+.FirstDigit
+ sub 10
+ jr c, .SecondDigit
+ inc b
+ jr .FirstDigit
+.SecondDigit
+ add 10
+ push af
+ ld a, b
+ ld [de], a
+ inc de
+ pop af
+ ld b, "0"
+ add b
+ ld [de], a
+ inc de
+ ld a, "@"
+ ld [de], a
+ pop af
+ ld [wd11e], a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+TechnicalPrefix::
+ db "TM"
+HiddenPrefix::
+ db "HM"
+
+; sets carry if item is HM, clears carry if item is not HM
+; Input: a = item ID
+IsItemHM::
+ cp HM_01
+ jr c, .notHM
+ cp TM_01
+ ret
+.notHM
+ and a
+ ret
+
+; sets carry if move is an HM, clears carry if move is not an HM
+; Input: a = move ID
+IsMoveHM::
+ ld hl, HMMoves
+ ld de, 1
+ jp IsInArray
+
+HMMoves::
+ db CUT,FLY,SURF,STRENGTH,FLASH
+ db $ff ; terminator
+
+GetMoveName::
+ push hl
+ ld a, MOVE_NAME
+ ld [wNameListType], a
+ ld a, [wd11e]
+ ld [wd0b5], a
+ ld a, BANK(MoveNames)
+ ld [wPredefBank], a
+ call GetName
+ ld de, wcd6d ; pointer to where move name is stored in RAM
+ pop hl
+ ret
+
+; reloads text box tile patterns, current map view, and tileset tile patterns
+ReloadMapData::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+ call DisableLCD
+ call LoadTextBoxTilePatterns
+ call LoadCurrentMapView
+ call LoadTilesetTilePatternData
+ call EnableLCD
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; reloads tileset tile patterns
+ReloadTilesetTilePatterns::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wCurMap]
+ call SwitchToMapRomBank
+ call DisableLCD
+ call LoadTilesetTilePatternData
+ call EnableLCD
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; shows the town map and lets the player choose a destination to fly to
+ChooseFlyDestination::
+ ld hl, wd72e
+ res 4, [hl]
+ jpba LoadTownMap_Fly
+
+; causes the text box to close without waiting for a button press after displaying text
+DisableWaitingAfterTextDisplay::
+ ld a, $01
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ret
+
+; uses an item
+; UseItem is used with dummy items to perform certain other functions as well
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wActionResultOrTookBattleTurn] = success
+; 00: unsuccessful
+; 01: successful
+; 02: not able to be used right now, no extra menu displayed (only certain items use this)
+UseItem::
+ jpba UseItem_
+
+; confirms the item toss and then tosses the item
+; INPUT:
+; hl = address of inventory (either wNumBagItems or wNumBoxItems)
+; [wcf91] = item ID
+; [wWhichPokemon] = index of item within inventory
+; [wItemQuantity] = quantity to toss
+; OUTPUT:
+; clears carry flag if the item is tossed, sets carry flag if not
+TossItem::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(TossItem_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call TossItem_
+ pop de
+ ld a, d
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; checks if an item is a key item
+; INPUT:
+; [wcf91] = item ID
+; OUTPUT:
+; [wIsKeyItem] = result
+; 00: item is not key item
+; 01: item is key item
+IsKeyItem::
+ push hl
+ push de
+ push bc
+ callba IsKeyItem_
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; function to draw various text boxes
+; INPUT:
+; [wTextBoxID] = text box ID
+; b, c = y, x cursor position (TWO_OPTION_MENU only)
+DisplayTextBoxID::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(DisplayTextBoxID_)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call DisplayTextBoxID_
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; not zero if an NPC movement script is running, the player character is
+; automatically stepping down from a door, or joypad states are being simulated
+IsPlayerCharacterBeingControlledByGame::
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret nz
+ ld a, [wd736]
+ bit 1, a ; currently stepping down from door bit
+ ret nz
+ ld a, [wd730]
+ and $80
+ ret
+
+RunNPCMovementScript::
+ ld hl, wd736
+ bit 0, [hl]
+ res 0, [hl]
+ jr nz, .playerStepOutFromDoor
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret z
+ dec a
+ add a
+ ld d, 0
+ ld e, a
+ ld hl, .NPCMovementScriptPointerTables
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wNPCMovementScriptBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld a, [wNPCMovementScriptFunctionNum]
+ call CallFunctionInTable
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+.NPCMovementScriptPointerTables
+ dw PalletMovementScriptPointerTable
+ dw PewterMuseumGuyMovementScriptPointerTable
+ dw PewterGymGuyMovementScriptPointerTable
+.playerStepOutFromDoor
+ jpba PlayerStepOutFromDoor
+
+EndNPCMovementScript::
+ jpba _EndNPCMovementScript
+
+EmptyFunc2::
+ ret
+
+; stores hl in [wTrainerHeaderPtr]
+StoreTrainerHeaderPointer::
+ ld a, h
+ ld [wTrainerHeaderPtr], a
+ ld a, l
+ ld [wTrainerHeaderPtr+1], a
+ ret
+
+; executes the current map script from the function pointer array provided in hl.
+; a: map script index to execute (unless overridden by [wd733] bit 4)
+ExecuteCurMapScriptInTable::
+ push af
+ push de
+ call StoreTrainerHeaderPointer
+ pop hl
+ pop af
+ push hl
+ ld hl, wFlags_D733
+ bit 4, [hl]
+ res 4, [hl]
+ jr z, .useProvidedIndex ; test if map script index was overridden manually
+ ld a, [wCurMapScript]
+.useProvidedIndex
+ pop hl
+ ld [wCurMapScript], a
+ call CallFunctionInTable
+ ld a, [wCurMapScript]
+ ret
+
+LoadGymLeaderAndCityName::
+ push de
+ ld de, wGymCityName
+ ld bc, $11
+ call CopyData ; load city name
+ pop hl
+ ld de, wGymLeaderName
+ ld bc, NAME_LENGTH
+ jp CopyData ; load gym leader name
+
+; reads specific information from trainer header (pointed to at wTrainerHeaderPtr)
+; a: offset in header data
+; 0 -> flag's bit (into wTrainerHeaderFlagBit)
+; 2 -> flag's byte ptr (into hl)
+; 4 -> before battle text (into hl)
+; 6 -> after battle text (into hl)
+; 8 -> end battle text (into hl)
+ReadTrainerHeaderInfo::
+ push de
+ push af
+ ld d, $0
+ ld e, a
+ ld hl, wTrainerHeaderPtr
+ ld a, [hli]
+ ld l, [hl]
+ ld h, a
+ add hl, de
+ pop af
+ and a
+ jr nz, .nonZeroOffset
+ ld a, [hl]
+ ld [wTrainerHeaderFlagBit], a ; store flag's bit
+ jr .done
+.nonZeroOffset
+ cp $2
+ jr z, .readPointer ; read flag's byte ptr
+ cp $4
+ jr z, .readPointer ; read before battle text
+ cp $6
+ jr z, .readPointer ; read after battle text
+ cp $8
+ jr z, .readPointer ; read end battle text
+ cp $a
+ jr nz, .done
+ ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?)
+ ld d, [hl]
+ ld e, a
+ jr .done
+.readPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.done
+ pop de
+ ret
+
+TrainerFlagAction::
+ predef_jump FlagActionPredef
+
+TalkToTrainer::
+ call StoreTrainerHeaderPointer
+ xor a
+ call ReadTrainerHeaderInfo ; read flag's bit
+ ld a, $2
+ call ReadTrainerHeaderInfo ; read flag's byte ptr
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ ld b, FLAG_TEST
+ call TrainerFlagAction ; read trainer's flag
+ ld a, c
+ and a
+ jr z, .trainerNotYetFought ; test trainer's flag
+ ld a, $6
+ call ReadTrainerHeaderInfo ; print after battle text
+ jp PrintText
+.trainerNotYetFought
+ ld a, $4
+ call ReadTrainerHeaderInfo ; print before battle text
+ call PrintText
+ ld a, $a
+ call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
+ push de
+ ld a, $8
+ call ReadTrainerHeaderInfo ; read end battle text
+ pop de
+ call SaveEndBattleTextPointers
+ ld hl, wFlags_D733
+ set 4, [hl] ; activate map script index override (index is set below)
+ ld hl, wFlags_0xcd60
+ bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
+ ret nz
+; if the player talked to the trainer of his own volition
+ call EngageMapTrainer
+ ld hl, wCurMapScript
+ inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
+ jp StartTrainerBattle
+
+; checks if any trainers are seeing the player and wanting to fight
+CheckFightingMapTrainers::
+ call CheckForEngagingTrainers
+ ld a, [wSpriteIndex]
+ cp $ff
+ jr nz, .trainerEngaging
+ xor a
+ ld [wSpriteIndex], a
+ ld [wTrainerHeaderFlagBit], a
+ ret
+.trainerEngaging
+ ld hl, wFlags_D733
+ set 3, [hl]
+ ld [wEmotionBubbleSpriteIndex], a
+ xor a ; EXCLAMATION_BUBBLE
+ ld [wWhichEmotionBubble], a
+ predef EmotionBubble
+ ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN
+ ld [wJoyIgnore], a
+ xor a
+ ld [hJoyHeld], a
+ call TrainerWalkUpToPlayer_Bank0
+ ld hl, wCurMapScript
+ inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
+ ret
+
+; display the before battle text after the enemy trainer has walked up to the player's sprite
+DisplayEnemyTrainerTextAndStartBattle::
+ ld a, [wd730]
+ and $1
+ ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
+ ld [wJoyIgnore], a
+ ld a, [wSpriteIndex]
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ ; fall through
+
+StartTrainerBattle::
+ xor a
+ ld [wJoyIgnore], a
+ call InitBattleEnemyParameters
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, wd72e
+ set 1, [hl]
+ ld hl, wCurMapScript
+ inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
+ ret
+
+EndTrainerBattle::
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+ set 6, [hl]
+ ld hl, wd72d
+ res 7, [hl]
+ ld hl, wFlags_0xcd60
+ res 0, [hl] ; player is no longer engaged by any trainer
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, ResetButtonPressedAndMapScript
+ ld a, $2
+ call ReadTrainerHeaderInfo
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ ld b, FLAG_SET
+ call TrainerFlagAction ; flag trainer as fought
+ ld a, [wEnemyMonOrTrainerClass]
+ cp 200
+ jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
+ ld hl, wMissableObjectList
+ ld de, $2
+ ld a, [wSpriteIndex]
+ call IsInArray ; search for sprite ID
+ inc hl
+ ld a, [hl]
+ ld [wMissableObjectIndex], a ; load corresponding missable object index and remove it
+ predef HideObject
+.skipRemoveSprite
+ ld hl, wd730
+ bit 4, [hl]
+ res 4, [hl]
+ ret nz
+
+ResetButtonPressedAndMapScript::
+ xor a
+ ld [wJoyIgnore], a
+ ld [hJoyHeld], a
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
+ ld [wCurMapScript], a ; reset battle status
+ ret
+
+; calls TrainerWalkUpToPlayer
+TrainerWalkUpToPlayer_Bank0::
+ jpba TrainerWalkUpToPlayer
+
+; sets opponent type and mon set/lvl based on the engaging trainer data
+InitBattleEnemyParameters::
+ ld a, [wEngagedTrainerClass]
+ ld [wCurOpponent], a
+ ld [wEnemyMonOrTrainerClass], a
+ cp 200
+ ld a, [wEngagedTrainerSet]
+ jr c, .noTrainer
+ ld [wTrainerNo], a
+ ret
+.noTrainer
+ ld [wCurEnemyLVL], a
+ ret
+
+GetSpritePosition1::
+ ld hl, _GetSpritePosition1
+ jr SpritePositionBankswitch
+
+GetSpritePosition2::
+ ld hl, _GetSpritePosition2
+ jr SpritePositionBankswitch
+
+SetSpritePosition1::
+ ld hl, _SetSpritePosition1
+ jr SpritePositionBankswitch
+
+SetSpritePosition2::
+ ld hl, _SetSpritePosition2
+SpritePositionBankswitch::
+ ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2)
+ jp Bankswitch ; indirect jump to one of the four functions
+
+CheckForEngagingTrainers::
+ xor a
+ call ReadTrainerHeaderInfo ; read trainer flag's bit (unused)
+ ld d, h ; store trainer header address in de
+ ld e, l
+.trainerLoop
+ call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer
+ ld a, [de]
+ ld [wSpriteIndex], a ; store trainer flag's bit
+ ld [wTrainerHeaderFlagBit], a
+ cp $ff
+ ret z
+ ld a, $2
+ call ReadTrainerHeaderInfo ; read trainer flag's byte ptr
+ ld b, FLAG_TEST
+ ld a, [wTrainerHeaderFlagBit]
+ ld c, a
+ call TrainerFlagAction ; read trainer flag
+ ld a, c
+ and a ; has the trainer already been defeated?
+ jr nz, .continue
+ push hl
+ push de
+ push hl
+ xor a
+ call ReadTrainerHeaderInfo ; get trainer header pointer
+ inc hl
+ ld a, [hl] ; read trainer engage distance
+ pop hl
+ ld [wTrainerEngageDistance], a
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wTrainerSpriteOffset], a
+ predef TrainerEngage
+ pop de
+ pop hl
+ ld a, [wTrainerSpriteOffset]
+ and a
+ ret nz ; break if the trainer is engaging
+.continue
+ ld hl, $c
+ add hl, de
+ ld d, h
+ ld e, l
+ jr .trainerLoop
+
+; hl = text if the player wins
+; de = text if the player loses
+SaveEndBattleTextPointers::
+ ld a, [H_LOADEDROMBANK]
+ ld [wEndBattleTextRomBank], a
+ ld a, h
+ ld [wEndBattleWinTextPointer], a
+ ld a, l
+ ld [wEndBattleWinTextPointer + 1], a
+ ld a, d
+ ld [wEndBattleLoseTextPointer], a
+ ld a, e
+ ld [wEndBattleLoseTextPointer + 1], a
+ ret
+
+; loads data of some trainer on the current map and plays pre-battle music
+; [wSpriteIndex]: sprite ID of trainer who is engaged
+EngageMapTrainer::
+ ld hl, wMapSpriteExtraData
+ ld d, $0
+ ld a, [wSpriteIndex]
+ dec a
+ add a
+ ld e, a
+ add hl, de ; seek to engaged trainer data
+ ld a, [hli] ; load trainer class
+ ld [wEngagedTrainerClass], a
+ ld a, [hl] ; load trainer mon set
+ ld [wEngagedTrainerSet], a
+ jp PlayTrainerMusic
+
+PrintEndBattleText::
+ push hl
+ ld hl, wd72d
+ bit 7, [hl]
+ res 7, [hl]
+ pop hl
+ ret z
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wEndBattleTextRomBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ push hl
+ callba SaveTrainerName
+ ld hl, TrainerEndBattleText
+ call PrintText
+ pop hl
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ callba FreezeEnemyTrainerSprite
+ jp WaitForSoundToFinish
+
+GetSavedEndBattleTextPointer::
+ ld a, [wBattleResult]
+ and a
+; won battle
+ jr nz, .lostBattle
+ ld a, [wEndBattleWinTextPointer]
+ ld h, a
+ ld a, [wEndBattleWinTextPointer + 1]
+ ld l, a
+ ret
+.lostBattle
+ ld a, [wEndBattleLoseTextPointer]
+ ld h, a
+ ld a, [wEndBattleLoseTextPointer + 1]
+ ld l, a
+ ret
+
+TrainerEndBattleText::
+ TX_FAR _TrainerNameText
+ TX_ASM
+ call GetSavedEndBattleTextPointer
+ call TextCommandProcessor
+ jp TextScriptEnd
+
+; only engage withe trainer if the player is not already
+; engaged with another trainer
+; XXX unused?
+CheckIfAlreadyEngaged::
+ ld a, [wFlags_0xcd60]
+ bit 0, a
+ ret nz
+ call EngageMapTrainer
+ xor a
+ ret
+
+PlayTrainerMusic::
+ ld a, [wEngagedTrainerClass]
+ cp OPP_SONY1
+ ret z
+ cp OPP_SONY2
+ ret z
+ cp OPP_SONY3
+ ret z
+ ld a, [wGymLeaderNo]
+ and a
+ ret nz
+ xor a
+ ld [wAudioFadeOutControl], a
+ ld a, $ff
+ call PlaySound
+ ld a, BANK(Music_MeetEvilTrainer)
+ ld [wAudioROMBank], a
+ ld [wAudioSavedROMBank], a
+ ld a, [wEngagedTrainerClass]
+ ld b, a
+ ld hl, EvilTrainerList
+.evilTrainerListLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .noEvilTrainer
+ cp b
+ jr nz, .evilTrainerListLoop
+ ld a, MUSIC_MEET_EVIL_TRAINER
+ jr .PlaySound
+.noEvilTrainer
+ ld hl, FemaleTrainerList
+.femaleTrainerListLoop
+ ld a, [hli]
+ cp $ff
+ jr z, .maleTrainer
+ cp b
+ jr nz, .femaleTrainerListLoop
+ ld a, MUSIC_MEET_FEMALE_TRAINER
+ jr .PlaySound
+.maleTrainer
+ ld a, MUSIC_MEET_MALE_TRAINER
+.PlaySound
+ ld [wNewSoundID], a
+ jp PlaySound
+
+INCLUDE "data/trainer_types.asm"
+
+; checks if the player's coordinates match an arrow movement tile's coordinates
+; and if so, decodes the RLE movement data
+; b = player Y
+; c = player X
+DecodeArrowMovementRLE::
+ ld a, [hli]
+ cp $ff
+ ret z ; no match in the list
+ cp b
+ jr nz, .nextArrowMovementTileEntry1
+ ld a, [hli]
+ cp c
+ jr nz, .nextArrowMovementTileEntry2
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+ ld hl, wSimulatedJoypadStatesEnd
+ call DecodeRLEList
+ dec a
+ ld [wSimulatedJoypadStatesIndex], a
+ ret
+.nextArrowMovementTileEntry1
+ inc hl
+.nextArrowMovementTileEntry2
+ inc hl
+ inc hl
+ jr DecodeArrowMovementRLE
+
+FuncTX_ItemStoragePC::
+ call SaveScreenTilesToBuffer2
+ ld b, BANK(PlayerPC)
+ ld hl, PlayerPC
+ jr bankswitchAndContinue
+
+FuncTX_BillsPC::
+ call SaveScreenTilesToBuffer2
+ ld b, BANK(BillsPC_)
+ ld hl, BillsPC_
+ jr bankswitchAndContinue
+
+FuncTX_GameCornerPrizeMenu::
+; XXX find a better name for this function
+; special_F7
+ ld b, BANK(CeladonPrizeMenu)
+ ld hl, CeladonPrizeMenu
+bankswitchAndContinue::
+ call Bankswitch
+ jp HoldTextDisplayOpen ; continue to main text-engine function
+
+FuncTX_PokemonCenterPC::
+ ld b, BANK(ActivatePC)
+ ld hl, ActivatePC
+ jr bankswitchAndContinue
+
+StartSimulatingJoypadStates::
+ xor a
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1
+ ld hl, wd730
+ set 7, [hl]
+ ret
+
+IsItemInBag::
+; given an item_id in b
+; set zero flag if item isn't in player's bag
+; else reset zero flag
+; related to Pokémon Tower and ghosts
+ predef GetQuantityOfItemInBag
+ ld a, b
+ and a
+ ret
+
+DisplayPokedex::
+ ld [wd11e], a
+ jpba _DisplayPokedex
+
+SetSpriteFacingDirectionAndDelay::
+ call SetSpriteFacingDirection
+ ld c, 6
+ jp DelayFrames
+
+SetSpriteFacingDirection::
+ ld a, $9
+ ld [H_SPRITEDATAOFFSET], a
+ call GetPointerWithinSpriteStateData1
+ ld a, [hSpriteFacingDirection]
+ ld [hl], a
+ ret
+
+SetSpriteImageIndexAfterSettingFacingDirection::
+ ld de, -7
+ add hl, de
+ ld [hl], a
+ ret
+
+; tests if the player's coordinates are in a specified array
+; INPUT:
+; hl = address of array
+; OUTPUT:
+; [wCoordIndex] = if there is match, the matching array index
+; sets carry if the coordinates are in the array, clears carry if not
+ArePlayerCoordsInArray::
+ ld a, [wYCoord]
+ ld b, a
+ ld a, [wXCoord]
+ ld c, a
+ ; fallthrough
+
+CheckCoords::
+ xor a
+ ld [wCoordIndex], a
+.loop
+ ld a, [hli]
+ cp $ff ; reached terminator?
+ jr z, .notInArray
+ push hl
+ ld hl, wCoordIndex
+ inc [hl]
+ pop hl
+.compareYCoord
+ cp b
+ jr z, .compareXCoord
+ inc hl
+ jr .loop
+.compareXCoord
+ ld a, [hli]
+ cp c
+ jr nz, .loop
+.inArray
+ scf
+ ret
+.notInArray
+ and a
+ ret
+
+; tests if a boulder's coordinates are in a specified array
+; INPUT:
+; hl = address of array
+; [H_SPRITEINDEX] = index of boulder sprite
+; OUTPUT:
+; [wCoordIndex] = if there is match, the matching array index
+; sets carry if the coordinates are in the array, clears carry if not
+CheckBoulderCoords::
+ push hl
+ ld hl, wSpriteStateData2 + $04
+ ld a, [H_SPRITEINDEX]
+ swap a
+ ld d, $0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ sub $4 ; because sprite coordinates are offset by 4
+ ld b, a
+ ld a, [hl]
+ sub $4 ; because sprite coordinates are offset by 4
+ ld c, a
+ pop hl
+ jp CheckCoords
+
+GetPointerWithinSpriteStateData1::
+ ld h, $c1
+ jr _GetPointerWithinSpriteStateData
+
+GetPointerWithinSpriteStateData2::
+ ld h, $c2
+
+_GetPointerWithinSpriteStateData:
+ ld a, [H_SPRITEDATAOFFSET]
+ ld b, a
+ ld a, [H_SPRITEINDEX]
+ swap a
+ add b
+ ld l, a
+ ret
+
+; decodes a $ff-terminated RLEncoded list
+; each entry is a pair of bytes <byte value> <repetitions>
+; the final $ff will be replicated in the output list and a contains the number of bytes written
+; de: input list
+; hl: output list
+DecodeRLEList::
+ xor a
+ ld [wRLEByteCount], a ; count written bytes here
+.listLoop
+ ld a, [de]
+ cp $ff
+ jr z, .endOfList
+ ld [hRLEByteValue], a ; store byte value to be written
+ inc de
+ ld a, [de]
+ ld b, $0
+ ld c, a ; number of bytes to be written
+ ld a, [wRLEByteCount]
+ add c
+ ld [wRLEByteCount], a ; update total number of written bytes
+ ld a, [hRLEByteValue]
+ call FillMemory ; write a c-times to output
+ inc de
+ jr .listLoop
+.endOfList
+ ld a, $ff
+ ld [hl], a ; write final $ff
+ ld a, [wRLEByteCount]
+ inc a ; include sentinel in counting
+ ret
+
+; sets movement byte 1 for sprite [H_SPRITEINDEX] to $FE and byte 2 to [hSpriteMovementByte2]
+SetSpriteMovementBytesToFE::
+ push hl
+ call GetSpriteMovementByte1Pointer
+ ld [hl], $fe
+ call GetSpriteMovementByte2Pointer
+ ld a, [hSpriteMovementByte2]
+ ld [hl], a
+ pop hl
+ ret
+
+; sets both movement bytes for sprite [H_SPRITEINDEX] to $FF
+SetSpriteMovementBytesToFF::
+ push hl
+ call GetSpriteMovementByte1Pointer
+ ld [hl], $FF
+ call GetSpriteMovementByte2Pointer
+ ld [hl], $FF ; prevent person from walking?
+ pop hl
+ ret
+
+; returns the sprite movement byte 1 pointer for sprite [H_SPRITEINDEX] in hl
+GetSpriteMovementByte1Pointer::
+ ld h, $C2
+ ld a, [H_SPRITEINDEX]
+ swap a
+ add 6
+ ld l, a
+ ret
+
+; returns the sprite movement byte 2 pointer for sprite [H_SPRITEINDEX] in hl
+GetSpriteMovementByte2Pointer::
+ push de
+ ld hl, wMapSpriteData
+ ld a, [H_SPRITEINDEX]
+ dec a
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ pop de
+ ret
+
+GetTrainerInformation::
+ call GetTrainerName
+ ld a, [wLinkState]
+ and a
+ jr nz, .linkBattle
+ ld a, Bank(TrainerPicAndMoneyPointers)
+ call BankswitchHome
+ ld a, [wTrainerClass]
+ dec a
+ ld hl, TrainerPicAndMoneyPointers
+ ld bc, $5
+ call AddNTimes
+ ld de, wTrainerPicPointer
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ ld de, wTrainerBaseMoney
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ jp BankswitchBack
+.linkBattle
+ ld hl, wTrainerPicPointer
+ ld de, RedPicFront
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ ret
+
+GetTrainerName::
+ jpba GetTrainerName_
+
+HasEnoughMoney::
+; Check if the player has at least as much
+; money as the 3-byte BCD value at hMoney.
+ ld de, wPlayerMoney
+ ld hl, hMoney
+ ld c, 3
+ jp StringCmp
+
+HasEnoughCoins::
+; Check if the player has at least as many
+; coins as the 2-byte BCD value at hCoins.
+ ld de, wPlayerCoins
+ ld hl, hCoins
+ ld c, 2
+ jp StringCmp
+
+
+BankswitchHome::
+; switches to bank # in a
+; Only use this when in the home bank!
+ ld [wBankswitchHomeTemp], a
+ ld a, [H_LOADEDROMBANK]
+ ld [wBankswitchHomeSavedROMBank], a
+ ld a, [wBankswitchHomeTemp]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+BankswitchBack::
+; returns from BankswitchHome
+ ld a, [wBankswitchHomeSavedROMBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+Bankswitch::
+; self-contained bankswitch, use this when not in the home bank
+; switches to the bank in b
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld bc, .Return
+ push bc
+ jp hl
+.Return
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; displays yes/no choice
+; yes -> set carry
+YesNoChoice::
+ call SaveScreenTilesToBuffer1
+ call InitYesNoTextBoxParameters
+ jr DisplayYesNoChoice
+
+Func_35f4::
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call InitYesNoTextBoxParameters
+ jp DisplayTextBoxID
+
+InitYesNoTextBoxParameters::
+ xor a ; YES_NO_MENU
+ ld [wTwoOptionMenuID], a
+ coord hl, 14, 7
+ ld bc, $80f
+ ret
+
+YesNoChoicePokeCenter::
+ call SaveScreenTilesToBuffer1
+ ld a, HEAL_CANCEL_MENU
+ ld [wTwoOptionMenuID], a
+ coord hl, 11, 6
+ lb bc, 8, 12
+ jr DisplayYesNoChoice
+
+WideYesNoChoice:: ; unused
+ call SaveScreenTilesToBuffer1
+ ld a, WIDE_YES_NO_MENU
+ ld [wTwoOptionMenuID], a
+ coord hl, 12, 7
+ lb bc, 8, 13
+
+DisplayYesNoChoice::
+ ld a, TWO_OPTION_MENU
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ jp LoadScreenTilesFromBuffer1
+
+; calculates the difference |a-b|, setting carry flag if a<b
+CalcDifference::
+ sub b
+ ret nc
+ cpl
+ add $1
+ scf
+ ret
+
+MoveSprite::
+; move the sprite [H_SPRITEINDEX] with the movement pointed to by de
+; actually only copies the movement data to wNPCMovementDirections for later
+ call SetSpriteMovementBytesToFF
+MoveSprite_::
+ push hl
+ push bc
+ call GetSpriteMovementByte1Pointer
+ xor a
+ ld [hl], a
+ ld hl, wNPCMovementDirections
+ ld c, 0
+
+.loop
+ ld a, [de]
+ ld [hli], a
+ inc de
+ inc c
+ cp $FF ; have we reached the end of the movement data?
+ jr nz, .loop
+
+ ld a, c
+ ld [wNPCNumScriptedSteps], a ; number of steps taken
+
+ pop bc
+ ld hl, wd730
+ set 0, [hl]
+ pop hl
+ xor a
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ ld [wSimulatedJoypadStatesEnd], a
+ dec a
+ ld [wJoyIgnore], a
+ ld [wWastedByteCD3A], a
+ ret
+
+; divides [hDividend2] by [hDivisor2] and stores the quotient in [hQuotient2]
+DivideBytes::
+ push hl
+ ld hl, hQuotient2
+ xor a
+ ld [hld], a
+ ld a, [hld]
+ and a
+ jr z, .done
+ ld a, [hli]
+.loop
+ sub [hl]
+ jr c, .done
+ inc hl
+ inc [hl]
+ dec hl
+ jr .loop
+.done
+ pop hl
+ ret
+
+
+LoadFontTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, FontGraphics
+ ld de, vFont
+ ld bc, FontGraphicsEnd - FontGraphics
+ ld a, BANK(FontGraphics)
+ jp FarCopyDataDouble ; if LCD is off, transfer all at once
+.on
+ ld de, FontGraphics
+ ld hl, vFont
+ lb bc, BANK(FontGraphics), (FontGraphicsEnd - FontGraphics) / $8
+ jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank
+
+LoadTextBoxTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, TextBoxGraphics
+ ld de, vChars2 + $600
+ ld bc, TextBoxGraphicsEnd - TextBoxGraphics
+ ld a, BANK(TextBoxGraphics)
+ jp FarCopyData2 ; if LCD is off, transfer all at once
+.on
+ ld de, TextBoxGraphics
+ ld hl, vChars2 + $600
+ lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10
+ jp CopyVideoData ; if LCD is on, transfer during V-blank
+
+LoadHpBarAndStatusTilePatterns::
+ ld a, [rLCDC]
+ bit 7, a ; is the LCD enabled?
+ jr nz, .on
+.off
+ ld hl, HpBarAndStatusGraphics
+ ld de, vChars2 + $620
+ ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics
+ ld a, BANK(HpBarAndStatusGraphics)
+ jp FarCopyData2 ; if LCD is off, transfer all at once
+.on
+ ld de, HpBarAndStatusGraphics
+ ld hl, vChars2 + $620
+ lb bc, BANK(HpBarAndStatusGraphics), (HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics) / $10
+ jp CopyVideoData ; if LCD is on, transfer during V-blank
+
+
+FillMemory::
+; Fill bc bytes at hl with a.
+ push de
+ ld d, a
+.loop
+ ld a, d
+ ld [hli], a
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ pop de
+ ret
+
+
+UncompressSpriteFromDE::
+; Decompress pic at a:de.
+ ld hl, wSpriteInputPtr
+ ld [hl], e
+ inc hl
+ ld [hl], d
+ jp UncompressSpriteData
+
+SaveScreenTilesToBuffer2::
+ coord hl, 0, 0
+ ld de, wTileMapBackup2
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyData
+ ret
+
+LoadScreenTilesFromBuffer2::
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
+LoadScreenTilesFromBuffer2DisableBGTransfer::
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wTileMapBackup2
+ coord de, 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyData
+ ret
+
+SaveScreenTilesToBuffer1::
+ coord hl, 0, 0
+ ld de, wTileMapBackup
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ jp CopyData
+
+LoadScreenTilesFromBuffer1::
+ xor a
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ld hl, wTileMapBackup
+ coord de, 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ call CopyData
+ ld a, 1
+ ld [H_AUTOBGTRANSFERENABLED], a
+ ret
+
+DelayFrames::
+; wait c frames
+ call DelayFrame
+ dec c
+ jr nz, DelayFrames
+ ret
+
+PlaySoundWaitForCurrent::
+ push af
+ call WaitForSoundToFinish
+ pop af
+ jp PlaySound
+
+; Wait for sound to finish playing
+WaitForSoundToFinish::
+ ld a, [wLowHealthAlarm]
+ and $80
+ ret nz
+ push hl
+.waitLoop
+ ld hl, wChannelSoundIDs + Ch4
+ xor a
+ or [hl]
+ inc hl
+ or [hl]
+ inc hl
+ inc hl
+ or [hl]
+ jr nz, .waitLoop
+ pop hl
+ ret
+
+NamePointers::
+ dw MonsterNames
+ dw MoveNames
+ dw UnusedNames
+ dw ItemNames
+ dw wPartyMonOT ; player's OT names list
+ dw wEnemyMonOT ; enemy's OT names list
+ dw TrainerNames
+
+GetName::
+; arguments:
+; [wd0b5] = which name
+; [wNameListType] = which list
+; [wPredefBank] = bank of list
+;
+; returns pointer to name in de
+ ld a, [wd0b5]
+ ld [wd11e], a
+
+ ; TM names are separate from item names.
+ ; BUG: This applies to all names instead of just items.
+ cp HM_01
+ jp nc, GetMachineName
+
+ ld a, [H_LOADEDROMBANK]
+ push af
+ push hl
+ push bc
+ push de
+ ld a, [wNameListType] ;List3759_entrySelector
+ dec a
+ jr nz, .otherEntries
+ ;1 = MON_NAMES
+ call GetMonName
+ ld hl, NAME_LENGTH
+ add hl, de
+ ld e, l
+ ld d, h
+ jr .gotPtr
+.otherEntries
+ ;2-7 = OTHER ENTRIES
+ ld a, [wPredefBank]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld a, [wNameListType] ;VariousNames' entryID
+ dec a
+ add a
+ ld d, 0
+ ld e, a
+ jr nc, .skip
+ inc d
+.skip
+ ld hl, NamePointers
+ add hl, de
+ ld a, [hli]
+ ld [$ff96], a
+ ld a, [hl]
+ ld [$ff95], a
+ ld a, [$ff95]
+ ld h, a
+ ld a, [$ff96]
+ ld l, a
+ ld a, [wd0b5]
+ ld b, a
+ ld c, 0
+.nextName
+ ld d, h
+ ld e, l
+.nextChar
+ ld a, [hli]
+ cp "@"
+ jr nz, .nextChar
+ inc c ;entry counter
+ ld a, b ;wanted entry
+ cp c
+ jr nz, .nextName
+ ld h, d
+ ld l, e
+ ld de, wcd6d
+ ld bc, $0014
+ call CopyData
+.gotPtr
+ ld a, e
+ ld [wUnusedCF8D], a
+ ld a, d
+ ld [wUnusedCF8D + 1], a
+ pop de
+ pop bc
+ pop hl
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+GetItemPrice::
+; Stores item's price as BCD at hItemPrice (3 bytes)
+; Input: [wcf91] = item id
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [wListMenuID]
+ cp MOVESLISTMENU
+ ld a, BANK(ItemPrices)
+ jr nz, .ok
+ ld a, $f ; hardcoded Bank
+.ok
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ld hl, wItemPrices
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wcf91] ; a contains item id
+ cp HM_01
+ jr nc, .getTMPrice
+ ld bc, $3
+.loop
+ add hl, bc
+ dec a
+ jr nz, .loop
+ dec hl
+ ld a, [hld]
+ ld [hItemPrice + 2], a
+ ld a, [hld]
+ ld [hItemPrice + 1], a
+ ld a, [hl]
+ ld [hItemPrice], a
+ jr .done
+.getTMPrice
+ ld a, Bank(GetMachinePrice)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call GetMachinePrice
+.done
+ ld de, hItemPrice
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; copies a string from [de] to [wcf4b]
+CopyStringToCF4B::
+ ld hl, wcf4b
+ ; fall through
+
+; copies a string from [de] to [hl]
+CopyString::
+ ld a, [de]
+ inc de
+ ld [hli], a
+ cp "@"
+ jr nz, CopyString
+ ret
+
+; this function is used when lower button sensitivity is wanted (e.g. menus)
+; OUTPUT: [hJoy5] = pressed buttons in usual format
+; there are two flags that control its functionality, [hJoy6] and [hJoy7]
+; there are essentially three modes of operation
+; 1. Get newly pressed buttons only
+; ([hJoy7] == 0, [hJoy6] == any)
+; Just copies [hJoyPressed] to [hJoy5].
+; 2. Get currently pressed buttons at low sample rate with delay
+; ([hJoy7] == 1, [hJoy6] != 0)
+; If the user holds down buttons for more than half a second,
+; report buttons as being pressed up to 12 times per second thereafter.
+; If the user holds down buttons for less than half a second,
+; report only one button press.
+; 3. Same as 2, but report no buttons as pressed if A or B is held down.
+; ([hJoy7] == 1, [hJoy6] == 0)
+JoypadLowSensitivity::
+ call Joypad
+ ld a, [hJoy7] ; flag
+ and a ; get all currently pressed buttons or only newly pressed buttons?
+ ld a, [hJoyPressed] ; newly pressed buttons
+ jr z, .storeButtonState
+ ld a, [hJoyHeld] ; all currently pressed buttons
+.storeButtonState
+ ld [hJoy5], a
+ ld a, [hJoyPressed] ; newly pressed buttons
+ and a ; have any buttons been newly pressed since last check?
+ jr z, .noNewlyPressedButtons
+.newlyPressedButtons
+ ld a, 30 ; half a second delay
+ ld [H_FRAMECOUNTER], a
+ ret
+.noNewlyPressedButtons
+ ld a, [H_FRAMECOUNTER]
+ and a ; is the delay over?
+ jr z, .delayOver
+.delayNotOver
+ xor a
+ ld [hJoy5], a ; report no buttons as pressed
+ ret
+.delayOver
+; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed
+ ld a, [hJoyHeld]
+ and A_BUTTON | B_BUTTON
+ jr z, .setShortDelay
+ ld a, [hJoy6] ; flag
+ and a
+ jr nz, .setShortDelay
+ xor a
+ ld [hJoy5], a
+.setShortDelay
+ ld a, 5 ; 1/12 of a second delay
+ ld [H_FRAMECOUNTER], a
+ ret
+
+WaitForTextScrollButtonPress::
+ ld a, [H_DOWNARROWBLINKCNT1]
+ push af
+ ld a, [H_DOWNARROWBLINKCNT2]
+ push af
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld a, $6
+ ld [H_DOWNARROWBLINKCNT2], a
+.loop
+ push hl
+ ld a, [wTownMapSpriteBlinkingEnabled]
+ and a
+ jr z, .skipAnimation
+ call TownMapSpriteBlinkingAnimation
+.skipAnimation
+ coord hl, 18, 16
+ call HandleDownArrowBlinkTiming
+ pop hl
+ call JoypadLowSensitivity
+ predef CableClub_Run
+ ld a, [hJoy5]
+ and A_BUTTON | B_BUTTON
+ jr z, .loop
+ pop af
+ ld [H_DOWNARROWBLINKCNT2], a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1], a
+ ret
+
+; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect
+ManualTextScroll::
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jr z, .inLinkBattle
+ call WaitForTextScrollButtonPress
+ ld a, SFX_PRESS_AB
+ jp PlaySound
+.inLinkBattle
+ ld c, 65
+ jp DelayFrames
+
+; function to do multiplication
+; all values are big endian
+; INPUT
+; FF96-FF98 = multiplicand
+; FF99 = multiplier
+; OUTPUT
+; FF95-FF98 = product
+Multiply::
+ push hl
+ push bc
+ callab _Multiply
+ pop bc
+ pop hl
+ ret
+
+; function to do division
+; all values are big endian
+; INPUT
+; FF95-FF98 = dividend
+; FF99 = divisor
+; b = number of bytes in the dividend (starting from FF95)
+; OUTPUT
+; FF95-FF98 = quotient
+; FF99 = remainder
+Divide::
+ push hl
+ push de
+ push bc
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, Bank(_Divide)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call _Divide
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; This function is used to wait a short period after printing a letter to the
+; screen unless the player presses the A/B button or the delay is turned off
+; through the [wd730] or [wLetterPrintingDelayFlags] flags.
+PrintLetterDelay::
+ ld a, [wd730]
+ bit 6, a
+ ret nz
+ ld a, [wLetterPrintingDelayFlags]
+ bit 1, a
+ ret z
+ push hl
+ push de
+ push bc
+ ld a, [wLetterPrintingDelayFlags]
+ bit 0, a
+ jr z, .waitOneFrame
+ ld a, [wOptions]
+ and $f
+ ld [H_FRAMECOUNTER], a
+ jr .checkButtons
+.waitOneFrame
+ ld a, 1
+ ld [H_FRAMECOUNTER], a
+.checkButtons
+ call Joypad
+ ld a, [hJoyHeld]
+.checkAButton
+ bit 0, a ; is the A button pressed?
+ jr z, .checkBButton
+ jr .endWait
+.checkBButton
+ bit 1, a ; is the B button pressed?
+ jr z, .buttonsNotPressed
+.endWait
+ call DelayFrame
+ jr .done
+.buttonsNotPressed ; if neither A nor B is pressed
+ ld a, [H_FRAMECOUNTER]
+ and a
+ jr nz, .checkButtons
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; Copies [hl, bc) to [de, bc - hl).
+; In other words, the source data is from hl up to but not including bc,
+; and the destination is de.
+CopyDataUntil::
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, h
+ cp b
+ jr nz, CopyDataUntil
+ ld a, l
+ cp c
+ jr nz, CopyDataUntil
+ ret
+
+; Function to remove a pokemon from the party or the current box.
+; wWhichPokemon determines the pokemon.
+; [wRemoveMonFromBox] == 0 specifies the party.
+; [wRemoveMonFromBox] != 0 specifies the current box.
+RemovePokemon::
+ jpab _RemovePokemon
+
+AddPartyMon::
+ push hl
+ push de
+ push bc
+ callba _AddPartyMon
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; calculates all 5 stats of current mon and writes them to [de]
+CalcStats::
+ ld c, $0
+.statsLoop
+ inc c
+ call CalcStat
+ ld a, [H_MULTIPLICAND+1]
+ ld [de], a
+ inc de
+ ld a, [H_MULTIPLICAND+2]
+ ld [de], a
+ inc de
+ ld a, c
+ cp NUM_STATS
+ jr nz, .statsLoop
+ ret
+
+; calculates stat c of current mon
+; c: stat to calc (HP=1,Atk=2,Def=3,Spd=4,Spc=5)
+; b: consider stat exp?
+; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c])
+CalcStat::
+ push hl
+ push de
+ push bc
+ ld a, b
+ ld d, a
+ push hl
+ ld hl, wMonHeader
+ ld b, $0
+ add hl, bc
+ ld a, [hl] ; read base value of stat
+ ld e, a
+ pop hl
+ push hl
+ sla c
+ ld a, d
+ and a
+ jr z, .statExpDone ; consider stat exp?
+ add hl, bc ; skip to corresponding stat exp value
+.statExpLoop ; calculates ceil(Sqrt(stat exp)) in b
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld [H_MULTIPLICAND+1], a
+ inc b ; increment current stat exp bonus
+ ld a, b
+ cp $ff
+ jr z, .statExpDone
+ ld [H_MULTIPLICAND+2], a
+ ld [H_MULTIPLIER], a
+ call Multiply
+ ld a, [hld]
+ ld d, a
+ ld a, [$ff98]
+ sub d
+ ld a, [hli]
+ ld d, a
+ ld a, [$ff97]
+ sbc d ; test if (current stat exp bonus)^2 < stat exp
+ jr c, .statExpLoop
+.statExpDone
+ srl c
+ pop hl
+ push bc
+ ld bc, wPartyMon1DVs - (wPartyMon1HPExp - 1) ; also wEnemyMonDVs - wEnemyMonHP
+ add hl, bc
+ pop bc
+ ld a, c
+ cp $2
+ jr z, .getAttackIV
+ cp $3
+ jr z, .getDefenseIV
+ cp $4
+ jr z, .getSpeedIV
+ cp $5
+ jr z, .getSpecialIV
+.getHpIV
+ push bc
+ ld a, [hl] ; Atk IV
+ swap a
+ and $1
+ sla a
+ sla a
+ sla a
+ ld b, a
+ ld a, [hli] ; Def IV
+ and $1
+ sla a
+ sla a
+ add b
+ ld b, a
+ ld a, [hl] ; Spd IV
+ swap a
+ and $1
+ sla a
+ add b
+ ld b, a
+ ld a, [hl] ; Spc IV
+ and $1
+ add b ; HP IV: LSB of the other 4 IVs
+ pop bc
+ jr .calcStatFromIV
+.getAttackIV
+ ld a, [hl]
+ swap a
+ and $f
+ jr .calcStatFromIV
+.getDefenseIV
+ ld a, [hl]
+ and $f
+ jr .calcStatFromIV
+.getSpeedIV
+ inc hl
+ ld a, [hl]
+ swap a
+ and $f
+ jr .calcStatFromIV
+.getSpecialIV
+ inc hl
+ ld a, [hl]
+ and $f
+.calcStatFromIV
+ ld d, $0
+ add e
+ ld e, a
+ jr nc, .noCarry
+ inc d ; de = Base + IV
+.noCarry
+ sla e
+ rl d ; de = (Base + IV) * 2
+ srl b
+ srl b ; b = ceil(Sqrt(stat exp)) / 4
+ ld a, b
+ add e
+ jr nc, .noCarry2
+ inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4
+.noCarry2
+ ld [H_MULTIPLICAND+2], a
+ ld a, d
+ ld [H_MULTIPLICAND+1], a
+ xor a
+ ld [H_MULTIPLICAND], a
+ ld a, [wCurEnemyLVL]
+ ld [H_MULTIPLIER], a
+ call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level
+ ld a, [H_MULTIPLICAND]
+ ld [H_DIVIDEND], a
+ ld a, [H_MULTIPLICAND+1]
+ ld [H_DIVIDEND+1], a
+ ld a, [H_MULTIPLICAND+2]
+ ld [H_DIVIDEND+2], a
+ ld a, $64
+ ld [H_DIVISOR], a
+ ld a, $3
+ ld b, a
+ call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100
+ ld a, c
+ cp $1
+ ld a, 5 ; + 5 for non-HP stat
+ jr nz, .notHPStat
+ ld a, [wCurEnemyLVL]
+ ld b, a
+ ld a, [H_MULTIPLICAND+2]
+ add b
+ ld [H_MULTIPLICAND+2], a
+ jr nc, .noCarry3
+ ld a, [H_MULTIPLICAND+1]
+ inc a
+ ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level
+.noCarry3
+ ld a, 10 ; +10 for HP stat
+.notHPStat
+ ld b, a
+ ld a, [H_MULTIPLICAND+2]
+ add b
+ ld [H_MULTIPLICAND+2], a
+ jr nc, .noCarry4
+ ld a, [H_MULTIPLICAND+1]
+ inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5
+ ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10
+.noCarry4
+ ld a, [H_MULTIPLICAND+1] ; check for overflow (>999)
+ cp 999 / $100 + 1
+ jr nc, .overflow
+ cp 999 / $100
+ jr c, .noOverflow
+ ld a, [H_MULTIPLICAND+2]
+ cp 999 % $100 + 1
+ jr c, .noOverflow
+.overflow
+ ld a, 999 / $100 ; overflow: cap at 999
+ ld [H_MULTIPLICAND+1], a
+ ld a, 999 % $100
+ ld [H_MULTIPLICAND+2], a
+.noOverflow
+ pop bc
+ pop de
+ pop hl
+ ret
+
+AddEnemyMonToPlayerParty::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(_AddEnemyMonToPlayerParty)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call _AddEnemyMonToPlayerParty
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+MoveMon::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, BANK(_MoveMon)
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ call _MoveMon
+ pop bc
+ ld a, b
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ ret
+
+; skips a text entries, each of size NAME_LENGTH (like trainer name, OT name, rival name, ...)
+; hl: base pointer, will be incremented by NAME_LENGTH * a
+SkipFixedLengthTextEntries::
+ and a
+ ret z
+ ld bc, NAME_LENGTH
+.skipLoop
+ add hl, bc
+ dec a
+ jr nz, .skipLoop
+ ret
+
+AddNTimes::
+; add bc to hl a times
+ and a
+ ret z
+.loop
+ add hl, bc
+ dec a
+ jr nz, .loop
+ ret
+
+; Compare strings, c bytes in length, at de and hl.
+; Often used to compare big endian numbers in battle calculations.
+StringCmp::
+ ld a, [de]
+ cp [hl]
+ ret nz
+ inc de
+ inc hl
+ dec c
+ jr nz, StringCmp
+ ret
+
+; INPUT:
+; a = oam block index (each block is 4 oam entries)
+; b = Y coordinate of upper left corner of sprite
+; c = X coordinate of upper left corner of sprite
+; de = base address of 4 tile number and attribute pairs
+WriteOAMBlock::
+ ld h, wOAMBuffer / $100
+ swap a ; multiply by 16
+ ld l, a
+ call .writeOneEntry ; upper left
+ push bc
+ ld a, 8
+ add c
+ ld c, a
+ call .writeOneEntry ; upper right
+ pop bc
+ ld a, 8
+ add b
+ ld b, a
+ call .writeOneEntry ; lower left
+ ld a, 8
+ add c
+ ld c, a
+ ; lower right
+.writeOneEntry
+ ld [hl], b ; Y coordinate
+ inc hl
+ ld [hl], c ; X coordinate
+ inc hl
+ ld a, [de] ; tile number
+ inc de
+ ld [hli], a
+ ld a, [de] ; attribute
+ inc de
+ ld [hli], a
+ ret
+
+HandleMenuInput::
+ xor a
+ ld [wPartyMenuAnimMonEnabled], a
+
+HandleMenuInput_::
+ ld a, [H_DOWNARROWBLINKCNT1]
+ push af
+ ld a, [H_DOWNARROWBLINKCNT2]
+ push af ; save existing values on stack
+ xor a
+ ld [H_DOWNARROWBLINKCNT1], a ; blinking down arrow timing value 1
+ ld a, 6
+ ld [H_DOWNARROWBLINKCNT2], a ; blinking down arrow timing value 2
+.loop1
+ xor a
+ ld [wAnimCounter], a ; counter for pokemon shaking animation
+ call PlaceMenuCursor
+ call Delay3
+.loop2
+ push hl
+ ld a, [wPartyMenuAnimMonEnabled]
+ and a ; is it a pokemon selection menu?
+ jr z, .getJoypadState
+ callba AnimatePartyMon ; shake mini sprite of selected pokemon
+.getJoypadState
+ pop hl
+ call JoypadLowSensitivity
+ ld a, [hJoy5]
+ and a ; was a key pressed?
+ jr nz, .keyPressed
+ push hl
+ coord hl, 18, 11 ; coordinates of blinking down arrow in some menus
+ call HandleDownArrowBlinkTiming ; blink down arrow (if any)
+ pop hl
+ ld a, [wMenuJoypadPollCount]
+ dec a
+ jr z, .giveUpWaiting
+ jr .loop2
+.giveUpWaiting
+; if a key wasn't pressed within the specified number of checks
+ pop af
+ ld [H_DOWNARROWBLINKCNT2], a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
+ xor a
+ ld [wMenuWrappingEnabled], a ; disable menu wrapping
+ ret
+.keyPressed
+ xor a
+ ld [wCheckFor180DegreeTurn], a
+ ld a, [hJoy5]
+ ld b, a
+ bit 6, a ; pressed Up key?
+ jr z, .checkIfDownPressed
+.upPressed
+ ld a, [wCurrentMenuItem] ; selected menu item
+ and a ; already at the top of the menu?
+ jr z, .alreadyAtTop
+.notAtTop
+ dec a
+ ld [wCurrentMenuItem], a ; move selected menu item up one space
+ jr .checkOtherKeys
+.alreadyAtTop
+ ld a, [wMenuWrappingEnabled]
+ and a ; is wrapping around enabled?
+ jr z, .noWrappingAround
+ ld a, [wMaxMenuItem]
+ ld [wCurrentMenuItem], a ; wrap to the bottom of the menu
+ jr .checkOtherKeys
+.checkIfDownPressed
+ bit 7, a
+ jr z, .checkOtherKeys
+.downPressed
+ ld a, [wCurrentMenuItem]
+ inc a
+ ld c, a
+ ld a, [wMaxMenuItem]
+ cp c
+ jr nc, .notAtBottom
+.alreadyAtBottom
+ ld a, [wMenuWrappingEnabled]
+ and a ; is wrapping around enabled?
+ jr z, .noWrappingAround
+ ld c, $00 ; wrap from bottom to top
+.notAtBottom
+ ld a, c
+ ld [wCurrentMenuItem], a
+.checkOtherKeys
+ ld a, [wMenuWatchedKeys]
+ and b ; does the menu care about any of the pressed keys?
+ jp z, .loop1
+.checkIfAButtonOrBButtonPressed
+ ld a, [hJoy5]
+ and A_BUTTON | B_BUTTON
+ jr z, .skipPlayingSound
+.AButtonOrBButtonPressed
+ push hl
+ ld hl, wFlags_0xcd60
+ bit 5, [hl]
+ pop hl
+ jr nz, .skipPlayingSound
+ ld a, SFX_PRESS_AB
+ call PlaySound
+.skipPlayingSound
+ pop af
+ ld [H_DOWNARROWBLINKCNT2], a
+ pop af
+ ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
+ xor a
+ ld [wMenuWrappingEnabled], a ; disable menu wrapping
+ ld a, [hJoy5]
+ ret
+.noWrappingAround
+ ld a, [wMenuWatchMovingOutOfBounds]
+ and a ; should we return if the user tried to go past the top or bottom?
+ jr z, .checkOtherKeys
+ jr .checkIfAButtonOrBButtonPressed
+
+PlaceMenuCursor::
+ ld a, [wTopMenuItemY]
+ and a ; is the y coordinate 0?
+ jr z, .adjustForXCoord
+ coord hl, 0, 0
+ ld bc, SCREEN_WIDTH
+.topMenuItemLoop
+ add hl, bc
+ dec a
+ jr nz, .topMenuItemLoop
+.adjustForXCoord
+ ld a, [wTopMenuItemX]
+ ld b, 0
+ ld c, a
+ add hl, bc
+ push hl
+ ld a, [wLastMenuItem]
+ and a ; was the previous menu id 0?
+ jr z, .checkForArrow1
+ push af
+ ld a, [hFlags_0xFFF6]
+ bit 1, a ; is the menu double spaced?
+ jr z, .doubleSpaced1
+ ld bc, 20
+ jr .getOldMenuItemScreenPosition
+.doubleSpaced1
+ ld bc, 40
+.getOldMenuItemScreenPosition
+ pop af
+.oldMenuItemLoop
+ add hl, bc
+ dec a
+ jr nz, .oldMenuItemLoop
+.checkForArrow1
+ ld a, [hl]
+ cp "▶" ; was an arrow next to the previously selected menu item?
+ jr nz, .skipClearingArrow
+.clearArrow
+ ld a, [wTileBehindCursor]
+ ld [hl], a
+.skipClearingArrow
+ pop hl
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .checkForArrow2
+ push af
+ ld a, [hFlags_0xFFF6]
+ bit 1, a ; is the menu double spaced?
+ jr z, .doubleSpaced2
+ ld bc, 20
+ jr .getCurrentMenuItemScreenPosition
+.doubleSpaced2
+ ld bc, 40
+.getCurrentMenuItemScreenPosition
+ pop af
+.currentMenuItemLoop
+ add hl, bc
+ dec a
+ jr nz, .currentMenuItemLoop
+.checkForArrow2
+ ld a, [hl]
+ cp "▶" ; has the right arrow already been placed?
+ jr z, .skipSavingTile ; if so, don't lose the saved tile
+ ld [wTileBehindCursor], a ; save tile before overwriting with right arrow
+.skipSavingTile
+ ld a, "▶" ; place right arrow
+ ld [hl], a
+ ld a, l
+ ld [wMenuCursorLocation], a
+ ld a, h
+ ld [wMenuCursorLocation + 1], a
+ ld a, [wCurrentMenuItem]
+ ld [wLastMenuItem], a
+ ret
+
+; This is used to mark a menu cursor other than the one currently being
+; manipulated. In the case of submenus, this is used to show the location of
+; the menu cursor in the parent menu. In the case of swapping items in list,
+; this is used to mark the item that was first chosen to be swapped.
+PlaceUnfilledArrowMenuCursor::
+ ld b, a
+ ld a, [wMenuCursorLocation]
+ ld l, a
+ ld a, [wMenuCursorLocation + 1]
+ ld h, a
+ ld [hl], $ec ; outline of right arrow
+ ld a, b
+ ret
+
+; Replaces the menu cursor with a blank space.
+EraseMenuCursor::
+ ld a, [wMenuCursorLocation]
+ ld l, a
+ ld a, [wMenuCursorLocation + 1]
+ ld h, a
+ ld [hl], " "
+ ret
+
+; This toggles a blinking down arrow at hl on and off after a delay has passed.
+; This is often called even when no blinking is occurring.
+; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0.
+; The effect is that if the tile at hl is initialized with a down arrow,
+; this function will toggle that down arrow on and off, but if the tile isn't
+; initialized with a down arrow, this function does nothing.
+; That allows this to be called without worrying about if a down arrow should
+; be blinking.
+HandleDownArrowBlinkTiming::
+ ld a, [hl]
+ ld b, a
+ ld a, "▼"
+ cp b
+ jr nz, .downArrowOff
+.downArrowOn
+ ld a, [H_DOWNARROWBLINKCNT1]
+ dec a
+ ld [H_DOWNARROWBLINKCNT1], a
+ ret nz
+ ld a, [H_DOWNARROWBLINKCNT2]
+ dec a
+ ld [H_DOWNARROWBLINKCNT2], a
+ ret nz
+ ld a, " "
+ ld [hl], a
+ ld a, $ff
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld a, $06
+ ld [H_DOWNARROWBLINKCNT2], a
+ ret
+.downArrowOff
+ ld a, [H_DOWNARROWBLINKCNT1]
+ and a
+ ret z
+ dec a
+ ld [H_DOWNARROWBLINKCNT1], a
+ ret nz
+ dec a
+ ld [H_DOWNARROWBLINKCNT1], a
+ ld a, [H_DOWNARROWBLINKCNT2]
+ dec a
+ ld [H_DOWNARROWBLINKCNT2], a
+ ret nz
+ ld a, $06
+ ld [H_DOWNARROWBLINKCNT2], a
+ ld a, "▼"
+ ld [hl], a
+ ret
+
+; The following code either enables or disables the automatic drawing of
+; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait
+; for a button press after displaying text (unless [wEnteringCableClub] is set).
+
+EnableAutoTextBoxDrawing::
+ xor a
+ jr AutoTextBoxDrawingCommon
+
+DisableAutoTextBoxDrawing::
+ ld a, $01
+
+AutoTextBoxDrawingCommon::
+ ld [wAutoTextBoxDrawingControl], a
+ xor a
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a ; make DisplayTextID wait for button press
+ ret
+
+PrintText::
+; Print text hl at (1, 14).
+ push hl
+ ld a, MESSAGE_BOX
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ call UpdateSprites
+ call Delay3
+ pop hl
+PrintText_NoCreatingTextBox::
+ coord bc, 1, 14
+ jp TextCommandProcessor
+
+
+PrintNumber::
+; Print the c-digit, b-byte value at de.
+; Allows 2 to 7 digits. For 1-digit numbers, add
+; the value to char "0" instead of calling PrintNumber.
+; Flags LEADING_ZEROES and LEFT_ALIGN can be given
+; in bits 7 and 6 of b respectively.
+ push bc
+ xor a
+ ld [H_PASTLEADINGZEROES], a
+ ld [H_NUMTOPRINT], a
+ ld [H_NUMTOPRINT + 1], a
+ ld a, b
+ and $f
+ cp 1
+ jr z, .byte
+ cp 2
+ jr z, .word
+.long
+ ld a, [de]
+ ld [H_NUMTOPRINT], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 1], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+ jr .start
+
+.word
+ ld a, [de]
+ ld [H_NUMTOPRINT + 1], a
+ inc de
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+ jr .start
+
+.byte
+ ld a, [de]
+ ld [H_NUMTOPRINT + 2], a
+
+.start
+ push de
+
+ ld d, b
+ ld a, c
+ ld b, a
+ xor a
+ ld c, a
+ ld a, b
+
+ cp 2
+ jr z, .tens
+ cp 3
+ jr z, .hundreds
+ cp 4
+ jr z, .thousands
+ cp 5
+ jr z, .ten_thousands
+ cp 6
+ jr z, .hundred_thousands
+
+print_digit: macro
+
+if (\1) / $10000
+ ld a, \1 / $10000 % $100
+else xor a
+endc
+ ld [H_POWEROFTEN + 0], a
+
+if (\1) / $100
+ ld a, \1 / $100 % $100
+else xor a
+endc
+ ld [H_POWEROFTEN + 1], a
+
+ ld a, \1 / $1 % $100
+ ld [H_POWEROFTEN + 2], a
+
+ call .PrintDigit
+ call .NextDigit
+endm
+
+.millions print_digit 1000000
+.hundred_thousands print_digit 100000
+.ten_thousands print_digit 10000
+.thousands print_digit 1000
+.hundreds print_digit 100
+
+.tens
+ ld c, 0
+ ld a, [H_NUMTOPRINT + 2]
+.mod
+ cp 10
+ jr c, .ok
+ sub 10
+ inc c
+ jr .mod
+.ok
+
+ ld b, a
+ ld a, [H_PASTLEADINGZEROES]
+ or c
+ ld [H_PASTLEADINGZEROES], a
+ jr nz, .past
+ call .PrintLeadingZero
+ jr .next
+.past
+ ld a, "0"
+ add c
+ ld [hl], a
+.next
+
+ call .NextDigit
+.ones
+ ld a, "0"
+ add b
+ ld [hli], a
+ pop de
+ dec de
+ pop bc
+ ret
+
+.PrintDigit:
+; Divide by the current decimal place.
+; Print the quotient, and keep the modulus.
+ ld c, 0
+.loop
+ ld a, [H_POWEROFTEN]
+ ld b, a
+ ld a, [H_NUMTOPRINT]
+ ld [H_SAVEDNUMTOPRINT], a
+ cp b
+ jr c, .underflow0
+ sub b
+ ld [H_NUMTOPRINT], a
+ ld a, [H_POWEROFTEN + 1]
+ ld b, a
+ ld a, [H_NUMTOPRINT + 1]
+ ld [H_SAVEDNUMTOPRINT + 1], a
+ cp b
+ jr nc, .noborrow1
+
+ ld a, [H_NUMTOPRINT]
+ or 0
+ jr z, .underflow1
+ dec a
+ ld [H_NUMTOPRINT], a
+ ld a, [H_NUMTOPRINT + 1]
+.noborrow1
+
+ sub b
+ ld [H_NUMTOPRINT + 1], a
+ ld a, [H_POWEROFTEN + 2]
+ ld b, a
+ ld a, [H_NUMTOPRINT + 2]
+ ld [H_SAVEDNUMTOPRINT + 2], a
+ cp b
+ jr nc, .noborrow2
+
+ ld a, [H_NUMTOPRINT + 1]
+ and a
+ jr nz, .borrowed
+
+ ld a, [H_NUMTOPRINT]
+ and a
+ jr z, .underflow2
+ dec a
+ ld [H_NUMTOPRINT], a
+ xor a
+.borrowed
+
+ dec a
+ ld [H_NUMTOPRINT + 1], a
+ ld a, [H_NUMTOPRINT + 2]
+.noborrow2
+ sub b
+ ld [H_NUMTOPRINT + 2], a
+ inc c
+ jr .loop
+
+.underflow2
+ ld a, [H_SAVEDNUMTOPRINT + 1]
+ ld [H_NUMTOPRINT + 1], a
+.underflow1
+ ld a, [H_SAVEDNUMTOPRINT]
+ ld [H_NUMTOPRINT], a
+.underflow0
+ ld a, [H_PASTLEADINGZEROES]
+ or c
+ jr z, .PrintLeadingZero
+
+ ld a, "0"
+ add c
+ ld [hl], a
+ ld [H_PASTLEADINGZEROES], a
+ ret
+
+.PrintLeadingZero:
+ bit BIT_LEADING_ZEROES, d
+ ret z
+ ld [hl], "0"
+ ret
+
+.NextDigit:
+; Increment unless the number is left-aligned,
+; leading zeroes are not printed, and no digits
+; have been printed yet.
+ bit BIT_LEADING_ZEROES, d
+ jr nz, .inc
+ bit BIT_LEFT_ALIGN, d
+ jr z, .inc
+ ld a, [H_PASTLEADINGZEROES]
+ and a
+ ret z
+.inc
+ inc hl
+ ret
+
+
+CallFunctionInTable::
+; Call function a in jumptable hl.
+; de is not preserved.
+ push hl
+ push de
+ push bc
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .returnAddress
+ push de
+ jp hl
+.returnAddress
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+IsInArray::
+; Search an array at hl for the value in a.
+; Entry size is de bytes.
+; Return count b and carry if found.
+ ld b, 0
+
+IsInRestOfArray::
+ ld c, a
+.loop
+ ld a, [hl]
+ cp -1
+ jr z, .notfound
+ cp c
+ jr z, .found
+ inc b
+ add hl, de
+ jr .loop
+
+.notfound
+ and a
+ ret
+
+.found
+ scf
+ ret
+
+
+RestoreScreenTilesAndReloadTilePatterns::
+ call ClearSprites
+ ld a, $1
+ ld [wUpdateSpritesEnabled], a
+ call ReloadMapSpriteTilePatterns
+ call LoadScreenTilesFromBuffer2
+ call LoadTextBoxTilePatterns
+ call RunDefaultPaletteCommand
+ jr Delay3
+
+
+GBPalWhiteOutWithDelay3::
+ call GBPalWhiteOut
+
+Delay3::
+; The bg map is updated each frame in thirds.
+; Wait three frames to let the bg map fully update.
+ ld c, 3
+ jp DelayFrames
+
+GBPalNormal::
+; Reset BGP and OBP0.
+ ld a, %11100100 ; 3210
+ ld [rBGP], a
+ ld a, %11010000 ; 3100
+ ld [rOBP0], a
+ ret
+
+GBPalWhiteOut::
+; White out all palettes.
+ xor a
+ ld [rBGP], a
+ ld [rOBP0], a
+ ld [rOBP1], a
+ ret
+
+
+RunDefaultPaletteCommand::
+ ld b, $ff
+RunPaletteCommand::
+ ld a, [wOnSGB]
+ and a
+ ret z
+ predef_jump _RunPaletteCommand
+
+GetHealthBarColor::
+; Return at hl the palette of
+; an HP bar e pixels long.
+ ld a, e
+ cp 27
+ ld d, 0 ; green
+ jr nc, .gotColor
+ cp 10
+ inc d ; yellow
+ jr nc, .gotColor
+ inc d ; red
+.gotColor
+ ld [hl], d
+ ret
+
+; Copy the current map's sprites' tile patterns to VRAM again after they have
+; been overwritten by other tile patterns.
+ReloadMapSpriteTilePatterns::
+ ld hl, wFontLoaded
+ ld a, [hl]
+ push af
+ res 0, [hl]
+ push hl
+ xor a
+ ld [wSpriteSetID], a
+ call DisableLCD
+ callba InitMapSprites
+ call EnableLCD
+ pop hl
+ pop af
+ ld [hl], a
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ jp UpdateSprites
+
+
+GiveItem::
+; Give player quantity c of item b,
+; and copy the item's name to wcf4b.
+; Return carry on success.
+ ld a, b
+ ld [wd11e], a
+ ld [wcf91], a
+ ld a, c
+ ld [wItemQuantity], a
+ ld hl, wNumBagItems
+ call AddItemToInventory
+ ret nc
+ call GetItemName
+ call CopyStringToCF4B
+ scf
+ ret
+
+GivePokemon::
+; Give the player monster b at level c.
+ ld a, b
+ ld [wcf91], a
+ ld a, c
+ ld [wCurEnemyLVL], a
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ jpba _GivePokemon
+
+
+Random::
+; Return a random number in a.
+; For battles, use BattleRandom.
+ push hl
+ push de
+ push bc
+ callba Random_
+ ld a, [hRandomAdd]
+ pop bc
+ pop de
+ pop hl
+ ret
+
+
+INCLUDE "home/predef.asm"
+
+
+UpdateCinnabarGymGateTileBlocks::
+ jpba UpdateCinnabarGymGateTileBlocks_
+
+CheckForHiddenObjectOrBookshelfOrCardKeyDoor::
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [hJoyHeld]
+ bit 0, a ; A button
+ jr z, .nothingFound
+; A button is pressed
+ ld a, Bank(CheckForHiddenObject)
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ call CheckForHiddenObject
+ ld a, [$ffee]
+ and a
+ jr nz, .hiddenObjectNotFound
+ ld a, [wHiddenObjectFunctionRomBank]
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ ld de, .returnAddress
+ push de
+ jp hl
+.returnAddress
+ xor a
+ jr .done
+.hiddenObjectNotFound
+ callba PrintBookshelfText
+ ld a, [$ffdb]
+ and a
+ jr z, .done
+.nothingFound
+ ld a, $ff
+.done
+ ld [$ffeb], a
+ pop af
+ ld [MBC1RomBank], a
+ ld [H_LOADEDROMBANK], a
+ ret
+
+PrintPredefTextID::
+ ld [hSpriteIndexOrTextID], a
+ ld hl, TextPredefs
+ call SetMapTextPointer
+ ld hl, wTextPredefFlag
+ set 0, [hl]
+ call DisplayTextID
+
+RestoreMapTextPointer::
+ ld hl, wMapTextPtr
+ ld a, [$ffec]
+ ld [hli], a
+ ld a, [$ffec + 1]
+ ld [hl], a
+ ret
+
+SetMapTextPointer::
+ ld a, [wMapTextPtr]
+ ld [$ffec], a
+ ld a, [wMapTextPtr + 1]
+ ld [$ffec + 1], a
+ ld a, l
+ ld [wMapTextPtr], a
+ ld a, h
+ ld [wMapTextPtr + 1], a
+ ret
+
+TextPredefs::
+const_value = 1
+
+ add_tx_pre CardKeySuccessText ; 01
+ add_tx_pre CardKeyFailText ; 02
+ add_tx_pre RedBedroomPCText ; 03
+ add_tx_pre RedBedroomSNESText ; 04
+ add_tx_pre PushStartText ; 05
+ add_tx_pre SaveOptionText ; 06
+ add_tx_pre StrengthsAndWeaknessesText ; 07
+ add_tx_pre OakLabEmailText ; 08
+ add_tx_pre AerodactylFossilText ; 09
+ add_tx_pre Route15UpstairsBinocularsText ; 0A
+ add_tx_pre KabutopsFossilText ; 0B
+ add_tx_pre GymStatueText1 ; 0C
+ add_tx_pre GymStatueText2 ; 0D
+ add_tx_pre BookcaseText ; 0E
+ add_tx_pre ViridianCityPokecenterBenchGuyText ; 0F
+ add_tx_pre PewterCityPokecenterBenchGuyText ; 10
+ add_tx_pre CeruleanCityPokecenterBenchGuyText ; 11
+ add_tx_pre LavenderCityPokecenterBenchGuyText ; 12
+ add_tx_pre VermilionCityPokecenterBenchGuyText ; 13
+ add_tx_pre CeladonCityPokecenterBenchGuyText ; 14
+ add_tx_pre CeladonCityHotelText ; 15
+ add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 16
+ add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 17
+ add_tx_pre SaffronCityPokecenterBenchGuyText ; 18
+ add_tx_pre MtMoonPokecenterBenchGuyText ; 19
+ add_tx_pre RockTunnelPokecenterBenchGuyText ; 1A
+ add_tx_pre UnusedBenchGuyText1 ; 1B XXX unused
+ add_tx_pre UnusedBenchGuyText2 ; 1C XXX unused
+ add_tx_pre UnusedBenchGuyText3 ; 1D XXX unused
+ add_tx_pre UnusedPredefText ; 1E XXX unused
+ add_tx_pre PokemonCenterPCText ; 1F
+ add_tx_pre ViridianSchoolNotebook ; 20
+ add_tx_pre ViridianSchoolBlackboard ; 21
+ add_tx_pre JustAMomentText ; 22
+ add_tx_pre OpenBillsPCText ; 23
+ add_tx_pre FoundHiddenItemText ; 24
+ add_tx_pre HiddenItemBagFullText ; 25 XXX unused
+ add_tx_pre VermilionGymTrashText ; 26
+ add_tx_pre IndigoPlateauHQText ; 27
+ add_tx_pre GameCornerOutOfOrderText ; 28
+ add_tx_pre GameCornerOutToLunchText ; 29
+ add_tx_pre GameCornerSomeonesKeysText ; 2A
+ add_tx_pre FoundHiddenCoinsText ; 2B
+ add_tx_pre DroppedHiddenCoinsText ; 2C
+ add_tx_pre BillsHouseMonitorText ; 2D
+ add_tx_pre BillsHouseInitiatedText ; 2E
+ add_tx_pre BillsHousePokemonList ; 2F
+ add_tx_pre MagazinesText ; 30
+ add_tx_pre CinnabarGymQuiz ; 31
+ add_tx_pre GameCornerNoCoinsText ; 32
+ add_tx_pre GameCornerCoinCaseText ; 33
+ add_tx_pre LinkCableHelp ; 34
+ add_tx_pre TMNotebook ; 35
+ add_tx_pre FightingDojoText ; 36
+ add_tx_pre EnemiesOnEverySideText ; 37
+ add_tx_pre WhatGoesAroundComesAroundText ; 38
+ add_tx_pre NewBicycleText ; 39
+ add_tx_pre IndigoPlateauStatues ; 3A
+ add_tx_pre VermilionGymTrashSuccessText1 ; 3B
+ add_tx_pre VermilionGymTrashSuccessText2 ; 3C XXX unused
+ add_tx_pre VermilionGymTrashSuccessText3 ; 3D
+ add_tx_pre VermilionGymTrashFailText ; 3E
+ add_tx_pre TownMapText ; 3F
+ add_tx_pre BookOrSculptureText ; 40
+ add_tx_pre ElevatorText ; 41
+ add_tx_pre PokemonStuffText ; 42
diff --git a/en/home/text.asm b/en/home/text.asm
new file mode 100644
index 00000000..9db81530
--- /dev/null
+++ b/en/home/text.asm
@@ -0,0 +1,711 @@
+TextBoxBorder::
+; Draw a c×b text box at hl.
+
+ ; top row
+ push hl
+ ld a, "┌"
+ ld [hli], a
+ inc a ; ─
+ call NPlaceChar
+ inc a ; ┐
+ ld [hl], a
+ pop hl
+
+ ld de, SCREEN_WIDTH
+ add hl, de
+
+ ; middle rows
+.next
+ push hl
+ ld a, "│"
+ ld [hli], a
+ ld a, " "
+ call NPlaceChar
+ ld [hl], "│"
+ pop hl
+
+ ld de, SCREEN_WIDTH
+ add hl, de
+ dec b
+ jr nz, .next
+
+ ; bottom row
+ ld a, "└"
+ ld [hli], a
+ ld a, "─"
+ call NPlaceChar
+ ld [hl], "┘"
+ ret
+
+NPlaceChar::
+; Place char a c times.
+ ld d, c
+.loop
+ ld [hli], a
+ dec d
+ jr nz, .loop
+ ret
+
+PlaceString::
+ push hl
+PlaceNextChar::
+ ld a, [de]
+
+ cp "@"
+ jr nz, Char4ETest
+ ld b, h
+ ld c, l
+ pop hl
+ ret
+
+Char4ETest::
+ cp $4E ; next
+ jr nz, .char4FTest
+ ld bc, 2 * SCREEN_WIDTH
+ ld a, [hFlags_0xFFF6]
+ bit 2, a
+ jr z, .ok
+ ld bc, SCREEN_WIDTH
+.ok
+ pop hl
+ add hl, bc
+ push hl
+ jp PlaceNextChar_inc
+
+.char4FTest
+ cp $4F ; line
+ jr nz, .next3
+ pop hl
+ coord hl, 1, 16
+ push hl
+ jp PlaceNextChar_inc
+
+.next3 ; Check against a dictionary
+dict: macro
+if \1 == 0
+ and a
+else
+ cp \1
+endc
+ jp z, \2
+endm
+
+ dict $00, Char00 ; error
+ dict $4C, Char4C ; autocont
+ dict $4B, Char4B ; cont_
+ dict $51, Char51 ; para
+ dict $49, Char49 ; page
+ dict $52, Char52 ; player
+ dict $53, Char53 ; rival
+ dict $54, Char54 ; POKé
+ dict $5B, Char5B ; PC
+ dict $5E, Char5E ; ROCKET
+ dict $5C, Char5C ; TM
+ dict $5D, Char5D ; TRAINER
+ dict $55, Char55 ; cont
+ dict $56, Char56 ; 6 dots
+ dict $57, Char57 ; done
+ dict $58, Char58 ; prompt
+ dict $4A, Char4A ; PKMN
+ dict $5F, Char5F ; dex
+ dict $59, Char59 ; TARGET
+ dict $5A, Char5A ; USER
+
+ ld [hli], a
+ call PrintLetterDelay
+PlaceNextChar_inc::
+ inc de
+ jp PlaceNextChar
+
+Char00::
+ ld b, h
+ ld c, l
+ pop hl
+ ld de, Char00Text
+ dec de
+ ret
+
+Char00Text:: ; “%d ERROR.”
+ TX_FAR _Char00Text
+ db "@"
+
+Char52:: ; player’s name
+ push de
+ ld de, wPlayerName
+ jr FinishDTE
+
+Char53:: ; rival’s name
+ push de
+ ld de, wRivalName
+ jr FinishDTE
+
+Char5D:: ; TRAINER
+ push de
+ ld de, Char5DText
+ jr FinishDTE
+
+Char5C:: ; TM
+ push de
+ ld de, Char5CText
+ jr FinishDTE
+
+Char5B:: ; PC
+ push de
+ ld de, Char5BText
+ jr FinishDTE
+
+Char5E:: ; ROCKET
+ push de
+ ld de, Char5EText
+ jr FinishDTE
+
+Char54:: ; POKé
+ push de
+ ld de, Char54Text
+ jr FinishDTE
+
+Char56:: ; ……
+ push de
+ ld de, Char56Text
+ jr FinishDTE
+
+Char4A:: ; PKMN
+ push de
+ ld de, Char4AText
+ jr FinishDTE
+
+Char59::
+; depending on whose turn it is, print
+; enemy active monster’s name, prefixed with “Enemy ”
+; or
+; player active monster’s name
+; (like Char5A but flipped)
+ ld a, [H_WHOSETURN]
+ xor 1
+ jr MonsterNameCharsCommon
+
+Char5A::
+; depending on whose turn it is, print
+; player active monster’s name
+; or
+; enemy active monster’s name, prefixed with “Enemy ”
+ ld a, [H_WHOSETURN]
+MonsterNameCharsCommon::
+ push de
+ and a
+ jr nz, .Enemy
+ ld de, wBattleMonNick ; player active monster name
+ jr FinishDTE
+
+.Enemy
+ ; print “Enemy ”
+ ld de, Char5AText
+ call PlaceString
+ ld h, b
+ ld l, c
+ ld de, wEnemyMonNick ; enemy active monster name
+
+FinishDTE::
+ call PlaceString
+ ld h, b
+ ld l, c
+ pop de
+ inc de
+ jp PlaceNextChar
+
+Char5CText::
+ db "TM@"
+Char5DText::
+ db "TRAINER@"
+Char5BText::
+ db "PC@"
+Char5EText::
+ db "ROCKET@"
+Char54Text::
+ db "POKé@"
+Char56Text::
+ db "……@"
+Char5AText::
+ db "Enemy @"
+Char4AText::
+ db $E1,$E2,"@" ; PKMN
+
+Char55::
+ push de
+ ld b, h
+ ld c, l
+ ld hl, Char55Text
+ call TextCommandProcessor
+ ld h, b
+ ld l, c
+ pop de
+ inc de
+ jp PlaceNextChar
+
+Char55Text::
+; equivalent to Char4B
+ TX_FAR _Char55Text
+ db "@"
+
+Char5F::
+; ends a Pokédex entry
+ ld [hl], "."
+ pop hl
+ ret
+
+Char58:: ; prompt
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jp z, .ok
+ ld a, "▼"
+ Coorda 18, 16
+.ok
+ call ProtectedDelay3
+ call ManualTextScroll
+ ld a, " "
+ Coorda 18, 16
+Char57:: ; done
+ pop hl
+ ld de, Char58Text
+ dec de
+ ret
+
+Char58Text::
+ db "@"
+
+Char51:: ; para
+ push de
+ ld a, "▼"
+ Coorda 18, 16
+ call ProtectedDelay3
+ call ManualTextScroll
+ coord hl, 1, 13
+ lb bc, 4, 18
+ call ClearScreenArea
+ ld c, 20
+ call DelayFrames
+ pop de
+ coord hl, 1, 14
+ jp PlaceNextChar_inc
+
+Char49::
+ push de
+ ld a, "▼"
+ Coorda 18, 16
+ call ProtectedDelay3
+ call ManualTextScroll
+ coord hl, 1, 10
+ lb bc, 7, 18
+ call ClearScreenArea
+ ld c, 20
+ call DelayFrames
+ pop de
+ pop hl
+ coord hl, 1, 11
+ push hl
+ jp PlaceNextChar_inc
+
+Char4B::
+ ld a, "▼"
+ Coorda 18, 16
+ call ProtectedDelay3
+ push de
+ call ManualTextScroll
+ pop de
+ ld a, " "
+ Coorda 18, 16
+ ;fall through
+Char4C::
+ push de
+ call ScrollTextUpOneLine
+ call ScrollTextUpOneLine
+ coord hl, 1, 16
+ pop de
+ jp PlaceNextChar_inc
+
+; move both rows of text in the normal text box up one row
+; always called twice in a row
+; first time, copy the two rows of text to the "in between" rows that are usually emtpy
+; second time, copy the bottom row of text into the top row of text
+ScrollTextUpOneLine::
+ coord hl, 0, 14 ; top row of text
+ coord de, 0, 13 ; empty line above text
+ ld b, SCREEN_WIDTH * 3
+.copyText
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyText
+ coord hl, 1, 16
+ ld a, " "
+ ld b, SCREEN_WIDTH - 2
+.clearText
+ ld [hli], a
+ dec b
+ jr nz, .clearText
+
+ ; wait five frames
+ ld b, 5
+.WaitFrame
+ call DelayFrame
+ dec b
+ jr nz, .WaitFrame
+
+ ret
+
+ProtectedDelay3::
+ push bc
+ call Delay3
+ pop bc
+ ret
+
+TextCommandProcessor::
+ ld a, [wLetterPrintingDelayFlags]
+ push af
+ set 1, a
+ ld e, a
+ ld a, [$fff4]
+ xor e
+ ld [wLetterPrintingDelayFlags], a
+ ld a, c
+ ld [wTextDest], a
+ ld a, b
+ ld [wTextDest + 1], a
+
+NextTextCommand::
+ ld a, [hli]
+ cp "@" ; terminator
+ jr nz, .doTextCommand
+ pop af
+ ld [wLetterPrintingDelayFlags], a
+ ret
+.doTextCommand
+ push hl
+ cp $17
+ jp z, TextCommand17
+ cp $0e
+ jp nc, TextCommand0B ; if a != 0x17 and a >= 0xE, go to command 0xB
+; if a < 0xE, use a jump table
+ ld hl, TextCommandJumpTable
+ push bc
+ add a
+ ld b, 0
+ ld c, a
+ add hl, bc
+ pop bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+; draw box
+; 04AAAABBCC
+; AAAA = address of upper left corner
+; BB = height
+; CC = width
+TextCommand04::
+ pop hl
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld c, a
+ push hl
+ ld h, d
+ ld l, e
+ call TextBoxBorder
+ pop hl
+ jr NextTextCommand
+
+; place string inline
+; 00{string}
+TextCommand00::
+ pop hl
+ ld d, h
+ ld e, l
+ ld h, b
+ ld l, c
+ call PlaceString
+ ld h, d
+ ld l, e
+ inc hl
+ jr NextTextCommand
+
+; place string from RAM
+; 01AAAA
+; AAAA = address of string
+TextCommand01::
+ pop hl
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ push hl
+ ld h, b
+ ld l, c
+ call PlaceString
+ pop hl
+ jr NextTextCommand
+
+; print BCD number
+; 02AAAABB
+; AAAA = address of BCD number
+; BB
+; bits 0-4 = length in bytes
+; bits 5-7 = unknown flags
+TextCommand02::
+ pop hl
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ push hl
+ ld h, b
+ ld l, c
+ ld c, a
+ call PrintBCDNumber
+ ld b, h
+ ld c, l
+ pop hl
+ jr NextTextCommand
+
+; repoint destination address
+; 03AAAA
+; AAAA = new destination address
+TextCommand03::
+ pop hl
+ ld a, [hli]
+ ld [wTextDest], a
+ ld c, a
+ ld a, [hli]
+ ld [wTextDest + 1], a
+ ld b, a
+ jp NextTextCommand
+
+; repoint destination to second line of dialogue text box
+; 05
+; (no arguments)
+TextCommand05::
+ pop hl
+ coord bc, 1, 16 ; address of second line of dialogue text box
+ jp NextTextCommand
+
+; blink arrow and wait for A or B to be pressed
+; 06
+; (no arguments)
+TextCommand06::
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ jp z, TextCommand0D
+ ld a, "▼"
+ Coorda 18, 16 ; place down arrow in lower right corner of dialogue text box
+ push bc
+ call ManualTextScroll ; blink arrow and wait for A or B to be pressed
+ pop bc
+ ld a, " "
+ Coorda 18, 16 ; overwrite down arrow with blank space
+ pop hl
+ jp NextTextCommand
+
+; scroll text up one line
+; 07
+; (no arguments)
+TextCommand07::
+ ld a, " "
+ Coorda 18, 16 ; place blank space in lower right corner of dialogue text box
+ call ScrollTextUpOneLine
+ call ScrollTextUpOneLine
+ pop hl
+ coord bc, 1, 16 ; address of second line of dialogue text box
+ jp NextTextCommand
+
+; execute asm inline
+; 08{code}
+TextCommand08::
+ pop hl
+ ld de, NextTextCommand
+ push de ; return address
+ jp hl
+
+; print decimal number (converted from binary number)
+; 09AAAABB
+; AAAA = address of number
+; BB
+; bits 0-3 = how many digits to display
+; bits 4-7 = how long the number is in bytes
+TextCommand09::
+ pop hl
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ push hl
+ ld h, b
+ ld l, c
+ ld b, a
+ and $0f
+ ld c, a
+ ld a, b
+ and $f0
+ swap a
+ set BIT_LEFT_ALIGN,a
+ ld b, a
+ call PrintNumber
+ ld b, h
+ ld c, l
+ pop hl
+ jp NextTextCommand
+
+; wait half a second if the user doesn't hold A or B
+; 0A
+; (no arguments)
+TextCommand0A::
+ push bc
+ call Joypad
+ ld a, [hJoyHeld]
+ and A_BUTTON | B_BUTTON
+ jr nz, .skipDelay
+ ld c, 30
+ call DelayFrames
+.skipDelay
+ pop bc
+ pop hl
+ jp NextTextCommand
+
+; plays sounds
+; this actually handles various command ID's, not just 0B
+; (no arguments)
+TextCommand0B::
+ pop hl
+ push bc
+ dec hl
+ ld a, [hli]
+ ld b, a ; b = command number that got us here
+ push hl
+ ld hl, TextCommandSounds
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .matchFound
+ inc hl
+ jr .loop
+.matchFound
+ cp $14
+ jr z, .pokemonCry
+ cp $15
+ jr z, .pokemonCry
+ cp $16
+ jr z, .pokemonCry
+ ld a, [hl]
+ call PlaySound
+ call WaitForSoundToFinish
+ pop hl
+ pop bc
+ jp NextTextCommand
+.pokemonCry
+ push de
+ ld a, [hl]
+ call PlayCry
+ pop de
+ pop hl
+ pop bc
+ jp NextTextCommand
+
+; format: text command ID, sound ID or cry ID
+TextCommandSounds::
+ db $0B, SFX_GET_ITEM_1 ; actually plays SFX_LEVEL_UP when the battle music engine is loaded
+ db $12, SFX_CAUGHT_MON
+ db $0E, SFX_POKEDEX_RATING ; unused?
+ db $0F, SFX_GET_ITEM_1 ; unused?
+ db $10, SFX_GET_ITEM_2
+ db $11, SFX_GET_KEY_ITEM
+ db $13, SFX_DEX_PAGE_ADDED
+ db $14, NIDORINA ; used in OakSpeech
+ db $15, PIDGEOT ; used in SaffronCityText12
+ db $16, DEWGONG ; unused?
+
+; draw ellipses
+; 0CAA
+; AA = number of ellipses to draw
+TextCommand0C::
+ pop hl
+ ld a, [hli]
+ ld d, a
+ push hl
+ ld h, b
+ ld l, c
+.loop
+ ld a, "…"
+ ld [hli], a
+ push de
+ call Joypad
+ pop de
+ ld a, [hJoyHeld] ; joypad state
+ and A_BUTTON | B_BUTTON
+ jr nz, .skipDelay ; if so, skip the delay
+ ld c, 10
+ call DelayFrames
+.skipDelay
+ dec d
+ jr nz, .loop
+ ld b, h
+ ld c, l
+ pop hl
+ jp NextTextCommand
+
+; wait for A or B to be pressed
+; 0D
+; (no arguments)
+TextCommand0D::
+ push bc
+ call ManualTextScroll ; wait for A or B to be pressed
+ pop bc
+ pop hl
+ jp NextTextCommand
+
+; process text commands in another ROM bank
+; 17AAAABB
+; AAAA = address of text commands
+; BB = bank
+TextCommand17::
+ pop hl
+ ld a, [H_LOADEDROMBANK]
+ push af
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ push hl
+ ld l, e
+ ld h, d
+ call TextCommandProcessor
+ pop hl
+ pop af
+ ld [H_LOADEDROMBANK], a
+ ld [MBC1RomBank], a
+ jp NextTextCommand
+
+TextCommandJumpTable::
+ dw TextCommand00
+ dw TextCommand01
+ dw TextCommand02
+ dw TextCommand03
+ dw TextCommand04
+ dw TextCommand05
+ dw TextCommand06
+ dw TextCommand07
+ dw TextCommand08
+ dw TextCommand09
+ dw TextCommand0A
+ dw TextCommand0B
+ dw TextCommand0C
+ dw TextCommand0D
diff --git a/en/main.asm b/en/main.asm
new file mode 100755
index 00000000..21d37aef
--- /dev/null
+++ b/en/main.asm
@@ -0,0 +1,2090 @@
+INCLUDE "constants.asm"
+
+NPC_SPRITES_1 EQU $4
+NPC_SPRITES_2 EQU $5
+
+GFX EQU $4
+
+PICS_1 EQU $9
+PICS_2 EQU $A
+PICS_3 EQU $B
+PICS_4 EQU $C
+PICS_5 EQU $D
+
+ inclang home.asm
+
+
+SECTION "bank1",ROMX,BANK[$1]
+
+INCLUDE "data/facing.asm"
+
+INCLUDE "engine/black_out.asm"
+
+MewPicFront:: INCBIN "pic/bmon/mew.pic"
+MewPicBack:: INCBIN "pic/monback/mewb.pic"
+INCLUDE "data/baseStats/mew.asm"
+
+INCLUDE "engine/battle/safari_zone.asm"
+
+ inclang engine/titlescreen.asm
+INCLUDE "engine/load_mon_data.asm"
+
+INCLUDE "data/item_prices.asm"
+ inclang text/item_names.asm
+INCLUDE "text/unused_names.asm"
+
+INCLUDE "engine/overworld/oam.asm"
+INCLUDE "engine/oam_dma.asm"
+
+ inclang engine/print_waiting_text.asm
+
+INCLUDE "engine/overworld/map_sprite_functions1.asm"
+
+INCLUDE "engine/test_battle.asm"
+
+INCLUDE "engine/overworld/item.asm"
+ inclang engine/overworld/movement.asm
+
+ inclang engine/cable_club.asm
+
+ inclang engine/menu/main_menu.asm
+
+INCLUDE "engine/oak_speech.asm"
+
+INCLUDE "engine/special_warps.asm"
+
+INCLUDE "engine/debug1.asm"
+
+ inclang engine/menu/naming_screen.asm
+
+ inclang engine/oak_speech2.asm
+
+INCLUDE "engine/subtract_paid_money.asm"
+
+INCLUDE "engine/menu/swap_items.asm"
+
+ inclang engine/overworld/pokemart.asm
+
+ inclang engine/learn_move.asm
+
+INCLUDE "engine/overworld/pokecenter.asm"
+
+INCLUDE "engine/overworld/set_blackout_map.asm"
+
+INCLUDE "engine/display_text_id_init.asm"
+ inclang engine/menu/draw_start_menu.asm
+
+INCLUDE "engine/overworld/cable_club_npc.asm"
+
+ inclang engine/menu/text_box.asm
+
+INCLUDE "engine/battle/moveEffects/drain_hp_effect.asm"
+
+ inclang engine/menu/players_pc.asm
+
+INCLUDE "engine/remove_pokemon.asm"
+
+INCLUDE "engine/display_pokedex.asm"
+
+SECTION "bank3",ROMX,BANK[$3]
+
+INCLUDE "engine/joypad.asm"
+
+INCLUDE "data/map_songs.asm"
+
+INCLUDE "data/map_header_banks.asm"
+
+INCLUDE "engine/overworld/clear_variables.asm"
+INCLUDE "engine/overworld/player_state.asm"
+INCLUDE "engine/overworld/poison.asm"
+INCLUDE "engine/overworld/tileset_header.asm"
+INCLUDE "engine/overworld/daycare_exp.asm"
+
+INCLUDE "data/hide_show_data.asm"
+
+INCLUDE "engine/overworld/field_move_messages.asm"
+
+INCLUDE "engine/items/inventory.asm"
+
+INCLUDE "engine/overworld/wild_mons.asm"
+
+ inclang engine/items/items.asm
+
+INCLUDE "engine/menu/draw_badges.asm"
+
+INCLUDE "engine/overworld/update_map.asm"
+INCLUDE "engine/overworld/cut.asm"
+INCLUDE "engine/overworld/missable_objects.asm"
+INCLUDE "engine/overworld/push_boulder.asm"
+
+INCLUDE "engine/add_mon.asm"
+INCLUDE "engine/flag_action.asm"
+INCLUDE "engine/heal_party.asm"
+INCLUDE "engine/bcd.asm"
+INCLUDE "engine/init_player_data.asm"
+INCLUDE "engine/get_bag_item_quantity.asm"
+INCLUDE "engine/pathfinding.asm"
+INCLUDE "engine/hp_bar.asm"
+INCLUDE "engine/hidden_object_functions3.asm"
+
+SECTION "NPC Sprites 1", ROMX, BANK[NPC_SPRITES_1]
+
+OakAideSprite: INCBIN "gfx/sprites/oak_aide.2bpp"
+RockerSprite: INCBIN "gfx/sprites/rocker.2bpp"
+SwimmerSprite: INCBIN "gfx/sprites/swimmer.2bpp"
+WhitePlayerSprite: INCBIN "gfx/sprites/white_player.2bpp"
+GymHelperSprite: INCBIN "gfx/sprites/gym_helper.2bpp"
+OldPersonSprite: INCBIN "gfx/sprites/old_person.2bpp"
+MartGuySprite: INCBIN "gfx/sprites/mart_guy.2bpp"
+FisherSprite: INCBIN "gfx/sprites/fisher.2bpp"
+OldMediumWomanSprite: INCBIN "gfx/sprites/old_medium_woman.2bpp"
+NurseSprite: INCBIN "gfx/sprites/nurse.2bpp"
+CableClubWomanSprite: INCBIN "gfx/sprites/cable_club_woman.2bpp"
+MrMasterballSprite: INCBIN "gfx/sprites/mr_masterball.2bpp"
+LaprasGiverSprite: INCBIN "gfx/sprites/lapras_giver.2bpp"
+WardenSprite: INCBIN "gfx/sprites/warden.2bpp"
+SsCaptainSprite: INCBIN "gfx/sprites/ss_captain.2bpp"
+Fisher2Sprite: INCBIN "gfx/sprites/fisher2.2bpp"
+BlackbeltSprite: INCBIN "gfx/sprites/blackbelt.2bpp"
+GuardSprite: INCBIN "gfx/sprites/guard.2bpp"
+BallSprite: INCBIN "gfx/sprites/ball.2bpp"
+OmanyteSprite: INCBIN "gfx/sprites/omanyte.2bpp"
+BoulderSprite: INCBIN "gfx/sprites/boulder.2bpp"
+PaperSheetSprite: INCBIN "gfx/sprites/paper_sheet.2bpp"
+BookMapDexSprite: INCBIN "gfx/sprites/book_map_dex.2bpp"
+ClipboardSprite: INCBIN "gfx/sprites/clipboard.2bpp"
+SnorlaxSprite: INCBIN "gfx/sprites/snorlax.2bpp"
+OldAmberSprite: INCBIN "gfx/sprites/old_amber.2bpp"
+LyingOldManSprite: INCBIN "gfx/sprites/lying_old_man.2bpp"
+
+
+SECTION "Graphics", ROMX, BANK[GFX]
+
+PokemonLogoGraphics: INCBIN "gfx/pokemon_logo.2bpp"
+FontGraphics: binlang gfx/font.1bpp
+FontGraphicsEnd:
+ABTiles: INCBIN "gfx/AB.2bpp"
+HpBarAndStatusGraphics: binlang gfx/hp_bar_and_status.2bpp
+HpBarAndStatusGraphicsEnd:
+BattleHudTiles1: binlang gfx/battle_hud1.1bpp
+BattleHudTiles1End:
+BattleHudTiles2: INCBIN "gfx/battle_hud2.1bpp"
+BattleHudTiles3: INCBIN "gfx/battle_hud3.1bpp"
+BattleHudTiles3End:
+NintendoCopyrightLogoGraphics: binlang gfx/copyright.2bpp
+GamefreakLogoGraphics: INCBIN "gfx/gamefreak.2bpp"
+GamefreakLogoGraphicsEnd:
+TextBoxGraphics: INCBIN "gfx/text_box.2bpp"
+TextBoxGraphicsEnd:
+PokedexTileGraphics: binlang gfx/pokedex.2bpp
+PokedexTileGraphicsEnd:
+WorldMapTileGraphics: binlang gfx/town_map.2bpp
+WorldMapTileGraphicsEnd:
+PlayerCharacterTitleGraphics: INCBIN "gfx/player_title.2bpp"
+PlayerCharacterTitleGraphicsEnd:
+
+
+SECTION "Battle (bank 4)", ROMX, BANK[$4]
+
+INCLUDE "engine/overworld/is_player_just_outside_map.asm"
+ inclang engine/menu/status_screen.asm
+ inclang engine/menu/party_menu.asm
+
+RedPicFront:: INCBIN "pic/trainer/red.pic"
+ShrinkPic1:: INCBIN "pic/trainer/shrink1.pic"
+ShrinkPic2:: INCBIN "pic/trainer/shrink2.pic"
+
+INCLUDE "engine/turn_sprite.asm"
+ inclang engine/menu/start_sub_menus.asm
+INCLUDE "engine/items/tms.asm"
+ inclang engine/battle/end_of_battle.asm
+INCLUDE "engine/battle/wild_encounters.asm"
+INCLUDE "engine/battle/moveEffects/recoil_effect.asm"
+INCLUDE "engine/battle/moveEffects/conversion_effect.asm"
+INCLUDE "engine/battle/moveEffects/haze_effect.asm"
+INCLUDE "engine/battle/get_trainer_name.asm"
+INCLUDE "engine/random.asm"
+
+
+SECTION "NPC Sprites 2", ROMX, BANK[NPC_SPRITES_2]
+
+RedCyclingSprite: INCBIN "gfx/sprites/cycling.2bpp"
+RedSprite: INCBIN "gfx/sprites/red.2bpp"
+BlueSprite: INCBIN "gfx/sprites/blue.2bpp"
+OakSprite: INCBIN "gfx/sprites/oak.2bpp"
+BugCatcherSprite: INCBIN "gfx/sprites/bug_catcher.2bpp"
+SlowbroSprite: INCBIN "gfx/sprites/slowbro.2bpp"
+LassSprite: INCBIN "gfx/sprites/lass.2bpp"
+BlackHairBoy1Sprite: INCBIN "gfx/sprites/black_hair_boy_1.2bpp"
+LittleGirlSprite: INCBIN "gfx/sprites/little_girl.2bpp"
+BirdSprite: INCBIN "gfx/sprites/bird.2bpp"
+FatBaldGuySprite: INCBIN "gfx/sprites/fat_bald_guy.2bpp"
+GamblerSprite: INCBIN "gfx/sprites/gambler.2bpp"
+BlackHairBoy2Sprite: INCBIN "gfx/sprites/black_hair_boy_2.2bpp"
+GirlSprite: INCBIN "gfx/sprites/girl.2bpp"
+HikerSprite: INCBIN "gfx/sprites/hiker.2bpp"
+FoulardWomanSprite: INCBIN "gfx/sprites/foulard_woman.2bpp"
+GentlemanSprite: INCBIN "gfx/sprites/gentleman.2bpp"
+DaisySprite: INCBIN "gfx/sprites/daisy.2bpp"
+BikerSprite: INCBIN "gfx/sprites/biker.2bpp"
+SailorSprite: INCBIN "gfx/sprites/sailor.2bpp"
+CookSprite: INCBIN "gfx/sprites/cook.2bpp"
+BikeShopGuySprite: INCBIN "gfx/sprites/bike_shop_guy.2bpp"
+MrFujiSprite: INCBIN "gfx/sprites/mr_fuji.2bpp"
+GiovanniSprite: INCBIN "gfx/sprites/giovanni.2bpp"
+RocketSprite: INCBIN "gfx/sprites/rocket.2bpp"
+MediumSprite: INCBIN "gfx/sprites/medium.2bpp"
+WaiterSprite: INCBIN "gfx/sprites/waiter.2bpp"
+ErikaSprite: INCBIN "gfx/sprites/erika.2bpp"
+MomGeishaSprite: INCBIN "gfx/sprites/mom_geisha.2bpp"
+BrunetteGirlSprite: INCBIN "gfx/sprites/brunette_girl.2bpp"
+LanceSprite: INCBIN "gfx/sprites/lance.2bpp"
+MomSprite: INCBIN "gfx/sprites/mom.2bpp"
+BaldingGuySprite: INCBIN "gfx/sprites/balding_guy.2bpp"
+YoungBoySprite: INCBIN "gfx/sprites/young_boy.2bpp"
+GameboyKidSprite: INCBIN "gfx/sprites/gameboy_kid.2bpp"
+ClefairySprite: INCBIN "gfx/sprites/clefairy.2bpp"
+AgathaSprite: INCBIN "gfx/sprites/agatha.2bpp"
+BrunoSprite: INCBIN "gfx/sprites/bruno.2bpp"
+LoreleiSprite: INCBIN "gfx/sprites/lorelei.2bpp"
+SeelSprite: INCBIN "gfx/sprites/seel.2bpp"
+
+
+SECTION "Battle (bank 5)", ROMX, BANK[$5]
+
+INCLUDE "engine/load_pokedex_tiles.asm"
+INCLUDE "engine/overworld/map_sprites.asm"
+INCLUDE "engine/overworld/emotion_bubbles.asm"
+ inclang engine/evolve_trade.asm
+INCLUDE "engine/battle/moveEffects/substitute_effect.asm"
+INCLUDE "engine/menu/pc.asm"
+
+
+SECTION "bank6",ROMX,BANK[$6]
+
+INCLUDE "data/mapHeaders/celadoncity.asm"
+INCLUDE "data/mapObjects/celadoncity.asm"
+CeladonCityBlocks: INCBIN "maps/celadoncity.blk"
+
+INCLUDE "data/mapHeaders/pallettown.asm"
+INCLUDE "data/mapObjects/pallettown.asm"
+PalletTownBlocks: INCBIN "maps/pallettown.blk"
+
+INCLUDE "data/mapHeaders/viridiancity.asm"
+INCLUDE "data/mapObjects/viridiancity.asm"
+ViridianCityBlocks: INCBIN "maps/viridiancity.blk"
+
+INCLUDE "data/mapHeaders/pewtercity.asm"
+INCLUDE "data/mapObjects/pewtercity.asm"
+PewterCityBlocks: INCBIN "maps/pewtercity.blk"
+
+INCLUDE "data/mapHeaders/ceruleancity.asm"
+INCLUDE "data/mapObjects/ceruleancity.asm"
+CeruleanCityBlocks: INCBIN "maps/ceruleancity.blk"
+
+INCLUDE "data/mapHeaders/vermilioncity.asm"
+INCLUDE "data/mapObjects/vermilioncity.asm"
+VermilionCityBlocks: INCBIN "maps/vermilioncity.blk"
+
+INCLUDE "data/mapHeaders/fuchsiacity.asm"
+INCLUDE "data/mapObjects/fuchsiacity.asm"
+FuchsiaCityBlocks: INCBIN "maps/fuchsiacity.blk"
+
+INCLUDE "engine/play_time.asm"
+
+INCLUDE "scripts/pallettown.asm"
+INCLUDE "scripts/viridiancity.asm"
+ inclang scripts/pewtercity.asm
+INCLUDE "scripts/ceruleancity.asm"
+INCLUDE "scripts/vermilioncity.asm"
+INCLUDE "scripts/celadoncity.asm"
+INCLUDE "scripts/fuchsiacity.asm"
+
+INCLUDE "data/mapHeaders/blueshouse.asm"
+INCLUDE "scripts/blueshouse.asm"
+INCLUDE "data/mapObjects/blueshouse.asm"
+BluesHouseBlocks: INCBIN "maps/blueshouse.blk"
+
+INCLUDE "data/mapHeaders/vermilionhouse3.asm"
+INCLUDE "scripts/vermilionhouse3.asm"
+INCLUDE "data/mapObjects/vermilionhouse3.asm"
+VermilionHouse3Blocks: INCBIN "maps/vermilionhouse3.blk"
+
+INCLUDE "data/mapHeaders/indigoplateaulobby.asm"
+INCLUDE "scripts/indigoplateaulobby.asm"
+INCLUDE "data/mapObjects/indigoplateaulobby.asm"
+IndigoPlateauLobbyBlocks: INCBIN "maps/indigoplateaulobby.blk"
+
+INCLUDE "data/mapHeaders/silphco4.asm"
+INCLUDE "scripts/silphco4.asm"
+INCLUDE "data/mapObjects/silphco4.asm"
+SilphCo4Blocks: INCBIN "maps/silphco4.blk"
+
+INCLUDE "data/mapHeaders/silphco5.asm"
+INCLUDE "scripts/silphco5.asm"
+INCLUDE "data/mapObjects/silphco5.asm"
+SilphCo5Blocks: INCBIN "maps/silphco5.blk"
+
+INCLUDE "data/mapHeaders/silphco6.asm"
+INCLUDE "scripts/silphco6.asm"
+INCLUDE "data/mapObjects/silphco6.asm"
+SilphCo6Blocks: INCBIN "maps/silphco6.blk"
+
+INCLUDE "engine/overworld/npc_movement.asm"
+INCLUDE "engine/overworld/doors.asm"
+INCLUDE "engine/overworld/ledges.asm"
+
+
+SECTION "bank7",ROMX,BANK[$7]
+
+INCLUDE "data/mapHeaders/cinnabarisland.asm"
+INCLUDE "data/mapObjects/cinnabarisland.asm"
+CinnabarIslandBlocks: INCBIN "maps/cinnabarisland.blk"
+
+INCLUDE "data/mapHeaders/route1.asm"
+INCLUDE "data/mapObjects/route1.asm"
+Route1Blocks: INCBIN "maps/route1.blk"
+
+UndergroundPathEntranceRoute8Blocks: INCBIN "maps/undergroundpathentranceroute8.blk"
+
+OaksLabBlocks: INCBIN "maps/oakslab.blk"
+
+Route16HouseBlocks:
+Route2HouseBlocks:
+SaffronHouse1Blocks:
+SaffronHouse2Blocks:
+VermilionHouse1Blocks:
+NameRaterBlocks:
+LavenderHouse1Blocks:
+LavenderHouse2Blocks:
+CeruleanHouse1Blocks:
+PewterHouse1Blocks:
+PewterHouse2Blocks:
+ViridianHouseBlocks: INCBIN "maps/viridianhouse.blk"
+
+CeladonMansion5Blocks:
+SchoolBlocks: INCBIN "maps/school.blk"
+
+CeruleanHouseTrashedBlocks: INCBIN "maps/ceruleanhousetrashed.blk"
+
+DiglettsCaveEntranceRoute11Blocks:
+DiglettsCaveRoute2Blocks: INCBIN "maps/diglettscaveroute2.blk"
+
+ inclang text/monster_names.asm
+
+ inclang engine/clear_save.asm
+
+INCLUDE "engine/predefs7.asm"
+
+INCLUDE "scripts/cinnabarisland.asm"
+
+INCLUDE "scripts/route1.asm"
+
+INCLUDE "data/mapHeaders/oakslab.asm"
+INCLUDE "scripts/oakslab.asm"
+INCLUDE "data/mapObjects/oakslab.asm"
+
+INCLUDE "data/mapHeaders/viridianmart.asm"
+INCLUDE "scripts/viridianmart.asm"
+INCLUDE "data/mapObjects/viridianmart.asm"
+ViridianMartBlocks: INCBIN "maps/viridianmart.blk"
+
+INCLUDE "data/mapHeaders/school.asm"
+INCLUDE "scripts/school.asm"
+INCLUDE "data/mapObjects/school.asm"
+
+INCLUDE "data/mapHeaders/viridianhouse.asm"
+INCLUDE "scripts/viridianhouse.asm"
+INCLUDE "data/mapObjects/viridianhouse.asm"
+
+INCLUDE "data/mapHeaders/pewterhouse1.asm"
+INCLUDE "scripts/pewterhouse1.asm"
+INCLUDE "data/mapObjects/pewterhouse1.asm"
+
+INCLUDE "data/mapHeaders/pewterhouse2.asm"
+INCLUDE "scripts/pewterhouse2.asm"
+INCLUDE "data/mapObjects/pewterhouse2.asm"
+
+INCLUDE "data/mapHeaders/ceruleanhousetrashed.asm"
+INCLUDE "scripts/ceruleanhousetrashed.asm"
+INCLUDE "data/mapObjects/ceruleanhousetrashed.asm"
+
+INCLUDE "data/mapHeaders/ceruleanhouse1.asm"
+INCLUDE "scripts/ceruleanhouse1.asm"
+INCLUDE "data/mapObjects/ceruleanhouse1.asm"
+
+INCLUDE "data/mapHeaders/bikeshop.asm"
+ inclang scripts/bikeshop.asm
+INCLUDE "data/mapObjects/bikeshop.asm"
+BikeShopBlocks: INCBIN "maps/bikeshop.blk"
+
+INCLUDE "data/mapHeaders/lavenderhouse1.asm"
+INCLUDE "scripts/lavenderhouse1.asm"
+INCLUDE "data/mapObjects/lavenderhouse1.asm"
+
+INCLUDE "data/mapHeaders/lavenderhouse2.asm"
+INCLUDE "scripts/lavenderhouse2.asm"
+INCLUDE "data/mapObjects/lavenderhouse2.asm"
+
+INCLUDE "data/mapHeaders/namerater.asm"
+INCLUDE "scripts/namerater.asm"
+INCLUDE "data/mapObjects/namerater.asm"
+
+INCLUDE "data/mapHeaders/vermilionhouse1.asm"
+INCLUDE "scripts/vermilionhouse1.asm"
+INCLUDE "data/mapObjects/vermilionhouse1.asm"
+
+INCLUDE "data/mapHeaders/vermiliondock.asm"
+INCLUDE "scripts/vermiliondock.asm"
+INCLUDE "data/mapObjects/vermiliondock.asm"
+VermilionDockBlocks: INCBIN "maps/vermiliondock.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion5.asm"
+INCLUDE "scripts/celadonmansion5.asm"
+INCLUDE "data/mapObjects/celadonmansion5.asm"
+
+INCLUDE "data/mapHeaders/fuchsiamart.asm"
+INCLUDE "scripts/fuchsiamart.asm"
+INCLUDE "data/mapObjects/fuchsiamart.asm"
+FuchsiaMartBlocks: INCBIN "maps/fuchsiamart.blk"
+
+INCLUDE "data/mapHeaders/saffronhouse1.asm"
+INCLUDE "scripts/saffronhouse1.asm"
+INCLUDE "data/mapObjects/saffronhouse1.asm"
+
+INCLUDE "data/mapHeaders/saffronhouse2.asm"
+INCLUDE "scripts/saffronhouse2.asm"
+INCLUDE "data/mapObjects/saffronhouse2.asm"
+
+INCLUDE "data/mapHeaders/diglettscaveroute2.asm"
+INCLUDE "scripts/diglettscaveroute2.asm"
+INCLUDE "data/mapObjects/diglettscaveroute2.asm"
+
+INCLUDE "data/mapHeaders/route2house.asm"
+INCLUDE "scripts/route2house.asm"
+INCLUDE "data/mapObjects/route2house.asm"
+
+INCLUDE "data/mapHeaders/route5gate.asm"
+INCLUDE "scripts/route5gate.asm"
+INCLUDE "data/mapObjects/route5gate.asm"
+Route5GateBlocks: INCBIN "maps/route5gate.blk"
+
+INCLUDE "data/mapHeaders/route6gate.asm"
+INCLUDE "scripts/route6gate.asm"
+INCLUDE "data/mapObjects/route6gate.asm"
+Route6GateBlocks: INCBIN "maps/route6gate.blk"
+
+INCLUDE "data/mapHeaders/route7gate.asm"
+INCLUDE "scripts/route7gate.asm"
+INCLUDE "data/mapObjects/route7gate.asm"
+Route7GateBlocks: INCBIN "maps/route7gate.blk"
+
+INCLUDE "data/mapHeaders/route8gate.asm"
+INCLUDE "scripts/route8gate.asm"
+INCLUDE "data/mapObjects/route8gate.asm"
+Route8GateBlocks: INCBIN "maps/route8gate.blk"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute8.asm"
+INCLUDE "scripts/undergroundpathentranceroute8.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute8.asm"
+
+INCLUDE "data/mapHeaders/powerplant.asm"
+INCLUDE "scripts/powerplant.asm"
+INCLUDE "data/mapObjects/powerplant.asm"
+PowerPlantBlocks: INCBIN "maps/powerplant.blk"
+
+INCLUDE "data/mapHeaders/diglettscaveroute11.asm"
+INCLUDE "scripts/diglettscaveroute11.asm"
+INCLUDE "data/mapObjects/diglettscaveroute11.asm"
+
+INCLUDE "data/mapHeaders/route16house.asm"
+INCLUDE "scripts/route16house.asm"
+INCLUDE "data/mapObjects/route16house.asm"
+
+INCLUDE "data/mapHeaders/route22gate.asm"
+INCLUDE "scripts/route22gate.asm"
+INCLUDE "data/mapObjects/route22gate.asm"
+Route22GateBlocks: INCBIN "maps/route22gate.blk"
+
+INCLUDE "data/mapHeaders/billshouse.asm"
+INCLUDE "scripts/billshouse.asm"
+INCLUDE "data/mapObjects/billshouse.asm"
+BillsHouseBlocks: INCBIN "maps/billshouse.blk"
+
+INCLUDE "engine/menu/oaks_pc.asm"
+
+ inclang engine/hidden_object_functions7.asm
+
+
+SECTION "Pics 1", ROMX, BANK[PICS_1]
+
+RhydonPicFront:: INCBIN "pic/bmon/rhydon.pic"
+RhydonPicBack:: INCBIN "pic/monback/rhydonb.pic"
+KangaskhanPicFront:: INCBIN "pic/bmon/kangaskhan.pic"
+KangaskhanPicBack:: INCBIN "pic/monback/kangaskhanb.pic"
+NidoranMPicFront:: INCBIN "pic/bmon/nidoranm.pic"
+NidoranMPicBack:: INCBIN "pic/monback/nidoranmb.pic"
+ClefairyPicFront:: INCBIN "pic/bmon/clefairy.pic"
+ClefairyPicBack:: INCBIN "pic/monback/clefairyb.pic"
+SpearowPicFront:: INCBIN "pic/bmon/spearow.pic"
+SpearowPicBack:: INCBIN "pic/monback/spearowb.pic"
+VoltorbPicFront:: INCBIN "pic/bmon/voltorb.pic"
+VoltorbPicBack:: INCBIN "pic/monback/voltorbb.pic"
+NidokingPicFront:: INCBIN "pic/bmon/nidoking.pic"
+NidokingPicBack:: INCBIN "pic/monback/nidokingb.pic"
+SlowbroPicFront:: INCBIN "pic/bmon/slowbro.pic"
+SlowbroPicBack:: INCBIN "pic/monback/slowbrob.pic"
+IvysaurPicFront:: INCBIN "pic/bmon/ivysaur.pic"
+IvysaurPicBack:: INCBIN "pic/monback/ivysaurb.pic"
+ExeggutorPicFront:: INCBIN "pic/bmon/exeggutor.pic"
+ExeggutorPicBack:: INCBIN "pic/monback/exeggutorb.pic"
+LickitungPicFront:: INCBIN "pic/bmon/lickitung.pic"
+LickitungPicBack:: INCBIN "pic/monback/lickitungb.pic"
+ExeggcutePicFront:: INCBIN "pic/bmon/exeggcute.pic"
+ExeggcutePicBack:: INCBIN "pic/monback/exeggcuteb.pic"
+GrimerPicFront:: INCBIN "pic/bmon/grimer.pic"
+GrimerPicBack:: INCBIN "pic/monback/grimerb.pic"
+GengarPicFront:: INCBIN "pic/bmon/gengar.pic"
+GengarPicBack:: INCBIN "pic/monback/gengarb.pic"
+NidoranFPicFront:: INCBIN "pic/bmon/nidoranf.pic"
+NidoranFPicBack:: INCBIN "pic/monback/nidoranfb.pic"
+NidoqueenPicFront:: INCBIN "pic/bmon/nidoqueen.pic"
+NidoqueenPicBack:: INCBIN "pic/monback/nidoqueenb.pic"
+CubonePicFront:: INCBIN "pic/bmon/cubone.pic"
+CubonePicBack:: INCBIN "pic/monback/cuboneb.pic"
+RhyhornPicFront:: INCBIN "pic/bmon/rhyhorn.pic"
+RhyhornPicBack:: INCBIN "pic/monback/rhyhornb.pic"
+LaprasPicFront:: INCBIN "pic/bmon/lapras.pic"
+LaprasPicBack:: INCBIN "pic/monback/laprasb.pic"
+ArcaninePicFront:: INCBIN "pic/bmon/arcanine.pic"
+ArcaninePicBack:: INCBIN "pic/monback/arcanineb.pic"
+GyaradosPicFront:: INCBIN "pic/bmon/gyarados.pic"
+GyaradosPicBack:: INCBIN "pic/monback/gyaradosb.pic"
+ShellderPicFront:: INCBIN "pic/bmon/shellder.pic"
+ShellderPicBack:: INCBIN "pic/monback/shellderb.pic"
+TentacoolPicFront:: INCBIN "pic/bmon/tentacool.pic"
+TentacoolPicBack:: INCBIN "pic/monback/tentacoolb.pic"
+GastlyPicFront:: INCBIN "pic/bmon/gastly.pic"
+GastlyPicBack:: INCBIN "pic/monback/gastlyb.pic"
+ScytherPicFront:: INCBIN "pic/bmon/scyther.pic"
+ScytherPicBack:: INCBIN "pic/monback/scytherb.pic"
+StaryuPicFront:: INCBIN "pic/bmon/staryu.pic"
+StaryuPicBack:: INCBIN "pic/monback/staryub.pic"
+BlastoisePicFront:: INCBIN "pic/bmon/blastoise.pic"
+BlastoisePicBack:: INCBIN "pic/monback/blastoiseb.pic"
+PinsirPicFront:: INCBIN "pic/bmon/pinsir.pic"
+PinsirPicBack:: INCBIN "pic/monback/pinsirb.pic"
+TangelaPicFront:: INCBIN "pic/bmon/tangela.pic"
+TangelaPicBack:: INCBIN "pic/monback/tangelab.pic"
+
+
+SECTION "Battle (bank 9)", ROMX, BANK[$9]
+INCLUDE "engine/battle/print_type.asm"
+ inclang engine/battle/save_trainer_name.asm
+INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm"
+
+
+SECTION "Pics 2", ROMX, BANK[PICS_2]
+
+GrowlithePicFront:: INCBIN "pic/bmon/growlithe.pic"
+GrowlithePicBack:: INCBIN "pic/monback/growlitheb.pic"
+OnixPicFront:: INCBIN "pic/bmon/onix.pic"
+OnixPicBack:: INCBIN "pic/monback/onixb.pic"
+FearowPicFront:: INCBIN "pic/bmon/fearow.pic"
+FearowPicBack:: INCBIN "pic/monback/fearowb.pic"
+PidgeyPicFront:: INCBIN "pic/bmon/pidgey.pic"
+PidgeyPicBack:: INCBIN "pic/monback/pidgeyb.pic"
+SlowpokePicFront:: INCBIN "pic/bmon/slowpoke.pic"
+SlowpokePicBack:: INCBIN "pic/monback/slowpokeb.pic"
+KadabraPicFront:: INCBIN "pic/bmon/kadabra.pic"
+KadabraPicBack:: INCBIN "pic/monback/kadabrab.pic"
+GravelerPicFront:: INCBIN "pic/bmon/graveler.pic"
+GravelerPicBack:: INCBIN "pic/monback/gravelerb.pic"
+ChanseyPicFront:: INCBIN "pic/bmon/chansey.pic"
+ChanseyPicBack:: INCBIN "pic/monback/chanseyb.pic"
+MachokePicFront:: INCBIN "pic/bmon/machoke.pic"
+MachokePicBack:: INCBIN "pic/monback/machokeb.pic"
+MrMimePicFront:: INCBIN "pic/bmon/mr.mime.pic"
+MrMimePicBack:: INCBIN "pic/monback/mr.mimeb.pic"
+HitmonleePicFront:: INCBIN "pic/bmon/hitmonlee.pic"
+HitmonleePicBack:: INCBIN "pic/monback/hitmonleeb.pic"
+HitmonchanPicFront:: INCBIN "pic/bmon/hitmonchan.pic"
+HitmonchanPicBack:: INCBIN "pic/monback/hitmonchanb.pic"
+ArbokPicFront:: INCBIN "pic/bmon/arbok.pic"
+ArbokPicBack:: INCBIN "pic/monback/arbokb.pic"
+ParasectPicFront:: INCBIN "pic/bmon/parasect.pic"
+ParasectPicBack:: INCBIN "pic/monback/parasectb.pic"
+PsyduckPicFront:: INCBIN "pic/bmon/psyduck.pic"
+PsyduckPicBack:: INCBIN "pic/monback/psyduckb.pic"
+DrowzeePicFront:: INCBIN "pic/bmon/drowzee.pic"
+DrowzeePicBack:: INCBIN "pic/monback/drowzeeb.pic"
+GolemPicFront:: INCBIN "pic/bmon/golem.pic"
+GolemPicBack:: INCBIN "pic/monback/golemb.pic"
+MagmarPicFront:: INCBIN "pic/bmon/magmar.pic"
+MagmarPicBack:: INCBIN "pic/monback/magmarb.pic"
+ElectabuzzPicFront:: INCBIN "pic/bmon/electabuzz.pic"
+ElectabuzzPicBack:: INCBIN "pic/monback/electabuzzb.pic"
+MagnetonPicFront:: INCBIN "pic/bmon/magneton.pic"
+MagnetonPicBack:: INCBIN "pic/monback/magnetonb.pic"
+KoffingPicFront:: INCBIN "pic/bmon/koffing.pic"
+KoffingPicBack:: INCBIN "pic/monback/koffingb.pic"
+MankeyPicFront:: INCBIN "pic/bmon/mankey.pic"
+MankeyPicBack:: INCBIN "pic/monback/mankeyb.pic"
+SeelPicFront:: INCBIN "pic/bmon/seel.pic"
+SeelPicBack:: INCBIN "pic/monback/seelb.pic"
+DiglettPicFront:: INCBIN "pic/bmon/diglett.pic"
+DiglettPicBack:: INCBIN "pic/monback/diglettb.pic"
+TaurosPicFront:: INCBIN "pic/bmon/tauros.pic"
+TaurosPicBack:: INCBIN "pic/monback/taurosb.pic"
+FarfetchdPicFront:: INCBIN "pic/bmon/farfetchd.pic"
+FarfetchdPicBack:: INCBIN "pic/monback/farfetchdb.pic"
+VenonatPicFront:: INCBIN "pic/bmon/venonat.pic"
+VenonatPicBack:: INCBIN "pic/monback/venonatb.pic"
+DragonitePicFront:: INCBIN "pic/bmon/dragonite.pic"
+DragonitePicBack:: INCBIN "pic/monback/dragoniteb.pic"
+DoduoPicFront:: INCBIN "pic/bmon/doduo.pic"
+DoduoPicBack:: INCBIN "pic/monback/doduob.pic"
+PoliwagPicFront:: INCBIN "pic/bmon/poliwag.pic"
+PoliwagPicBack:: INCBIN "pic/monback/poliwagb.pic"
+JynxPicFront:: INCBIN "pic/bmon/jynx.pic"
+JynxPicBack:: INCBIN "pic/monback/jynxb.pic"
+MoltresPicFront:: INCBIN "pic/bmon/moltres.pic"
+MoltresPicBack:: INCBIN "pic/monback/moltresb.pic"
+
+
+SECTION "Battle (bank A)", ROMX, BANK[$A]
+INCLUDE "engine/battle/moveEffects/leech_seed_effect.asm"
+
+
+SECTION "Pics 3", ROMX, BANK[PICS_3]
+
+ArticunoPicFront:: INCBIN "pic/bmon/articuno.pic"
+ArticunoPicBack:: INCBIN "pic/monback/articunob.pic"
+ZapdosPicFront:: INCBIN "pic/bmon/zapdos.pic"
+ZapdosPicBack:: INCBIN "pic/monback/zapdosb.pic"
+DittoPicFront:: INCBIN "pic/bmon/ditto.pic"
+DittoPicBack:: INCBIN "pic/monback/dittob.pic"
+MeowthPicFront:: INCBIN "pic/bmon/meowth.pic"
+MeowthPicBack:: INCBIN "pic/monback/meowthb.pic"
+KrabbyPicFront:: INCBIN "pic/bmon/krabby.pic"
+KrabbyPicBack:: INCBIN "pic/monback/krabbyb.pic"
+VulpixPicFront:: INCBIN "pic/bmon/vulpix.pic"
+VulpixPicBack:: INCBIN "pic/monback/vulpixb.pic"
+NinetalesPicFront:: INCBIN "pic/bmon/ninetales.pic"
+NinetalesPicBack:: INCBIN "pic/monback/ninetalesb.pic"
+PikachuPicFront:: INCBIN "pic/bmon/pikachu.pic"
+PikachuPicBack:: INCBIN "pic/monback/pikachub.pic"
+RaichuPicFront:: INCBIN "pic/bmon/raichu.pic"
+RaichuPicBack:: INCBIN "pic/monback/raichub.pic"
+DratiniPicFront:: INCBIN "pic/bmon/dratini.pic"
+DratiniPicBack:: INCBIN "pic/monback/dratinib.pic"
+DragonairPicFront:: INCBIN "pic/bmon/dragonair.pic"
+DragonairPicBack:: INCBIN "pic/monback/dragonairb.pic"
+KabutoPicFront:: INCBIN "pic/bmon/kabuto.pic"
+KabutoPicBack:: INCBIN "pic/monback/kabutob.pic"
+KabutopsPicFront:: INCBIN "pic/bmon/kabutops.pic"
+KabutopsPicBack:: INCBIN "pic/monback/kabutopsb.pic"
+HorseaPicFront:: INCBIN "pic/bmon/horsea.pic"
+HorseaPicBack:: INCBIN "pic/monback/horseab.pic"
+SeadraPicFront:: INCBIN "pic/bmon/seadra.pic"
+SeadraPicBack:: INCBIN "pic/monback/seadrab.pic"
+SandshrewPicFront:: INCBIN "pic/bmon/sandshrew.pic"
+SandshrewPicBack:: INCBIN "pic/monback/sandshrewb.pic"
+SandslashPicFront:: INCBIN "pic/bmon/sandslash.pic"
+SandslashPicBack:: INCBIN "pic/monback/sandslashb.pic"
+OmanytePicFront:: INCBIN "pic/bmon/omanyte.pic"
+OmanytePicBack:: INCBIN "pic/monback/omanyteb.pic"
+OmastarPicFront:: INCBIN "pic/bmon/omastar.pic"
+OmastarPicBack:: INCBIN "pic/monback/omastarb.pic"
+JigglypuffPicFront:: INCBIN "pic/bmon/jigglypuff.pic"
+JigglypuffPicBack:: INCBIN "pic/monback/jigglypuffb.pic"
+WigglytuffPicFront:: INCBIN "pic/bmon/wigglytuff.pic"
+WigglytuffPicBack:: INCBIN "pic/monback/wigglytuffb.pic"
+EeveePicFront:: INCBIN "pic/bmon/eevee.pic"
+EeveePicBack:: INCBIN "pic/monback/eeveeb.pic"
+FlareonPicFront:: INCBIN "pic/bmon/flareon.pic"
+FlareonPicBack:: INCBIN "pic/monback/flareonb.pic"
+JolteonPicFront:: INCBIN "pic/bmon/jolteon.pic"
+JolteonPicBack:: INCBIN "pic/monback/jolteonb.pic"
+VaporeonPicFront:: INCBIN "pic/bmon/vaporeon.pic"
+VaporeonPicBack:: INCBIN "pic/monback/vaporeonb.pic"
+MachopPicFront:: INCBIN "pic/bmon/machop.pic"
+MachopPicBack:: INCBIN "pic/monback/machopb.pic"
+ZubatPicFront:: INCBIN "pic/bmon/zubat.pic"
+ZubatPicBack:: INCBIN "pic/monback/zubatb.pic"
+EkansPicFront:: INCBIN "pic/bmon/ekans.pic"
+EkansPicBack:: INCBIN "pic/monback/ekansb.pic"
+ParasPicFront:: INCBIN "pic/bmon/paras.pic"
+ParasPicBack:: INCBIN "pic/monback/parasb.pic"
+PoliwhirlPicFront:: INCBIN "pic/bmon/poliwhirl.pic"
+PoliwhirlPicBack:: INCBIN "pic/monback/poliwhirlb.pic"
+PoliwrathPicFront:: INCBIN "pic/bmon/poliwrath.pic"
+PoliwrathPicBack:: INCBIN "pic/monback/poliwrathb.pic"
+WeedlePicFront:: INCBIN "pic/bmon/weedle.pic"
+WeedlePicBack:: INCBIN "pic/monback/weedleb.pic"
+KakunaPicFront:: INCBIN "pic/bmon/kakuna.pic"
+KakunaPicBack:: INCBIN "pic/monback/kakunab.pic"
+BeedrillPicFront:: INCBIN "pic/bmon/beedrill.pic"
+BeedrillPicBack:: INCBIN "pic/monback/beedrillb.pic"
+
+FossilKabutopsPic:: INCBIN "pic/bmon/fossilkabutops.pic"
+
+
+SECTION "Battle (bank B)", ROMX, BANK[$B]
+
+INCLUDE "engine/battle/display_effectiveness.asm"
+
+TrainerInfoTextBoxTileGraphics: INCBIN "gfx/trainer_info.2bpp"
+TrainerInfoTextBoxTileGraphicsEnd:
+BlankLeaderNames: INCBIN "gfx/blank_leader_names.2bpp"
+CircleTile: INCBIN "gfx/circle_tile.2bpp"
+BadgeNumbersTileGraphics: INCBIN "gfx/badge_numbers.2bpp"
+
+INCLUDE "engine/items/tmhm.asm"
+INCLUDE "engine/battle/scale_sprites.asm"
+INCLUDE "engine/battle/moveEffects/pay_day_effect.asm"
+INCLUDE "engine/game_corner_slots2.asm"
+
+
+SECTION "Pics 4", ROMX, BANK[PICS_4]
+
+DodrioPicFront:: INCBIN "pic/bmon/dodrio.pic"
+DodrioPicBack:: INCBIN "pic/monback/dodriob.pic"
+PrimeapePicFront:: INCBIN "pic/bmon/primeape.pic"
+PrimeapePicBack:: INCBIN "pic/monback/primeapeb.pic"
+DugtrioPicFront:: INCBIN "pic/bmon/dugtrio.pic"
+DugtrioPicBack:: INCBIN "pic/monback/dugtriob.pic"
+VenomothPicFront:: INCBIN "pic/bmon/venomoth.pic"
+VenomothPicBack:: INCBIN "pic/monback/venomothb.pic"
+DewgongPicFront:: INCBIN "pic/bmon/dewgong.pic"
+DewgongPicBack:: INCBIN "pic/monback/dewgongb.pic"
+CaterpiePicFront:: INCBIN "pic/bmon/caterpie.pic"
+CaterpiePicBack:: INCBIN "pic/monback/caterpieb.pic"
+MetapodPicFront:: INCBIN "pic/bmon/metapod.pic"
+MetapodPicBack:: INCBIN "pic/monback/metapodb.pic"
+ButterfreePicFront:: INCBIN "pic/bmon/butterfree.pic"
+ButterfreePicBack:: INCBIN "pic/monback/butterfreeb.pic"
+MachampPicFront:: INCBIN "pic/bmon/machamp.pic"
+MachampPicBack:: INCBIN "pic/monback/machampb.pic"
+GolduckPicFront:: INCBIN "pic/bmon/golduck.pic"
+GolduckPicBack:: INCBIN "pic/monback/golduckb.pic"
+HypnoPicFront:: INCBIN "pic/bmon/hypno.pic"
+HypnoPicBack:: INCBIN "pic/monback/hypnob.pic"
+GolbatPicFront:: INCBIN "pic/bmon/golbat.pic"
+GolbatPicBack:: INCBIN "pic/monback/golbatb.pic"
+MewtwoPicFront:: INCBIN "pic/bmon/mewtwo.pic"
+MewtwoPicBack:: INCBIN "pic/monback/mewtwob.pic"
+SnorlaxPicFront:: INCBIN "pic/bmon/snorlax.pic"
+SnorlaxPicBack:: INCBIN "pic/monback/snorlaxb.pic"
+MagikarpPicFront:: INCBIN "pic/bmon/magikarp.pic"
+MagikarpPicBack:: INCBIN "pic/monback/magikarpb.pic"
+MukPicFront:: INCBIN "pic/bmon/muk.pic"
+MukPicBack:: INCBIN "pic/monback/mukb.pic"
+KinglerPicFront:: INCBIN "pic/bmon/kingler.pic"
+KinglerPicBack:: INCBIN "pic/monback/kinglerb.pic"
+CloysterPicFront:: INCBIN "pic/bmon/cloyster.pic"
+CloysterPicBack:: INCBIN "pic/monback/cloysterb.pic"
+ElectrodePicFront:: INCBIN "pic/bmon/electrode.pic"
+ElectrodePicBack:: INCBIN "pic/monback/electrodeb.pic"
+ClefablePicFront:: INCBIN "pic/bmon/clefable.pic"
+ClefablePicBack:: INCBIN "pic/monback/clefableb.pic"
+WeezingPicFront:: INCBIN "pic/bmon/weezing.pic"
+WeezingPicBack:: INCBIN "pic/monback/weezingb.pic"
+PersianPicFront:: INCBIN "pic/bmon/persian.pic"
+PersianPicBack:: INCBIN "pic/monback/persianb.pic"
+MarowakPicFront:: INCBIN "pic/bmon/marowak.pic"
+MarowakPicBack:: INCBIN "pic/monback/marowakb.pic"
+HaunterPicFront:: INCBIN "pic/bmon/haunter.pic"
+HaunterPicBack:: INCBIN "pic/monback/haunterb.pic"
+AbraPicFront:: INCBIN "pic/bmon/abra.pic"
+AbraPicBack:: INCBIN "pic/monback/abrab.pic"
+AlakazamPicFront:: INCBIN "pic/bmon/alakazam.pic"
+AlakazamPicBack:: INCBIN "pic/monback/alakazamb.pic"
+PidgeottoPicFront:: INCBIN "pic/bmon/pidgeotto.pic"
+PidgeottoPicBack:: INCBIN "pic/monback/pidgeottob.pic"
+PidgeotPicFront:: INCBIN "pic/bmon/pidgeot.pic"
+PidgeotPicBack:: INCBIN "pic/monback/pidgeotb.pic"
+StarmiePicFront:: INCBIN "pic/bmon/starmie.pic"
+StarmiePicBack:: INCBIN "pic/monback/starmieb.pic"
+
+RedPicBack:: INCBIN "pic/trainer/redb.pic"
+OldManPic:: INCBIN "pic/trainer/oldman.pic"
+
+
+SECTION "Battle (bank C)", ROMX, BANK[$C]
+INCLUDE "engine/battle/moveEffects/mist_effect.asm"
+INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm"
+
+
+SECTION "Pics 5", ROMX, BANK[PICS_5]
+
+BulbasaurPicFront:: INCBIN "pic/bmon/bulbasaur.pic"
+BulbasaurPicBack:: INCBIN "pic/monback/bulbasaurb.pic"
+VenusaurPicFront:: INCBIN "pic/bmon/venusaur.pic"
+VenusaurPicBack:: INCBIN "pic/monback/venusaurb.pic"
+TentacruelPicFront:: INCBIN "pic/bmon/tentacruel.pic"
+TentacruelPicBack:: INCBIN "pic/monback/tentacruelb.pic"
+GoldeenPicFront:: INCBIN "pic/bmon/goldeen.pic"
+GoldeenPicBack:: INCBIN "pic/monback/goldeenb.pic"
+SeakingPicFront:: INCBIN "pic/bmon/seaking.pic"
+SeakingPicBack:: INCBIN "pic/monback/seakingb.pic"
+PonytaPicFront:: INCBIN "pic/bmon/ponyta.pic"
+RapidashPicFront:: INCBIN "pic/bmon/rapidash.pic"
+PonytaPicBack:: INCBIN "pic/monback/ponytab.pic"
+RapidashPicBack:: INCBIN "pic/monback/rapidashb.pic"
+RattataPicFront:: INCBIN "pic/bmon/rattata.pic"
+RattataPicBack:: INCBIN "pic/monback/rattatab.pic"
+RaticatePicFront:: INCBIN "pic/bmon/raticate.pic"
+RaticatePicBack:: INCBIN "pic/monback/raticateb.pic"
+NidorinoPicFront:: INCBIN "pic/bmon/nidorino.pic"
+NidorinoPicBack:: INCBIN "pic/monback/nidorinob.pic"
+NidorinaPicFront:: INCBIN "pic/bmon/nidorina.pic"
+NidorinaPicBack:: INCBIN "pic/monback/nidorinab.pic"
+GeodudePicFront:: INCBIN "pic/bmon/geodude.pic"
+GeodudePicBack:: INCBIN "pic/monback/geodudeb.pic"
+PorygonPicFront:: INCBIN "pic/bmon/porygon.pic"
+PorygonPicBack:: INCBIN "pic/monback/porygonb.pic"
+AerodactylPicFront:: INCBIN "pic/bmon/aerodactyl.pic"
+AerodactylPicBack:: INCBIN "pic/monback/aerodactylb.pic"
+MagnemitePicFront:: INCBIN "pic/bmon/magnemite.pic"
+MagnemitePicBack:: INCBIN "pic/monback/magnemiteb.pic"
+CharmanderPicFront:: INCBIN "pic/bmon/charmander.pic"
+CharmanderPicBack:: INCBIN "pic/monback/charmanderb.pic"
+SquirtlePicFront:: INCBIN "pic/bmon/squirtle.pic"
+SquirtlePicBack:: INCBIN "pic/monback/squirtleb.pic"
+CharmeleonPicFront:: INCBIN "pic/bmon/charmeleon.pic"
+CharmeleonPicBack:: INCBIN "pic/monback/charmeleonb.pic"
+WartortlePicFront:: INCBIN "pic/bmon/wartortle.pic"
+WartortlePicBack:: INCBIN "pic/monback/wartortleb.pic"
+CharizardPicFront:: INCBIN "pic/bmon/charizard.pic"
+CharizardPicBack:: INCBIN "pic/monback/charizardb.pic"
+FossilAerodactylPic:: INCBIN "pic/bmon/fossilaerodactyl.pic"
+GhostPic:: INCBIN "pic/other/ghost.pic"
+OddishPicFront:: INCBIN "pic/bmon/oddish.pic"
+OddishPicBack:: INCBIN "pic/monback/oddishb.pic"
+GloomPicFront:: INCBIN "pic/bmon/gloom.pic"
+GloomPicBack:: INCBIN "pic/monback/gloomb.pic"
+VileplumePicFront:: INCBIN "pic/bmon/vileplume.pic"
+VileplumePicBack:: INCBIN "pic/monback/vileplumeb.pic"
+BellsproutPicFront:: INCBIN "pic/bmon/bellsprout.pic"
+BellsproutPicBack:: INCBIN "pic/monback/bellsproutb.pic"
+WeepinbellPicFront:: INCBIN "pic/bmon/weepinbell.pic"
+WeepinbellPicBack:: INCBIN "pic/monback/weepinbellb.pic"
+VictreebelPicFront:: INCBIN "pic/bmon/victreebel.pic"
+VictreebelPicBack:: INCBIN "pic/monback/victreebelb.pic"
+
+
+SECTION "Battle (bank D)", ROMX, BANK[$D]
+
+INCLUDE "engine/titlescreen2.asm"
+ inclang engine/battle/link_battle_versus_text.asm
+ inclang engine/slot_machine.asm
+INCLUDE "engine/overworld/pewter_guys.asm"
+INCLUDE "engine/multiply_divide.asm"
+INCLUDE "engine/game_corner_slots.asm"
+
+
+SECTION "bankE",ROMX,BANK[$E]
+
+INCLUDE "data/moves.asm"
+BaseStats: INCLUDE "data/base_stats.asm"
+INCLUDE "data/cries.asm"
+INCLUDE "engine/battle/unused_stats_functions.asm"
+INCLUDE "engine/battle/scroll_draw_trainer_pic.asm"
+INCLUDE "engine/battle/trainer_ai.asm"
+INCLUDE "engine/battle/draw_hud_pokeball_gfx.asm"
+
+TradingAnimationGraphics:
+INCBIN "gfx/game_boy.2bpp"
+INCBIN "gfx/link_cable.2bpp"
+TradingAnimationGraphicsEnd:
+
+; Pokeball traveling through the link cable.
+TradingAnimationGraphics2: INCBIN "gfx/trade2.2bpp"
+TradingAnimationGraphics2End:
+
+INCLUDE "engine/evos_moves.asm"
+INCLUDE "engine/battle/moveEffects/heal_effect.asm"
+INCLUDE "engine/battle/moveEffects/transform_effect.asm"
+INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm"
+
+
+SECTION "bankF",ROMX,BANK[$F]
+
+ inclang engine/battle/core.asm
+
+
+SECTION "bank10",ROMX,BANK[$10]
+
+ inclang engine/menu/pokedex.asm
+ inclang engine/trade.asm
+INCLUDE "engine/intro.asm"
+INCLUDE "engine/trade2.asm"
+
+
+SECTION "bank11",ROMX,BANK[$11]
+
+INCLUDE "data/mapHeaders/lavendertown.asm"
+INCLUDE "data/mapObjects/lavendertown.asm"
+LavenderTownBlocks: INCBIN "maps/lavendertown.blk"
+
+ViridianPokecenterBlocks: INCBIN "maps/viridianpokecenter.blk"
+
+SafariZoneRestHouse1Blocks:
+SafariZoneRestHouse2Blocks:
+SafariZoneRestHouse3Blocks:
+SafariZoneRestHouse4Blocks: INCBIN "maps/safarizoneresthouse1.blk"
+
+INCLUDE "scripts/lavendertown.asm"
+
+INCLUDE "engine/pokedex_rating.asm"
+
+INCLUDE "data/mapHeaders/viridianpokecenter.asm"
+INCLUDE "scripts/viridianpokecenter.asm"
+INCLUDE "data/mapObjects/viridianpokecenter.asm"
+
+INCLUDE "data/mapHeaders/mansion1.asm"
+INCLUDE "scripts/mansion1.asm"
+INCLUDE "data/mapObjects/mansion1.asm"
+Mansion1Blocks: INCBIN "maps/mansion1.blk"
+
+INCLUDE "data/mapHeaders/rocktunnel1.asm"
+INCLUDE "scripts/rocktunnel1.asm"
+INCLUDE "data/mapObjects/rocktunnel1.asm"
+RockTunnel1Blocks: INCBIN "maps/rocktunnel1.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands1.asm"
+INCLUDE "scripts/seafoamislands1.asm"
+INCLUDE "data/mapObjects/seafoamislands1.asm"
+SeafoamIslands1Blocks: INCBIN "maps/seafoamislands1.blk"
+
+INCLUDE "data/mapHeaders/ssanne3.asm"
+INCLUDE "scripts/ssanne3.asm"
+INCLUDE "data/mapObjects/ssanne3.asm"
+SSAnne3Blocks: INCBIN "maps/ssanne3.blk"
+
+INCLUDE "data/mapHeaders/victoryroad3.asm"
+INCLUDE "scripts/victoryroad3.asm"
+INCLUDE "data/mapObjects/victoryroad3.asm"
+VictoryRoad3Blocks: INCBIN "maps/victoryroad3.blk"
+
+INCLUDE "data/mapHeaders/rockethideout1.asm"
+INCLUDE "scripts/rockethideout1.asm"
+INCLUDE "data/mapObjects/rockethideout1.asm"
+RocketHideout1Blocks: INCBIN "maps/rockethideout1.blk"
+
+INCLUDE "data/mapHeaders/rockethideout2.asm"
+INCLUDE "scripts/rockethideout2.asm"
+INCLUDE "data/mapObjects/rockethideout2.asm"
+RocketHideout2Blocks: INCBIN "maps/rockethideout2.blk"
+
+INCLUDE "data/mapHeaders/rockethideout3.asm"
+INCLUDE "scripts/rockethideout3.asm"
+INCLUDE "data/mapObjects/rockethideout3.asm"
+RocketHideout3Blocks: INCBIN "maps/rockethideout3.blk"
+
+INCLUDE "data/mapHeaders/rockethideout4.asm"
+INCLUDE "scripts/rockethideout4.asm"
+INCLUDE "data/mapObjects/rockethideout4.asm"
+RocketHideout4Blocks: INCBIN "maps/rockethideout4.blk"
+
+INCLUDE "data/mapHeaders/rockethideoutelevator.asm"
+INCLUDE "scripts/rockethideoutelevator.asm"
+INCLUDE "data/mapObjects/rockethideoutelevator.asm"
+RocketHideoutElevatorBlocks: INCBIN "maps/rockethideoutelevator.blk"
+
+INCLUDE "data/mapHeaders/silphcoelevator.asm"
+INCLUDE "scripts/silphcoelevator.asm"
+INCLUDE "data/mapObjects/silphcoelevator.asm"
+SilphCoElevatorBlocks: INCBIN "maps/silphcoelevator.blk"
+
+INCLUDE "data/mapHeaders/safarizoneeast.asm"
+INCLUDE "scripts/safarizoneeast.asm"
+INCLUDE "data/mapObjects/safarizoneeast.asm"
+SafariZoneEastBlocks: INCBIN "maps/safarizoneeast.blk"
+
+INCLUDE "data/mapHeaders/safarizonenorth.asm"
+INCLUDE "scripts/safarizonenorth.asm"
+INCLUDE "data/mapObjects/safarizonenorth.asm"
+SafariZoneNorthBlocks: INCBIN "maps/safarizonenorth.blk"
+
+INCLUDE "data/mapHeaders/safarizonecenter.asm"
+INCLUDE "scripts/safarizonecenter.asm"
+INCLUDE "data/mapObjects/safarizonecenter.asm"
+SafariZoneCenterBlocks: INCBIN "maps/safarizonecenter.blk"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse1.asm"
+INCLUDE "scripts/safarizoneresthouse1.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse1.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse2.asm"
+INCLUDE "scripts/safarizoneresthouse2.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse2.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse3.asm"
+INCLUDE "scripts/safarizoneresthouse3.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse3.asm"
+
+INCLUDE "data/mapHeaders/safarizoneresthouse4.asm"
+INCLUDE "scripts/safarizoneresthouse4.asm"
+INCLUDE "data/mapObjects/safarizoneresthouse4.asm"
+
+INCLUDE "data/mapHeaders/unknowndungeon2.asm"
+INCLUDE "scripts/unknowndungeon2.asm"
+INCLUDE "data/mapObjects/unknowndungeon2.asm"
+UnknownDungeon2Blocks: INCBIN "maps/unknowndungeon2.blk"
+
+INCLUDE "data/mapHeaders/unknowndungeon3.asm"
+INCLUDE "scripts/unknowndungeon3.asm"
+INCLUDE "data/mapObjects/unknowndungeon3.asm"
+UnknownDungeon3Blocks: INCBIN "maps/unknowndungeon3.blk"
+
+INCLUDE "data/mapHeaders/rocktunnel2.asm"
+INCLUDE "scripts/rocktunnel2.asm"
+INCLUDE "data/mapObjects/rocktunnel2.asm"
+RockTunnel2Blocks: INCBIN "maps/rocktunnel2.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands2.asm"
+INCLUDE "scripts/seafoamislands2.asm"
+INCLUDE "data/mapObjects/seafoamislands2.asm"
+SeafoamIslands2Blocks: INCBIN "maps/seafoamislands2.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands3.asm"
+INCLUDE "scripts/seafoamislands3.asm"
+INCLUDE "data/mapObjects/seafoamislands3.asm"
+SeafoamIslands3Blocks: INCBIN "maps/seafoamislands3.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands4.asm"
+INCLUDE "scripts/seafoamislands4.asm"
+INCLUDE "data/mapObjects/seafoamislands4.asm"
+SeafoamIslands4Blocks: INCBIN "maps/seafoamislands4.blk"
+
+INCLUDE "data/mapHeaders/seafoamislands5.asm"
+INCLUDE "scripts/seafoamislands5.asm"
+INCLUDE "data/mapObjects/seafoamislands5.asm"
+SeafoamIslands5Blocks: INCBIN "maps/seafoamislands5.blk"
+
+INCLUDE "engine/overworld/hidden_objects.asm"
+
+
+SECTION "bank12",ROMX,BANK[$12]
+
+INCLUDE "data/mapHeaders/route7.asm"
+INCLUDE "data/mapObjects/route7.asm"
+Route7Blocks: INCBIN "maps/route7.blk"
+
+CeladonPokecenterBlocks:
+RockTunnelPokecenterBlocks:
+MtMoonPokecenterBlocks: INCBIN "maps/mtmoonpokecenter.blk"
+
+Route18GateBlocks:
+Route15GateBlocks:
+Route11GateBlocks: INCBIN "maps/route11gate.blk"
+
+Route18GateUpstairsBlocks:
+Route16GateUpstairsBlocks:
+Route12GateUpstairsBlocks:
+Route15GateUpstairsBlocks:
+Route11GateUpstairsBlocks: INCBIN "maps/route11gateupstairs.blk"
+
+INCLUDE "engine/predefs12.asm"
+
+INCLUDE "scripts/route7.asm"
+
+INCLUDE "data/mapHeaders/redshouse1f.asm"
+INCLUDE "scripts/redshouse1f.asm"
+INCLUDE "data/mapObjects/redshouse1f.asm"
+RedsHouse1FBlocks: INCBIN "maps/redshouse1f.blk"
+
+INCLUDE "data/mapHeaders/celadonmart3.asm"
+INCLUDE "scripts/celadonmart3.asm"
+INCLUDE "data/mapObjects/celadonmart3.asm"
+CeladonMart3Blocks: INCBIN "maps/celadonmart3.blk"
+
+INCLUDE "data/mapHeaders/celadonmart4.asm"
+INCLUDE "scripts/celadonmart4.asm"
+INCLUDE "data/mapObjects/celadonmart4.asm"
+CeladonMart4Blocks: INCBIN "maps/celadonmart4.blk"
+
+INCLUDE "data/mapHeaders/celadonmartroof.asm"
+INCLUDE "scripts/celadonmartroof.asm"
+INCLUDE "data/mapObjects/celadonmartroof.asm"
+CeladonMartRoofBlocks: INCBIN "maps/celadonmartroof.blk"
+
+INCLUDE "data/mapHeaders/celadonmartelevator.asm"
+INCLUDE "scripts/celadonmartelevator.asm"
+INCLUDE "data/mapObjects/celadonmartelevator.asm"
+CeladonMartElevatorBlocks: INCBIN "maps/celadonmartelevator.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion1.asm"
+INCLUDE "scripts/celadonmansion1.asm"
+INCLUDE "data/mapObjects/celadonmansion1.asm"
+CeladonMansion1Blocks: INCBIN "maps/celadonmansion1.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion2.asm"
+INCLUDE "scripts/celadonmansion2.asm"
+INCLUDE "data/mapObjects/celadonmansion2.asm"
+CeladonMansion2Blocks: INCBIN "maps/celadonmansion2.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion3.asm"
+INCLUDE "scripts/celadonmansion3.asm"
+INCLUDE "data/mapObjects/celadonmansion3.asm"
+CeladonMansion3Blocks: INCBIN "maps/celadonmansion3.blk"
+
+INCLUDE "data/mapHeaders/celadonmansion4.asm"
+INCLUDE "scripts/celadonmansion4.asm"
+INCLUDE "data/mapObjects/celadonmansion4.asm"
+CeladonMansion4Blocks: INCBIN "maps/celadonmansion4.blk"
+
+INCLUDE "data/mapHeaders/celadonpokecenter.asm"
+INCLUDE "scripts/celadonpokecenter.asm"
+INCLUDE "data/mapObjects/celadonpokecenter.asm"
+
+INCLUDE "data/mapHeaders/celadongym.asm"
+ inclang scripts/celadongym.asm
+INCLUDE "data/mapObjects/celadongym.asm"
+CeladonGymBlocks: INCBIN "maps/celadongym.blk"
+
+INCLUDE "data/mapHeaders/celadongamecorner.asm"
+ inclang scripts/celadongamecorner.asm
+INCLUDE "data/mapObjects/celadongamecorner.asm"
+CeladonGameCornerBlocks: INCBIN "maps/celadongamecorner.blk"
+
+INCLUDE "data/mapHeaders/celadonmart5.asm"
+INCLUDE "scripts/celadonmart5.asm"
+INCLUDE "data/mapObjects/celadonmart5.asm"
+CeladonMart5Blocks: INCBIN "maps/celadonmart5.blk"
+
+INCLUDE "data/mapHeaders/celadonprizeroom.asm"
+INCLUDE "scripts/celadonprizeroom.asm"
+INCLUDE "data/mapObjects/celadonprizeroom.asm"
+CeladonPrizeRoomBlocks: INCBIN "maps/celadonprizeroom.blk"
+
+INCLUDE "data/mapHeaders/celadondiner.asm"
+INCLUDE "scripts/celadondiner.asm"
+INCLUDE "data/mapObjects/celadondiner.asm"
+CeladonDinerBlocks: INCBIN "maps/celadondiner.blk"
+
+INCLUDE "data/mapHeaders/celadonhouse.asm"
+INCLUDE "scripts/celadonhouse.asm"
+INCLUDE "data/mapObjects/celadonhouse.asm"
+CeladonHouseBlocks: INCBIN "maps/celadonhouse.blk"
+
+INCLUDE "data/mapHeaders/celadonhotel.asm"
+INCLUDE "scripts/celadonhotel.asm"
+INCLUDE "data/mapObjects/celadonhotel.asm"
+CeladonHotelBlocks: INCBIN "maps/celadonhotel.blk"
+
+INCLUDE "data/mapHeaders/mtmoonpokecenter.asm"
+INCLUDE "scripts/mtmoonpokecenter.asm"
+INCLUDE "data/mapObjects/mtmoonpokecenter.asm"
+
+INCLUDE "data/mapHeaders/rocktunnelpokecenter.asm"
+INCLUDE "scripts/rocktunnelpokecenter.asm"
+INCLUDE "data/mapObjects/rocktunnelpokecenter.asm"
+
+INCLUDE "data/mapHeaders/route11gate.asm"
+INCLUDE "scripts/route11gate.asm"
+INCLUDE "data/mapObjects/route11gate.asm"
+
+INCLUDE "data/mapHeaders/route11gateupstairs.asm"
+INCLUDE "scripts/route11gateupstairs.asm"
+INCLUDE "data/mapObjects/route11gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route12gate.asm"
+INCLUDE "scripts/route12gate.asm"
+INCLUDE "data/mapObjects/route12gate.asm"
+Route12GateBlocks: INCBIN "maps/route12gate.blk"
+
+INCLUDE "data/mapHeaders/route12gateupstairs.asm"
+INCLUDE "scripts/route12gateupstairs.asm"
+INCLUDE "data/mapObjects/route12gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route15gate.asm"
+INCLUDE "scripts/route15gate.asm"
+INCLUDE "data/mapObjects/route15gate.asm"
+
+INCLUDE "data/mapHeaders/route15gateupstairs.asm"
+INCLUDE "scripts/route15gateupstairs.asm"
+INCLUDE "data/mapObjects/route15gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route16gate.asm"
+INCLUDE "scripts/route16gate.asm"
+INCLUDE "data/mapObjects/route16gate.asm"
+Route16GateBlocks: INCBIN "maps/route16gate.blk"
+
+INCLUDE "data/mapHeaders/route16gateupstairs.asm"
+INCLUDE "scripts/route16gateupstairs.asm"
+INCLUDE "data/mapObjects/route16gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/route18gate.asm"
+INCLUDE "scripts/route18gate.asm"
+INCLUDE "data/mapObjects/route18gate.asm"
+
+INCLUDE "data/mapHeaders/route18gateupstairs.asm"
+INCLUDE "scripts/route18gateupstairs.asm"
+INCLUDE "data/mapObjects/route18gateupstairs.asm"
+
+INCLUDE "data/mapHeaders/mtmoon1.asm"
+INCLUDE "scripts/mtmoon1.asm"
+INCLUDE "data/mapObjects/mtmoon1.asm"
+MtMoon1Blocks: INCBIN "maps/mtmoon1.blk"
+
+INCLUDE "data/mapHeaders/mtmoon3.asm"
+INCLUDE "scripts/mtmoon3.asm"
+INCLUDE "data/mapObjects/mtmoon3.asm"
+MtMoon3Blocks: INCBIN "maps/mtmoon3.blk"
+
+INCLUDE "data/mapHeaders/safarizonewest.asm"
+INCLUDE "scripts/safarizonewest.asm"
+INCLUDE "data/mapObjects/safarizonewest.asm"
+SafariZoneWestBlocks: INCBIN "maps/safarizonewest.blk"
+
+INCLUDE "data/mapHeaders/safarizonesecrethouse.asm"
+INCLUDE "scripts/safarizonesecrethouse.asm"
+INCLUDE "data/mapObjects/safarizonesecrethouse.asm"
+SafariZoneSecretHouseBlocks: INCBIN "maps/safarizonesecrethouse.blk"
+
+
+SECTION "bank13",ROMX,BANK[$13]
+
+TrainerPics::
+YoungsterPic:: INCBIN "pic/trainer/youngster.pic"
+BugCatcherPic:: INCBIN "pic/trainer/bugcatcher.pic"
+LassPic:: INCBIN "pic/trainer/lass.pic"
+SailorPic:: INCBIN "pic/trainer/sailor.pic"
+JrTrainerMPic:: INCBIN "pic/trainer/jr.trainerm.pic"
+JrTrainerFPic:: INCBIN "pic/trainer/jr.trainerf.pic"
+PokemaniacPic:: INCBIN "pic/trainer/pokemaniac.pic"
+SuperNerdPic:: INCBIN "pic/trainer/supernerd.pic"
+HikerPic:: INCBIN "pic/trainer/hiker.pic"
+BikerPic:: INCBIN "pic/trainer/biker.pic"
+BurglarPic:: INCBIN "pic/trainer/burglar.pic"
+EngineerPic:: INCBIN "pic/trainer/engineer.pic"
+FisherPic:: INCBIN "pic/trainer/fisher.pic"
+SwimmerPic:: INCBIN "pic/trainer/swimmer.pic"
+CueBallPic:: INCBIN "pic/trainer/cueball.pic"
+GamblerPic:: INCBIN "pic/trainer/gambler.pic"
+BeautyPic:: INCBIN "pic/trainer/beauty.pic"
+PsychicPic:: INCBIN "pic/trainer/psychic.pic"
+RockerPic:: INCBIN "pic/trainer/rocker.pic"
+JugglerPic:: INCBIN "pic/trainer/juggler.pic"
+TamerPic:: INCBIN "pic/trainer/tamer.pic"
+BirdKeeperPic:: INCBIN "pic/trainer/birdkeeper.pic"
+BlackbeltPic:: INCBIN "pic/trainer/blackbelt.pic"
+Rival1Pic:: INCBIN "pic/trainer/rival1.pic"
+ProfOakPic:: INCBIN "pic/trainer/prof.oak.pic"
+ChiefPic::
+ScientistPic:: INCBIN "pic/trainer/scientist.pic"
+GiovanniPic:: INCBIN "pic/trainer/giovanni.pic"
+RocketPic:: INCBIN "pic/trainer/rocket.pic"
+CooltrainerMPic:: INCBIN "pic/trainer/cooltrainerm.pic"
+CooltrainerFPic:: INCBIN "pic/trainer/cooltrainerf.pic"
+BrunoPic:: INCBIN "pic/trainer/bruno.pic"
+BrockPic:: INCBIN "pic/trainer/brock.pic"
+MistyPic:: INCBIN "pic/trainer/misty.pic"
+LtSurgePic:: INCBIN "pic/trainer/lt.surge.pic"
+ErikaPic:: INCBIN "pic/trainer/erika.pic"
+KogaPic:: INCBIN "pic/trainer/koga.pic"
+BlainePic:: INCBIN "pic/trainer/blaine.pic"
+SabrinaPic:: INCBIN "pic/trainer/sabrina.pic"
+GentlemanPic:: INCBIN "pic/trainer/gentleman.pic"
+Rival2Pic:: INCBIN "pic/trainer/rival2.pic"
+Rival3Pic:: INCBIN "pic/trainer/rival3.pic"
+LoreleiPic:: INCBIN "pic/trainer/lorelei.pic"
+ChannelerPic:: INCBIN "pic/trainer/channeler.pic"
+AgathaPic:: INCBIN "pic/trainer/agatha.pic"
+LancePic:: INCBIN "pic/trainer/lance.pic"
+
+INCLUDE "data/mapHeaders/tradecenter.asm"
+INCLUDE "scripts/tradecenter.asm"
+INCLUDE "data/mapObjects/tradecenter.asm"
+TradeCenterBlocks: INCBIN "maps/tradecenter.blk"
+
+INCLUDE "data/mapHeaders/colosseum.asm"
+INCLUDE "scripts/colosseum.asm"
+INCLUDE "data/mapObjects/colosseum.asm"
+ColosseumBlocks: INCBIN "maps/colosseum.blk"
+
+INCLUDE "engine/give_pokemon.asm"
+
+INCLUDE "engine/predefs.asm"
+
+
+SECTION "bank14",ROMX,BANK[$14]
+
+INCLUDE "data/mapHeaders/route22.asm"
+INCLUDE "data/mapObjects/route22.asm"
+Route22Blocks: INCBIN "maps/route22.blk"
+
+INCLUDE "data/mapHeaders/route20.asm"
+INCLUDE "data/mapObjects/route20.asm"
+Route20Blocks: INCBIN "maps/route20.blk"
+
+INCLUDE "data/mapHeaders/route23.asm"
+INCLUDE "data/mapObjects/route23.asm"
+Route23Blocks: INCBIN "maps/route23.blk"
+
+INCLUDE "data/mapHeaders/route24.asm"
+INCLUDE "data/mapObjects/route24.asm"
+Route24Blocks: INCBIN "maps/route24.blk"
+
+INCLUDE "data/mapHeaders/route25.asm"
+INCLUDE "data/mapObjects/route25.asm"
+Route25Blocks: INCBIN "maps/route25.blk"
+
+INCLUDE "data/mapHeaders/indigoplateau.asm"
+INCLUDE "scripts/indigoplateau.asm"
+INCLUDE "data/mapObjects/indigoplateau.asm"
+IndigoPlateauBlocks: INCBIN "maps/indigoplateau.blk"
+
+INCLUDE "data/mapHeaders/saffroncity.asm"
+INCLUDE "data/mapObjects/saffroncity.asm"
+SaffronCityBlocks: INCBIN "maps/saffroncity.blk"
+INCLUDE "scripts/saffroncity.asm"
+
+INCLUDE "scripts/route20.asm"
+INCLUDE "scripts/route22.asm"
+ inclang scripts/route23.asm
+INCLUDE "scripts/route24.asm"
+INCLUDE "scripts/route25.asm"
+
+INCLUDE "data/mapHeaders/victoryroad2.asm"
+INCLUDE "scripts/victoryroad2.asm"
+INCLUDE "data/mapObjects/victoryroad2.asm"
+VictoryRoad2Blocks: INCBIN "maps/victoryroad2.blk"
+
+INCLUDE "data/mapHeaders/mtmoon2.asm"
+INCLUDE "scripts/mtmoon2.asm"
+INCLUDE "data/mapObjects/mtmoon2.asm"
+MtMoon2Blocks: INCBIN "maps/mtmoon2.blk"
+
+INCLUDE "data/mapHeaders/silphco7.asm"
+INCLUDE "scripts/silphco7.asm"
+INCLUDE "data/mapObjects/silphco7.asm"
+SilphCo7Blocks: INCBIN "maps/silphco7.blk"
+
+INCLUDE "data/mapHeaders/mansion2.asm"
+INCLUDE "scripts/mansion2.asm"
+INCLUDE "data/mapObjects/mansion2.asm"
+Mansion2Blocks: INCBIN "maps/mansion2.blk"
+
+INCLUDE "data/mapHeaders/mansion3.asm"
+INCLUDE "scripts/mansion3.asm"
+INCLUDE "data/mapObjects/mansion3.asm"
+Mansion3Blocks: INCBIN "maps/mansion3.blk"
+
+INCLUDE "data/mapHeaders/mansion4.asm"
+INCLUDE "scripts/mansion4.asm"
+INCLUDE "data/mapObjects/mansion4.asm"
+Mansion4Blocks: INCBIN "maps/mansion4.blk"
+
+INCLUDE "engine/battle/init_battle_variables.asm"
+INCLUDE "engine/battle/moveEffects/paralyze_effect.asm"
+
+INCLUDE "engine/overworld/card_key.asm"
+
+ inclang engine/menu/prize_menu.asm
+
+INCLUDE "engine/hidden_object_functions14.asm"
+
+
+SECTION "bank15",ROMX,BANK[$15]
+
+INCLUDE "data/mapHeaders/route2.asm"
+INCLUDE "data/mapObjects/route2.asm"
+Route2Blocks: INCBIN "maps/route2.blk"
+
+INCLUDE "data/mapHeaders/route3.asm"
+INCLUDE "data/mapObjects/route3.asm"
+Route3Blocks: INCBIN "maps/route3.blk"
+
+INCLUDE "data/mapHeaders/route4.asm"
+INCLUDE "data/mapObjects/route4.asm"
+Route4Blocks: INCBIN "maps/route4.blk"
+
+INCLUDE "data/mapHeaders/route5.asm"
+INCLUDE "data/mapObjects/route5.asm"
+Route5Blocks: INCBIN "maps/route5.blk"
+
+INCLUDE "data/mapHeaders/route9.asm"
+INCLUDE "data/mapObjects/route9.asm"
+Route9Blocks: INCBIN "maps/route9.blk"
+
+INCLUDE "data/mapHeaders/route13.asm"
+INCLUDE "data/mapObjects/route13.asm"
+Route13Blocks: INCBIN "maps/route13.blk"
+
+INCLUDE "data/mapHeaders/route14.asm"
+INCLUDE "data/mapObjects/route14.asm"
+Route14Blocks: INCBIN "maps/route14.blk"
+
+INCLUDE "data/mapHeaders/route17.asm"
+INCLUDE "data/mapObjects/route17.asm"
+Route17Blocks: INCBIN "maps/route17.blk"
+
+INCLUDE "data/mapHeaders/route19.asm"
+INCLUDE "data/mapObjects/route19.asm"
+Route19Blocks: INCBIN "maps/route19.blk"
+
+INCLUDE "data/mapHeaders/route21.asm"
+INCLUDE "data/mapObjects/route21.asm"
+Route21Blocks: INCBIN "maps/route21.blk"
+
+VermilionHouse2Blocks:
+Route12HouseBlocks:
+DayCareMBlocks: INCBIN "maps/daycarem.blk"
+
+FuchsiaHouse3Blocks: INCBIN "maps/fuchsiahouse3.blk"
+
+INCLUDE "engine/battle/experience.asm"
+
+INCLUDE "scripts/route2.asm"
+INCLUDE "scripts/route3.asm"
+INCLUDE "scripts/route4.asm"
+INCLUDE "scripts/route5.asm"
+INCLUDE "scripts/route9.asm"
+INCLUDE "scripts/route13.asm"
+INCLUDE "scripts/route14.asm"
+INCLUDE "scripts/route17.asm"
+INCLUDE "scripts/route19.asm"
+INCLUDE "scripts/route21.asm"
+
+INCLUDE "data/mapHeaders/vermilionhouse2.asm"
+INCLUDE "scripts/vermilionhouse2.asm"
+INCLUDE "data/mapObjects/vermilionhouse2.asm"
+
+INCLUDE "data/mapHeaders/celadonmart2.asm"
+INCLUDE "scripts/celadonmart2.asm"
+INCLUDE "data/mapObjects/celadonmart2.asm"
+CeladonMart2Blocks: INCBIN "maps/celadonmart2.blk"
+
+INCLUDE "data/mapHeaders/fuchsiahouse3.asm"
+INCLUDE "scripts/fuchsiahouse3.asm"
+INCLUDE "data/mapObjects/fuchsiahouse3.asm"
+
+INCLUDE "data/mapHeaders/daycarem.asm"
+INCLUDE "scripts/daycarem.asm"
+INCLUDE "data/mapObjects/daycarem.asm"
+
+INCLUDE "data/mapHeaders/route12house.asm"
+INCLUDE "scripts/route12house.asm"
+INCLUDE "data/mapObjects/route12house.asm"
+
+INCLUDE "data/mapHeaders/silphco8.asm"
+INCLUDE "scripts/silphco8.asm"
+INCLUDE "data/mapObjects/silphco8.asm"
+SilphCo8Blocks: INCBIN "maps/silphco8.blk"
+
+ inclang engine/menu/diploma.asm
+
+INCLUDE "engine/overworld/trainers.asm"
+
+
+SECTION "bank16",ROMX,BANK[$16]
+
+INCLUDE "data/mapHeaders/route6.asm"
+INCLUDE "data/mapObjects/route6.asm"
+Route6Blocks: INCBIN "maps/route6.blk"
+
+INCLUDE "data/mapHeaders/route8.asm"
+INCLUDE "data/mapObjects/route8.asm"
+Route8Blocks: INCBIN "maps/route8.blk"
+
+INCLUDE "data/mapHeaders/route10.asm"
+INCLUDE "data/mapObjects/route10.asm"
+Route10Blocks: INCBIN "maps/route10.blk"
+
+INCLUDE "data/mapHeaders/route11.asm"
+INCLUDE "data/mapObjects/route11.asm"
+Route11Blocks: INCBIN "maps/route11.blk"
+
+INCLUDE "data/mapHeaders/route12.asm"
+INCLUDE "data/mapObjects/route12.asm"
+Route12Blocks: INCBIN "maps/route12.blk"
+
+INCLUDE "data/mapHeaders/route15.asm"
+INCLUDE "data/mapObjects/route15.asm"
+Route15Blocks: INCBIN "maps/route15.blk"
+
+INCLUDE "data/mapHeaders/route16.asm"
+INCLUDE "data/mapObjects/route16.asm"
+Route16Blocks: INCBIN "maps/route16.blk"
+
+INCLUDE "data/mapHeaders/route18.asm"
+INCLUDE "data/mapObjects/route18.asm"
+Route18Blocks: INCBIN "maps/route18.blk"
+
+ INCBIN "maps/unusedblocks58d7d.blk"
+
+INCLUDE "engine/battle/common_text.asm"
+
+INCLUDE "engine/experience.asm"
+
+INCLUDE "engine/overworld/oaks_aide.asm"
+
+INCLUDE "scripts/route6.asm"
+INCLUDE "scripts/route8.asm"
+INCLUDE "scripts/route10.asm"
+INCLUDE "scripts/route11.asm"
+INCLUDE "scripts/route12.asm"
+INCLUDE "scripts/route15.asm"
+INCLUDE "scripts/route16.asm"
+INCLUDE "scripts/route18.asm"
+
+INCLUDE "data/mapHeaders/fanclub.asm"
+INCLUDE "scripts/fanclub.asm"
+INCLUDE "data/mapObjects/fanclub.asm"
+FanClubBlocks: INCBIN "maps/fanclub.blk"
+
+INCLUDE "data/mapHeaders/silphco2.asm"
+INCLUDE "scripts/silphco2.asm"
+INCLUDE "data/mapObjects/silphco2.asm"
+SilphCo2Blocks: INCBIN "maps/silphco2.blk"
+
+INCLUDE "data/mapHeaders/silphco3.asm"
+INCLUDE "scripts/silphco3.asm"
+INCLUDE "data/mapObjects/silphco3.asm"
+SilphCo3Blocks: INCBIN "maps/silphco3.blk"
+
+INCLUDE "data/mapHeaders/silphco10.asm"
+INCLUDE "scripts/silphco10.asm"
+INCLUDE "data/mapObjects/silphco10.asm"
+SilphCo10Blocks: INCBIN "maps/silphco10.blk"
+
+INCLUDE "data/mapHeaders/lance.asm"
+INCLUDE "scripts/lance.asm"
+INCLUDE "data/mapObjects/lance.asm"
+LanceBlocks: INCBIN "maps/lance.blk"
+
+INCLUDE "data/mapHeaders/halloffameroom.asm"
+INCLUDE "scripts/halloffameroom.asm"
+INCLUDE "data/mapObjects/halloffameroom.asm"
+HallofFameRoomBlocks: INCBIN "maps/halloffameroom.blk"
+
+INCLUDE "engine/overworld/saffron_guards.asm"
+
+
+SECTION "bank17",ROMX,BANK[$17]
+
+SaffronMartBlocks:
+LavenderMartBlocks:
+CeruleanMartBlocks:
+VermilionMartBlocks: INCBIN "maps/vermilionmart.blk"
+
+CopycatsHouse2FBlocks:
+RedsHouse2FBlocks: INCBIN "maps/redshouse2f.blk"
+
+Museum1FBlocks: INCBIN "maps/museum1f.blk"
+
+Museum2FBlocks: INCBIN "maps/museum2f.blk"
+
+SaffronPokecenterBlocks:
+VermilionPokecenterBlocks:
+LavenderPokecenterBlocks:
+PewterPokecenterBlocks: INCBIN "maps/pewterpokecenter.blk"
+
+UndergroundPathEntranceRoute7Blocks:
+UndergroundPathEntranceRoute7CopyBlocks:
+UndergroundPathEntranceRoute6Blocks:
+UndergroundPathEntranceRoute5Blocks: INCBIN "maps/undergroundpathentranceroute5.blk"
+
+Route2GateBlocks:
+ViridianForestEntranceBlocks:
+ViridianForestExitBlocks: INCBIN "maps/viridianforestexit.blk"
+
+INCLUDE "data/mapHeaders/redshouse2f.asm"
+INCLUDE "scripts/redshouse2f.asm"
+INCLUDE "data/mapObjects/redshouse2f.asm"
+
+INCLUDE "engine/predefs17.asm"
+
+INCLUDE "data/mapHeaders/museum1f.asm"
+INCLUDE "scripts/museum1f.asm"
+INCLUDE "data/mapObjects/museum1f.asm"
+
+INCLUDE "data/mapHeaders/museum2f.asm"
+INCLUDE "scripts/museum2f.asm"
+INCLUDE "data/mapObjects/museum2f.asm"
+
+INCLUDE "data/mapHeaders/pewtergym.asm"
+ inclang scripts/pewtergym.asm
+INCLUDE "data/mapObjects/pewtergym.asm"
+PewterGymBlocks: INCBIN "maps/pewtergym.blk"
+
+INCLUDE "data/mapHeaders/pewterpokecenter.asm"
+INCLUDE "scripts/pewterpokecenter.asm"
+INCLUDE "data/mapObjects/pewterpokecenter.asm"
+
+INCLUDE "data/mapHeaders/ceruleanpokecenter.asm"
+INCLUDE "scripts/ceruleanpokecenter.asm"
+INCLUDE "data/mapObjects/ceruleanpokecenter.asm"
+CeruleanPokecenterBlocks: INCBIN "maps/ceruleanpokecenter.blk"
+
+INCLUDE "data/mapHeaders/ceruleangym.asm"
+ inclang scripts/ceruleangym.asm
+INCLUDE "data/mapObjects/ceruleangym.asm"
+CeruleanGymBlocks: INCBIN "maps/ceruleangym.blk"
+
+INCLUDE "data/mapHeaders/ceruleanmart.asm"
+INCLUDE "scripts/ceruleanmart.asm"
+INCLUDE "data/mapObjects/ceruleanmart.asm"
+
+INCLUDE "data/mapHeaders/lavenderpokecenter.asm"
+INCLUDE "scripts/lavenderpokecenter.asm"
+INCLUDE "data/mapObjects/lavenderpokecenter.asm"
+
+INCLUDE "data/mapHeaders/lavendermart.asm"
+INCLUDE "scripts/lavendermart.asm"
+INCLUDE "data/mapObjects/lavendermart.asm"
+
+INCLUDE "data/mapHeaders/vermilionpokecenter.asm"
+INCLUDE "scripts/vermilionpokecenter.asm"
+INCLUDE "data/mapObjects/vermilionpokecenter.asm"
+
+INCLUDE "data/mapHeaders/vermilionmart.asm"
+INCLUDE "scripts/vermilionmart.asm"
+INCLUDE "data/mapObjects/vermilionmart.asm"
+
+INCLUDE "data/mapHeaders/vermiliongym.asm"
+ inclang scripts/vermiliongym.asm
+INCLUDE "data/mapObjects/vermiliongym.asm"
+VermilionGymBlocks: INCBIN "maps/vermiliongym.blk"
+
+INCLUDE "data/mapHeaders/copycatshouse2f.asm"
+INCLUDE "scripts/copycatshouse2f.asm"
+INCLUDE "data/mapObjects/copycatshouse2f.asm"
+
+INCLUDE "data/mapHeaders/fightingdojo.asm"
+INCLUDE "scripts/fightingdojo.asm"
+INCLUDE "data/mapObjects/fightingdojo.asm"
+FightingDojoBlocks: INCBIN "maps/fightingdojo.blk"
+
+INCLUDE "data/mapHeaders/saffrongym.asm"
+ inclang scripts/saffrongym.asm
+INCLUDE "data/mapObjects/saffrongym.asm"
+SaffronGymBlocks: INCBIN "maps/saffrongym.blk"
+
+INCLUDE "data/mapHeaders/saffronmart.asm"
+INCLUDE "scripts/saffronmart.asm"
+INCLUDE "data/mapObjects/saffronmart.asm"
+
+INCLUDE "data/mapHeaders/silphco1.asm"
+INCLUDE "scripts/silphco1.asm"
+INCLUDE "data/mapObjects/silphco1.asm"
+SilphCo1Blocks: INCBIN "maps/silphco1.blk"
+
+INCLUDE "data/mapHeaders/saffronpokecenter.asm"
+INCLUDE "scripts/saffronpokecenter.asm"
+INCLUDE "data/mapObjects/saffronpokecenter.asm"
+
+INCLUDE "data/mapHeaders/viridianforestexit.asm"
+INCLUDE "scripts/viridianforestexit.asm"
+INCLUDE "data/mapObjects/viridianforestexit.asm"
+
+INCLUDE "data/mapHeaders/route2gate.asm"
+INCLUDE "scripts/route2gate.asm"
+INCLUDE "data/mapObjects/route2gate.asm"
+
+INCLUDE "data/mapHeaders/viridianforestentrance.asm"
+INCLUDE "scripts/viridianforestentrance.asm"
+INCLUDE "data/mapObjects/viridianforestentrance.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute5.asm"
+INCLUDE "scripts/undergroundpathentranceroute5.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute5.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute6.asm"
+INCLUDE "scripts/undergroundpathentranceroute6.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute6.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute7.asm"
+INCLUDE "scripts/undergroundpathentranceroute7.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute7.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathentranceroute7copy.asm"
+INCLUDE "scripts/undergroundpathentranceroute7copy.asm"
+INCLUDE "data/mapObjects/undergroundpathentranceroute7copy.asm"
+
+INCLUDE "data/mapHeaders/silphco9.asm"
+INCLUDE "scripts/silphco9.asm"
+INCLUDE "data/mapObjects/silphco9.asm"
+SilphCo9Blocks: INCBIN "maps/silphco9.blk"
+
+INCLUDE "data/mapHeaders/victoryroad1.asm"
+INCLUDE "scripts/victoryroad1.asm"
+INCLUDE "data/mapObjects/victoryroad1.asm"
+VictoryRoad1Blocks: INCBIN "maps/victoryroad1.blk"
+
+INCLUDE "engine/predefs17_2.asm"
+
+ inclang engine/hidden_object_functions17.asm
+
+
+SECTION "bank18",ROMX,BANK[$18]
+
+ViridianForestBlocks: INCBIN "maps/viridianforest.blk"
+UndergroundPathNSBlocks: INCBIN "maps/undergroundpathns.blk"
+UndergroundPathWEBlocks: INCBIN "maps/undergroundpathwe.blk"
+
+ INCBIN "maps/unusedblocks60258.blk"
+
+SSAnne10Blocks:
+SSAnne9Blocks: INCBIN "maps/ssanne9.blk"
+
+INCLUDE "data/mapHeaders/pokemontower1.asm"
+INCLUDE "scripts/pokemontower1.asm"
+INCLUDE "data/mapObjects/pokemontower1.asm"
+PokemonTower1Blocks: INCBIN "maps/pokemontower1.blk"
+
+INCLUDE "data/mapHeaders/pokemontower2.asm"
+INCLUDE "scripts/pokemontower2.asm"
+INCLUDE "data/mapObjects/pokemontower2.asm"
+PokemonTower2Blocks: INCBIN "maps/pokemontower2.blk"
+
+INCLUDE "data/mapHeaders/pokemontower3.asm"
+INCLUDE "scripts/pokemontower3.asm"
+INCLUDE "data/mapObjects/pokemontower3.asm"
+PokemonTower3Blocks: INCBIN "maps/pokemontower3.blk"
+
+INCLUDE "data/mapHeaders/pokemontower4.asm"
+INCLUDE "scripts/pokemontower4.asm"
+INCLUDE "data/mapObjects/pokemontower4.asm"
+PokemonTower4Blocks: INCBIN "maps/pokemontower4.blk"
+
+INCLUDE "data/mapHeaders/pokemontower5.asm"
+INCLUDE "scripts/pokemontower5.asm"
+INCLUDE "data/mapObjects/pokemontower5.asm"
+PokemonTower5Blocks: INCBIN "maps/pokemontower5.blk"
+
+INCLUDE "data/mapHeaders/pokemontower6.asm"
+INCLUDE "scripts/pokemontower6.asm"
+INCLUDE "data/mapObjects/pokemontower6.asm"
+PokemonTower6Blocks: INCBIN "maps/pokemontower6.blk"
+
+ INCBIN "maps/unusedblocks60cef.blk"
+
+INCLUDE "data/mapHeaders/pokemontower7.asm"
+INCLUDE "scripts/pokemontower7.asm"
+INCLUDE "data/mapObjects/pokemontower7.asm"
+PokemonTower7Blocks: INCBIN "maps/pokemontower7.blk"
+
+INCLUDE "data/mapHeaders/celadonmart1.asm"
+INCLUDE "scripts/celadonmart1.asm"
+INCLUDE "data/mapObjects/celadonmart1.asm"
+CeladonMart1Blocks: INCBIN "maps/celadonmart1.blk"
+
+INCLUDE "engine/overworld/cinnabar_lab.asm"
+
+INCLUDE "data/mapHeaders/viridianforest.asm"
+INCLUDE "scripts/viridianforest.asm"
+INCLUDE "data/mapObjects/viridianforest.asm"
+
+INCLUDE "data/mapHeaders/ssanne1.asm"
+INCLUDE "scripts/ssanne1.asm"
+INCLUDE "data/mapObjects/ssanne1.asm"
+SSAnne1Blocks: INCBIN "maps/ssanne1.blk"
+
+INCLUDE "data/mapHeaders/ssanne2.asm"
+INCLUDE "scripts/ssanne2.asm"
+INCLUDE "data/mapObjects/ssanne2.asm"
+SSAnne2Blocks: INCBIN "maps/ssanne2.blk"
+
+INCLUDE "data/mapHeaders/ssanne4.asm"
+INCLUDE "scripts/ssanne4.asm"
+INCLUDE "data/mapObjects/ssanne4.asm"
+SSAnne4Blocks: INCBIN "maps/ssanne4.blk"
+
+INCLUDE "data/mapHeaders/ssanne5.asm"
+INCLUDE "scripts/ssanne5.asm"
+INCLUDE "data/mapObjects/ssanne5.asm"
+SSAnne5Blocks: INCBIN "maps/ssanne5.blk"
+
+INCLUDE "data/mapHeaders/ssanne6.asm"
+INCLUDE "scripts/ssanne6.asm"
+INCLUDE "data/mapObjects/ssanne6.asm"
+SSAnne6Blocks: INCBIN "maps/ssanne6.blk"
+
+INCLUDE "data/mapHeaders/ssanne7.asm"
+INCLUDE "scripts/ssanne7.asm"
+INCLUDE "data/mapObjects/ssanne7.asm"
+SSAnne7Blocks: INCBIN "maps/ssanne7.blk"
+
+INCLUDE "data/mapHeaders/ssanne8.asm"
+INCLUDE "scripts/ssanne8.asm"
+INCLUDE "data/mapObjects/ssanne8.asm"
+SSAnne8Blocks: INCBIN "maps/ssanne8.blk"
+
+INCLUDE "data/mapHeaders/ssanne9.asm"
+INCLUDE "scripts/ssanne9.asm"
+INCLUDE "data/mapObjects/ssanne9.asm"
+
+INCLUDE "data/mapHeaders/ssanne10.asm"
+INCLUDE "scripts/ssanne10.asm"
+INCLUDE "data/mapObjects/ssanne10.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathns.asm"
+INCLUDE "scripts/undergroundpathns.asm"
+INCLUDE "data/mapObjects/undergroundpathns.asm"
+
+INCLUDE "data/mapHeaders/undergroundpathwe.asm"
+INCLUDE "scripts/undergroundpathwe.asm"
+INCLUDE "data/mapObjects/undergroundpathwe.asm"
+
+INCLUDE "data/mapHeaders/diglettscave.asm"
+INCLUDE "scripts/diglettscave.asm"
+INCLUDE "data/mapObjects/diglettscave.asm"
+DiglettsCaveBlocks: INCBIN "maps/diglettscave.blk"
+
+INCLUDE "data/mapHeaders/silphco11.asm"
+INCLUDE "scripts/silphco11.asm"
+INCLUDE "data/mapObjects/silphco11.asm"
+SilphCo11Blocks: INCBIN "maps/silphco11.blk"
+
+INCLUDE "engine/hidden_object_functions18.asm"
+
+
+SECTION "bank19",ROMX,BANK[$19]
+
+Overworld_GFX: binlang gfx/tilesets/overworld.2bpp
+Overworld_Block: INCBIN "gfx/blocksets/overworld.bst"
+
+RedsHouse1_GFX:
+RedsHouse2_GFX: INCBIN "gfx/tilesets/reds_house.2bpp"
+ ds 16
+RedsHouse1_Block:
+RedsHouse2_Block: INCBIN "gfx/blocksets/reds_house.bst"
+
+House_GFX: INCBIN "gfx/tilesets/house.2bpp"
+House_Block: INCBIN "gfx/blocksets/house.bst"
+Mansion_GFX: INCBIN "gfx/tilesets/mansion.2bpp"
+Mansion_Block: INCBIN "gfx/blocksets/mansion.bst"
+ShipPort_GFX: INCBIN "gfx/tilesets/ship_port.2bpp"
+ShipPort_Block: INCBIN "gfx/blocksets/ship_port.bst"
+Interior_GFX: INCBIN "gfx/tilesets/interior.2bpp"
+Interior_Block: INCBIN "gfx/blocksets/interior.bst"
+Plateau_GFX: INCBIN "gfx/tilesets/plateau.2bpp"
+Plateau_Block: INCBIN "gfx/blocksets/plateau.bst"
+
+
+SECTION "bank1A",ROMX,BANK[$1A]
+
+INCLUDE "engine/battle/decrement_pp.asm"
+
+Version_GFX:
+IF DEF(_RED)
+ binlang gfx/red/redgreenversion.1bpp ; 10 tiles
+ENDC
+IF DEF(_BLUE)
+ binlang gfx/blue/blueversion.1bpp ; 8 tiles
+ENDC
+Version_GFXEnd:
+
+Dojo_GFX:
+Gym_GFX: INCBIN "gfx/tilesets/gym.2bpp"
+Dojo_Block:
+Gym_Block: INCBIN "gfx/blocksets/gym.bst"
+
+Mart_GFX:
+Pokecenter_GFX: INCBIN "gfx/tilesets/pokecenter.2bpp"
+Mart_Block:
+Pokecenter_Block: INCBIN "gfx/blocksets/pokecenter.bst"
+
+ForestGate_GFX:
+Museum_GFX:
+Gate_GFX: INCBIN "gfx/tilesets/gate.2bpp"
+ForestGate_Block:
+Museum_Block:
+Gate_Block: INCBIN "gfx/blocksets/gate.bst"
+
+Forest_GFX: INCBIN "gfx/tilesets/forest.2bpp"
+Forest_Block: INCBIN "gfx/blocksets/forest.bst"
+Facility_GFX: INCBIN "gfx/tilesets/facility.2bpp"
+Facility_Block: INCBIN "gfx/blocksets/facility.bst"
+
+
+SECTION "bank1B",ROMX,BANK[$1B]
+
+Cemetery_GFX: INCBIN "gfx/tilesets/cemetery.2bpp"
+Cemetery_Block: INCBIN "gfx/blocksets/cemetery.bst"
+Cavern_GFX: INCBIN "gfx/tilesets/cavern.2bpp"
+Cavern_Block: INCBIN "gfx/blocksets/cavern.bst"
+Lobby_GFX: INCBIN "gfx/tilesets/lobby.2bpp"
+Lobby_Block: INCBIN "gfx/blocksets/lobby.bst"
+Ship_GFX: INCBIN "gfx/tilesets/ship.2bpp"
+Ship_Block: INCBIN "gfx/blocksets/ship.bst"
+Lab_GFX: INCBIN "gfx/tilesets/lab.2bpp"
+Lab_Block: INCBIN "gfx/blocksets/lab.bst"
+Club_GFX: INCBIN "gfx/tilesets/club.2bpp"
+Club_Block: INCBIN "gfx/blocksets/club.bst"
+Underground_GFX: INCBIN "gfx/tilesets/underground.2bpp"
+Underground_Block: INCBIN "gfx/blocksets/underground.bst"
+
+
+SECTION "bank1C",ROMX,BANK[$1C]
+
+INCLUDE "engine/gamefreak.asm"
+ inclang engine/hall_of_fame.asm
+INCLUDE "engine/overworld/healing_machine.asm"
+INCLUDE "engine/overworld/player_animations.asm"
+INCLUDE "engine/battle/ghost_marowak_anim.asm"
+INCLUDE "engine/battle/battle_transitions.asm"
+ inclang engine/town_map.asm
+INCLUDE "engine/mon_party_sprites.asm"
+INCLUDE "engine/in_game_trades.asm"
+INCLUDE "engine/palettes.asm"
+ inclang engine/save.asm
+
+
+SECTION "bank1D",ROMX,BANK[$1D]
+
+CopycatsHouse1FBlocks: INCBIN "maps/copycatshouse1f.blk"
+
+CinnabarMartBlocks:
+PewterMartBlocks: INCBIN "maps/pewtermart.blk"
+
+FuchsiaHouse1Blocks: INCBIN "maps/fuchsiahouse1.blk"
+
+CinnabarPokecenterBlocks:
+FuchsiaPokecenterBlocks: INCBIN "maps/fuchsiapokecenter.blk"
+
+CeruleanHouse2Blocks: INCBIN "maps/ceruleanhouse2.blk"
+
+ inclang engine/HoF_room_pc.asm
+
+ inclang engine/status_ailments.asm
+
+INCLUDE "engine/items/itemfinder.asm"
+
+INCLUDE "scripts/ceruleancity2.asm"
+
+INCLUDE "data/mapHeaders/viridiangym.asm"
+ inclang scripts/viridiangym.asm
+INCLUDE "data/mapObjects/viridiangym.asm"
+ViridianGymBlocks: INCBIN "maps/viridiangym.blk"
+
+INCLUDE "data/mapHeaders/pewtermart.asm"
+INCLUDE "scripts/pewtermart.asm"
+INCLUDE "data/mapObjects/pewtermart.asm"
+
+INCLUDE "data/mapHeaders/unknowndungeon1.asm"
+INCLUDE "scripts/unknowndungeon1.asm"
+INCLUDE "data/mapObjects/unknowndungeon1.asm"
+UnknownDungeon1Blocks: INCBIN "maps/unknowndungeon1.blk"
+
+INCLUDE "data/mapHeaders/ceruleanhouse2.asm"
+INCLUDE "scripts/ceruleanhouse2.asm"
+INCLUDE "data/mapObjects/ceruleanhouse2.asm"
+
+ inclang engine/menu/vending_machine.asm
+
+INCLUDE "data/mapHeaders/fuchsiahouse1.asm"
+INCLUDE "scripts/fuchsiahouse1.asm"
+INCLUDE "data/mapObjects/fuchsiahouse1.asm"
+
+INCLUDE "data/mapHeaders/fuchsiapokecenter.asm"
+INCLUDE "scripts/fuchsiapokecenter.asm"
+INCLUDE "data/mapObjects/fuchsiapokecenter.asm"
+
+INCLUDE "data/mapHeaders/fuchsiahouse2.asm"
+INCLUDE "scripts/fuchsiahouse2.asm"
+INCLUDE "data/mapObjects/fuchsiahouse2.asm"
+FuchsiaHouse2Blocks: INCBIN "maps/fuchsiahouse2.blk"
+
+INCLUDE "data/mapHeaders/safarizoneentrance.asm"
+INCLUDE "scripts/safarizoneentrance.asm"
+INCLUDE "data/mapObjects/safarizoneentrance.asm"
+SafariZoneEntranceBlocks: INCBIN "maps/safarizoneentrance.blk"
+
+INCLUDE "data/mapHeaders/fuchsiagym.asm"
+ inclang scripts/fuchsiagym.asm
+INCLUDE "data/mapObjects/fuchsiagym.asm"
+FuchsiaGymBlocks: INCBIN "maps/fuchsiagym.blk"
+
+INCLUDE "data/mapHeaders/fuchsiameetingroom.asm"
+INCLUDE "scripts/fuchsiameetingroom.asm"
+INCLUDE "data/mapObjects/fuchsiameetingroom.asm"
+FuchsiaMeetingRoomBlocks: INCBIN "maps/fuchsiameetingroom.blk"
+
+INCLUDE "data/mapHeaders/cinnabargym.asm"
+ inclang scripts/cinnabargym.asm
+INCLUDE "data/mapObjects/cinnabargym.asm"
+CinnabarGymBlocks: INCBIN "maps/cinnabargym.blk"
+
+INCLUDE "data/mapHeaders/lab1.asm"
+INCLUDE "scripts/lab1.asm"
+INCLUDE "data/mapObjects/lab1.asm"
+Lab1Blocks: INCBIN "maps/lab1.blk"
+
+INCLUDE "data/mapHeaders/lab2.asm"
+INCLUDE "scripts/lab2.asm"
+INCLUDE "data/mapObjects/lab2.asm"
+Lab2Blocks: INCBIN "maps/lab2.blk"
+
+INCLUDE "data/mapHeaders/lab3.asm"
+INCLUDE "scripts/lab3.asm"
+INCLUDE "data/mapObjects/lab3.asm"
+Lab3Blocks: INCBIN "maps/lab3.blk"
+
+INCLUDE "data/mapHeaders/lab4.asm"
+INCLUDE "scripts/lab4.asm"
+INCLUDE "data/mapObjects/lab4.asm"
+Lab4Blocks: INCBIN "maps/lab4.blk"
+
+INCLUDE "data/mapHeaders/cinnabarpokecenter.asm"
+INCLUDE "scripts/cinnabarpokecenter.asm"
+INCLUDE "data/mapObjects/cinnabarpokecenter.asm"
+
+INCLUDE "data/mapHeaders/cinnabarmart.asm"
+INCLUDE "scripts/cinnabarmart.asm"
+INCLUDE "data/mapObjects/cinnabarmart.asm"
+
+INCLUDE "data/mapHeaders/copycatshouse1f.asm"
+INCLUDE "scripts/copycatshouse1f.asm"
+INCLUDE "data/mapObjects/copycatshouse1f.asm"
+
+INCLUDE "data/mapHeaders/gary.asm"
+INCLUDE "scripts/gary.asm"
+INCLUDE "data/mapObjects/gary.asm"
+GaryBlocks: INCBIN "maps/gary.blk"
+
+INCLUDE "data/mapHeaders/lorelei.asm"
+INCLUDE "scripts/lorelei.asm"
+INCLUDE "data/mapObjects/lorelei.asm"
+LoreleiBlocks: INCBIN "maps/lorelei.blk"
+
+INCLUDE "data/mapHeaders/bruno.asm"
+INCLUDE "scripts/bruno.asm"
+INCLUDE "data/mapObjects/bruno.asm"
+BrunoBlocks: INCBIN "maps/bruno.blk"
+
+INCLUDE "data/mapHeaders/agatha.asm"
+INCLUDE "scripts/agatha.asm"
+INCLUDE "data/mapObjects/agatha.asm"
+AgathaBlocks: INCBIN "maps/agatha.blk"
+
+ inclang engine/menu/league_pc.asm
+
+INCLUDE "engine/overworld/hidden_items.asm"
+
+
+SECTION "bank1E",ROMX,BANK[$1E]
+
+INCLUDE "engine/battle/animations.asm"
+
+INCLUDE "engine/overworld/cut2.asm"
+
+INCLUDE "engine/overworld/ssanne.asm"
+
+RedFishingTilesFront: INCBIN "gfx/red_fishing_tile_front.2bpp"
+RedFishingTilesBack: INCBIN "gfx/red_fishing_tile_back.2bpp"
+RedFishingTilesSide: INCBIN "gfx/red_fishing_tile_side.2bpp"
+RedFishingRodTiles: INCBIN "gfx/red_fishingrod_tiles.2bpp"
+
+INCLUDE "data/animations.asm"
+
+INCLUDE "engine/evolution.asm"
+
+INCLUDE "engine/overworld/elevator.asm"
+
+INCLUDE "engine/items/tm_prices.asm"
diff --git a/en/scripts/bikeshop.asm b/en/scripts/bikeshop.asm
new file mode 100755
index 00000000..4d6853be
--- /dev/null
+++ b/en/scripts/bikeshop.asm
@@ -0,0 +1,147 @@
+BikeShopScript:
+ jp EnableAutoTextBoxDrawing
+
+BikeShopTextPointers:
+ dw BikeShopText1
+ dw BikeShopText2
+ dw BikeShopText3
+
+BikeShopText1:
+ TX_ASM
+ CheckEvent EVENT_GOT_BICYCLE
+ jr z, .asm_260d4
+ ld hl, BikeShopText_1d82f
+ call PrintText
+ jp .Done
+.asm_260d4
+ ld b, BIKE_VOUCHER
+ call IsItemInBag
+ jr z, .asm_41190
+ ld hl, BikeShopText_1d81f
+ call PrintText
+ lb bc, BICYCLE, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, BIKE_VOUCHER
+ ld [$ffdb], a
+ callba RemoveItemByID
+ SetEvent EVENT_GOT_BICYCLE
+ ld hl, BikeShopText_1d824
+ call PrintText
+ jr .Done
+.BagFull
+ ld hl, BikeShopText_1d834
+ call PrintText
+ jr .Done
+.asm_41190
+ ld hl, BikeShopText_1d810
+ call PrintText
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wLastMenuItem], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuWatchedKeys], a
+ ld a, $1
+ ld [wMaxMenuItem], a
+ ld a, $2
+ ld [wTopMenuItemY], a
+ ld a, $1
+ ld [wTopMenuItemX], a
+ ld hl, wd730
+ set 6, [hl]
+ coord hl, 0, 0
+ ld b, $4
+ ld c, $f
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 2, 2
+ ld de, BikeShopMenuText
+ call PlaceString
+ coord hl, 8, 3
+ ld de, BikeShopMenuPrice
+ call PlaceString
+ ld hl, BikeShopText_1d815
+ call PrintText
+ call HandleMenuInput
+ bit 1, a
+ jr nz, .cancel
+ ld hl, wd730
+ res 6, [hl]
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .cancel
+ ld hl, BikeShopCantAffordText
+ call PrintText
+.cancel
+ ld hl, BikeShopComeAgainText
+ call PrintText
+.Done
+ jp TextScriptEnd
+
+BikeShopMenuText:
+ db "BICYCLE"
+ next "CANCEL@"
+
+BikeShopMenuPrice:
+ db "¥1000000@"
+
+BikeShopText_1d810:
+ TX_FAR _BikeShopText_1d810
+ db "@"
+
+BikeShopText_1d815:
+ TX_FAR _BikeShopText_1d815
+ db "@"
+
+BikeShopCantAffordText:
+ TX_FAR _BikeShopCantAffordText
+ db "@"
+
+BikeShopText_1d81f:
+ TX_FAR _BikeShopText_1d81f
+ db "@"
+
+BikeShopText_1d824:
+ TX_FAR _BikeShopText_1d824
+ TX_SFX_KEY_ITEM
+ db "@"
+
+BikeShopComeAgainText:
+ TX_FAR _BikeShopComeAgainText
+ db "@"
+
+BikeShopText_1d82f:
+ TX_FAR _BikeShopText_1d82f
+ db "@"
+
+BikeShopText_1d834:
+ TX_FAR _BikeShopText_1d834
+ db "@"
+
+BikeShopText2:
+ TX_ASM
+ ld hl, BikeShopText_1d843
+ call PrintText
+ jp TextScriptEnd
+
+BikeShopText_1d843:
+ TX_FAR _BikeShopText_1d843
+ db "@"
+
+BikeShopText3:
+ TX_ASM
+ CheckEvent EVENT_GOT_BICYCLE
+ ld hl, BikeShopText_1d861
+ jr nz, .asm_34d2d
+ ld hl, BikeShopText_1d85c
+.asm_34d2d
+ call PrintText
+ jp TextScriptEnd
+
+BikeShopText_1d85c:
+ TX_FAR _BikeShopText_1d85c
+ db "@"
+
+BikeShopText_1d861:
+ TX_FAR _BikeShopText_1d861
+ db "@"
diff --git a/en/scripts/celadongamecorner.asm b/en/scripts/celadongamecorner.asm
new file mode 100755
index 00000000..cc81b076
--- /dev/null
+++ b/en/scripts/celadongamecorner.asm
@@ -0,0 +1,527 @@
+CeladonGameCornerScript:
+ call CeladonGameCornerScript_48bcf
+ call CeladonGameCornerScript_48bec
+ call EnableAutoTextBoxDrawing
+ ld hl, CeladonGameCornerScriptPointers
+ ld a, [wCeladonGameCornerCurScript]
+ jp CallFunctionInTable
+
+CeladonGameCornerScript_48bcf:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ ret z
+ call Random
+ ld a, [hRandomAdd]
+ cp $7
+ jr nc, .asm_48be2
+ ld a, $8
+.asm_48be2
+ srl a
+ srl a
+ srl a
+ ld [wLuckySlotHiddenObjectIndex], a
+ ret
+
+CeladonGameCornerScript_48bec:
+ ld hl, wCurrentMapScriptFlags
+ bit 5, [hl]
+ res 5, [hl]
+ ret z
+ CheckEvent EVENT_FOUND_ROCKET_HIDEOUT
+ ret nz
+ ld a, $2a
+ ld [wNewTileBlockID], a
+ lb bc, 2, 8
+ predef_jump ReplaceTileBlock
+
+CeladonGameCornerScript_48c07:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wCeladonGameCornerCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+CeladonGameCornerScriptPointers:
+ dw CeladonGameCornerScript0
+ dw CeladonGameCornerScript1
+ dw CeladonGameCornerScript2
+
+CeladonGameCornerScript0:
+ ret
+
+CeladonGameCornerScript1:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, CeladonGameCornerScript_48c07
+ ld a, $f0
+ ld [wJoyIgnore], a
+ ld a, $d
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ ld a, $b
+ ld [H_SPRITEINDEX], a
+ call SetSpriteMovementBytesToFF
+ ld de, MovementData_48c5a
+ ld a, [wYCoord]
+ cp $6
+ jr nz, .asm_48c43
+ ld de, MovementData_48c63
+ jr .asm_48c4d
+.asm_48c43
+ ld a, [wXCoord]
+ cp $8
+ jr nz, .asm_48c4d
+ ld de, MovementData_48c63
+.asm_48c4d
+ ld a, $b
+ ld [H_SPRITEINDEX], a
+ call MoveSprite
+ ld a, $2
+ ld [wCeladonGameCornerCurScript], a
+ ret
+
+MovementData_48c5a:
+ db NPC_MOVEMENT_DOWN
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_UP
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db $FF
+
+MovementData_48c63:
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db $FF
+
+CeladonGameCornerScript2:
+ ld a, [wd730]
+ bit 0, a
+ ret nz
+ xor a
+ ld [wJoyIgnore], a
+ ld a, HS_GAME_CORNER_ROCKET
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+ set 6, [hl]
+ ld a, $0
+ ld [wCeladonGameCornerCurScript], a
+ ret
+
+CeladonGameCornerTextPointers:
+ dw CeladonGameCornerText1
+ dw CeladonGameCornerText2
+ dw CeladonGameCornerText3
+ dw CeladonGameCornerText4
+ dw CeladonGameCornerText5
+ dw CeladonGameCornerText6
+ dw CeladonGameCornerText7
+ dw CeladonGameCornerText8
+ dw CeladonGameCornerText9
+ dw CeladonGameCornerText10
+ dw CeladonGameCornerText11
+ dw CeladonGameCornerText12
+ dw CeladonGameCornerText13
+
+CeladonGameCornerText1:
+ TX_FAR _CeladonGameCornerText1
+ db "@"
+
+CeladonGameCornerText2:
+ TX_ASM
+ call CeladonGameCornerScript_48f1e
+ ld hl, CeladonGameCornerText_48d22
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .asm_48d0f
+ ld b, COIN_CASE
+ call IsItemInBag
+ jr z, .asm_48d19
+ call Has9990Coins
+ jr nc, .asm_48d14
+ xor a
+ ld [hMoney], a
+ ld [hMoney + 2], a
+ ld a, $10
+ ld [hMoney + 1], a
+ call HasEnoughMoney
+ jr nc, .asm_48cdb
+ ld hl, CeladonGameCornerText_48d31
+ jr .asm_48d1c
+.asm_48cdb
+ xor a
+ ld [hMoney], a
+ ld [hMoney + 2], a
+ ld a, $10
+ ld [hMoney + 1], a
+ ld hl, hMoney + 2
+ ld de, wPlayerMoney + 2
+ ld c, $3
+ predef SubBCDPredef
+ xor a
+ ld [hUnusedCoinsByte], a
+ ld [hCoins], a
+ ld a, $50
+ ld [hCoins + 1], a
+ ld de, wPlayerCoins + 1
+ ld hl, hCoins + 1
+ ld c, $2
+ predef AddBCDPredef
+ call CeladonGameCornerScript_48f1e
+ ld hl, CeladonGameCornerText_48d27
+ jr .asm_48d1c
+.asm_48d0f
+ ld hl, CeladonGameCornerText_48d2c
+ jr .asm_48d1c
+.asm_48d14
+ ld hl, CeladonGameCornerText_48d36
+ jr .asm_48d1c
+.asm_48d19
+ ld hl, CeladonGameCornerText_48d3b
+.asm_48d1c
+ call PrintText
+ jp TextScriptEnd
+
+CeladonGameCornerText_48d22:
+ TX_FAR _CeladonGameCornerText_48d22
+ db "@"
+
+CeladonGameCornerText_48d27:
+ TX_FAR _CeladonGameCornerText_48d27
+ db "@"
+
+CeladonGameCornerText_48d2c:
+ TX_FAR _CeladonGameCornerText_48d2c
+ db "@"
+
+CeladonGameCornerText_48d31:
+ TX_FAR _CeladonGameCornerText_48d31
+ db "@"
+
+CeladonGameCornerText_48d36:
+ TX_FAR _CeladonGameCornerText_48d36
+ db "@"
+
+CeladonGameCornerText_48d3b:
+ TX_FAR _CeladonGameCornerText_48d3b
+ db "@"
+
+CeladonGameCornerText3:
+ TX_FAR _CeladonGameCornerText3
+ db "@"
+
+CeladonGameCornerText4:
+ TX_FAR _CeladonGameCornerText4
+ db "@"
+
+CeladonGameCornerText5:
+ TX_ASM
+ CheckEvent EVENT_GOT_10_COINS
+ jr nz, .asm_48d89
+ ld hl, CeladonGameCornerText_48d9c
+ call PrintText
+ ld b, COIN_CASE
+ call IsItemInBag
+ jr z, .asm_48d93
+ call Has9990Coins
+ jr nc, .asm_48d8e
+ xor a
+ ld [hUnusedCoinsByte], a
+ ld [hCoins], a
+ ld a, $10
+ ld [hCoins + 1], a
+ ld de, wPlayerCoins + 1
+ ld hl, hCoins + 1
+ ld c, $2
+ predef AddBCDPredef
+ SetEvent EVENT_GOT_10_COINS
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld hl, Received10CoinsText
+ jr .asm_48d96
+.asm_48d89
+ ld hl, CeladonGameCornerText_48dac
+ jr .asm_48d96
+.asm_48d8e
+ ld hl, CeladonGameCornerText_48da7
+ jr .asm_48d96
+.asm_48d93
+ ld hl, CeladonGameCornerText_48f19
+.asm_48d96
+ call PrintText
+ jp TextScriptEnd
+
+CeladonGameCornerText_48d9c:
+ TX_FAR _CeladonGameCornerText_48d9c
+ db "@"
+
+Received10CoinsText:
+ TX_FAR _Received10CoinsText
+ TX_SFX_ITEM_1
+ db "@"
+
+CeladonGameCornerText_48da7:
+ TX_FAR _CeladonGameCornerText_48da7
+ db "@"
+
+CeladonGameCornerText_48dac:
+ TX_FAR _CeladonGameCornerText_48dac
+ db "@"
+
+CeladonGameCornerText6:
+ TX_FAR _CeladonGameCornerText6
+ db "@"
+
+CeladonGameCornerText7:
+ TX_ASM
+ CheckEvent EVENT_BEAT_ERIKA
+ ld hl, CeladonGameCornerText_48dca
+ jr z, .asm_48dc4
+ ld hl, CeladonGameCornerText_48dcf
+.asm_48dc4
+ call PrintText
+ jp TextScriptEnd
+
+CeladonGameCornerText_48dca:
+ TX_FAR _CeladonGameCornerText_48dca
+ db "@"
+
+CeladonGameCornerText_48dcf:
+ TX_FAR _CeladonGameCornerText_48dcf
+ db "@"
+
+CeladonGameCornerText8:
+ TX_FAR _CeladonGameCornerText8
+ db "@"
+
+CeladonGameCornerText9:
+ TX_ASM
+ CheckEvent EVENT_GOT_20_COINS_2
+ jr nz, .asm_48e13
+ ld hl, CeladonGameCornerText_48e26
+ call PrintText
+ ld b, COIN_CASE
+ call IsItemInBag
+ jr z, .asm_48e1d
+ call Has9990Coins
+ jr nc, .asm_48e18
+ xor a
+ ld [hUnusedCoinsByte], a
+ ld [hCoins], a
+ ld a, $20
+ ld [hCoins + 1], a
+ ld de, wPlayerCoins + 1
+ ld hl, hCoins + 1
+ ld c, $2
+ predef AddBCDPredef
+ SetEvent EVENT_GOT_20_COINS_2
+ ld hl, Received20CoinsText
+ jr .asm_48e20
+.asm_48e13
+ ld hl, CeladonGameCornerText_48e36
+ jr .asm_48e20
+.asm_48e18
+ ld hl, CeladonGameCornerText_48e31
+ jr .asm_48e20
+.asm_48e1d
+ ld hl, CeladonGameCornerText_48f19
+.asm_48e20
+ call PrintText
+ jp TextScriptEnd
+
+CeladonGameCornerText_48e26:
+ TX_FAR _CeladonGameCornerText_48e26
+ db "@"
+
+Received20CoinsText:
+ TX_FAR _Received20CoinsText
+ TX_SFX_ITEM_1
+ db "@"
+
+CeladonGameCornerText_48e31:
+ TX_FAR _CeladonGameCornerText_48e31
+ db "@"
+
+CeladonGameCornerText_48e36:
+ TX_FAR _CeladonGameCornerText_48e36
+ db "@"
+
+CeladonGameCornerText10:
+ TX_ASM
+ CheckEvent EVENT_GOT_20_COINS
+ jr nz, .asm_48e75
+ ld hl, CeladonGameCornerText_48e88
+ call PrintText
+ ld b, COIN_CASE
+ call IsItemInBag
+ jr z, .asm_48e7f
+ call Has9990Coins
+ jr z, .asm_48e7a
+ xor a
+ ld [hUnusedCoinsByte], a
+ ld [hCoins], a
+ ld a, $20
+ ld [hCoins + 1], a
+ ld de, wPlayerCoins + 1
+ ld hl, hCoins + 1
+ ld c, $2
+ predef AddBCDPredef
+ SetEvent EVENT_GOT_20_COINS
+ ld hl, CeladonGameCornerText_48e8d
+ jr .asm_48e82
+.asm_48e75
+ ld hl, CeladonGameCornerText_48e98
+ jr .asm_48e82
+.asm_48e7a
+ ld hl, CeladonGameCornerText_48e93
+ jr .asm_48e82
+.asm_48e7f
+ ld hl, CeladonGameCornerText_48f19
+.asm_48e82
+ call PrintText
+ jp TextScriptEnd
+
+CeladonGameCornerText_48e88:
+ TX_FAR _CeladonGameCornerText_48e88
+ db "@"
+
+CeladonGameCornerText_48e8d:
+ TX_FAR _CeladonGameCornerText_48e8d
+ TX_SFX_ITEM_1
+ db "@"
+
+CeladonGameCornerText_48e93:
+ TX_FAR _CeladonGameCornerText_48e93
+ db "@"
+
+CeladonGameCornerText_48e98:
+ TX_FAR _CeladonGameCornerText_48e98
+ db "@"
+
+CeladonGameCornerText11:
+ TX_ASM
+ ld hl, CeladonGameCornerText_48ece
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, CeladonGameCornerText_48ed3
+ ld de, CeladonGameCornerText_48ed3
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ xor a
+ ld [hJoyHeld], a
+ ld [hJoyPressed], a
+ ld [hJoyReleased], a
+ ld a, $1
+ ld [wCeladonGameCornerCurScript], a
+ jp TextScriptEnd
+
+CeladonGameCornerText_48ece:
+ TX_FAR _CeladonGameCornerText_48ece
+ db "@"
+
+CeladonGameCornerText_48ed3:
+ TX_FAR _CeladonGameCornerText_48ed3
+ db "@"
+
+CeladonGameCornerText13:
+ TX_FAR _CeladonGameCornerText_48ed8
+ db "@"
+
+CeladonGameCornerText12:
+ TX_ASM
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld hl, CeladonGameCornerText_48f09
+ call PrintText
+ call WaitForSoundToFinish
+ ld a, SFX_GO_INSIDE
+ call PlaySound
+ call WaitForSoundToFinish
+ SetEvent EVENT_FOUND_ROCKET_HIDEOUT
+ ld a, $43
+ ld [wNewTileBlockID], a
+ lb bc, 2, 8
+ predef ReplaceTileBlock
+ jp TextScriptEnd
+
+CeladonGameCornerText_48f09:
+ TX_FAR _CeladonGameCornerText_48f09
+ TX_ASM
+ ld a, SFX_SWITCH
+ call PlaySound
+ call WaitForSoundToFinish
+ jp TextScriptEnd
+
+CeladonGameCornerText_48f19:
+ TX_FAR _CeladonGameCornerText_48f19
+ db "@"
+
+CeladonGameCornerScript_48f1e:
+ ld hl, wd730
+ set 6, [hl]
+ coord hl, 11, 0
+ ld b, $5
+ ld c, $7
+ call TextBoxBorder
+ call UpdateSprites
+ coord hl, 12, 1
+ ld b, 4
+ ld c, 7
+ call ClearScreenArea
+ coord hl, 12, 2
+ ld de, GameCornerMoneyText
+ call PlaceString
+ coord hl, 12, 3
+ ld de, GameCornerBlankText1
+ call PlaceString
+ coord hl, 12, 3
+ ld de, wPlayerMoney
+ ld c, $a3
+ call PrintBCDNumber
+ coord hl, 12, 4
+ ld de, GameCornerCoinText
+ call PlaceString
+ coord hl, 12, 5
+ ld de, GameCornerBlankText2
+ call PlaceString
+ coord hl, 15, 5
+ ld de, wPlayerCoins
+ ld c, $82
+ call PrintBCDNumber
+ ld hl, wd730
+ res 6, [hl]
+ ret
+
+GameCornerMoneyText:
+ db "MONEY@"
+
+GameCornerCoinText:
+ db "COIN@"
+
+GameCornerBlankText1:
+ db " @"
+
+GameCornerBlankText2:
+ db " @"
+
+Has9990Coins:
+ ld a, $99
+ ld [hCoins], a
+ ld a, $90
+ ld [hCoins + 1], a
+ jp HasEnoughCoins
diff --git a/en/scripts/celadongym.asm b/en/scripts/celadongym.asm
new file mode 100755
index 00000000..ae7e6846
--- /dev/null
+++ b/en/scripts/celadongym.asm
@@ -0,0 +1,335 @@
+CeladonGymScript:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ call nz, CeladonGymScript_48927
+ call EnableAutoTextBoxDrawing
+ ld hl, CeladonGymTrainerHeader0
+ ld de, CeladonGymScriptPointers
+ ld a, [wCeladonGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wCeladonGymCurScript], a
+ ret
+
+CeladonGymScript_48927:
+ ld hl, Gym4CityName
+ ld de, Gym4LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym4CityName:
+ db "CELADON CITY@"
+
+Gym4LeaderName:
+ db "ERIKA@"
+
+CeladonGymText_48943:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wCeladonGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+CeladonGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw CeladonGymScript3
+
+CeladonGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, CeladonGymText_48943
+ ld a, $f0
+ ld [wJoyIgnore], a
+
+CeladonGymText_48963:
+ ld a, $9
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_ERIKA
+ lb bc, TM_21, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $a
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM21
+ jr .asm_4898c
+.BagFull
+ ld a, $b
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_4898c
+ ld hl, wObtainedBadges
+ set 3, [hl]
+ ld hl, wBeatGymFlags
+ set 3, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_CELADON_GYM_TRAINER_0, EVENT_BEAT_CELADON_GYM_TRAINER_6
+
+ jp CeladonGymText_48943
+
+CeladonGymTextPointers:
+ dw CeladonGymText1
+ dw CeladonGymText2
+ dw CeladonGymText3
+ dw CeladonGymText4
+ dw CeladonGymText5
+ dw CeladonGymText6
+ dw CeladonGymText7
+ dw CeladonGymText8
+ dw CeladonGymText9
+ dw TM21Text
+ dw TM21NoRoomText
+
+CeladonGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_0
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_0
+ dw CeladonGymBattleText2 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText2 ; TextAfterBattle
+ dw CeladonGymEndBattleText2 ; TextEndBattle
+ dw CeladonGymEndBattleText2 ; TextEndBattle
+
+CeladonGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_1
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_1
+ dw CeladonGymBattleText3 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText3 ; TextAfterBattle
+ dw CeladonGymEndBattleText3 ; TextEndBattle
+ dw CeladonGymEndBattleText3 ; TextEndBattle
+
+CeladonGymTrainerHeader2:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_2
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_2
+ dw CeladonGymBattleText4 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText4 ; TextAfterBattle
+ dw CeladonGymEndBattleText4 ; TextEndBattle
+ dw CeladonGymEndBattleText4 ; TextEndBattle
+
+CeladonGymTrainerHeader3:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_3
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_3
+ dw CeladonGymBattleText5 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText5 ; TextAfterBattle
+ dw CeladonGymEndBattleText5 ; TextEndBattle
+ dw CeladonGymEndBattleText5 ; TextEndBattle
+
+CeladonGymTrainerHeader4:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_4
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_4
+ dw CeladonGymBattleText6 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText6 ; TextAfterBattle
+ dw CeladonGymEndBattleText6 ; TextEndBattle
+ dw CeladonGymEndBattleText6 ; TextEndBattle
+
+CeladonGymTrainerHeader5:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_5
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_5
+ dw CeladonGymBattleText7 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText7 ; TextAfterBattle
+ dw CeladonGymEndBattleText7 ; TextEndBattle
+ dw CeladonGymEndBattleText7 ; TextEndBattle
+
+CeladonGymTrainerHeader6:
+ dbEventFlagBit EVENT_BEAT_CELADON_GYM_TRAINER_6, 1
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CELADON_GYM_TRAINER_6, 1
+ dw CeladonGymBattleText8 ; TextBeforeBattle
+ dw CeladonGymAfterBattleText8 ; TextAfterBattle
+ dw CeladonGymEndBattleText8 ; TextEndBattle
+ dw CeladonGymEndBattleText8 ; TextEndBattle
+
+ db $ff
+
+CeladonGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_ERIKA
+ jr z, .asm_48a2d
+ CheckEventReuseA EVENT_GOT_TM21
+ jr nz, .asm_48a25
+ call z, CeladonGymText_48963
+ call DisableWaitingAfterTextDisplay
+ jr .asm_48a5b
+.asm_48a25
+ ld hl, CeladonGymText_48a68
+ call PrintText
+ jr .asm_48a5b
+.asm_48a2d
+ ld hl, CeladonGymText_48a5e
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, CeladonGymText_48a63
+ ld de, CeladonGymText_48a63
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $4
+ ld [wGymLeaderNo], a
+ ld a, $3
+ ld [wCeladonGymCurScript], a
+ ld [wCurMapScript], a
+.asm_48a5b
+ jp TextScriptEnd
+
+CeladonGymText_48a5e:
+ TX_FAR _CeladonGymText_48a5e
+ db "@"
+
+CeladonGymText_48a63:
+ TX_FAR _CeladonGymText_48a63
+ db "@"
+
+CeladonGymText_48a68:
+ TX_FAR _CeladonGymText_48a68
+ db "@"
+
+CeladonGymText9:
+ TX_FAR _CeladonGymText9
+ db "@"
+
+TM21Text:
+ TX_FAR _ReceivedTM21Text
+ TX_SFX_ITEM_1
+ TX_FAR _TM21ExplanationText
+ db "@"
+
+TM21NoRoomText:
+ TX_FAR _TM21NoRoomText
+ db "@"
+
+CeladonGymText2:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText2:
+ TX_FAR _CeladonGymBattleText2
+ db "@"
+
+CeladonGymEndBattleText2:
+ TX_FAR _CeladonGymEndBattleText2
+ db "@"
+
+CeladonGymAfterBattleText2:
+ TX_FAR _CeladonGymAfterBattleText2
+ db "@"
+
+CeladonGymText3:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText3:
+ TX_FAR _CeladonGymBattleText3
+ db "@"
+
+CeladonGymEndBattleText3:
+ TX_FAR _CeladonGymEndBattleText3
+ db "@"
+
+CeladonGymAfterBattleText3:
+ TX_FAR _CeladonGymAfterBattleText3
+ db "@"
+
+CeladonGymText4:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader2
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText4:
+ TX_FAR _CeladonGymBattleText4
+ db "@"
+
+CeladonGymEndBattleText4:
+ TX_FAR _CeladonGymEndBattleText4
+ db "@"
+
+CeladonGymAfterBattleText4:
+ TX_FAR _CeladonGymAfterBattleText4
+ db "@"
+
+CeladonGymText5:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader3
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText5:
+ TX_FAR _CeladonGymBattleText5
+ db "@"
+
+CeladonGymEndBattleText5:
+ TX_FAR _CeladonGymEndBattleText5
+ db "@"
+
+CeladonGymAfterBattleText5:
+ TX_FAR _CeladonGymAfterBattleText5
+ db "@"
+
+CeladonGymText6:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader4
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText6:
+ TX_FAR _CeladonGymBattleText6
+ db "@"
+
+CeladonGymEndBattleText6:
+ TX_FAR _CeladonGymEndBattleText6
+ db "@"
+
+CeladonGymAfterBattleText6:
+ TX_FAR _CeladonGymAfterBattleText6
+ db "@"
+
+CeladonGymText7:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader5
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText7:
+ TX_FAR _CeladonGymBattleText7
+ db "@"
+
+CeladonGymEndBattleText7:
+ TX_FAR _CeladonGymEndBattleText7
+ db "@"
+
+CeladonGymAfterBattleText7:
+ TX_FAR _CeladonGymAfterBattleText7
+ db "@"
+
+CeladonGymText8:
+ TX_ASM
+ ld hl, CeladonGymTrainerHeader6
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeladonGymBattleText8:
+ TX_FAR _CeladonGymBattleText8
+ db "@"
+
+CeladonGymEndBattleText8:
+ TX_FAR _CeladonGymEndBattleText8
+ db "@"
+
+CeladonGymAfterBattleText8:
+ TX_FAR _CeladonGymAfterBattleText8
+ db "@"
diff --git a/en/scripts/ceruleangym.asm b/en/scripts/ceruleangym.asm
new file mode 100755
index 00000000..b82b89f6
--- /dev/null
+++ b/en/scripts/ceruleangym.asm
@@ -0,0 +1,219 @@
+CeruleanGymScript:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ call nz, CeruleanGymScript_5c6d0
+ call EnableAutoTextBoxDrawing
+ ld hl, CeruleanGymTrainerHeader0
+ ld de, CeruleanGymScriptPointers
+ ld a, [wCeruleanGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wCeruleanGymCurScript], a
+ ret
+
+CeruleanGymScript_5c6d0:
+ ld hl, Gym2CityName
+ ld de, Gym2LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym2CityName:
+ db "CERULEAN CITY@"
+
+Gym2LeaderName:
+ db "MISTY@"
+
+CeruleanGymScript_5c6ed:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wCeruleanGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+CeruleanGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw CeruleanGymScript3
+
+CeruleanGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, CeruleanGymScript_5c6ed
+ ld a, $f0
+ ld [wJoyIgnore], a
+
+CeruleanGymScript_5c70d:
+ ld a, $5
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_MISTY
+ lb bc, TM_11, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $6
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM11
+ jr .asm_5c736
+.BagFull
+ ld a, $7
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_5c736
+ ld hl, wObtainedBadges
+ set 1, [hl]
+ ld hl, wBeatGymFlags
+ set 1, [hl]
+
+ ; deactivate gym trainers
+ SetEvents EVENT_BEAT_CERULEAN_GYM_TRAINER_0, EVENT_BEAT_CERULEAN_GYM_TRAINER_1
+
+ jp CeruleanGymScript_5c6ed
+
+CeruleanGymTextPointers:
+ dw CeruleanGymText1
+ dw CeruleanGymText2
+ dw CeruleanGymText3
+ dw CeruleanGymText4
+ dw CeruleanGymText5
+ dw CeruleanGymText6
+ dw CeruleanGymText7
+
+CeruleanGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_CERULEAN_GYM_TRAINER_0
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CERULEAN_GYM_TRAINER_0
+ dw CeruleanGymBattleText1 ; TextBeforeBattle
+ dw CeruleanGymAfterBattleText1 ; TextAfterBattle
+ dw CeruleanGymEndBattleText1 ; TextEndBattle
+ dw CeruleanGymEndBattleText1 ; TextEndBattle
+
+CeruleanGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_CERULEAN_GYM_TRAINER_1
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_CERULEAN_GYM_TRAINER_1
+ dw CeruleanGymBattleText2 ; TextBeforeBattle
+ dw CeruleanGymAfterBattleText2 ; TextAfterBattle
+ dw CeruleanGymEndBattleText2 ; TextEndBattle
+ dw CeruleanGymEndBattleText2 ; TextEndBattle
+
+ db $ff
+
+CeruleanGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_MISTY
+ jr z, .asm_5c78d
+ CheckEventReuseA EVENT_GOT_TM11
+ jr nz, .asm_5c785
+ call z, CeruleanGymScript_5c70d
+ call DisableWaitingAfterTextDisplay
+ jr .asm_5c7bb
+.asm_5c785
+ ld hl, CeruleanGymText_5c7c3
+ call PrintText
+ jr .asm_5c7bb
+.asm_5c78d
+ ld hl, CeruleanGymText_5c7be
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, CeruleanGymText_5c7d8
+ ld de, CeruleanGymText_5c7d8
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $2
+ ld [wGymLeaderNo], a
+ xor a
+ ld [hJoyHeld], a
+ ld a, $3
+ ld [wCeruleanGymCurScript], a
+.asm_5c7bb
+ jp TextScriptEnd
+
+CeruleanGymText_5c7be:
+ TX_FAR _CeruleanGymText_5c7be
+ db "@"
+
+CeruleanGymText_5c7c3:
+ TX_FAR _CeruleanGymText_5c7c3
+ db "@"
+
+CeruleanGymText5:
+ TX_FAR _CeruleanGymText_5c7c8
+ db "@"
+
+CeruleanGymText6:
+ TX_FAR _ReceivedTM11Text
+ TX_SFX_ITEM_1
+ db "@"
+
+CeruleanGymText7:
+ TX_FAR _CeruleanGymText_5c7d3
+ db "@"
+
+CeruleanGymText_5c7d8:
+ TX_FAR _CeruleanGymText_5c7d8
+ TX_SFX_KEY_ITEM ; actually plays the second channel of SFX_BALL_POOF due to the wrong music bank being loaded
+ TX_BLINK
+ db "@"
+
+CeruleanGymText2:
+ TX_ASM
+ ld hl, CeruleanGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeruleanGymBattleText1:
+ TX_FAR _CeruleanGymBattleText1
+ db "@"
+
+CeruleanGymEndBattleText1:
+ TX_FAR _CeruleanGymEndBattleText1
+ db "@"
+
+CeruleanGymAfterBattleText1:
+ TX_FAR _CeruleanGymAfterBattleText1
+ db "@"
+
+CeruleanGymText3:
+ TX_ASM
+ ld hl, CeruleanGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+CeruleanGymBattleText2:
+ TX_FAR _CeruleanGymBattleText2
+ db "@"
+
+CeruleanGymEndBattleText2:
+ TX_FAR _CeruleanGymEndBattleText2
+ db "@"
+
+CeruleanGymAfterBattleText2:
+ TX_FAR _CeruleanGymAfterBattleText2
+ db "@"
+
+CeruleanGymText4:
+ TX_ASM
+ CheckEvent EVENT_BEAT_MISTY
+ jr nz, .asm_5c821
+ ld hl, CeruleanGymText_5c82a
+ call PrintText
+ jr .asm_5c827
+.asm_5c821
+ ld hl, CeruleanGymText_5c82f
+ call PrintText
+.asm_5c827
+ jp TextScriptEnd
+
+CeruleanGymText_5c82a:
+ TX_FAR _CeruleanGymText_5c82a
+ db "@"
+
+CeruleanGymText_5c82f:
+ TX_FAR _CeruleanGymText_5c82f
+ db "@"
diff --git a/en/scripts/cinnabargym.asm b/en/scripts/cinnabargym.asm
new file mode 100755
index 00000000..8af7bbd3
--- /dev/null
+++ b/en/scripts/cinnabargym.asm
@@ -0,0 +1,472 @@
+CinnabarGymScript:
+ call CinnabarGymScript_75759
+ call EnableAutoTextBoxDrawing
+ ld hl, CinnabarGymScriptPointers
+ ld a, [wCinnabarGymCurScript]
+ jp CallFunctionInTable
+
+CinnabarGymScript_75759:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ push hl
+ call nz, CinnabarGymScript_75772
+ pop hl
+ bit 5, [hl]
+ res 5, [hl]
+ call nz, UpdateCinnabarGymGateTileBlocks
+ ResetEvent EVENT_2A7
+ ret
+CinnabarGymScript_75772:
+ ld hl, Gym7CityName
+ ld de, Gym7LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym7CityName:
+ db "CINNABAR ISLAND@"
+Gym7LeaderName:
+ db "BLAINE@"
+
+CinnabarGymScript_75792:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wCinnabarGymCurScript], a
+ ld [wCurMapScript], a
+ ld [wOpponentAfterWrongAnswer], a
+ ret
+
+CinnabarGymScript_757a0:
+ ld a, [hSpriteIndexOrTextID]
+ ld [wTrainerHeaderFlagBit], a
+ ret
+
+CinnabarGymScriptPointers:
+ dw CinnabarGymScript0
+ dw CinnabarGymScript1
+ dw CinnabarGymScript2
+ dw CinnabarGymScript3
+
+CinnabarGymScript0:
+ ld a, [wOpponentAfterWrongAnswer]
+ and a
+ ret z
+ ld [H_SPRITEINDEX], a
+ cp $4
+ jr nz, .asm_757c3
+ ld a, PLAYER_DIR_DOWN
+ ld [wPlayerMovingDirection], a
+ ld de, MovementData_757d7
+ jr .asm_757cb
+.asm_757c3
+ ld de, MovementData_757da
+ ld a, PLAYER_DIR_RIGHT
+ ld [wPlayerMovingDirection], a
+.asm_757cb
+ call MoveSprite
+ ld a, $1
+ ld [wCinnabarGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+MovementData_757d7:
+ db NPC_MOVEMENT_LEFT
+ db NPC_MOVEMENT_UP
+ db $FF
+
+MovementData_757da:
+ db NPC_MOVEMENT_LEFT
+ db $FF
+
+CinnabarGymScript1:
+ ld a, [wd730]
+ bit 0, a
+ ret nz
+ xor a
+ ld [wJoyIgnore], a
+ ld a, [wOpponentAfterWrongAnswer]
+ ld [wTrainerHeaderFlagBit], a
+ ld [hSpriteIndexOrTextID], a
+ jp DisplayTextID
+
+CinnabarGymFlagAction:
+ predef_jump FlagActionPredef
+
+CinnabarGymScript2:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, CinnabarGymScript_75792
+ ld a, [wTrainerHeaderFlagBit]
+ ld [$ffdb], a
+ AdjustEventBit EVENT_BEAT_CINNABAR_GYM_TRAINER_0, 2
+ ld c, a
+ ld b, FLAG_TEST
+ EventFlagAddress hl, EVENT_BEAT_CINNABAR_GYM_TRAINER_0
+ call CinnabarGymFlagAction
+ ld a, c
+ and a
+ jr nz, .asm_7581b
+ call WaitForSoundToFinish
+ ld a, SFX_GO_INSIDE
+ call PlaySound
+ call WaitForSoundToFinish
+.asm_7581b
+ ld a, [wTrainerHeaderFlagBit]
+ ld [$ffdb], a
+ AdjustEventBit EVENT_BEAT_CINNABAR_GYM_TRAINER_0, 2
+ ld c, a
+ ld b, FLAG_SET
+ EventFlagAddress hl, EVENT_BEAT_CINNABAR_GYM_TRAINER_0
+ call CinnabarGymFlagAction
+ ld a, [wTrainerHeaderFlagBit]
+ sub $2
+ AdjustEventBit EVENT_CINNABAR_GYM_GATE0_UNLOCKED, 0
+ ld c, a
+ ld b, FLAG_SET
+ EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED
+ call CinnabarGymFlagAction
+ call UpdateCinnabarGymGateTileBlocks
+ xor a
+ ld [wJoyIgnore], a
+ ld [wOpponentAfterWrongAnswer], a
+ ld a, $0
+ ld [wCinnabarGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+CinnabarGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, CinnabarGymScript_75792
+ ld a, $f0
+ ld [wJoyIgnore], a
+CinnabarGymScript3_75857:
+ ld a, $a
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_BLAINE
+ lb bc, TM_38, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $b
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM38
+ jr .asm_75880
+.BagFull
+ ld a, $c
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_75880
+ ld hl, wObtainedBadges
+ set 6, [hl]
+ ld hl, wBeatGymFlags
+ set 6, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_CINNABAR_GYM_TRAINER_0, EVENT_BEAT_CINNABAR_GYM_TRAINER_6
+
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+
+ jp CinnabarGymScript_75792
+
+CinnabarGymTextPointers:
+ dw CinnabarGymText1
+ dw CinnabarGymText2
+ dw CinnabarGymText3
+ dw CinnabarGymText4
+ dw CinnabarGymText5
+ dw CinnabarGymText6
+ dw CinnabarGymText7
+ dw CinnabarGymText8
+ dw CinnabarGymText9
+ dw BlaineBadgeText
+ dw ReceivedTM38Text
+ dw TM38NoRoomText
+
+CinnabarGymScript_758b7:
+ ld a, [hSpriteIndexOrTextID]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld a, [wSpriteIndex]
+ cp $1
+ jr z, .asm_758d4
+ ld a, $2
+ jr .asm_758d6
+.asm_758d4
+ ld a, $3
+.asm_758d6
+ ld [wCinnabarGymCurScript], a
+ ld [wCurMapScript], a
+ jp TextScriptEnd
+
+CinnabarGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_BLAINE
+ jr z, .asm_d9332
+ CheckEventReuseA EVENT_GOT_TM38
+ jr nz, .asm_3012f
+ call z, CinnabarGymScript3_75857
+ call DisableWaitingAfterTextDisplay
+ jp TextScriptEnd
+.asm_3012f
+ ld hl, BlaineFireBlastText
+ call PrintText
+ jp TextScriptEnd
+.asm_d9332
+ ld hl, BlaineBattleText
+ call PrintText
+ ld hl, BlaineEndBattleText
+ ld de, BlaineEndBattleText
+ call SaveEndBattleTextPointers
+ ld a, $7
+ ld [wGymLeaderNo], a
+ jp CinnabarGymScript_758b7
+
+BlaineBattleText:
+ TX_FAR _BlaineBattleText
+ db "@"
+
+BlaineEndBattleText:
+ TX_FAR _BlaineEndBattleText
+ TX_SFX_KEY_ITEM ; actually plays the second channel of SFX_BALL_POOF due to the wrong music bank being loaded
+ TX_WAIT
+ db "@"
+
+BlaineFireBlastText:
+ TX_FAR _BlaineFireBlastText
+ db "@"
+
+BlaineBadgeText:
+ TX_FAR _BlaineBadgeText
+ db "@"
+
+ReceivedTM38Text:
+ TX_FAR _ReceivedTM38Text
+ TX_SFX_ITEM_1
+ TX_FAR _TM38ExplanationText
+ db "@"
+
+TM38NoRoomText:
+ TX_FAR _TM38NoRoomText
+ db "@"
+
+CinnabarGymText2:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_0
+ jr nz, .asm_46bb4
+ ld hl, CinnabarGymText_7595f
+ call PrintText
+ ld hl, CinnabarGymText_75964
+ ld de, CinnabarGymText_75964
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_46bb4
+ ld hl, CinnabarGymText_75969
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_7595f:
+ TX_FAR _CinnabarGymText_7595f
+ db "@"
+
+CinnabarGymText_75964:
+ TX_FAR _CinnabarGymText_75964
+ db "@"
+
+CinnabarGymText_75969:
+ TX_FAR _CinnabarGymText_75969
+ db "@"
+
+CinnabarGymText3:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_1
+ jr nz, .asm_4b406
+ ld hl, CinnabarGymText_75994
+ call PrintText
+ ld hl, CinnabarGymText_75999
+ ld de, CinnabarGymText_75999
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_4b406
+ ld hl, CinnabarGymText_7599e
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_75994:
+ TX_FAR _CinnabarGymText_75994
+ db "@"
+
+CinnabarGymText_75999:
+ TX_FAR _CinnabarGymText_75999
+ db "@"
+
+CinnabarGymText_7599e:
+ TX_FAR _CinnabarGymText_7599e
+ db "@"
+
+CinnabarGymText4:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_2
+ jr nz, .asm_c0673
+ ld hl, CinnabarGymText_759c9
+ call PrintText
+ ld hl, CinnabarGymText_759ce
+ ld de, CinnabarGymText_759ce
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_c0673
+ ld hl, CinnabarGymText_759d3
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_759c9:
+ TX_FAR _CinnabarGymText_759c9
+ db "@"
+
+CinnabarGymText_759ce:
+ TX_FAR _CinnabarGymText_759ce
+ db "@"
+
+CinnabarGymText_759d3:
+ TX_FAR _CinnabarGymText_759d3
+ db "@"
+
+CinnabarGymText5:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_3
+ jr nz, .asm_5cfd7
+ ld hl, CinnabarGymText_759fe
+ call PrintText
+ ld hl, CinnabarGymText_75a03
+ ld de, CinnabarGymText_75a03
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_5cfd7
+ ld hl, CinnabarGymText_75a08
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_759fe:
+ TX_FAR _CinnabarGymText_759fe
+ db "@"
+
+CinnabarGymText_75a03:
+ TX_FAR _CinnabarGymText_75a03
+ db "@"
+
+CinnabarGymText_75a08:
+ TX_FAR _CinnabarGymText_75a08
+ db "@"
+
+CinnabarGymText6:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_4
+ jr nz, .asm_776b4
+ ld hl, CinnabarGymText_75a33
+ call PrintText
+ ld hl, CinnabarGymText_75a38
+ ld de, CinnabarGymText_75a38
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_776b4
+ ld hl, CinnabarGymText_75a3d
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_75a33:
+ TX_FAR _CinnabarGymText_75a33
+ db "@"
+
+CinnabarGymText_75a38:
+ TX_FAR _CinnabarGymText_75a38
+ db "@"
+
+CinnabarGymText_75a3d:
+ TX_FAR _CinnabarGymText_75a3d
+ db "@"
+
+CinnabarGymText7:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_5
+ jr nz, .asm_2f755
+ ld hl, CinnabarGymText_75a68
+ call PrintText
+ ld hl, CinnabarGymText_75a6d
+ ld de, CinnabarGymText_75a6d
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_2f755
+ ld hl, CinnabarGymText_75a72
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_75a68:
+ TX_FAR _CinnabarGymText_75a68
+ db "@"
+
+CinnabarGymText_75a6d:
+ TX_FAR _CinnabarGymText_75a6d
+ db "@"
+
+CinnabarGymText_75a72:
+ TX_FAR _CinnabarGymText_75a72
+ db "@"
+
+CinnabarGymText8:
+ TX_ASM
+ call CinnabarGymScript_757a0
+ CheckEvent EVENT_BEAT_CINNABAR_GYM_TRAINER_6
+ jr nz, .asm_d87be
+ ld hl, CinnabarGymText_75a9d
+ call PrintText
+ ld hl, CinnabarGymText_75aa2
+ ld de, CinnabarGymText_75aa2
+ call SaveEndBattleTextPointers
+ jp CinnabarGymScript_758b7
+.asm_d87be
+ ld hl, CinnabarGymText_75aa7
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_75a9d:
+ TX_FAR _CinnabarGymText_75a9d
+ db "@"
+
+CinnabarGymText_75aa2:
+ TX_FAR _CinnabarGymText_75aa2
+ db "@"
+
+CinnabarGymText_75aa7:
+ TX_FAR _CinnabarGymText_75aa7
+ db "@"
+
+CinnabarGymText9:
+ TX_ASM
+ CheckEvent EVENT_BEAT_BLAINE
+ jr nz, .asm_627d9
+ ld hl, CinnabarGymText_75ac2
+ jr .asm_0b11d
+.asm_627d9
+ ld hl, CinnabarGymText_75ac7
+.asm_0b11d
+ call PrintText
+ jp TextScriptEnd
+
+CinnabarGymText_75ac2:
+ TX_FAR _CinnabarGymText_75ac2
+ db "@"
+
+CinnabarGymText_75ac7:
+ TX_FAR _CinnabarGymText_75ac7
+ db "@"
diff --git a/en/scripts/fuchsiagym.asm b/en/scripts/fuchsiagym.asm
new file mode 100755
index 00000000..3628ebc0
--- /dev/null
+++ b/en/scripts/fuchsiagym.asm
@@ -0,0 +1,329 @@
+FuchsiaGymScript:
+ call FuchsiaGymScript_75453
+ call EnableAutoTextBoxDrawing
+ ld hl, FuchsiaGymTrainerHeader0
+ ld de, FuchsiaGymScriptPointers
+ ld a, [wFuchsiaGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wFuchsiaGymCurScript], a
+ ret
+
+FuchsiaGymScript_75453:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ ret z
+ ld hl, Gym5CityName
+ ld de, Gym5LeaderName
+ call LoadGymLeaderAndCityName
+ ret
+
+Gym5CityName:
+ db "FUCHSIA CITY@"
+Gym5LeaderName:
+ db "KOGA@"
+
+FuchsiaGymScript_75477:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wFuchsiaGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+FuchsiaGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw FuchsiaGymScript3
+
+FuchsiaGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, FuchsiaGymScript_75477
+ ld a, $f0
+ ld [wJoyIgnore], a
+FuchsiaGymScript3_75497:
+ ld a, $9
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_KOGA
+ lb bc, TM_06, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $a
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM06
+ jr .asm_754c0
+.BagFull
+ ld a, $b
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_754c0
+ ld hl, wObtainedBadges
+ set 4, [hl]
+ ld hl, wBeatGymFlags
+ set 4, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_FUCHSIA_GYM_TRAINER_0, EVENT_BEAT_FUCHSIA_GYM_TRAINER_5
+
+ jp FuchsiaGymScript_75477
+
+FuchsiaGymTextPointers:
+ dw FuchsiaGymText1
+ dw FuchsiaGymText2
+ dw FuchsiaGymText3
+ dw FuchsiaGymText4
+ dw FuchsiaGymText5
+ dw FuchsiaGymText6
+ dw FuchsiaGymText7
+ dw FuchsiaGymText8
+ dw FuchsiaGymText9
+ dw FuchsiaGymText10
+ dw FuchsiaGymText11
+
+FuchsiaGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_0
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_0
+ dw FuchsiaGymBattleText1 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText1 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText1 ; TextEndBattle
+ dw FuchsiaGymEndBattleText1 ; TextEndBattle
+
+FuchsiaGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_1
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_1
+ dw FuchsiaGymBattleText2 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText2 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText2 ; TextEndBattle
+ dw FuchsiaGymEndBattleText2 ; TextEndBattle
+
+FuchsiaGymTrainerHeader2:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_2
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_2
+ dw FuchsiaGymBattleText3 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText3 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText3 ; TextEndBattle
+ dw FuchsiaGymEndBattleText3 ; TextEndBattle
+
+FuchsiaGymTrainerHeader3:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_3
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_3
+ dw FuchsiaGymBattleText4 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText4 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText4 ; TextEndBattle
+ dw FuchsiaGymEndBattleText4 ; TextEndBattle
+
+FuchsiaGymTrainerHeader4:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_4
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_4
+ dw FuchsiaGymBattleText5 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText5 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText5 ; TextEndBattle
+ dw FuchsiaGymEndBattleText5 ; TextEndBattle
+
+FuchsiaGymTrainerHeader5:
+ dbEventFlagBit EVENT_BEAT_FUCHSIA_GYM_TRAINER_5
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_FUCHSIA_GYM_TRAINER_5
+ dw FuchsiaGymBattleText6 ; TextBeforeBattle
+ dw FuchsiaGymAfterBattleText6 ; TextAfterBattle
+ dw FuchsiaGymEndBattleText6 ; TextEndBattle
+ dw FuchsiaGymEndBattleText6 ; TextEndBattle
+
+ db $ff
+
+FuchsiaGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_KOGA
+ jr z, .asm_181b6
+ CheckEventReuseA EVENT_GOT_TM06
+ jr nz, .asm_adc3b
+ call z, FuchsiaGymScript3_75497
+ call DisableWaitingAfterTextDisplay
+ jr .asm_e84c6
+.asm_adc3b
+ ld hl, KogaExplainToxicText
+ call PrintText
+ jr .asm_e84c6
+.asm_181b6
+ ld hl, KogaBeforeBattleText
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, KogaAfterBattleText
+ ld de, KogaAfterBattleText
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $5
+ ld [wGymLeaderNo], a
+ xor a
+ ld [hJoyHeld], a
+ ld a, $3
+ ld [wFuchsiaGymCurScript], a
+.asm_e84c6
+ jp TextScriptEnd
+
+KogaBeforeBattleText:
+ TX_FAR _KogaBeforeBattleText
+ db "@"
+
+KogaAfterBattleText:
+ TX_FAR _KogaAfterBattleText
+ db "@"
+
+KogaExplainToxicText:
+ TX_FAR _KogaExplainToxicText
+ db "@"
+
+FuchsiaGymText9:
+ TX_FAR _FuchsiaGymText9
+ db "@"
+
+FuchsiaGymText10:
+ TX_FAR _ReceivedTM06Text
+ TX_SFX_KEY_ITEM
+
+TM06ExplanationText:
+ TX_FAR _TM06ExplanationText
+ db "@"
+
+FuchsiaGymText11:
+ TX_FAR _TM06NoRoomText
+ db "@"
+
+FuchsiaGymText2:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText1:
+ TX_FAR _FuchsiaGymBattleText1
+ db "@"
+
+FuchsiaGymEndBattleText1:
+ TX_FAR _FuchsiaGymEndBattleText1
+ db "@"
+
+FuchsiaGymAfterBattleText1:
+ TX_FAR _FuchsiaGymAfterBattleText1
+ db "@"
+
+FuchsiaGymText3:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText2:
+ TX_FAR _FuchsiaGymBattleText2
+ db "@"
+
+FuchsiaGymEndBattleText2:
+ TX_FAR _FuchsiaGymEndBattleText2
+ db "@"
+
+FuchsiaGymAfterBattleText2:
+ TX_FAR _FuchsiaGymAfterBattleText2
+ db "@"
+
+FuchsiaGymText4:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader2
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText3:
+ TX_FAR _FuchsiaGymBattleText3
+ db "@"
+
+FuchsiaGymEndBattleText3:
+ TX_FAR _FuchsiaGymEndBattleText3
+ db "@"
+
+FuchsiaGymAfterBattleText3:
+ TX_FAR _FuchsiaGymAfterBattleText3
+ db "@"
+
+FuchsiaGymText5:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader3
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText4:
+ TX_FAR _FuchsiaGymBattleText4
+ db "@"
+
+FuchsiaGymEndBattleText4:
+ TX_FAR _FuchsiaGymEndBattleText4
+ db "@"
+
+FuchsiaGymAfterBattleText4:
+ TX_FAR _FuchsiaGymAfterBattleText4
+ db "@"
+
+FuchsiaGymText6:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader4
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText5:
+ TX_FAR _FuchsiaGymBattleText5
+ db "@"
+
+FuchsiaGymEndBattleText5:
+ TX_FAR _FuchsiaGymEndBattleText5
+ db "@"
+
+FuchsiaGymAfterBattleText5:
+ TX_FAR _FuchsiaGymAfterBattleText5
+ db "@"
+
+FuchsiaGymText7:
+ TX_ASM
+ ld hl, FuchsiaGymTrainerHeader5
+ call TalkToTrainer
+ jp TextScriptEnd
+
+FuchsiaGymBattleText6:
+ TX_FAR _FuchsiaGymBattleText6
+ db "@"
+
+FuchsiaGymEndBattleText6:
+ TX_FAR _FuchsiaGymEndBattleText6
+ db "@"
+
+FuchsiaGymAfterBattleText6:
+ TX_FAR _FuchsiaGymAfterBattleText6
+ db "@"
+
+FuchsiaGymText8:
+ TX_ASM
+ CheckEvent EVENT_BEAT_KOGA
+ ld hl, FuchsiaGymText_75653
+ jr nz, .asm_50671
+ ld hl, FuchsiaGymText_7564e
+.asm_50671
+ call PrintText
+ jp TextScriptEnd
+
+FuchsiaGymText_7564e:
+ TX_FAR _FuchsiaGymText_7564e
+ db "@"
+
+FuchsiaGymText_75653:
+ TX_FAR _FuchsiaGymText_75653
+ db "@"
diff --git a/en/scripts/pewtercity.asm b/en/scripts/pewtercity.asm
new file mode 100755
index 00000000..80acede8
--- /dev/null
+++ b/en/scripts/pewtercity.asm
@@ -0,0 +1,322 @@
+PewterCityScript:
+ call EnableAutoTextBoxDrawing
+ ld hl, PewterCityScriptPointers
+ ld a, [wPewterCityCurScript]
+ jp CallFunctionInTable
+
+PewterCityScriptPointers:
+ dw PewterCityScript0
+ dw PewterCityScript1
+ dw PewterCityScript2
+ dw PewterCityScript3
+ dw PewterCityScript4
+ dw PewterCityScript5
+ dw PewterCityScript6
+
+PewterCityScript0:
+ xor a
+ ld [wMuseum1fCurScript], a
+ ResetEvent EVENT_BOUGHT_MUSEUM_TICKET
+ call PewterCityScript_1925e
+ ret
+
+PewterCityScript_1925e:
+ CheckEvent EVENT_BEAT_BROCK
+ ret nz
+ ld hl, CoordsData_19277
+ call ArePlayerCoordsInArray
+ ret nc
+ ld a, $f0
+ ld [wJoyIgnore], a
+ ld a, $5
+ ld [hSpriteIndexOrTextID], a
+ jp DisplayTextID
+
+CoordsData_19277:
+ db $11,$23
+ db $11,$24
+ db $12,$25
+ db $13,$25
+ db $ff
+
+PewterCityScript1:
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret nz
+ ld a, $3
+ ld [H_SPRITEINDEX], a
+ ld a, SPRITE_FACING_UP
+ ld [hSpriteFacingDirection], a
+ call SetSpriteFacingDirectionAndDelay
+ ld a, ($3 << 4) | SPRITE_FACING_UP
+ ld [hSpriteImageIndex], a
+ call SetSpriteImageIndexAfterSettingFacingDirection
+ call PlayDefaultMusic
+ ld hl, wFlags_0xcd60
+ set 4, [hl]
+ ld a, $d
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ ld a, $3c
+ ld [$ffeb], a
+ ld a, $30
+ ld [$ffec], a
+ ld a, $c
+ ld [$ffed], a
+ ld a, $11
+ ld [$ffee], a
+ ld a, $3
+ ld [wSpriteIndex], a
+ call SetSpritePosition1
+ ld a, $3
+ ld [H_SPRITEINDEX], a
+ ld de, MovementData_PewterMuseumGuyExit
+ call MoveSprite
+ ld a, $2
+ ld [wPewterCityCurScript], a
+ ret
+
+MovementData_PewterMuseumGuyExit:
+ db NPC_MOVEMENT_DOWN
+ db NPC_MOVEMENT_DOWN
+ db NPC_MOVEMENT_DOWN
+ db NPC_MOVEMENT_DOWN
+ db $FF
+
+PewterCityScript2:
+ ld a, [wd730]
+ bit 0, a
+ ret nz
+ ld a, HS_MUSEUM_GUY
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld a, $3
+ ld [wPewterCityCurScript], a
+ ret
+
+PewterCityScript3:
+ ld a, $3
+ ld [wSpriteIndex], a
+ call SetSpritePosition2
+ ld a, HS_MUSEUM_GUY
+ ld [wMissableObjectIndex], a
+ predef ShowObject
+ xor a
+ ld [wJoyIgnore], a
+ ld a, $0
+ ld [wPewterCityCurScript], a
+ ret
+
+PewterCityScript4:
+ ld a, [wNPCMovementScriptPointerTableNum]
+ and a
+ ret nz
+ ld a, $5
+ ld [H_SPRITEINDEX], a
+ ld a, SPRITE_FACING_LEFT
+ ld [hSpriteFacingDirection], a
+ call SetSpriteFacingDirectionAndDelay
+ ld a, ($1 << 4) | SPRITE_FACING_LEFT
+ ld [hSpriteImageIndex], a
+ call SetSpriteImageIndexAfterSettingFacingDirection
+ call PlayDefaultMusic
+ ld hl, wFlags_0xcd60
+ set 4, [hl]
+ ld a, $e
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ ld a, $3c
+ ld [$ffeb], a
+ ld a, $40
+ ld [$ffec], a
+ ld a, $16
+ ld [$ffed], a
+ ld a, $10
+ ld [$ffee], a
+ ld a, $5
+ ld [wSpriteIndex], a
+ call SetSpritePosition1
+ ld a, $5
+ ld [H_SPRITEINDEX], a
+ ld de, MovementData_PewterGymGuyExit
+ call MoveSprite
+ ld a, $5
+ ld [wPewterCityCurScript], a
+ ret
+
+MovementData_PewterGymGuyExit:
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db NPC_MOVEMENT_RIGHT
+ db $FF
+
+PewterCityScript5:
+ ld a, [wd730]
+ bit 0, a
+ ret nz
+ ld a, HS_GYM_GUY
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld a, $6
+ ld [wPewterCityCurScript], a
+ ret
+
+PewterCityScript6:
+ ld a, $5
+ ld [wSpriteIndex], a
+ call SetSpritePosition2
+ ld a, HS_GYM_GUY
+ ld [wMissableObjectIndex], a
+ predef ShowObject
+ xor a
+ ld [wJoyIgnore], a
+ ld a, $0
+ ld [wPewterCityCurScript], a
+ ret
+
+PewterCityTextPointers:
+ dw PewterCityText1
+ dw PewterCityText2
+ dw PewterCityText3
+ dw PewterCityText4
+ dw PewterCityText5
+ dw PewterCityText6
+ dw PewterCityText7
+ dw MartSignText
+ dw PokeCenterSignText
+ dw PewterCityText10
+ dw PewterCityText11
+ dw PewterCityText12
+ dw PewterCityText13
+ dw PewterCityText14
+
+PewterCityText1:
+ TX_FAR _PewterCityText1
+ db "@"
+
+PewterCityText2:
+ TX_FAR _PewterCityText2
+ db "@"
+
+PewterCityText3:
+ TX_ASM
+ ld hl, PewterCityText_193f1
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .asm_193c9
+ ld hl, PewterCityText_193f6
+ call PrintText
+ jr .asm_193ee
+.asm_193c9
+ ld hl, PewterCityText_193fb
+ call PrintText
+ xor a
+ ld [hJoyPressed], a
+ ld [hJoyHeld], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ld a, $2
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld a, [H_LOADEDROMBANK]
+ ld [wNPCMovementScriptBank], a
+ ld a, $3
+ ld [wSpriteIndex], a
+ call GetSpritePosition2
+ ld a, $1
+ ld [wPewterCityCurScript], a
+.asm_193ee
+ jp TextScriptEnd
+
+PewterCityText_193f1:
+ TX_FAR _PewterCityText_193f1
+ db "@"
+
+PewterCityText_193f6:
+ TX_FAR _PewterCityText_193f6
+ db "@"
+
+PewterCityText_193fb:
+ TX_FAR _PewterCityText_193fb
+ db "@"
+
+PewterCityText13:
+ TX_FAR _PewterCityText13
+ db "@"
+
+PewterCityText4:
+ TX_ASM
+ ld hl, PewterCityText_19427
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ cp $0
+ jr nz, .asm_1941e
+ ld hl, PewterCityText_1942c
+ call PrintText
+ jr .asm_19424
+.asm_1941e
+ ld hl, PewterCityText_19431
+ call PrintText
+.asm_19424
+ jp TextScriptEnd
+
+PewterCityText_19427:
+ TX_FAR _PewterCityText_19427
+ db "@"
+
+PewterCityText_1942c:
+ TX_FAR _PewterCityText_1942c
+ db "@"
+
+PewterCityText_19431:
+ TX_FAR _PewterCityText_19431
+ db "@"
+
+PewterCityText5:
+ TX_ASM
+ ld hl, PewterCityText_1945d
+ call PrintText
+ xor a
+ ld [hJoyHeld], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ld a, $3
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld a, [H_LOADEDROMBANK]
+ ld [wNPCMovementScriptBank], a
+ ld a, $5
+ ld [wSpriteIndex], a
+ call GetSpritePosition2
+ ld a, $4
+ ld [wPewterCityCurScript], a
+ jp TextScriptEnd
+
+PewterCityText_1945d:
+ TX_FAR _PewterCityText_1945d
+ db "@"
+
+PewterCityText14:
+ TX_FAR _PewterCityText14
+ db "@"
+
+PewterCityText6:
+ TX_FAR _PewterCityText6
+ db "@"
+
+PewterCityText7:
+ TX_FAR _PewterCityText7
+ db "@"
+
+PewterCityText10:
+ TX_FAR _PewterCityText10
+ db "@"
+
+PewterCityText11:
+ TX_FAR _PewterCityText11
+ db "@"
+
+PewterCityText12:
+ TX_FAR _PewterCityText12
+ db "@"
diff --git a/en/scripts/pewtergym.asm b/en/scripts/pewtergym.asm
new file mode 100755
index 00000000..2cfee6c0
--- /dev/null
+++ b/en/scripts/pewtergym.asm
@@ -0,0 +1,228 @@
+PewterGymScript:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ call nz, PewterGymScript_5c3a4
+ call EnableAutoTextBoxDrawing
+ ld hl, PewterGymTrainerHeader0
+ ld de, PewterGymScriptPointers
+ ld a, [wPewterGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wPewterGymCurScript], a
+ ret
+
+PewterGymScript_5c3a4:
+ ld hl, Gym1CityName
+ ld de, Gym1LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym1CityName:
+ db "PEWTER CITY@"
+
+Gym1LeaderName:
+ db "BROCK@"
+
+PewterGymScript_5c3bf:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wPewterGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+PewterGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw PewterGymScript3
+
+PewterGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, PewterGymScript_5c3bf
+ ld a, $f0
+ ld [wJoyIgnore], a
+
+PewterGymScript_5c3df:
+ ld a, $4
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_BROCK
+ lb bc, TM_34, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $5
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM34
+ jr .asm_5c408
+.BagFull
+ ld a, $6
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_5c408
+ ld hl, wObtainedBadges
+ set 0, [hl]
+ ld hl, wBeatGymFlags
+ set 0, [hl]
+
+ ld a, HS_GYM_GUY
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld a, HS_ROUTE_22_RIVAL_1
+ ld [wMissableObjectIndex], a
+ predef HideObject
+
+ ResetEvents EVENT_1ST_ROUTE22_RIVAL_BATTLE, EVENT_ROUTE22_RIVAL_WANTS_BATTLE
+
+ ; deactivate gym trainers
+ SetEvent EVENT_BEAT_PEWTER_GYM_TRAINER_0
+
+ jp PewterGymScript_5c3bf
+
+PewterGymTextPointers:
+ dw PewterGymText1
+ dw PewterGymText2
+ dw PewterGymText3
+ dw PewterGymText4
+ dw PewterGymText5
+ dw PewterGymText6
+
+PewterGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_PEWTER_GYM_TRAINER_0
+ db ($5 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_PEWTER_GYM_TRAINER_0
+ dw PewterGymBattleText1 ; TextBeforeBattle
+ dw PewterGymAfterBattleText1 ; TextAfterBattle
+ dw PewterGymEndBattleText1 ; TextEndBattle
+ dw PewterGymEndBattleText1 ; TextEndBattle
+
+ db $ff
+
+PewterGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_BROCK
+ jr z, .asm_5c46a
+ CheckEventReuseA EVENT_GOT_TM34
+ jr nz, .asm_5c462
+ call z, PewterGymScript_5c3df
+ call DisableWaitingAfterTextDisplay
+ jr .asm_5c49b
+.asm_5c462
+ ld hl, PewterGymText_5c4a3
+ call PrintText
+ jr .asm_5c49b
+.asm_5c46a
+ ld hl, PewterGymText_5c49e
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, PewterGymText_5c4bc
+ ld de, PewterGymText_5c4bc
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $1
+ ld [wGymLeaderNo], a
+ xor a
+ ld [hJoyHeld], a
+ ld a, $3
+ ld [wPewterGymCurScript], a
+ ld [wCurMapScript], a
+.asm_5c49b
+ jp TextScriptEnd
+
+PewterGymText_5c49e:
+ TX_FAR _PewterGymText_5c49e
+ db "@"
+
+PewterGymText_5c4a3:
+ TX_FAR _PewterGymText_5c4a3
+ db "@"
+
+PewterGymText4:
+ TX_FAR _TM34PreReceiveText
+ db "@"
+
+PewterGymText5:
+ TX_FAR _ReceivedTM34Text
+ TX_SFX_ITEM_1
+ TX_FAR _TM34ExplanationText
+ db "@"
+
+PewterGymText6:
+ TX_FAR _TM34NoRoomText
+ db "@"
+
+PewterGymText_5c4bc:
+ TX_FAR _PewterGymText_5c4bc
+ TX_SFX_LEVEL_UP ; probably supposed to play SFX_GET_ITEM_1 but the wrong music bank is loaded
+ TX_FAR _PewterGymText_5c4c1
+ db "@"
+
+PewterGymText2:
+ TX_ASM
+ ld hl, PewterGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+PewterGymBattleText1:
+ TX_FAR _PewterGymBattleText1
+ db "@"
+
+PewterGymEndBattleText1:
+ TX_FAR _PewterGymEndBattleText1
+ db "@"
+
+PewterGymAfterBattleText1:
+ TX_FAR _PewterGymAfterBattleText1
+ db "@"
+
+PewterGymText3:
+ TX_ASM
+ ld a, [wBeatGymFlags]
+ bit 0, a
+ jr nz, .asm_5c50c
+ ld hl, PewterGymText_5c515
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .asm_5c4fe
+ ld hl, PewterGymText_5c51a
+ call PrintText
+ jr .asm_5c504
+.asm_5c4fe
+ ld hl, PewterGymText_5c524
+ call PrintText
+.asm_5c504
+ ld hl, PewterGymText_5c51f
+ call PrintText
+ jr .asm_5c512
+.asm_5c50c
+ ld hl, PewterGymText_5c529
+ call PrintText
+.asm_5c512
+ jp TextScriptEnd
+
+PewterGymText_5c515:
+ TX_FAR _PewterGymText_5c515
+ db "@"
+
+PewterGymText_5c51a:
+ TX_FAR _PewterGymText_5c51a
+ db "@"
+
+PewterGymText_5c51f:
+ TX_FAR _PewterGymText_5c51f
+ db "@"
+
+PewterGymText_5c524:
+ TX_FAR _PewterGymText_5c524
+ db "@"
+
+PewterGymText_5c529:
+ TX_FAR _PewterGymText_5c529
+ db "@"
diff --git a/en/scripts/route23.asm b/en/scripts/route23.asm
new file mode 100755
index 00000000..4eb6b5f7
--- /dev/null
+++ b/en/scripts/route23.asm
@@ -0,0 +1,236 @@
+Route23Script:
+ call Route23Script_511e9
+ call EnableAutoTextBoxDrawing
+ ld hl, Route23ScriptPointers
+ ld a, [wRoute23CurScript]
+ jp CallFunctionInTable
+
+Route23Script_511e9:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ ret z
+ ResetEvents EVENT_VICTORY_ROAD_2_BOULDER_ON_SWITCH1, EVENT_VICTORY_ROAD_2_BOULDER_ON_SWITCH2
+ ResetEvents EVENT_VICTORY_ROAD_3_BOULDER_ON_SWITCH1, EVENT_VICTORY_ROAD_3_BOULDER_ON_SWITCH2
+ ld a, HS_VICTORY_ROAD_3_BOULDER
+ ld [wMissableObjectIndex], a
+ predef ShowObject
+ ld a, HS_VICTORY_ROAD_2_BOULDER
+ ld [wMissableObjectIndex], a
+ predef_jump HideObject
+
+Route23ScriptPointers:
+ dw Route23Script0
+ dw Route23Script1
+ dw Route23Script2
+
+Route23Script0:
+ ld hl, YCoordsData_51255
+ ld a, [wYCoord]
+ ld b, a
+ ld e, $0
+ EventFlagBit c, EVENT_PASSED_EARTHBADGE_CHECK + 1, EVENT_PASSED_CASCADEBADGE_CHECK
+.asm_51224
+ ld a, [hli]
+ cp $ff
+ ret z
+ inc e
+ dec c
+ cp b
+ jr nz, .asm_51224
+ cp $23
+ jr nz, .asm_51237
+ ld a, [wXCoord]
+ cp $e
+ ret nc
+.asm_51237
+ ld a, e
+ ld [hSpriteIndexOrTextID], a
+ ld a, c
+ ld [wWhichBadge], a
+ ld b, FLAG_TEST
+ EventFlagAddress hl, EVENT_PASSED_CASCADEBADGE_CHECK
+ predef FlagActionPredef
+ ld a, c
+ and a
+ ret nz
+ call Route23Script_5125d
+ call DisplayTextID
+ xor a
+ ld [hJoyHeld], a
+ ret
+
+YCoordsData_51255:
+ db $23,$38,$55,$60,$69,$77,$88,$FF
+
+Route23Script_5125d:
+ ld hl, BadgeTextPointers
+ ld a, [wWhichBadge]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wcd6d
+.copyTextLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp "@"
+ jr nz, .copyTextLoop
+ ret
+
+BadgeTextPointers:
+ dw CascadeBadgeText
+ dw ThunderBadgeText
+ dw RainbowBadgeText
+ dw SoulBadgeText
+ dw MarshBadgeText
+ dw VolcanoBadgeText
+ dw EarthBadgeText
+
+EarthBadgeText:
+ db "EARTHBADGE@"
+
+VolcanoBadgeText:
+ db "VOLCANOBADGE@"
+
+MarshBadgeText:
+ db "MARSHBADGE@"
+
+SoulBadgeText:
+ db "SOULBADGE@"
+
+RainbowBadgeText:
+ db "RAINBOWBADGE@"
+
+ThunderBadgeText:
+ db "THUNDERBADGE@"
+
+CascadeBadgeText:
+ db "CASCADEBADGE@"
+
+Route23Script_512d8:
+ ld a, $1
+ ld [wSimulatedJoypadStatesIndex], a
+ ld a, D_DOWN
+ ld [wSimulatedJoypadStatesEnd], a
+ xor a
+ ld [wSpriteStateData1 + 9], a
+ ld [wJoyIgnore], a
+ jp StartSimulatingJoypadStates
+
+Route23Script1:
+ ld a, [wSimulatedJoypadStatesIndex]
+ and a
+ ret nz
+Route23Script2:
+ ld a, $0
+ ld [wRoute23CurScript], a
+ ret
+
+Route23TextPointers:
+ dw Route23Text1
+ dw Route23Text2
+ dw Route23Text3
+ dw Route23Text4
+ dw Route23Text5
+ dw Route23Text6
+ dw Route23Text7
+ dw Route23Text8
+
+Route23Text1:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_EARTHBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text2:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_VOLCANOBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text3:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_MARSHBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text4:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_SOULBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text5:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_RAINBOWBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text6:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_THUNDERBADGE_CHECK, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Text7:
+ TX_ASM
+ EventFlagBit a, EVENT_PASSED_CASCADEBADGE_CHECK
+ call Route23Script_51346
+ jp TextScriptEnd
+
+Route23Script_51346:
+ ld [wWhichBadge], a
+ call Route23Script_5125d
+ ld a, [wWhichBadge]
+ inc a
+ ld c, a
+ ld b, FLAG_TEST
+ ld hl, wObtainedBadges
+ predef FlagActionPredef
+ ld a, c
+ and a
+ jr nz, .asm_5136e
+ ld hl, VictoryRoadGuardText1
+ call PrintText
+ call Route23Script_512d8
+ ld a, $1
+ ld [wRoute23CurScript], a
+ ret
+.asm_5136e
+ ld hl, VictoryRoadGuardText2
+ call PrintText
+ ld a, [wWhichBadge]
+ ld c, a
+ ld b, FLAG_SET
+ EventFlagAddress hl, EVENT_PASSED_CASCADEBADGE_CHECK
+ predef FlagActionPredef
+ ld a, $2
+ ld [wRoute23CurScript], a
+ ret
+
+Route23Script_51388:
+ ld hl, VictoryRoadGuardText2
+ jp PrintText
+
+VictoryRoadGuardText1:
+ TX_FAR _VictoryRoadGuardText1
+ TX_ASM
+ ld a, SFX_DENIED
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ jp TextScriptEnd
+
+VictoryRoadGuardText2:
+ TX_FAR _VictoryRoadGuardText2
+ TX_SFX_ITEM_1
+ TX_FAR _VictoryRoadGuardText_513a3
+ db "@"
+
+Route23Text8:
+ TX_FAR _Route23Text8
+ db "@"
diff --git a/en/scripts/saffrongym.asm b/en/scripts/saffrongym.asm
new file mode 100755
index 00000000..cbf935e7
--- /dev/null
+++ b/en/scripts/saffrongym.asm
@@ -0,0 +1,358 @@
+SaffronGymScript:
+ ld hl, wCurrentMapScriptFlags
+ bit 6, [hl]
+ res 6, [hl]
+ call nz, .extra
+ call EnableAutoTextBoxDrawing
+ ld hl, SaffronGymTrainerHeader0
+ ld de, SaffronGymScriptPointers
+ ld a, [wSaffronGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wSaffronGymCurScript], a
+ ret
+
+.extra
+ ld hl, Gym6CityName
+ ld de, Gym6LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym6CityName:
+ db "SAFFRON CITY@"
+
+Gym6LeaderName:
+ db "SABRINA@"
+
+SaffronGymText_5d048:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wSaffronGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+SaffronGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw SaffronGymScript3
+
+SaffronGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, SaffronGymText_5d048
+ ld a, $f0
+ ld [wJoyIgnore], a
+
+SaffronGymText_5d068:
+ ld a, $a
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_SABRINA
+ lb bc, TM_46, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $b
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM46
+ jr .asm_5d091
+.BagFull
+ ld a, $c
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_5d091
+ ld hl, wObtainedBadges
+ set 5, [hl]
+ ld hl, wBeatGymFlags
+ set 5, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_SAFFRON_GYM_TRAINER_0, EVENT_BEAT_SAFFRON_GYM_TRAINER_6
+
+ jp SaffronGymText_5d048
+
+SaffronGymTextPointers:
+ dw SaffronGymText1
+ dw SaffronGymText2
+ dw SaffronGymText3
+ dw SaffronGymText4
+ dw SaffronGymText5
+ dw SaffronGymText6
+ dw SaffronGymText7
+ dw SaffronGymText8
+ dw SaffronGymText9
+ dw SaffronGymText10
+ dw SaffronGymText11
+ dw SaffronGymText12
+
+SaffronGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_0
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_0
+ dw SaffronGymBattleText1 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText1 ; TextAfterBattle
+ dw SaffronGymEndBattleText1 ; TextEndBattle
+ dw SaffronGymEndBattleText1 ; TextEndBattle
+
+SaffronGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_1
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_1
+ dw SaffronGymBattleText2 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText2 ; TextAfterBattle
+ dw SaffronGymEndBattleText2 ; TextEndBattle
+ dw SaffronGymEndBattleText2 ; TextEndBattle
+
+SaffronGymTrainerHeader2:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_2
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_2
+ dw SaffronGymBattleText3 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText3 ; TextAfterBattle
+ dw SaffronGymEndBattleText3 ; TextEndBattle
+ dw SaffronGymEndBattleText3 ; TextEndBattle
+
+SaffronGymTrainerHeader3:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_3
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_3
+ dw SaffronGymBattleText4 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText4 ; TextAfterBattle
+ dw SaffronGymEndBattleText4 ; TextEndBattle
+ dw SaffronGymEndBattleText4 ; TextEndBattle
+
+SaffronGymTrainerHeader4:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_4
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_4
+ dw SaffronGymBattleText5 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText5 ; TextAfterBattle
+ dw SaffronGymEndBattleText5 ; TextEndBattle
+ dw SaffronGymEndBattleText5 ; TextEndBattle
+
+SaffronGymTrainerHeader5:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_5
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_5
+ dw SaffronGymBattleText6 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText6 ; TextAfterBattle
+ dw SaffronGymEndBattleText6 ; TextEndBattle
+ dw SaffronGymEndBattleText6 ; TextEndBattle
+
+SaffronGymTrainerHeader6:
+ dbEventFlagBit EVENT_BEAT_SAFFRON_GYM_TRAINER_6, 1
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_SAFFRON_GYM_TRAINER_6, 1
+ dw SaffronGymBattleText7 ; TextBeforeBattle
+ dw SaffronGymAfterBattleText7 ; TextAfterBattle
+ dw SaffronGymEndBattleText7 ; TextEndBattle
+ dw SaffronGymEndBattleText7 ; TextEndBattle
+
+ db $ff
+
+SaffronGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_SABRINA
+ jr z, .asm_5d134
+ CheckEventReuseA EVENT_GOT_TM46
+ jr nz, .asm_5d12c
+ call z, SaffronGymText_5d068
+ call DisableWaitingAfterTextDisplay
+ jr .asm_5d15f
+.asm_5d12c
+ ld hl, SaffronGymText_5d16e
+ call PrintText
+ jr .asm_5d15f
+.asm_5d134
+ ld hl, SaffronGymText_5d162
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, SaffronGymText_5d167
+ ld de, SaffronGymText_5d167
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $6
+ ld [wGymLeaderNo], a
+ ld a, $3
+ ld [wSaffronGymCurScript], a
+.asm_5d15f
+ jp TextScriptEnd
+
+SaffronGymText_5d162:
+ TX_FAR _SaffronGymText_5d162
+ db "@"
+
+SaffronGymText_5d167:
+ TX_FAR _SaffronGymText_5d167
+ TX_SFX_KEY_ITEM ; actually plays the second channel of SFX_BALL_POOF due to the wrong music bank being loaded
+ TX_BLINK
+ db "@"
+
+SaffronGymText_5d16e:
+ TX_FAR _SaffronGymText_5d16e
+ db "@"
+
+SaffronGymText10:
+ TX_FAR _SaffronGymText_5d173
+ db "@"
+
+SaffronGymText11:
+ TX_FAR ReceivedTM46Text
+ TX_SFX_ITEM_1
+ TX_FAR _TM46ExplanationText
+ db "@"
+
+SaffronGymText12:
+ TX_FAR _TM46NoRoomText
+ db "@"
+
+SaffronGymText2:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText3:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText4:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader2
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText5:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader3
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText6:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader4
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText7:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader5
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText8:
+ TX_ASM
+ ld hl, SaffronGymTrainerHeader6
+ call TalkToTrainer
+ jp TextScriptEnd
+
+SaffronGymText9:
+ TX_ASM
+ CheckEvent EVENT_BEAT_SABRINA
+ jr nz, .asm_5d1dd
+ ld hl, SaffronGymText_5d1e6
+ call PrintText
+ jr .asm_5d1e3
+.asm_5d1dd
+ ld hl, SaffronGymText_5d1eb
+ call PrintText
+.asm_5d1e3
+ jp TextScriptEnd
+
+SaffronGymText_5d1e6:
+ TX_FAR _SaffronGymText_5d1e6
+ db "@"
+
+SaffronGymText_5d1eb:
+ TX_FAR _SaffronGymText_5d1eb
+ db "@"
+
+SaffronGymBattleText1:
+ TX_FAR _SaffronGymBattleText1
+ db "@"
+
+SaffronGymEndBattleText1:
+ TX_FAR _SaffronGymEndBattleText1
+ db "@"
+
+SaffronGymAfterBattleText1:
+ TX_FAR _SaffronGymAfterBattleText1
+ db "@"
+
+SaffronGymBattleText2:
+ TX_FAR _SaffronGymBattleText2
+ db "@"
+
+SaffronGymEndBattleText2:
+ TX_FAR _SaffronGymEndBattleText2
+ db "@"
+
+SaffronGymAfterBattleText2:
+ TX_FAR _SaffronGymAfterBattleText2
+ db "@"
+
+SaffronGymBattleText3:
+ TX_FAR _SaffronGymBattleText3
+ db "@"
+
+SaffronGymEndBattleText3:
+ TX_FAR _SaffronGymEndBattleText3
+ db "@"
+
+SaffronGymAfterBattleText3:
+ TX_FAR _SaffronGymAfterBattleText3
+ db "@"
+
+SaffronGymBattleText4:
+ TX_FAR _SaffronGymBattleText4
+ db "@"
+
+SaffronGymEndBattleText4:
+ TX_FAR _SaffronGymEndBattleText4
+ db "@"
+
+SaffronGymAfterBattleText4:
+ TX_FAR _SaffronGymAfterBattleText4
+ db "@"
+
+SaffronGymBattleText5:
+ TX_FAR _SaffronGymBattleText5
+ db "@"
+
+SaffronGymEndBattleText5:
+ TX_FAR _SaffronGymEndBattleText5
+ db "@"
+
+SaffronGymAfterBattleText5:
+ TX_FAR _SaffronGymAfterBattleText5
+ db "@"
+
+SaffronGymBattleText6:
+ TX_FAR _SaffronGymBattleText6
+ db "@"
+
+SaffronGymEndBattleText6:
+ TX_FAR _SaffronGymEndBattleText6
+ db "@"
+
+SaffronGymAfterBattleText6:
+ TX_FAR _SaffronGymAfterBattleText6
+ db "@"
+
+SaffronGymBattleText7:
+ TX_FAR _SaffronGymBattleText7
+ db "@"
+
+SaffronGymEndBattleText7:
+ TX_FAR _SaffronGymEndBattleText7
+ db "@"
+
+SaffronGymAfterBattleText7:
+ TX_FAR _SaffronGymAfterBattleText7
+ db "@"
diff --git a/en/scripts/vermiliongym.asm b/en/scripts/vermiliongym.asm
new file mode 100755
index 00000000..c22ce9ce
--- /dev/null
+++ b/en/scripts/vermiliongym.asm
@@ -0,0 +1,267 @@
+VermilionGymScript:
+ ld hl, wCurrentMapScriptFlags
+ bit 5, [hl]
+ res 5, [hl]
+ push hl
+ call nz, VermilionGymScript_5ca4c
+ pop hl
+ bit 6, [hl]
+ res 6, [hl]
+ call nz, VermilionGymScript_5ca6d
+ call EnableAutoTextBoxDrawing
+ ld hl, VermilionGymTrainerHeader0
+ ld de, VermilionGymScriptPointers
+ ld a, [wVermilionGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wVermilionGymCurScript], a
+ ret
+
+VermilionGymScript_5ca4c:
+ ld hl, Gym3CityName
+ ld de, Gym3LeaderName
+ jp LoadGymLeaderAndCityName
+
+Gym3CityName:
+ db "VERMILION CITY@"
+
+Gym3LeaderName:
+ db "LT.SURGE@"
+
+VermilionGymScript_5ca6d:
+ CheckEvent EVENT_2ND_LOCK_OPENED
+ jr nz, .asm_5ca78
+ ld a, $24
+ jr .asm_5ca7f
+.asm_5ca78
+ ld a, SFX_GO_INSIDE
+ call PlaySound
+ ld a, $5
+.asm_5ca7f
+ ld [wNewTileBlockID], a
+ lb bc, 2, 2
+ predef_jump ReplaceTileBlock
+
+VermilionGymScript_5ca8a:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wVermilionGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+VermilionGymScriptPointers:
+ dw CheckFightingMapTrainers
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw VermilionGymScript3
+
+VermilionGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, VermilionGymScript_5ca8a
+ ld a, $f0
+ ld [wJoyIgnore], a
+
+VermilionGymScript_5caaa:
+ ld a, $6
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_LT_SURGE
+ lb bc, TM_24, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $7
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM24
+ jr .asm_5cad3
+.BagFull
+ ld a, $8
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_5cad3
+ ld hl, wObtainedBadges
+ set 2, [hl]
+ ld hl, wBeatGymFlags
+ set 2, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_VERMILION_GYM_TRAINER_0, EVENT_BEAT_VERMILION_GYM_TRAINER_2
+
+ jp VermilionGymScript_5ca8a
+
+VermilionGymTextPointers:
+ dw VermilionGymText1
+ dw VermilionGymText2
+ dw VermilionGymText3
+ dw VermilionGymText4
+ dw VermilionGymText5
+ dw VermilionGymText6
+ dw VermilionGymText7
+ dw VermilionGymText8
+
+VermilionGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_VERMILION_GYM_TRAINER_0
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VERMILION_GYM_TRAINER_0
+ dw VermilionGymBattleText1 ; TextBeforeBattle
+ dw VermilionGymAfterBattleText1 ; TextAfterBattle
+ dw VermilionGymEndBattleText1 ; TextEndBattle
+ dw VermilionGymEndBattleText1 ; TextEndBattle
+
+VermilionGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_VERMILION_GYM_TRAINER_1
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VERMILION_GYM_TRAINER_1
+ dw VermilionGymBattleText2 ; TextBeforeBattle
+ dw VermilionGymAfterBattleText2 ; TextAfterBattle
+ dw VermilionGymEndBattleText2 ; TextEndBattle
+ dw VermilionGymEndBattleText2 ; TextEndBattle
+
+VermilionGymTrainerHeader2:
+ dbEventFlagBit EVENT_BEAT_VERMILION_GYM_TRAINER_2
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VERMILION_GYM_TRAINER_2
+ dw VermilionGymBattleText3 ; TextBeforeBattle
+ dw VermilionGymAfterBattleText3 ; TextAfterBattle
+ dw VermilionGymEndBattleText3 ; TextEndBattle
+ dw VermilionGymEndBattleText3 ; TextEndBattle
+
+ db $ff
+
+VermilionGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_LT_SURGE
+ jr z, .asm_5cb39
+ CheckEventReuseA EVENT_GOT_TM24
+ jr nz, .asm_5cb31
+ call z, VermilionGymScript_5caaa
+ call DisableWaitingAfterTextDisplay
+ jr .asm_5cb6a
+.asm_5cb31
+ ld hl, VermilionGymText_5cb72
+ call PrintText
+ jr .asm_5cb6a
+.asm_5cb39
+ ld hl, VermilionGymText_5cb6d
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, ReceivedThunderbadgeText
+ ld de, ReceivedThunderbadgeText
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $3
+ ld [wGymLeaderNo], a
+ xor a
+ ld [hJoyHeld], a
+ ld a, $3
+ ld [wVermilionGymCurScript], a
+ ld [wCurMapScript], a
+.asm_5cb6a
+ jp TextScriptEnd
+
+VermilionGymText_5cb6d:
+ TX_FAR _VermilionGymText_5cb6d
+ db "@"
+
+VermilionGymText_5cb72:
+ TX_FAR _VermilionGymText_5cb72
+ db "@"
+
+VermilionGymText6:
+ TX_FAR _VermilionGymText_5cb77
+ db "@"
+
+VermilionGymText7:
+ TX_FAR _ReceivedTM24Text
+ TX_SFX_KEY_ITEM
+ TX_FAR _TM24ExplanationText
+ db "@"
+
+VermilionGymText8:
+ TX_FAR _TM24NoRoomText
+ db "@"
+
+ReceivedThunderbadgeText:
+ TX_FAR _ReceivedThunderbadgeText
+ db "@"
+
+VermilionGymText2:
+ TX_ASM
+ ld hl, VermilionGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+VermilionGymBattleText1:
+ TX_FAR _VermilionGymBattleText1
+ db "@"
+
+VermilionGymEndBattleText1:
+ TX_FAR _VermilionGymEndBattleText1
+ db "@"
+
+VermilionGymAfterBattleText1:
+ TX_FAR _VermilionGymAfterBattleText1
+ db "@"
+
+VermilionGymText3:
+ TX_ASM
+ ld hl, VermilionGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+VermilionGymBattleText2:
+ TX_FAR _VermilionGymBattleText2
+ db "@"
+
+VermilionGymEndBattleText2:
+ TX_FAR _VermilionGymEndBattleText2
+ db "@"
+
+VermilionGymAfterBattleText2:
+ TX_FAR _VermilionGymAfterBattleText2
+ db "@"
+
+VermilionGymText4:
+ TX_ASM
+ ld hl, VermilionGymTrainerHeader2
+ call TalkToTrainer
+ jp TextScriptEnd
+
+VermilionGymBattleText3:
+ TX_FAR _VermilionGymBattleText3
+ db "@"
+
+VermilionGymEndBattleText3:
+ TX_FAR _VermilionGymEndBattleText3
+ db "@"
+
+VermilionGymAfterBattleText3:
+ TX_FAR _VermilionGymAfterBattleText3
+ db "@"
+
+VermilionGymText5:
+ TX_ASM
+ ld a, [wBeatGymFlags]
+ bit 2, a
+ jr nz, .asm_5cbeb
+ ld hl, VermilionGymText_5cbf4
+ call PrintText
+ jr .asm_5cbf1
+.asm_5cbeb
+ ld hl, VermilionGymText_5cbf9
+ call PrintText
+.asm_5cbf1
+ jp TextScriptEnd
+
+VermilionGymText_5cbf4:
+ TX_FAR _VermilionGymText_5cbf4
+ db "@"
+
+VermilionGymText_5cbf9:
+ TX_FAR _VermilionGymText_5cbf9
+ db "@"
diff --git a/en/scripts/viridiangym.asm b/en/scripts/viridiangym.asm
new file mode 100755
index 00000000..cc8dcb90
--- /dev/null
+++ b/en/scripts/viridiangym.asm
@@ -0,0 +1,496 @@
+ViridianGymScript:
+ ld hl, Gym8CityName
+ ld de, Gym8LeaderName
+ call LoadGymLeaderAndCityName
+ call EnableAutoTextBoxDrawing
+ ld hl, ViridianGymTrainerHeader0
+ ld de, ViridianGymScriptPointers
+ ld a, [wViridianGymCurScript]
+ call ExecuteCurMapScriptInTable
+ ld [wViridianGymCurScript], a
+ ret
+
+Gym8CityName:
+ db "VIRIDIAN CITY@"
+Gym8LeaderName:
+ db "GIOVANNI@"
+
+ViridianGymScript_748d6:
+ xor a
+ ld [wJoyIgnore], a
+ ld [wViridianGymCurScript], a
+ ld [wCurMapScript], a
+ ret
+
+ViridianGymScriptPointers:
+ dw ViridianGymScript0
+ dw DisplayEnemyTrainerTextAndStartBattle
+ dw EndTrainerBattle
+ dw ViridianGymScript3
+ dw ViridianGymScript4
+
+ViridianGymScript0:
+ ld a, [wYCoord]
+ ld b, a
+ ld a, [wXCoord]
+ ld c, a
+ ld hl, ViridianGymArrowTilePlayerMovement
+ call DecodeArrowMovementRLE
+ cp $ff
+ jp z, CheckFightingMapTrainers
+ call StartSimulatingJoypadStates
+ ld hl, wd736
+ set 7, [hl]
+ ld a, SFX_ARROW_TILES
+ call PlaySound
+ ld a, $ff
+ ld [wJoyIgnore], a
+ ld a, $4
+ ld [wCurMapScript], a
+ ret
+
+;format:
+;db y,x
+;dw pointer to movement
+ViridianGymArrowTilePlayerMovement:
+ db $b,$13
+ dw ViridianGymArrowMovement1
+ db $1,$13
+ dw ViridianGymArrowMovement2
+ db $2,$12
+ dw ViridianGymArrowMovement3
+ db $2,$b
+ dw ViridianGymArrowMovement4
+ db $a,$10
+ dw ViridianGymArrowMovement5
+ db $6,$4
+ dw ViridianGymArrowMovement6
+ db $d,$5
+ dw ViridianGymArrowMovement7
+ db $e,$4
+ dw ViridianGymArrowMovement8
+ db $f,$0
+ dw ViridianGymArrowMovement9
+ db $f,$1
+ dw ViridianGymArrowMovement10
+ db $10,$d
+ dw ViridianGymArrowMovement11
+ db $11,$d
+ dw ViridianGymArrowMovement12
+ db $FF
+
+;format: direction, count
+ViridianGymArrowMovement1:
+ db D_UP,$09,$FF
+
+ViridianGymArrowMovement2:
+ db D_LEFT,$08,$FF
+
+ViridianGymArrowMovement3:
+ db D_DOWN,$09,$FF
+
+ViridianGymArrowMovement4:
+ db D_RIGHT,$06,$FF
+
+ViridianGymArrowMovement5:
+ db D_DOWN,$02,$FF
+
+ViridianGymArrowMovement6:
+ db D_DOWN,$07,$FF
+
+ViridianGymArrowMovement7:
+ db D_RIGHT,$08,$FF
+
+ViridianGymArrowMovement8:
+ db D_RIGHT,$09,$FF
+
+ViridianGymArrowMovement9:
+ db D_UP,$08,$FF
+
+ViridianGymArrowMovement10:
+ db D_UP,$06,$FF
+
+ViridianGymArrowMovement11:
+ db D_LEFT,$06,$FF
+
+ViridianGymArrowMovement12:
+ db D_LEFT,$0C,$FF
+
+ViridianGymScript4:
+ ld a, [wSimulatedJoypadStatesIndex]
+ and a
+ jr nz, .asm_74980
+ xor a
+ ld [wJoyIgnore], a
+ ld hl, wd736
+ res 7, [hl]
+ ld a, $0
+ ld [wCurMapScript], a
+ ret
+.asm_74980
+ jpba LoadSpinnerArrowTiles
+
+ViridianGymScript3:
+ ld a, [wIsInBattle]
+ cp $ff
+ jp z, ViridianGymScript_748d6
+ ld a, $f0
+ ld [wJoyIgnore], a
+ViridianGymScript3_74995:
+ ld a, $c
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_BEAT_VIRIDIAN_GYM_GIOVANNI
+ lb bc, TM_27, 1
+ call GiveItem
+ jr nc, .BagFull
+ ld a, $d
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ SetEvent EVENT_GOT_TM27
+ jr .asm_749be
+.BagFull
+ ld a, $e
+ ld [hSpriteIndexOrTextID], a
+ call DisplayTextID
+.asm_749be
+ ld hl, wObtainedBadges
+ set 7, [hl]
+ ld hl, wBeatGymFlags
+ set 7, [hl]
+
+ ; deactivate gym trainers
+ SetEventRange EVENT_BEAT_VIRIDIAN_GYM_TRAINER_0, EVENT_BEAT_VIRIDIAN_GYM_TRAINER_7
+
+ ld a, HS_ROUTE_22_RIVAL_2
+ ld [wMissableObjectIndex], a
+ predef ShowObject
+ SetEvents EVENT_2ND_ROUTE22_RIVAL_BATTLE, EVENT_ROUTE22_RIVAL_WANTS_BATTLE
+ jp ViridianGymScript_748d6
+
+ViridianGymTextPointers:
+ dw ViridianGymText1
+ dw ViridianGymText2
+ dw ViridianGymText3
+ dw ViridianGymText4
+ dw ViridianGymText5
+ dw ViridianGymText6
+ dw ViridianGymText7
+ dw ViridianGymText8
+ dw ViridianGymText9
+ dw ViridianGymText10
+ dw PickUpItemText
+ dw ViridianGymText12
+ dw ViridianGymText13
+ dw ViridianGymText14
+
+ViridianGymTrainerHeader0:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_0
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_0
+ dw ViridianGymBattleText1 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText1 ; TextAfterBattle
+ dw ViridianGymEndBattleText1 ; TextEndBattle
+ dw ViridianGymEndBattleText1 ; TextEndBattle
+
+ViridianGymTrainerHeader1:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_1
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_1
+ dw ViridianGymBattleText2 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText2 ; TextAfterBattle
+ dw ViridianGymEndBattleText2 ; TextEndBattle
+ dw ViridianGymEndBattleText2 ; TextEndBattle
+
+ViridianGymTrainerHeader2:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_2
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_2
+ dw ViridianGymBattleText3 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText3 ; TextAfterBattle
+ dw ViridianGymEndBattleText3 ; TextEndBattle
+ dw ViridianGymEndBattleText3 ; TextEndBattle
+
+ViridianGymTrainerHeader3:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_3
+ db ($2 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_3
+ dw ViridianGymBattleText4 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText4 ; TextAfterBattle
+ dw ViridianGymEndBattleText4 ; TextEndBattle
+ dw ViridianGymEndBattleText4 ; TextEndBattle
+
+ViridianGymTrainerHeader4:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_4
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_4
+ dw ViridianGymBattleText5 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText5 ; TextAfterBattle
+ dw ViridianGymEndBattleText5 ; TextEndBattle
+ dw ViridianGymEndBattleText5 ; TextEndBattle
+
+ViridianGymTrainerHeader5:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_5
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_5
+ dw ViridianGymBattleText6 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText6 ; TextAfterBattle
+ dw ViridianGymEndBattleText6 ; TextEndBattle
+ dw ViridianGymEndBattleText6 ; TextEndBattle
+
+ViridianGymTrainerHeader6:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_6, 1
+ db ($3 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_6, 1
+ dw ViridianGymBattleText7 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText7 ; TextAfterBattle
+ dw ViridianGymEndBattleText7 ; TextEndBattle
+ dw ViridianGymEndBattleText7 ; TextEndBattle
+
+ViridianGymTrainerHeader7:
+ dbEventFlagBit EVENT_BEAT_VIRIDIAN_GYM_TRAINER_7, 1
+ db ($4 << 4) ; trainer's view range
+ dwEventFlagAddress EVENT_BEAT_VIRIDIAN_GYM_TRAINER_7, 1
+ dw ViridianGymBattleText8 ; TextBeforeBattle
+ dw ViridianGymAfterBattleText8 ; TextAfterBattle
+ dw ViridianGymEndBattleText8 ; TextEndBattle
+ dw ViridianGymEndBattleText8 ; TextEndBattle
+
+ db $ff
+
+ViridianGymText1:
+ TX_ASM
+ CheckEvent EVENT_BEAT_VIRIDIAN_GYM_GIOVANNI
+ jr z, .asm_6de66
+ CheckEventReuseA EVENT_GOT_TM27
+ jr nz, .asm_9fc95
+ call z, ViridianGymScript3_74995
+ call DisableWaitingAfterTextDisplay
+ jr .asm_6dff7
+.asm_9fc95
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld hl, ViridianGymText_74ad9
+ call PrintText
+ call GBFadeOutToBlack
+ ld a, HS_VIRIDIAN_GYM_GIOVANNI
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ call UpdateSprites
+ call Delay3
+ call GBFadeInFromBlack
+ jr .asm_6dff7
+.asm_6de66
+ ld hl, ViridianGymText_74ace
+ call PrintText
+ ld hl, wd72d
+ set 6, [hl]
+ set 7, [hl]
+ ld hl, ViridianGymText_74ad3
+ ld de, ViridianGymText_74ad3
+ call SaveEndBattleTextPointers
+ ld a, [H_SPRITEINDEX]
+ ld [wSpriteIndex], a
+ call EngageMapTrainer
+ call InitBattleEnemyParameters
+ ld a, $8
+ ld [wGymLeaderNo], a
+ ld a, $3
+ ld [wViridianGymCurScript], a
+.asm_6dff7
+ jp TextScriptEnd
+
+ViridianGymText_74ace:
+ TX_FAR _ViridianGymText_74ace
+ db "@"
+
+ViridianGymText_74ad3:
+ TX_FAR _ViridianGymText_74ad3
+ TX_SFX_LEVEL_UP ; probably supposed to play SFX_GET_ITEM_1 but the wrong music bank is loaded
+ db "@"
+
+ViridianGymText_74ad9:
+ TX_FAR _ViridianGymText_74ad9
+ TX_WAIT
+ db "@"
+
+ViridianGymText12:
+ TX_FAR _ViridianGymText12
+ db "@"
+
+ViridianGymText13:
+ TX_FAR _ReceivedTM27Text
+ TX_SFX_ITEM_1
+
+TM27ExplanationText:
+ TX_FAR _TM27ExplanationText
+ db "@"
+
+ViridianGymText14:
+ TX_FAR _TM27NoRoomText
+ db "@"
+
+ViridianGymText2:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader0
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText1:
+ TX_FAR _ViridianGymBattleText1
+ db "@"
+
+ViridianGymEndBattleText1:
+ TX_FAR _ViridianGymEndBattleText1
+ db "@"
+
+ViridianGymAfterBattleText1:
+ TX_FAR _ViridianGymAfterBattleText1
+ db "@"
+
+ViridianGymText3:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader1
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText2:
+ TX_FAR _ViridianGymBattleText2
+ db "@"
+
+ViridianGymEndBattleText2:
+ TX_FAR _ViridianGymEndBattleText2
+ db "@"
+
+ViridianGymAfterBattleText2:
+ TX_FAR _ViridianGymAfterBattleText2
+ db "@"
+
+ViridianGymText4:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader2
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText3:
+ TX_FAR _ViridianGymBattleText3
+ db "@"
+
+ViridianGymEndBattleText3:
+ TX_FAR _ViridianGymEndBattleText3
+ db "@"
+
+ViridianGymAfterBattleText3:
+ TX_FAR _ViridianGymAfterBattleText3
+ db "@"
+
+ViridianGymText5:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader3
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText4:
+ TX_FAR _ViridianGymBattleText4
+ db "@"
+
+ViridianGymEndBattleText4:
+ TX_FAR _ViridianGymEndBattleText4
+ db "@"
+
+ViridianGymAfterBattleText4:
+ TX_FAR _ViridianGymAfterBattleText4
+ db "@"
+
+ViridianGymText6:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader4
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText5:
+ TX_FAR _ViridianGymBattleText5
+ db "@"
+
+ViridianGymEndBattleText5:
+ TX_FAR _ViridianGymEndBattleText5
+ db "@"
+
+ViridianGymAfterBattleText5:
+ TX_FAR _ViridianGymAfterBattleText5
+ db "@"
+
+ViridianGymText7:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader5
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText6:
+ TX_FAR _ViridianGymBattleText6
+ db "@"
+
+ViridianGymEndBattleText6:
+ TX_FAR _ViridianGymEndBattleText6
+ db "@"
+
+ViridianGymAfterBattleText6:
+ TX_FAR _ViridianGymAfterBattleText6
+ db "@"
+
+ViridianGymText8:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader6
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText7:
+ TX_FAR _ViridianGymBattleText7
+ db "@"
+
+ViridianGymEndBattleText7:
+ TX_FAR _ViridianGymEndBattleText7
+ db "@"
+
+ViridianGymAfterBattleText7:
+ TX_FAR _ViridianGymAfterBattleText7
+ db "@"
+
+ViridianGymText9:
+ TX_ASM
+ ld hl, ViridianGymTrainerHeader7
+ call TalkToTrainer
+ jp TextScriptEnd
+
+ViridianGymBattleText8:
+ TX_FAR _ViridianGymBattleText8
+ db "@"
+
+ViridianGymEndBattleText8:
+ TX_FAR _ViridianGymEndBattleText8
+ db "@"
+
+ViridianGymAfterBattleText8:
+ TX_FAR _ViridianGymAfterBattleText8
+ db "@"
+
+ViridianGymText10:
+ TX_ASM
+ CheckEvent EVENT_BEAT_VIRIDIAN_GYM_GIOVANNI
+ jr nz, .asm_1abd1
+ ld hl, ViridianGymText_74bd4
+ call PrintText
+ jr .asm_6064d
+.asm_1abd1
+ ld hl, ViridianGymText_74bd9
+ call PrintText
+.asm_6064d
+ jp TextScriptEnd
+
+ViridianGymText_74bd4:
+ TX_FAR _ViridianGymText_74bd4
+ db "@"
+
+ViridianGymText_74bd9:
+ TX_FAR _ViridianGymText_74bd9
+ db "@"
diff --git a/en/text/credits_text.asm b/en/text/credits_text.asm
new file mode 100755
index 00000000..a68c33d3
--- /dev/null
+++ b/en/text/credits_text.asm
@@ -0,0 +1,199 @@
+CreditsTextPointers:
+ dw CredVersion
+ dw CredTajiri
+ dw CredTaOota
+ dw CredMorimoto
+ dw CredWatanabe
+ dw CredMasuda
+ dw CredNisino
+ dw CredSugimori
+ dw CredNishida
+ dw CredMiyamoto
+ dw CredKawaguchi
+ dw CredIshihara
+ dw CredYamauchi
+ dw CredZinnai
+ dw CredHishida
+ dw CredSakai
+ dw CredYamaguchi
+ dw CredYamamoto
+ dw CredTaniguchi
+ dw CredNonomura
+ dw CredFuziwara
+ dw CredMatsusima
+ dw CredTomisawa
+ dw CredKawamoto
+ dw CredKakei
+ dw CredTsuchiya
+ dw CredTaNakamura
+ dw CredYuda
+ dw CredMon
+ dw CredDirector
+ dw CredProgrammers
+ dw CredCharDesign
+ dw CredMusic
+ dw CredSoundEffects
+ dw CredGameDesign
+ dw CredMonsterDesign
+ dw CredGameScene
+ dw CredParam
+ dw CredMap
+ dw CredTest
+ dw CredSpecial
+ dw CredProducers
+ dw CredProducer
+ dw CredExecutive
+ dw CredTamada
+ dw CredSaOota
+ dw CredYoshikawa
+ dw CredToOota
+ dw CredUSStaff
+ dw CredUSCoord
+ dw CredTilden
+ dw CredKawakami
+ dw CredHiNakamura
+ dw CredGiese
+ dw CredOsborne
+ dw CredTrans
+ dw CredOgasawara
+ dw CredIwata
+ dw CredIzushi
+ dw CredHarada
+ dw CredMurakawa
+ dw CredFukui
+ dw CredClub
+ dw CredPAAD
+
+CredVersion: ; this 1 byte difference makes all bank addresses offset by 1 in the blue version
+IF DEF(_RED)
+ db -8, "RED VERSION STAFF@"
+ENDC
+IF DEF(_BLUE)
+ db -8, "BLUE VERSION STAFF@"
+ENDC
+CredTajiri:
+ db -6, "SATOSHI TAJIRI@"
+CredTaOota:
+ db -6, "TAKENORI OOTA@"
+CredMorimoto:
+ db -7, "SHIGEKI MORIMOTO@"
+CredWatanabe:
+ db -7, "TETSUYA WATANABE@"
+CredMasuda:
+ db -6, "JUNICHI MASUDA@"
+CredNisino:
+ db -5, "KOHJI NISINO@"
+CredSugimori:
+ db -5, "KEN SUGIMORI@"
+CredNishida:
+ db -6, "ATSUKO NISHIDA@"
+CredMiyamoto:
+ db -7, "SHIGERU MIYAMOTO@"
+CredKawaguchi:
+ db -8, "TAKASHI KAWAGUCHI@"
+CredIshihara:
+ db -8, "TSUNEKAZU ISHIHARA@"
+CredYamauchi:
+ db -7, "HIROSHI YAMAUCHI@"
+CredZinnai:
+ db -7, "HIROYUKI ZINNAI@"
+CredHishida:
+ db -7, "TATSUYA HISHIDA@"
+CredSakai:
+ db -6, "YASUHIRO SAKAI@"
+CredYamaguchi:
+ db -7, "WATARU YAMAGUCHI@"
+CredYamamoto:
+ db -8, "KAZUYUKI YAMAMOTO@"
+CredTaniguchi:
+ db -8, "RYOHSUKE TANIGUCHI@"
+CredNonomura:
+ db -8, "FUMIHIRO NONOMURA@"
+CredFuziwara:
+ db -7, "MOTOFUMI FUZIWARA@"
+CredMatsusima:
+ db -7, "KENJI MATSUSIMA@"
+CredTomisawa:
+ db -7, "AKIHITO TOMISAWA@"
+CredKawamoto:
+ db -7, "HIROSHI KAWAMOTO@"
+CredKakei:
+ db -6, "AKIYOSHI KAKEI@"
+CredTsuchiya:
+ db -7, "KAZUKI TSUCHIYA@"
+CredTaNakamura:
+ db -6, "TAKEO NAKAMURA@"
+CredYuda:
+ db -6, "MASAMITSU YUDA@"
+CredMon:
+ db -3, "#MON@"
+CredDirector:
+ db -3, "DIRECTOR@"
+CredProgrammers:
+ db -5, "PROGRAMMERS@"
+CredCharDesign:
+ db -7, "CHARACTER DESIGN@"
+CredMusic:
+ db -2, "MUSIC@"
+CredSoundEffects:
+ db -6, "SOUND EFFECTS@"
+CredGameDesign:
+ db -5, "GAME DESIGN@"
+CredMonsterDesign:
+ db -6, "MONSTER DESIGN@"
+CredGameScene:
+ db -6, "GAME SCENARIO@"
+CredParam:
+ db -8, "PARAMETRIC DESIGN@"
+CredMap:
+ db -4, "MAP DESIGN@"
+CredTest:
+ db -7, "PRODUCT TESTING@"
+CredSpecial:
+ db -6, "SPECIAL THANKS@"
+CredProducers:
+ db -4, "PRODUCERS@"
+CredProducer:
+ db -4, "PRODUCER@"
+CredExecutive:
+ db -8, "EXECUTIVE PRODUCER@"
+CredTamada:
+ db -6, "SOUSUKE TAMADA@"
+CredSaOota:
+ db -5, "SATOSHI OOTA@"
+CredYoshikawa:
+ db -6, "RENA YOSHIKAWA@"
+CredToOota:
+ db -6, "TOMOMICHI OOTA@"
+CredUSStaff:
+ db -7, "US VERSION STAFF@"
+CredUSCoord:
+ db -7, "US COORDINATION@"
+CredTilden:
+ db -5, "GAIL TILDEN@"
+CredKawakami:
+ db -6, "NAOKO KAWAKAMI@"
+CredHiNakamura:
+ db -6, "HIRO NAKAMURA@"
+CredGiese:
+ db -6, "WILLIAM GIESE@"
+CredOsborne:
+ db -5, "SARA OSBORNE@"
+CredTrans:
+ db -7, "TEXT TRANSLATION@"
+CredOgasawara:
+ db -6, "NOB OGASAWARA@"
+CredIwata:
+ db -5, "SATORU IWATA@"
+CredIzushi:
+ db -7, "TAKEHIRO IZUSHI@"
+CredHarada:
+ db -7, "TAKAHIRO HARADA@"
+CredMurakawa:
+ db -7, "TERUKI MURAKAWA@"
+CredFukui:
+ db -5, "KOHTA FUKUI@"
+CredClub:
+ db -9, "NCL SUPER MARIO CLUB@"
+CredPAAD:
+ db -5, "PAAD TESTING@"
diff --git a/en/text/item_names.asm b/en/text/item_names.asm
new file mode 100755
index 00000000..e436d74d
--- /dev/null
+++ b/en/text/item_names.asm
@@ -0,0 +1,98 @@
+ItemNames:
+ db "MASTER BALL@"
+ db "ULTRA BALL@"
+ db "GREAT BALL@"
+ db "POKé BALL@"
+ db "TOWN MAP@"
+ db "BICYCLE@"
+ db "?????@"
+ db "SAFARI BALL@"
+ db "POKéDEX@"
+ db "MOON STONE@"
+ db "ANTIDOTE@"
+ db "BURN HEAL@"
+ db "ICE HEAL@"
+ db "AWAKENING@"
+ db "PARLYZ HEAL@"
+ db "FULL RESTORE@"
+ db "MAX POTION@"
+ db "HYPER POTION@"
+ db "SUPER POTION@"
+ db "POTION@"
+ db "BOULDERBADGE@"
+ db "CASCADEBADGE@"
+ db "THUNDERBADGE@"
+ db "RAINBOWBADGE@"
+ db "SOULBADGE@"
+ db "MARSHBADGE@"
+ db "VOLCANOBADGE@"
+ db "EARTHBADGE@"
+ db "ESCAPE ROPE@"
+ db "REPEL@"
+ db "OLD AMBER@"
+ db "FIRE STONE@"
+ db "THUNDERSTONE@"
+ db "WATER STONE@"
+ db "HP UP@"
+ db "PROTEIN@"
+ db "IRON@"
+ db "CARBOS@"
+ db "CALCIUM@"
+ db "RARE CANDY@"
+ db "DOME FOSSIL@"
+ db "HELIX FOSSIL@"
+ db "SECRET KEY@"
+ db "?????@"
+ db "BIKE VOUCHER@"
+ db "X ACCURACY@"
+ db "LEAF STONE@"
+ db "CARD KEY@"
+ db "NUGGET@"
+ db "PP UP@"
+ db "POKé DOLL@"
+ db "FULL HEAL@"
+ db "REVIVE@"
+ db "MAX REVIVE@"
+ db "GUARD SPEC.@"
+ db "SUPER REPEL@"
+ db "MAX REPEL@"
+ db "DIRE HIT@"
+ db "COIN@"
+ db "FRESH WATER@"
+ db "SODA POP@"
+ db "LEMONADE@"
+ db "S.S.TICKET@"
+ db "GOLD TEETH@"
+ db "X ATTACK@"
+ db "X DEFEND@"
+ db "X SPEED@"
+ db "X SPECIAL@"
+ db "COIN CASE@"
+ db "OAK's PARCEL@"
+ db "ITEMFINDER@"
+ db "SILPH SCOPE@"
+ db "POKé FLUTE@"
+ db "LIFT KEY@"
+ db "EXP.ALL@"
+ db "OLD ROD@"
+ db "GOOD ROD@"
+ db "SUPER ROD@"
+ db "PP UP@"
+ db "ETHER@"
+ db "MAX ETHER@"
+ db "ELIXER@"
+ db "MAX ELIXER@"
+ db "B2F@"
+ db "B1F@"
+ db "1F@"
+ db "2F@"
+ db "3F@"
+ db "4F@"
+ db "5F@"
+ db "6F@"
+ db "7F@"
+ db "8F@"
+ db "9F@"
+ db "10F@"
+ db "11F@"
+ db "B4F@"
diff --git a/en/text/map_names.asm b/en/text/map_names.asm
new file mode 100755
index 00000000..cd9f6640
--- /dev/null
+++ b/en/text/map_names.asm
@@ -0,0 +1,107 @@
+MapNames:
+PalletTownName:
+ db "PALLET TOWN@"
+ViridianCityName:
+ db "VIRIDIAN CITY@"
+PewterCityName:
+ db "PEWTER CITY@"
+CeruleanCityName:
+ db "CERULEAN CITY@"
+LavenderTownName:
+ db "LAVENDER TOWN@"
+VermilionCityName:
+ db "VERMILION CITY@"
+CeladonCityName:
+ db "CELADON CITY@"
+FuchsiaCityName:
+ db "FUCHSIA CITY@"
+CinnabarIslandName:
+ db "CINNABAR ISLAND@"
+IndigoPlateauName:
+ db "INDIGO PLATEAU@"
+SaffronCityName:
+ db "SAFFRON CITY@"
+Route1Name:
+ db "ROUTE 1@"
+Route2Name:
+ db "ROUTE 2@"
+Route3Name:
+ db "ROUTE 3@"
+Route4Name:
+ db "ROUTE 4@"
+Route5Name:
+ db "ROUTE 5@"
+Route6Name:
+ db "ROUTE 6@"
+Route7Name:
+ db "ROUTE 7@"
+Route8Name:
+ db "ROUTE 8@"
+Route9Name:
+ db "ROUTE 9@"
+Route10Name:
+ db "ROUTE 10@"
+Route11Name:
+ db "ROUTE 11@"
+Route12Name:
+ db "ROUTE 12@"
+Route13Name:
+ db "ROUTE 13@"
+Route14Name:
+ db "ROUTE 14@"
+Route15Name:
+ db "ROUTE 15@"
+Route16Name:
+ db "ROUTE 16@"
+Route17Name:
+ db "ROUTE 17@"
+Route18Name:
+ db "ROUTE 18@"
+Route19Name:
+ db "SEA ROUTE 19@"
+Route20Name:
+ db "SEA ROUTE 20@"
+Route21Name:
+ db "SEA ROUTE 21@"
+Route22Name:
+ db "ROUTE 22@"
+Route23Name:
+ db "ROUTE 23@"
+Route24Name:
+ db "ROUTE 24@"
+Route25Name:
+ db "ROUTE 25@"
+ViridianForestName:
+ db "VIRIDIAN FOREST@"
+MountMoonName:
+ db "MT.MOON@"
+RockTunnelName:
+ db "ROCK TUNNEL@"
+SeaCottageName:
+ db "SEA COTTAGE@"
+SSAnneName:
+ db "S.S.ANNE@"
+PokemonLeagueName:
+ db "#MON LEAGUE@"
+UndergroundPathName:
+ db "UNDERGROUND PATH@"
+PokemonTowerName:
+ db "#MON TOWER@"
+SeafoamIslandsName:
+ db "SEAFOAM ISLANDS@"
+VictoryRoadName:
+ db "VICTORY ROAD@"
+DiglettsCaveName:
+ db "DIGLETT's CAVE@"
+RocketHQName:
+ db "ROCKET HQ@"
+SilphCoName:
+ db "SILPH CO.@"
+PokemonMansionName:
+ db $4a," MANSION@"
+SafariZoneName:
+ db "SAFARI ZONE@"
+CeruleanCaveName:
+ db "CERULEAN CAVE@"
+PowerPlantName:
+ db "POWER PLANT@"
diff --git a/en/text/maps/agatha.asm b/en/text/maps/agatha.asm
new file mode 100644
index 00000000..9ef5059a
--- /dev/null
+++ b/en/text/maps/agatha.asm
@@ -0,0 +1,44 @@
+_AgathaBeforeBattleText::
+ text "I am AGATHA of"
+ line "the ELITE FOUR!"
+
+ para "OAK's taken a lot"
+ line "of interest in"
+ cont "you, child!"
+
+ para "That old duff was"
+ line "once tough and"
+ cont "handsome! That"
+ cont "was decades ago!"
+
+ para "Now he just wants"
+ line "to fiddle with"
+ cont "his #DEX! He's"
+ cont "wrong! #MON"
+ cont "are for fighting!"
+
+ para "<PLAYER>! I'll show"
+ line "you how a real"
+ cont "trainer fights!"
+ done
+
+_AgathaEndBattleText::
+ text "Oh ho!"
+ line "You're something"
+ cont "special, child!"
+ prompt
+
+_AgathaAfterBattleText::
+ text "You win! I see"
+ line "what the old duff"
+ cont "sees in you now!"
+
+ para "I have nothing"
+ line "else to say! Run"
+ cont "along now, child!"
+ done
+
+_AgathaDontRunAwayText::
+ text "Someone's voice:"
+ line "Don't run away!"
+ done
diff --git a/en/text/maps/bike_shop.asm b/en/text/maps/bike_shop.asm
new file mode 100644
index 00000000..86799865
--- /dev/null
+++ b/en/text/maps/bike_shop.asm
@@ -0,0 +1,70 @@
+_BikeShopText_1d810::
+ text "Hi! Welcome to"
+ line "our BIKE SHOP."
+
+ para "Have we got just"
+ line "the BIKE for you!"
+ prompt
+
+_BikeShopText_1d815::
+ text "It's a cool BIKE!"
+ line "Do you want it?"
+ done
+
+_BikeShopCantAffordText::
+ text "Sorry! You can't"
+ line "afford it!"
+ prompt
+
+_BikeShopText_1d81f::
+ text "Oh, that's..."
+
+ para "A BIKE VOUCHER!"
+
+ para "OK! Here you go!"
+ prompt
+
+_BikeShopText_1d824::
+ text "<PLAYER> exchanged"
+ line "the BIKE VOUCHER"
+ cont "for a BICYCLE.@@"
+
+_BikeShopComeAgainText::
+ text "Come back again"
+ line "some time!"
+ done
+
+_BikeShopText_1d82f::
+ text "How do you like"
+ line "your new BICYCLE?"
+
+ para "You can take it"
+ line "on CYCLING ROAD"
+ cont "and in caves!"
+ done
+
+_BikeShopText_1d834::
+ text "You better make"
+ line "room for this!"
+ done
+
+_BikeShopText_1d843::
+ text "A plain city BIKE"
+ line "is good enough"
+ cont "for me!"
+
+ para "You can't put a"
+ line "shopping basket"
+ cont "on an MTB!"
+ done
+
+_BikeShopText_1d85c::
+ text "These BIKEs are"
+ line "cool, but they're"
+ cont "way expensive!"
+ done
+
+_BikeShopText_1d861::
+ text "Wow. Your BIKE is"
+ line "really cool!"
+ done
diff --git a/en/text/maps/bills_house.asm b/en/text/maps/bills_house.asm
new file mode 100644
index 00000000..5ece48d7
--- /dev/null
+++ b/en/text/maps/bills_house.asm
@@ -0,0 +1,87 @@
+_BillsHouseText_1e865::
+ text "Hiya! I'm a"
+ line "#MON..."
+ cont "...No I'm not!"
+
+ para "Call me BILL!"
+ line "I'm a true blue"
+ cont "#MANIAC! Hey!"
+ cont "What's with that"
+ cont "skeptical look?"
+
+ para "I'm not joshing"
+ line "you, I screwed up"
+ cont "an experiment and"
+ cont "got combined with"
+ cont "a #MON!"
+
+ para "So, how about it?"
+ line "Help me out here!"
+ done
+
+_BillsHouseText_1e86a::
+ text "When I'm in the"
+ line "TELEPORTER, go to"
+ cont "my PC and run the"
+ cont "Cell Separation"
+ cont "System!"
+ done
+
+_BillsHouseText_1e86f::
+ text "No!? Come on, you"
+ line "gotta help a guy"
+ cont "in deep trouble!"
+
+ para "What do you say,"
+ line "chief? Please?"
+ cont "OK? All right!"
+ prompt
+
+_BillThankYouText::
+ text "BILL: Yeehah!"
+ line "Thanks, bud! I"
+ cont "owe you one!"
+
+ para "So, did you come"
+ line "to see my #MON"
+ cont "collection?"
+ cont "You didn't?"
+ cont "That's a bummer."
+
+ para "I've got to thank"
+ line "you... Oh here,"
+ cont "maybe this'll do."
+ prompt
+
+_SSTicketReceivedText::
+ text "<PLAYER> received"
+ line "an @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_SSTicketNoRoomText::
+ text "You've got too"
+ line "much stuff, bud!"
+ done
+
+_BillsHouseText_1e8cb::
+ text "That cruise ship,"
+ line "S.S.ANNE, is in"
+ cont "VERMILION CITY."
+ cont "Its passengers"
+ cont "are all trainers!"
+
+ para "They invited me"
+ line "to their party,"
+ cont "but I can't stand"
+ cont "fancy do's. Why"
+ cont "don't you go"
+ cont "instead of me?"
+ done
+
+_BillsHouseText_1e8da::
+ text "BILL: Look, bud,"
+ line "just check out"
+ cont "some of my rare"
+ cont "#MON on my PC!"
+ done
diff --git a/en/text/maps/blues_house.asm b/en/text/maps/blues_house.asm
new file mode 100644
index 00000000..1898636a
--- /dev/null
+++ b/en/text/maps/blues_house.asm
@@ -0,0 +1,41 @@
+_DaisyInitialText::
+ text "Hi <PLAYER>!"
+ line "<RIVAL> is out at"
+ cont "Grandpa's lab."
+ done
+
+_DaisyOfferMapText::
+ text "Grandpa asked you"
+ line "to run an errand?"
+ cont "Here, this will"
+ cont "help you!"
+ prompt
+
+_GotMapText::
+ text "<PLAYER> got a"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_DaisyBagFullText::
+ text "You have too much"
+ line "stuff with you."
+ done
+
+_DaisyUseMapText::
+ text "Use the TOWN MAP"
+ line "to find out where"
+ cont "you are."
+ done
+
+_BluesHouseText2::
+ text "#MON are living"
+ line "things! If they"
+ cont "get tired, give"
+ cont "them a rest!"
+ done
+
+_BluesHouseText3::
+ text "It's a big map!"
+ line "This is useful!"
+ done
diff --git a/en/text/maps/bruno.asm b/en/text/maps/bruno.asm
new file mode 100644
index 00000000..9c493c4a
--- /dev/null
+++ b/en/text/maps/bruno.asm
@@ -0,0 +1,37 @@
+_BrunoBeforeBattleText::
+ text "I am BRUNO of"
+ line "the ELITE FOUR!"
+
+ para "Through rigorous"
+ line "training, people"
+ cont "and #MON can"
+ cont "become stronger!"
+
+ para "I've weight"
+ line "trained with"
+ cont "my #MON!"
+
+ para "<PLAYER>!"
+
+ para "We will grind you"
+ line "down with our"
+ cont "superior power!"
+
+ para "Hoo hah!"
+ done
+
+_BrunoEndBattleText::
+ text "Why?"
+ line "How could I lose?"
+ prompt
+
+_BrunoAfterBattleText::
+ text "My job is done!"
+ line "Go face your next"
+ cont "challenge!"
+ done
+
+_BrunoDontRunAwayText::
+ text "Someone's voice:"
+ line "Don't run away!"
+ done
diff --git a/en/text/maps/celadon_city.asm b/en/text/maps/celadon_city.asm
new file mode 100644
index 00000000..1dbd5cdf
--- /dev/null
+++ b/en/text/maps/celadon_city.asm
@@ -0,0 +1,152 @@
+_CeladonCityText1::
+ text "I got my KOFFING"
+ line "in CINNABAR!"
+
+ para "It's nice, but it"
+ line "breathes poison"
+ cont "when it's angry!"
+ done
+
+_CeladonCityText2::
+ text "Heheh! This GYM"
+ line "is great! It's"
+ cont "full of women!"
+ done
+
+_CeladonCityText3::
+ text "The GAME CORNER"
+ line "is bad for our"
+ cont "city's image!"
+ done
+
+_CeladonCityText4::
+ text "Moan! I blew it"
+ line "all at the slots!"
+
+ para "I knew I should"
+ line "have cashed in my"
+ cont "coins for prizes!"
+ done
+
+_TM41PreText::
+ text "Hello, there!"
+
+ para "I've seen you,"
+ line "but I never had a"
+ cont "chance to talk!"
+
+ para "Here's a gift for"
+ line "dropping by!"
+ prompt
+
+_ReceivedTM41Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM41ExplanationText::
+ text "TM41 teaches"
+ line "SOFTBOILED!"
+
+ para "Only one #MON"
+ line "can use it!"
+
+ para "That #MON is"
+ line "CHANSEY!"
+ done
+
+_TM41NoRoomText::
+ text "Oh, your pack is"
+ line "full of items!"
+ done
+
+_CeladonCityText6::
+ text "This is my trusted"
+ line "pal, POLIWRATH!"
+
+ para "It evolved from"
+ line "POLIWHIRL when I"
+ cont "used WATER STONE!"
+ done
+
+_CeladonCityText7::
+ text "POLIWRATH: Ribi"
+ line "ribit!@@"
+
+_CeladonCityText8::
+ text "What are you"
+ line "staring at?"
+ done
+
+_CeladonCityText9::
+ text "Keep out of TEAM"
+ line "ROCKET's way!"
+ done
+
+_CeladonCityText10::
+ text "TRAINER TIPS"
+
+ para "X ACCURACY boosts"
+ line "the accuracy of"
+ cont "techniques!"
+
+ para "DIRE HIT jacks up"
+ line "the likelihood of"
+ cont "critical hits!"
+
+ para "Get your items at"
+ line "CELADON DEPT."
+ cont "STORE!"
+ done
+
+_CeladonCityText11::
+ text "CELADON CITY"
+ line "The City of"
+ cont "Rainbow Dreams"
+ done
+
+_CeladonCityText13::
+ text "CELADON CITY"
+ line "#MON GYM"
+ cont "LEADER: ERIKA"
+
+ para "The Nature Loving"
+ line "Princess!"
+ done
+
+_CeladonCityText14::
+ text "CELADON MANSION"
+ done
+
+_CeladonCityText15::
+ text "Find what you"
+ line "need at CELADON"
+ cont "DEPT. STORE!"
+ done
+
+_CeladonCityText16::
+ text "TRAINER TIPS"
+
+ para "GUARD SPEC."
+ line "protects #MON"
+ cont "against SPECIAL"
+ cont "attacks such as"
+ cont "fire and water!"
+
+ para "Get your items at"
+ line "CELADON DEPT."
+ cont "STORE!"
+ done
+
+_CeladonCityText17::
+ text "Coins exchanged"
+ line "for prizes!"
+ cont "PRIZE EXCHANGE"
+ done
+
+_CeladonCityText18::
+ text "ROCKET GAME CORNER"
+ line "The playground"
+ cont "for grown-ups!"
+ done
diff --git a/en/text/maps/celadon_dept_store_1f.asm b/en/text/maps/celadon_dept_store_1f.asm
new file mode 100644
index 00000000..8d805edc
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_1f.asm
@@ -0,0 +1,31 @@
+_CeladonMart1Text1::
+ text "Hello! Welcome to"
+ line "CELADON DEPT."
+ cont "STORE."
+
+ para "The board on the"
+ line "right describes"
+ cont "the store layout."
+ done
+
+_CeladonMart1Text2::
+ text "1F: SERVICE"
+ line " COUNTER"
+
+ para "2F: TRAINER'S"
+ line " MARKET"
+
+ para "3F: TV GAME SHOP"
+
+ para "4F: WISEMAN GIFTS"
+
+ para "5F: DRUG STORE"
+
+ para "ROOFTOP SQUARE:"
+ line "VENDING MACHINES"
+ done
+
+_CeladonMart1Text3::
+ text "1F: SERVICE"
+ line " COUNTER"
+ done
diff --git a/en/text/maps/celadon_dept_store_2f.asm b/en/text/maps/celadon_dept_store_2f.asm
new file mode 100644
index 00000000..74869902
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_2f.asm
@@ -0,0 +1,22 @@
+_CeladonMart2Text3::
+ text "SUPER REPEL keeps"
+ line "weak #MON at"
+ cont "bay..."
+
+ para "Hmm, it's a more"
+ line "powerful REPEL!"
+ done
+
+_CeladonMart2Text4::
+ text "For long outings,"
+ line "you should buy"
+ cont "REVIVE."
+ done
+
+_CeladonMart2Text5::
+ text "Top Grade Items"
+ line "for Trainers!"
+
+ para "2F: TRAINER'S"
+ line " MARKET"
+ done
diff --git a/en/text/maps/celadon_dept_store_3f.asm b/en/text/maps/celadon_dept_store_3f.asm
new file mode 100644
index 00000000..8211750d
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_3f.asm
@@ -0,0 +1,98 @@
+_TM18PreReceiveText::
+ text "Oh, hi! I finally"
+ line "finished #MON!"
+
+ para "Not done yet?"
+ line "This might be"
+ cont "useful!"
+ prompt
+
+_ReceivedTM18Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM18ExplanationText::
+ text "TM18 is COUNTER!"
+ line "Not like the one"
+ cont "I'm leaning on,"
+ cont "mind you!"
+ done
+
+_TM18NoRoomText::
+ text "Your pack is full"
+ line "of items!"
+ done
+
+_CeladonMart3Text2::
+ text "Captured #MON"
+ line "are registered"
+ cont "with an ID No."
+ cont "and OT, the name"
+ cont "of the Original"
+ cont "Trainer that"
+ cont "caught it!"
+ done
+
+_CeladonMart3Text3::
+ text "All right!"
+
+ para "My buddy's going"
+ line "to trade me his"
+ cont "KANGASKHAN for my"
+ cont "GRAVELER!"
+ done
+
+_CeladonMart3Text4::
+ text "Come on GRAVELER!"
+
+ para "I love GRAVELER!"
+ line "I collect them!"
+
+ para "Huh?"
+
+ para "GRAVELER turned"
+ line "into a different"
+ cont "#MON!"
+ done
+
+_CeladonMart3Text5::
+ text "You can identify"
+ line "#MON you got"
+ cont "in trades by"
+ cont "their ID Numbers!"
+ done
+
+_CeladonMart3Text6::
+ text "It's an SNES!"
+ done
+
+_CeladonMart3Text7::
+ text "An RPG! There's"
+ line "no time for that!"
+ done
+
+_CeladonMart3Text9::
+ text "A sports game!"
+ line "Dad'll like that!"
+ done
+
+_CeladonMart3Text11::
+ text "A puzzle game!"
+ line "Looks addictive!"
+ done
+
+_CeladonMart3Text13::
+ text "A fighting game!"
+ line "Looks tough!"
+ done
+
+_CeladonMart3Text14::
+ text "3F: TV GAME SHOP"
+ done
+
+_CeladonMart3Text15::
+ text "Red and Blue!"
+ line "Both are #MON!"
+ done
diff --git a/en/text/maps/celadon_dept_store_4f.asm b/en/text/maps/celadon_dept_store_4f.asm
new file mode 100644
index 00000000..78fa0b66
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_4f.asm
@@ -0,0 +1,26 @@
+_CeladonMart4Text2::
+ text "I'm getting a"
+ line "# DOLL for my"
+ cont "girl friend!"
+ done
+
+_CeladonMart4Text3::
+ text "I heard something"
+ line "useful."
+
+ para "You can run from"
+ line "wild #MON by"
+ cont "distracting them"
+ cont "with a # DOLL!"
+ done
+
+_CeladonMart4Text4::
+ text "Express yourself"
+ line "with gifts!"
+
+ para "4F: WISEMAN GIFTS"
+
+ para "Evolution Special!"
+ line "Element STONEs on"
+ cont "sale now!"
+ done
diff --git a/en/text/maps/celadon_dept_store_5f.asm b/en/text/maps/celadon_dept_store_5f.asm
new file mode 100644
index 00000000..1871194b
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_5f.asm
@@ -0,0 +1,28 @@
+_CeladonMart5Text1::
+ text "#MON ability"
+ line "enhancers can be"
+ cont "bought only here."
+
+ para "Use CALCIUM to"
+ line "increase SPECIAL"
+ cont "abilities."
+
+ para "Use CARBOS to"
+ line "increase SPEED."
+ done
+
+_CeladonMart5Text2::
+ text "I'm here for"
+ line "#MON ability"
+ cont "enhancers."
+
+ para "PROTEIN increases"
+ line "ATTACK power."
+
+ para "IRON increases"
+ line "DEFENSE!"
+ done
+
+_CeladonMart5Text5::
+ text "5F: DRUG STORE"
+ done
diff --git a/en/text/maps/celadon_dept_store_roof.asm b/en/text/maps/celadon_dept_store_roof.asm
new file mode 100644
index 00000000..5d104cf5
--- /dev/null
+++ b/en/text/maps/celadon_dept_store_roof.asm
@@ -0,0 +1,138 @@
+_CeladonMartRoofText_484ee::
+ text "Give her which"
+ line "drink?"
+ done
+
+_CeladonMartRoofText_484f3::
+ text "Yay!"
+
+ para "FRESH WATER!"
+
+ para "Thank you!"
+
+ para "You can have this"
+ line "from me!@@"
+
+_CeladonMartRoofText_484f9::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_CeladonMartRoofText_484fe::
+ db $0
+ para "@"
+ TX_RAM wcf4b
+ text " contains"
+ line "ICE BEAM!"
+
+ para "It can freeze the"
+ line "target sometimes!@@"
+
+_CeladonMartRoofText_48504::
+ text "Yay!"
+
+ para "SODA POP!"
+
+ para "Thank you!"
+
+ para "You can have this"
+ line "from me!@@"
+
+_CeladonMartRoofText_4850a::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_CeladonMartRoofText_4850f::
+ db $0
+ para "@"
+ TX_RAM wcf4b
+ text " contains"
+ line "ROCK SLIDE!"
+
+ para "It can spook the"
+ line "target sometimes!@@"
+
+_CeladonMartRoofText_48515::
+ text "Yay!"
+
+ para "LEMONADE!"
+
+ para "Thank you!"
+
+ para "You can have this"
+ line "from me!@@"
+
+_ReceivedTM49Text::
+ text "<PLAYER> received"
+ line "TM49!@@"
+
+_CeladonMartRoofText_48520::
+ db $0
+ para "TM49 contains"
+ line "TRI ATTACK!@@"
+
+_CeladonMartRoofText_48526::
+ text "You don't have"
+ line "space for this!@@"
+
+_CeladonMartRoofText_4852c::
+ text "No thank you!"
+ line "I'm not thirsty"
+ cont "after all!@@"
+
+_CeladonMartRoofText1::
+ text "My sister is a"
+ line "trainer, believe"
+ cont "it or not."
+
+ para "But, she's so"
+ line "immature, she"
+ cont "drives me nuts!"
+ done
+
+_CeladonMartRoofText_48598::
+ text "I'm thirsty!"
+ line "I want something"
+ cont "to drink!"
+ done
+
+_CeladonMartRoofText4::
+ text "I'm thirsty!"
+ line "I want something"
+ cont "to drink!"
+
+ para "Give her a drink?"
+ done
+
+_CeladonMartRoofText6::
+ text "ROOFTOP SQUARE:"
+ line "VENDING MACHINES"
+ done
+
+_VendingMachineText1::
+ text "A vending machine!"
+ line "Here's the menu!"
+ prompt
+
+_VendingMachineText4::
+ text "Oops, not enough"
+ line "money!"
+ done
+
+_VendingMachineText5::
+ TX_RAM wcf4b
+ db $0
+ line "popped out!"
+ done
+
+_VendingMachineText6::
+ text "There's no more"
+ line "room for stuff!"
+ done
+
+_VendingMachineText7::
+ text "Not thirsty!"
+ done
diff --git a/en/text/maps/celadon_diner.asm b/en/text/maps/celadon_diner.asm
new file mode 100644
index 00000000..dc5e9350
--- /dev/null
+++ b/en/text/maps/celadon_diner.asm
@@ -0,0 +1,59 @@
+_CeladonDinerText1::
+ text "Hi!"
+
+ para "We're taking a"
+ line "break now."
+ done
+
+_CeladonDinerText2::
+ text "My #MON are"
+ line "weak, so I often"
+ cont "have to go to the"
+ cont "DRUG STORE."
+ done
+
+_CeladonDinerText3::
+ text "Psst! There's a"
+ line "basement under"
+ cont "the GAME CORNER."
+ done
+
+_CeladonDinerText4::
+ text "Munch..."
+
+ para "The man at that"
+ line "table lost it all"
+ cont "at the slots."
+ done
+
+_CeladonDinerText_491a7::
+ text "Go ahead! Laugh!"
+
+ para "I'm flat out"
+ line "busted!"
+
+ para "No more slots for"
+ line "me! I'm going"
+ cont "straight!"
+
+ para "Here! I won't be"
+ line "needing this any-"
+ cont "more!"
+ prompt
+
+_ReceivedCoinCaseText::
+ text "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_CoinCaseNoRoomText::
+ text "Make room for"
+ line "this!"
+ done
+
+_CeladonDinerText_491b7::
+ text "I always thought"
+ line "I was going to"
+ cont "win it back..."
+ done
diff --git a/en/text/maps/celadon_game_corner.asm b/en/text/maps/celadon_game_corner.asm
new file mode 100644
index 00000000..1e59f83e
--- /dev/null
+++ b/en/text/maps/celadon_game_corner.asm
@@ -0,0 +1,186 @@
+_CeladonGameCornerText1::
+ text "Welcome!"
+
+ para "You can exchange"
+ line "your coins for"
+ cont "fabulous prizes"
+ cont "next door."
+ done
+
+_CeladonGameCornerText_48d22::
+ text "Welcome to ROCKET"
+ line "GAME CORNER!"
+
+ para "Do you need some"
+ line "game coins?"
+
+ para "It's ¥1000 for 50"
+ line "coins. Would you"
+ cont "like some?"
+ done
+
+_CeladonGameCornerText_48d27::
+ text "Thanks! Here are"
+ line "your 50 coins!"
+ done
+
+_CeladonGameCornerText_48d2c::
+ text "No? Please come"
+ line "play sometime!"
+ done
+
+_CeladonGameCornerText_48d31::
+ text "You can't afford"
+ line "the coins!"
+ done
+
+_CeladonGameCornerText_48d36::
+ text "Oops! Your COIN"
+ line "CASE is full."
+ done
+
+_CeladonGameCornerText_48d3b::
+ text "You don't have a"
+ line "COIN CASE!"
+ done
+
+_CeladonGameCornerText3::
+ text "Keep this quiet."
+
+ para "It's rumored that"
+ line "this place is run"
+ cont "by TEAM ROCKET."
+ done
+
+_CeladonGameCornerText4::
+ text "I think these"
+ line "machines have"
+ cont "different odds."
+ done
+
+_CeladonGameCornerText_48d9c::
+ text "Kid, do you want"
+ line "to play?"
+ prompt
+
+_Received10CoinsText::
+ text "<PLAYER> received"
+ line "10 coins!@@"
+
+_CeladonGameCornerText_48da7::
+ text "You don't need my"
+ line "coins!"
+ done
+
+_CeladonGameCornerText_48dac::
+ text "Wins seem to come"
+ line "and go."
+ done
+
+_CeladonGameCornerText6::
+ text "I'm having a"
+ line "wonderful time!"
+ done
+
+_CeladonGameCornerText_48dca::
+ text "Hey!"
+
+ para "You have better"
+ line "things to do,"
+ cont "champ in making!"
+
+ para "CELADON GYM's"
+ line "LEADER is ERIKA!"
+ cont "She uses grass-"
+ cont "type #MON!"
+
+ para "She might appear"
+ line "docile, but don't"
+ cont "be fooled!"
+ done
+
+_CeladonGameCornerText_48dcf::
+ text "They offer rare"
+ line "#MON that can"
+ cont "be exchanged for"
+ cont "your coins."
+
+ para "But, I just can't"
+ line "seem to win!"
+ done
+
+_CeladonGameCornerText8::
+ text "Games are scary!"
+ line "It's so easy to"
+ cont "get hooked!"
+ done
+
+_CeladonGameCornerText_48e26::
+ text "What's up? Want"
+ line "some coins?"
+ prompt
+
+_Received20CoinsText::
+ text "<PLAYER> received"
+ line "20 coins!@@"
+
+_CeladonGameCornerText_48e31::
+ text "You have lots of"
+ line "coins!"
+ done
+
+_CeladonGameCornerText_48e36::
+ text "Darn! I need more"
+ line "coins for the"
+ cont "#MON I want!"
+ done
+
+_CeladonGameCornerText_48e88::
+ text "Hey, what? You're"
+ line "throwing me off!"
+ cont "Here are some"
+ cont "coins, shoo!"
+ prompt
+
+_CeladonGameCornerText_48e8d::
+ text "<PLAYER> received"
+ line "20 coins!@@"
+
+_CeladonGameCornerText_48e93::
+ text "You've got your"
+ line "own coins!"
+ done
+
+_CeladonGameCornerText_48e98::
+ text "The trick is to"
+ line "watch the reels"
+ cont "closely!"
+ done
+
+_CeladonGameCornerText_48ece::
+ text "I'm guarding this"
+ line "poster!"
+ cont "Go away, or else!"
+ done
+
+_CeladonGameCornerText_48ed3::
+ text "Dang!"
+ prompt
+
+_CeladonGameCornerText_48ed8::
+ text "Our hideout might"
+ line "be discovered! I"
+ cont "better tell BOSS!"
+ done
+
+_CeladonGameCornerText_48f09::
+ text "Hey!"
+
+ para "A switch behind"
+ line "the poster!?"
+ cont "Let's push it!@@"
+
+_CeladonGameCornerText_48f19::
+ text "Oops! Forgot the"
+ line "COIN CASE!"
+ done
diff --git a/en/text/maps/celadon_gym.asm b/en/text/maps/celadon_gym.asm
new file mode 100644
index 00000000..d8f9394c
--- /dev/null
+++ b/en/text/maps/celadon_gym.asm
@@ -0,0 +1,218 @@
+_CeladonGymText_48a5e::
+ text "Hello. Lovely"
+ line "weather isn't it?"
+ cont "It's so pleasant."
+
+ para "...Oh dear..."
+ line "I must have dozed"
+ cont "off. Welcome."
+
+ para "My name is ERIKA."
+ line "I am the LEADER"
+ cont "of CELADON GYM."
+
+ para "I teach the art of"
+ line "flower arranging."
+ cont "My #MON are of"
+ cont "the grass-type."
+
+ para "Oh, I'm sorry, I"
+ line "had no idea that"
+ cont "you wished to"
+ cont "challenge me."
+
+ para "Very well, but I"
+ line "shall not lose."
+ done
+
+_CeladonGymText_48a63::
+ text "Oh!"
+ line "I concede defeat."
+
+ para "You are remarkably"
+ line "strong."
+
+ para "I must confer you"
+ line "the RAINBOWBADGE."
+ prompt
+
+_CeladonGymText_48a68::
+ text "You are cataloging"
+ line "#MON? I must"
+ cont "say I'm impressed."
+
+ para "I would never"
+ line "collect #MON"
+ cont "if they were"
+ cont "unattractive."
+ done
+
+_CeladonGymText9::
+ text "The RAINBOWBADGE"
+ line "will make #MON"
+ cont "up to L50 obey."
+
+ para "It also allows"
+ line "#MON to use"
+ cont "STRENGTH in and"
+ cont "out of battle."
+
+ para "Please also take"
+ line "this with you."
+ done
+
+_ReceivedTM21Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM21ExplanationText::
+ db $0
+ para "TM21 contains"
+ line "MEGA DRAIN."
+
+ para "Half the damage"
+ line "it inflicts is"
+ cont "drained to heal"
+ cont "your #MON!"
+ done
+
+_TM21NoRoomText::
+ text "You should make"
+ line "room for this."
+ done
+
+_CeladonGymBattleText2::
+ text "Hey!"
+
+ para "You are not"
+ line "allowed in here!"
+ done
+
+_CeladonGymEndBattleText2::
+ text "You're"
+ line "too rough!"
+ prompt
+
+_CeladonGymAfterBattleText2::
+ text "Bleaah!"
+ line "I hope ERIKA"
+ cont "wipes you out!"
+ done
+
+_CeladonGymBattleText3::
+ text "I was getting"
+ line "bored."
+ done
+
+_CeladonGymEndBattleText3::
+ text "My"
+ line "makeup!"
+ prompt
+
+_CeladonGymAfterBattleText3::
+ text "Grass-type #MON"
+ line "are tough against"
+ cont "the water-type!"
+
+ para "They also have an"
+ line "edge on rock and"
+ cont "ground #MON!"
+ done
+
+_CeladonGymBattleText4::
+ text "Aren't you the"
+ line "peeping Tom?"
+ done
+
+_CeladonGymEndBattleText4::
+ text "I'm"
+ line "in shock!"
+ prompt
+
+_CeladonGymAfterBattleText4::
+ text "Oh, you weren't"
+ line "peeping? We get a"
+ cont "lot of gawkers!"
+ done
+
+_CeladonGymBattleText5::
+ text "Look at my grass"
+ line "#MON!"
+
+ para "They're so easy"
+ line "to raise!"
+ done
+
+_CeladonGymEndBattleText5::
+ text "No!"
+ prompt
+
+_CeladonGymAfterBattleText5::
+ text "We only use grass-"
+ line "type #MON at"
+ cont "our GYM!"
+
+ para "We also use them"
+ line "for making flower"
+ cont "arrangements!"
+ done
+
+_CeladonGymBattleText6::
+ text "Don't bring any"
+ line "bugs or fire"
+ cont "#MON in here!"
+ done
+
+_CeladonGymEndBattleText6::
+ text "Oh!"
+ line "You!"
+ prompt
+
+_CeladonGymAfterBattleText6::
+ text "Our LEADER, ERIKA,"
+ line "might be quiet,"
+ cont "but she's also"
+ cont "very skilled!"
+ done
+
+_CeladonGymBattleText7::
+ text "Pleased to meet"
+ line "you. My hobby is"
+ cont "#MON training."
+ done
+
+_CeladonGymEndBattleText7::
+ text "Oh!"
+ line "Splendid!"
+ prompt
+
+_CeladonGymAfterBattleText7::
+ text "I have a blind"
+ line "date coming up."
+ cont "I have to learn"
+ cont "to be polite."
+ done
+
+_CeladonGymBattleText8::
+ text "Welcome to"
+ line "CELADON GYM!"
+
+ para "You better not"
+ line "underestimate"
+ cont "girl power!"
+ done
+
+_CeladonGymEndBattleText8::
+ text "Oh!"
+ line "Beaten!"
+ prompt
+
+_CeladonGymAfterBattleText8::
+ text "I didn't bring my"
+ line "best #MON!"
+
+ para "Wait 'til next"
+ line "time!"
+ done
diff --git a/en/text/maps/celadon_hotel.asm b/en/text/maps/celadon_hotel.asm
new file mode 100644
index 00000000..f2eb059e
--- /dev/null
+++ b/en/text/maps/celadon_hotel.asm
@@ -0,0 +1,21 @@
+_CeladonHotelText1::
+ text "#MON? No, this"
+ line "is a hotel for"
+ cont "people."
+
+ para "We're full up."
+ done
+
+_CeladonHotelText2::
+ text "I'm on vacation"
+ line "with my brother"
+ cont "and boy friend."
+
+ para "CELADON is such a"
+ line "pretty city!"
+ done
+
+_CeladonHotelText3::
+ text "Why did she bring"
+ line "her brother?"
+ done
diff --git a/en/text/maps/celadon_house.asm b/en/text/maps/celadon_house.asm
new file mode 100644
index 00000000..19e59bd6
--- /dev/null
+++ b/en/text/maps/celadon_house.asm
@@ -0,0 +1,22 @@
+_CeladonHouseText1::
+ text "Hehehe! The slots"
+ line "just reel in the"
+ cont "dough, big time!"
+ done
+
+_CeladonHouseText2::
+ text "CHIEF!"
+
+ para "We just shipped"
+ line "2000 #MON as"
+ cont "slot prizes!"
+ done
+
+_CeladonHouseText3::
+ text "Don't touch the"
+ line "poster at the"
+ cont "GAME CORNER!"
+
+ para "There's no secret"
+ line "switch behind it!"
+ done
diff --git a/en/text/maps/celadon_mansion_1f.asm b/en/text/maps/celadon_mansion_1f.asm
new file mode 100644
index 00000000..fc175cd5
--- /dev/null
+++ b/en/text/maps/celadon_mansion_1f.asm
@@ -0,0 +1,23 @@
+_CeladonMansion1Text1::
+ text "MEOWTH: Meow!@@"
+
+_CeladonMansion1Text2::
+ text "My dear #MON"
+ line "keep me company."
+
+ para "MEOWTH even brings"
+ line "money home!"
+ done
+
+_CeladonMansion1Text3::
+ text "CLEFAIRY: Pi"
+ line "pippippi!@@"
+
+_CeladonMansion1Text4::
+ text "NIDORAN: Kya"
+ line "kyaoo!@@"
+
+_CeladonMansion1Text5::
+ text "CELADON MANSION"
+ line "Manager's Suite"
+ done
diff --git a/en/text/maps/celadon_mansion_2f.asm b/en/text/maps/celadon_mansion_2f.asm
new file mode 100644
index 00000000..b2ecb4fa
--- /dev/null
+++ b/en/text/maps/celadon_mansion_2f.asm
@@ -0,0 +1,4 @@
+_CeladonMansion2Text1::
+ text "GAME FREAK"
+ line "Meeting Room"
+ done
diff --git a/en/text/maps/celadon_mansion_3f.asm b/en/text/maps/celadon_mansion_3f.asm
new file mode 100644
index 00000000..c8858281
--- /dev/null
+++ b/en/text/maps/celadon_mansion_3f.asm
@@ -0,0 +1,66 @@
+_ProgrammerText::
+ text "Me? I'm the"
+ line "programmer!"
+ done
+
+_GraphicArtistText::
+ text "I'm the graphic"
+ line "artist!"
+ cont "I drew you!"
+ done
+
+_WriterText::
+ text "I wrote the story!"
+ line "Isn't ERIKA cute?"
+
+ para "I like MISTY a"
+ line "lot too!"
+
+ para "Oh, and SABRINA,"
+ line "I like her!"
+ done
+
+_GameDesignerText::
+ text "Is that right?"
+
+ para "I'm the game"
+ line "designer!"
+
+ para "Filling up your"
+ line "#DEX is tough,"
+ cont "but don't quit!"
+
+ para "When you finish,"
+ line "come tell me!"
+ done
+
+_CompletedDexText::
+ text "Wow! Excellent!"
+ line "You completed"
+ cont "your #DEX!"
+ cont "Congratulations!"
+ cont "...@@"
+
+_CeladonMansion3Text5::
+ text "It's the game"
+ line "program! Messing"
+ cont "with it could bug"
+ cont "out the game!"
+ done
+
+_CeladonMansion3Text6::
+ text "Someone's playing"
+ line "a game instead of"
+ cont "working!"
+ done
+
+_CeladonMansion3Text7::
+ text "It's the script!"
+ line "Better not look"
+ cont "at the ending!"
+ done
+
+_CeladonMansion3Text8::
+ text "GAME FREAK"
+ line "Development Room"
+ done
diff --git a/en/text/maps/celadon_mansion_4f_inside.asm b/en/text/maps/celadon_mansion_4f_inside.asm
new file mode 100644
index 00000000..dab81a8d
--- /dev/null
+++ b/en/text/maps/celadon_mansion_4f_inside.asm
@@ -0,0 +1,10 @@
+_CeladonMansion5Text1::
+ text "I know everything"
+ line "about the world"
+ cont "of #MON in"
+ cont "your GAME BOY!"
+
+ para "Get together with"
+ line "your friends and"
+ cont "trade #MON!"
+ done
diff --git a/en/text/maps/celadon_mansion_4f_outside.asm b/en/text/maps/celadon_mansion_4f_outside.asm
new file mode 100644
index 00000000..c8fd7ec8
--- /dev/null
+++ b/en/text/maps/celadon_mansion_4f_outside.asm
@@ -0,0 +1,3 @@
+_CeladonMansion4Text1::
+ text "I KNOW EVERYTHING!"
+ done
diff --git a/en/text/maps/celadon_pokecenter.asm b/en/text/maps/celadon_pokecenter.asm
new file mode 100644
index 00000000..a04f51c9
--- /dev/null
+++ b/en/text/maps/celadon_pokecenter.asm
@@ -0,0 +1,12 @@
+_CeladonPokecenterText2::
+ text "# FLUTE awakens"
+ line "#MON with a"
+ cont "sound that only"
+ cont "they can hear!"
+ done
+
+_CeladonPokecenterText3::
+ text "I rode uphill on"
+ line "CYCLING ROAD from"
+ cont "FUCHSIA!"
+ done
diff --git a/en/text/maps/celadon_prize_room.asm b/en/text/maps/celadon_prize_room.asm
new file mode 100644
index 00000000..6b2bb537
--- /dev/null
+++ b/en/text/maps/celadon_prize_room.asm
@@ -0,0 +1,12 @@
+_CeladonPrizeRoomText1::
+ text "I sure do fancy"
+ line "that PORYGON!"
+
+ para "But, it's hard to"
+ line "win at slots!"
+ done
+
+_CeladonPrizeRoomText2::
+ text "I had a major"
+ line "haul today!"
+ done
diff --git a/en/text/maps/cerulean_badge_house.asm b/en/text/maps/cerulean_badge_house.asm
new file mode 100644
index 00000000..9d701443
--- /dev/null
+++ b/en/text/maps/cerulean_badge_house.asm
@@ -0,0 +1,97 @@
+_CeruleanHouse2Text_74e77::
+ text "#MON BADGEs"
+ line "are owned only by"
+ cont "skilled trainers."
+
+ para "I see you have"
+ line "at least one."
+
+ para "Those BADGEs have"
+ line "amazing secrets!"
+ prompt
+
+_CeruleanHouse2Text_74e7c::
+ text "Now then..."
+
+ para "Which of the 8"
+ line "BADGEs should I"
+ cont "describe?"
+ done
+
+_CeruleanHouse2Text_74e81::
+ text "Come visit me any"
+ line "time you wish."
+ done
+
+_CeruleanHouse2Text_74e96::
+ text "The ATTACK of all"
+ line "#MON increases"
+ cont "a little bit."
+
+ para "It also lets you"
+ line "use FLASH any"
+ cont "time you desire."
+ prompt
+
+_CeruleanHouse2Text_74e9b::
+ text "#MON up to L30"
+ line "will obey you."
+
+ para "Any higher, they"
+ line "become unruly!"
+
+ para "It also lets you"
+ line "use CUT outside"
+ cont "of battle."
+ prompt
+
+_CeruleanHouse2Text_74ea0::
+ text "The SPEED of all"
+ line "#MON increases"
+ cont "a little bit."
+
+ para "It also lets you"
+ line "use FLY outside"
+ cont "of battle."
+ prompt
+
+_CeruleanHouse2Text_74ea5::
+ text "#MON up to L50"
+ line "will obey you."
+
+ para "Any higher, they"
+ line "become unruly!"
+
+ para "It also lets you"
+ line "use STRENGTH out-"
+ cont "side of battle."
+ prompt
+
+_CeruleanHouse2Text_74eaa::
+ text "The DEFENSE of all"
+ line "#MON increases"
+ cont "a little bit."
+
+ para "It also lets you"
+ line "use SURF outside"
+ cont "of battle."
+ prompt
+
+_CeruleanHouse2Text_74eaf::
+ text "#MON up to L70"
+ line "will obey you."
+
+ para "Any higher, they"
+ line "become unruly!"
+ prompt
+
+_CeruleanHouse2Text_74eb4::
+ text "Your #MON's"
+ line "SPECIAL abilities"
+ cont "increase a bit."
+ prompt
+
+_CeruleanHouse2Text_74eb9::
+ text "All #MON will"
+ line "obey you!"
+ prompt
diff --git a/en/text/maps/cerulean_city.asm b/en/text/maps/cerulean_city.asm
new file mode 100644
index 00000000..b5319d04
--- /dev/null
+++ b/en/text/maps/cerulean_city.asm
@@ -0,0 +1,232 @@
+_CeruleanCityText_19668::
+ text "<RIVAL>: Yo!"
+ line "<PLAYER>!"
+
+ para "You're still"
+ line "struggling along"
+ cont "back here?"
+
+ para "I'm doing great!"
+ line "I caught a bunch"
+ cont "of strong and"
+ cont "smart #MON!"
+
+ para "Here, let me see"
+ line "what you caught,"
+ cont "<PLAYER>!"
+ done
+
+_CeruleanCityText_1966d::
+ text "Hey!"
+ line "Take it easy!"
+ cont "You won already!"
+ prompt
+
+_CeruleanCityText_19672::
+ text "Heh!"
+ line "You're no match"
+ cont "for my genius!"
+ prompt
+
+_CeruleanCityText_19677::
+ text "<RIVAL>: Hey,"
+ line "guess what?"
+
+ para "I went to BILL's"
+ line "and got him to"
+ cont "show me his rare"
+ cont "#MON!"
+
+ para "That added a lot"
+ line "of pages to my"
+ cont "#DEX!"
+
+ para "After all, BILL's"
+ line "world famous as a"
+ cont "#MANIAC!"
+
+ para "He invented the"
+ line "#MON Storage"
+ cont "System on PC!"
+
+ para "Since you're using"
+ line "his system, go"
+ cont "thank him!"
+
+ para "Well, I better"
+ line "get rolling!"
+ cont "Smell ya later!"
+ done
+
+_CeruleanCityText_196d9::
+ text "Hey! Stay out!"
+ line "It's not your"
+ cont "yard! Huh? Me?"
+
+ para "I'm an innocent"
+ line "bystander! Don't"
+ cont "you believe me?"
+ done
+
+_ReceivedTM28Text::
+ text "<PLAYER> recovered"
+ line "TM28!@@"
+
+_ReceivedTM28Text2::
+ db $0
+ para "I better get"
+ line "moving! Bye!@@"
+
+_TM28NoRoomText::
+ text "Make room for"
+ line "this!"
+
+ para "I can't run until"
+ line "I give it to you!"
+ done
+
+_CeruleanCityText_196ee::
+ text "Stop!"
+ line "I give up! I'll"
+ cont "leave quietly!"
+ prompt
+
+_CeruleanCityText_196f3::
+ text "OK! I'll return"
+ line "the TM I stole!"
+ prompt
+
+_CeruleanCityText3::
+ text "You're a trainer"
+ line "too? Collecting,"
+ cont "fighting, it's a"
+ cont "tough life."
+ done
+
+_CeruleanCityText4::
+ text "That bush in"
+ line "front of the shop"
+ cont "is in the way."
+
+ para "There might be a"
+ line "way around."
+ done
+
+_CeruleanCityText5::
+ text "You're making an"
+ line "encyclopedia on"
+ cont "#MON? That"
+ cont "sounds amusing."
+ done
+
+_CeruleanCityText6::
+ text "The people here"
+ line "were robbed."
+
+ para "It's obvious that"
+ line "TEAM ROCKET is"
+ cont "behind this most"
+ cont "heinous crime!"
+
+ para "Even our POLICE"
+ line "force has trouble"
+ cont "with the ROCKETs!"
+ done
+
+_CeruleanCityText_19730::
+ text "OK! SLOWBRO!"
+ line "Use SONICBOOM!"
+ cont "Come on, SLOWBRO"
+ cont "pay attention!"
+ done
+
+_CeruleanCityText_19735::
+ text "SLOWBRO punch!"
+ line "No! You blew it"
+ cont "again!"
+ done
+
+_CeruleanCityText_1973a::
+ text "SLOWBRO, WITHDRAW!"
+ line "No! That's wrong!"
+
+ para "It's so hard to"
+ line "control #MON!"
+
+ para "Your #MON's"
+ line "obedience depends"
+ cont "on your abilities"
+ cont "as a trainer!"
+ done
+
+_CeruleanCityText_1976f::
+ text "SLOWBRO took a"
+ line "snooze..."
+ done
+
+_CeruleanCityText_19774::
+ text "SLOWBRO is"
+ line "loafing around..."
+ done
+
+_CeruleanCityText_19779::
+ text "SLOWBRO turned"
+ line "away..."
+ done
+
+_CeruleanCityText_1977e::
+ text "SLOWBRO"
+ line "ignored orders..."
+ done
+
+_CeruleanCityText9::
+ text "I want a bright"
+ line "red BICYCLE!"
+
+ para "I'll keep it at"
+ line "home, so it won't"
+ cont "get dirty!"
+ done
+
+_CeruleanCityText10::
+ text "This is CERULEAN"
+ line "CAVE! Horribly"
+ cont "strong #MON"
+ cont "live in there!"
+
+ para "The #MON LEAGUE"
+ line "champion is the"
+ cont "only person who"
+ cont "is allowed in!"
+ done
+
+_CeruleanCityText12::
+ text "CERULEAN CITY"
+ line "A Mysterious,"
+ cont "Blue Aura"
+ cont "Surrounds It"
+ done
+
+_CeruleanCityText13::
+ text "TRAINER TIPS"
+
+ para "Pressing B Button"
+ line "during evolution"
+ cont "cancels the whole"
+ cont "process."
+ done
+
+_CeruleanCityText16::
+ text "Grass and caves"
+ line "handled easily!"
+ cont "BIKE SHOP"
+ done
+
+_CeruleanCityText17::
+ text "CERULEAN CITY"
+ line "#MON GYM"
+ cont "LEADER: MISTY"
+
+ para "The Tomboyish"
+ line "Mermaid!"
+ done
diff --git a/en/text/maps/cerulean_gym.asm b/en/text/maps/cerulean_gym.asm
new file mode 100644
index 00000000..1d1d6d1c
--- /dev/null
+++ b/en/text/maps/cerulean_gym.asm
@@ -0,0 +1,131 @@
+_CeruleanGymText_5c7be::
+ text "Hi, you're a new"
+ line "face!"
+
+ para "Trainers who want"
+ line "to turn pro have"
+ cont "to have a policy"
+ cont "about #MON!"
+
+ para "What is your"
+ line "approach when you"
+ cont "catch #MON?"
+
+ para "My policy is an"
+ line "all-out offensive"
+ cont "with water-type"
+ cont "#MON!"
+ done
+
+_CeruleanGymText_5c7c3::
+ text "TM11 teaches"
+ line "BUBBLEBEAM!"
+
+ para "Use it on an"
+ line "aquatic #MON!"
+ done
+
+_CeruleanGymText_5c7c8::
+ text "The CASCADEBADGE"
+ line "makes all #MON"
+ cont "up to L30 obey!"
+
+ para "That includes"
+ line "even outsiders!"
+
+ para "There's more, you"
+ line "can now use CUT"
+ cont "any time!"
+
+ para "You can CUT down"
+ line "small bushes to"
+ cont "open new paths!"
+
+ para "You can also have"
+ line "my favorite TM!"
+ done
+
+_ReceivedTM11Text::
+ text "<PLAYER> received"
+ line "TM11!@@"
+
+_CeruleanGymText_5c7d3::
+ text "You better make"
+ line "room for this!"
+ done
+
+_CeruleanGymText_5c7d8::
+ text "Wow!"
+ line "You're too much!"
+
+ para "All right!"
+
+ para "You can have the"
+ line "CASCADEBADGE to"
+ cont "show you beat me!@@"
+
+_CeruleanGymBattleText1::
+ text "I'm more than good"
+ line "enough for you!"
+
+ para "MISTY can wait!"
+ done
+
+_CeruleanGymEndBattleText1::
+ text "You"
+ line "overwhelmed me!"
+ prompt
+
+_CeruleanGymAfterBattleText1::
+ text "You have to face"
+ line "other trainers to"
+ cont "find out how good"
+ cont "you really are."
+ done
+
+_CeruleanGymBattleText2::
+ text "Splash!"
+
+ para "I'm first up!"
+ line "Let's do it!"
+ done
+
+_CeruleanGymEndBattleText2::
+ text "That"
+ line "can't be!"
+ prompt
+
+_CeruleanGymAfterBattleText2::
+ text "MISTY is going to"
+ line "keep improving!"
+
+ para "She won't lose to"
+ line "someone like you!"
+ done
+
+_CeruleanGymText_5c82a::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "Here's my advice!"
+
+ para "The LEADER, MISTY,"
+ line "is a pro who uses"
+ cont "water #MON!"
+
+ para "You can drain all"
+ line "their water with"
+ cont "plant #MON!"
+
+ para "Or, zap them with"
+ line "electricity!"
+ done
+
+_CeruleanGymText_5c82f::
+ text "You beat MISTY!"
+ line "What'd I tell ya?"
+
+ para "You and me kid,"
+ line "we make a pretty"
+ cont "darn good team!"
+ done
diff --git a/en/text/maps/cerulean_mart.asm b/en/text/maps/cerulean_mart.asm
new file mode 100644
index 00000000..86a74588
--- /dev/null
+++ b/en/text/maps/cerulean_mart.asm
@@ -0,0 +1,19 @@
+_CeruleanMartText2::
+ text "Use REPEL to keep"
+ line "bugs and weak"
+ cont "#MON away."
+
+ para "Put your strongest"
+ line "#MON at the"
+ cont "top of the list"
+ cont "for best results!"
+ done
+
+_CeruleanMartText3::
+ text "Have you seen any"
+ line "RARE CANDY?"
+
+ para "It's supposed to"
+ line "make #MON go"
+ cont "up one level!"
+ done
diff --git a/en/text/maps/cerulean_pokecenter.asm b/en/text/maps/cerulean_pokecenter.asm
new file mode 100644
index 00000000..497fbce3
--- /dev/null
+++ b/en/text/maps/cerulean_pokecenter.asm
@@ -0,0 +1,24 @@
+_CeruleanPokecenterText2::
+ text "That BILL!"
+
+ para "I heard that"
+ line "he'll do whatever"
+ cont "it takes to get"
+ cont "rare #MON!"
+ done
+
+_CeruleanPokecenterText3::
+ text "Have you heard"
+ line "about BILL?"
+
+ para "Everyone calls"
+ line "him a #MANIAC!"
+
+ para "I think people"
+ line "are just jealous"
+ cont "of BILL, though."
+
+ para "Who wouldn't want"
+ line "to boast about"
+ cont "their #MON?"
+ done
diff --git a/en/text/maps/cerulean_trade_house.asm b/en/text/maps/cerulean_trade_house.asm
new file mode 100644
index 00000000..b606613b
--- /dev/null
+++ b/en/text/maps/cerulean_trade_house.asm
@@ -0,0 +1,9 @@
+_CeruleanHouse1Text1::
+ text "My husband likes"
+ line "trading #MON."
+
+ para "If you are a"
+ line "collector, would"
+ cont "you please trade"
+ cont "with him?"
+ done
diff --git a/en/text/maps/cerulean_trashed_house.asm b/en/text/maps/cerulean_trashed_house.asm
new file mode 100644
index 00000000..f79540ae
--- /dev/null
+++ b/en/text/maps/cerulean_trashed_house.asm
@@ -0,0 +1,36 @@
+_CeruleanTrashedText_1d6ab::
+ text "Those miserable"
+ line "ROCKETs!"
+
+ para "Look what they"
+ line "did here!"
+
+ para "They stole a TM"
+ line "for teaching"
+ cont "#MON how to"
+ cont "DIG holes!"
+
+ para "That cost me a"
+ line "bundle, it did!"
+ done
+
+_CeruleanTrashedText_1d6b0::
+ text "I figure what's"
+ line "lost is lost!"
+
+ para "I decided to teach"
+ line "DIGLETT how to"
+ cont "DIG without a TM!"
+ done
+
+_CeruleanHouseTrashedText2::
+ text "TEAM ROCKET must"
+ line "be trying to DIG"
+ cont "their way into no"
+ cont "good!"
+ done
+
+_CeruleanHouseTrashedText3::
+ text "TEAM ROCKET left"
+ line "a way out!"
+ done
diff --git a/en/text/maps/champion.asm b/en/text/maps/champion.asm
new file mode 100644
index 00000000..61050565
--- /dev/null
+++ b/en/text/maps/champion.asm
@@ -0,0 +1,146 @@
+_GaryChampionIntroText::
+ text "<RIVAL>: Hey!"
+
+ para "I was looking"
+ line "forward to seeing"
+ cont "you, <PLAYER>!"
+
+ para "My rival should"
+ line "be strong to keep"
+ cont "me sharp!"
+
+ para "While working on"
+ line "#DEX, I looked"
+ cont "all over for"
+ cont "powerful #MON!"
+
+ para "Not only that, I"
+ line "assembled teams"
+ cont "that would beat"
+ cont "any #MON type!"
+
+ para "And now!"
+
+ para "I'm the #MON"
+ line "LEAGUE champion!"
+
+ para "<PLAYER>! Do you"
+ line "know what that"
+ cont "means?"
+
+ para "I'll tell you!"
+
+ para "I am the most"
+ line "powerful trainer"
+ cont "in the world!"
+ done
+
+_GaryDefeatedText::
+ text "NO!"
+ line "That can't be!"
+ cont "You beat my best!"
+
+ para "After all that"
+ line "work to become"
+ cont "LEAGUE champ?"
+
+ para "My reign is over"
+ line "already?"
+ cont "It's not fair!"
+ prompt
+
+_GaryVictoryText::
+ text "Hahaha!"
+ line "I won, I won!"
+
+ para "I'm too good for"
+ line "you, <PLAYER>!"
+
+ para "You did well to"
+ line "even reach me,"
+ cont "<RIVAL>, the"
+ cont "#MON genius!"
+
+ para "Nice try, loser!"
+ line "Hahaha!"
+ prompt
+
+_GaryText_76103::
+ text "Why?"
+ line "Why did I lose?"
+
+ para "I never made any"
+ line "mistakes raising"
+ cont "my #MON..."
+
+ para "Darn it! You're"
+ line "the new #MON"
+ cont "LEAGUE champion!"
+
+ para "Although I don't"
+ line "like to admit it."
+ done
+
+_GaryText2::
+ text "OAK: <PLAYER>!"
+ done
+
+_GaryText_76120::
+ text "OAK: So, you won!"
+ line "Congratulations!"
+ cont "You're the new"
+ cont "#MON LEAGUE"
+ cont "champion!"
+
+ para "You've grown up so"
+ line "much since you"
+ cont "first left with"
+ cont "@"
+ TX_RAM wcd6d
+ text "!"
+
+ para "<PLAYER>, you have"
+ line "come of age!"
+ done
+
+_GaryText_76125::
+ text "OAK: <RIVAL>! I'm"
+ line "disappointed!"
+
+ para "I came when I"
+ line "heard you beat"
+ cont "the ELITE FOUR!"
+
+ para "But, when I got"
+ line "here, you had"
+ cont "already lost!"
+
+ para "<RIVAL>! Do you"
+ line "understand why"
+ cont "you lost?"
+
+ para "You have forgotten"
+ line "to treat your"
+ cont "#MON with"
+ cont "trust and love!"
+
+ para "Without them, you"
+ line "will never become"
+ cont "a champ again!"
+ done
+
+_GaryText_7612a::
+ text "OAK: <PLAYER>!"
+
+ para "You understand"
+ line "that your victory"
+ cont "was not just your"
+ cont "own doing!"
+
+ para "The bond you share"
+ line "with your #MON"
+ cont "is marvelous!"
+
+ para "<PLAYER>!"
+ line "Come with me!"
+ done
diff --git a/en/text/maps/cinnabar_gym.asm b/en/text/maps/cinnabar_gym.asm
new file mode 100644
index 00000000..173f94d2
--- /dev/null
+++ b/en/text/maps/cinnabar_gym.asm
@@ -0,0 +1,209 @@
+_BlaineBattleText::
+ text "Hah!"
+
+ para "I am BLAINE! I"
+ line "am the LEADER of"
+ cont "CINNABAR GYM!"
+
+ para "My fiery #MON"
+ line "will incinerate"
+ cont "all challengers!"
+
+ para "Hah! You better"
+ line "have BURN HEAL!"
+ done
+
+_BlaineEndBattleText::
+ text "I have"
+ line "burnt out!"
+
+ para "You have earned"
+ line "the VOLCANOBADGE!@@"
+
+_BlaineFireBlastText::
+ text "FIRE BLAST is the"
+ line "ultimate fire"
+ cont "technique!"
+
+ para "Don't waste it on"
+ line "water #MON!"
+ done
+
+_BlaineBadgeText::
+ text "Hah!"
+
+ para "The VOLCANOBADGE"
+ line "heightens the"
+ cont "SPECIAL abilities"
+ cont "of your #MON!"
+
+ para "Here, you can"
+ line "have this too!"
+ done
+
+_ReceivedTM38Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM38ExplanationText::
+ db $0
+ para "TM38 contains"
+ line "FIRE BLAST!"
+
+ para "Teach it to fire-"
+ line "type #MON!"
+
+ para "CHARMELEON or"
+ line "PONYTA would be"
+ cont "good bets!"
+ done
+
+_TM38NoRoomText::
+ text "Make room for my"
+ line "gift!"
+ done
+
+_CinnabarGymText_7595f::
+ text "Do you know how"
+ line "hot #MON fire"
+ cont "breath can get?"
+ done
+
+_CinnabarGymText_75964::
+ text "Yow!"
+ line "Hot, hot, hot!"
+ prompt
+
+_CinnabarGymText_75969::
+ text "Fire, or to be"
+ line "more precise,"
+ cont "combustion..."
+
+ para "Blah, blah, blah,"
+ line "blah..."
+ done
+
+_CinnabarGymText_75994::
+ text "I was a thief, but"
+ line "I became straight"
+ cont "as a trainer!"
+ done
+
+_CinnabarGymText_75999::
+ text "I"
+ line "surrender!"
+ prompt
+
+_CinnabarGymText_7599e::
+ text "I can't help"
+ line "stealing other"
+ cont "people's #MON!"
+ done
+
+_CinnabarGymText_759c9::
+ text "You can't win!"
+ line "I have studied"
+ cont "#MON totally!"
+ done
+
+_CinnabarGymText_759ce::
+ text "Waah!"
+ line "My studies!"
+ prompt
+
+_CinnabarGymText_759d3::
+ text "My theories are"
+ line "too complicated"
+ cont "for you!"
+ done
+
+_CinnabarGymText_759fe::
+ text "I just like using"
+ line "fire #MON!"
+ done
+
+_CinnabarGymText_75a03::
+ text "Too hot"
+ line "to handle!"
+ prompt
+
+_CinnabarGymText_75a08::
+ text "I wish there was"
+ line "a thief #MON!"
+ cont "I'd use that!"
+ done
+
+_CinnabarGymText_75a33::
+ text "I know why BLAINE"
+ line "became a trainer!"
+ done
+
+_CinnabarGymText_75a38::
+ text "Ow!"
+ prompt
+
+_CinnabarGymText_75a3d::
+ text "BLAINE was lost"
+ line "in the mountains"
+ cont "when a fiery bird"
+ cont "#MON appeared."
+
+ para "Its light enabled"
+ line "BLAINE to find"
+ cont "his way down!"
+ done
+
+_CinnabarGymText_75a68::
+ text "I've been to many"
+ line "GYMs, but this is"
+ cont "my favorite!"
+ done
+
+_CinnabarGymText_75a6d::
+ text "Yowza!"
+ line "Too hot!"
+ prompt
+
+_CinnabarGymText_75a72::
+ text "Us fire #MON"
+ line "fans like PONYTA"
+ cont "and NINETALES!"
+ done
+
+_CinnabarGymText_75a9d::
+ text "Fire is weak"
+ line "against H2O!"
+ done
+
+_CinnabarGymText_75aa2::
+ text "Oh!"
+ line "Snuffed out!"
+ prompt
+
+_CinnabarGymText_75aa7::
+ text "Water beats fire!"
+ line "But, fire melts"
+ cont "ice #MON!"
+ done
+
+_CinnabarGymText_75ac2::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "The hot-headed"
+ line "BLAINE is a fire"
+ cont "#MON pro!"
+
+ para "Douse his spirits"
+ line "with water!"
+
+ para "You better take"
+ line "some BURN HEALs!"
+ done
+
+_CinnabarGymText_75ac7::
+ text "<PLAYER>! You beat"
+ line "that fire brand!"
+ done
diff --git a/en/text/maps/cinnabar_island.asm b/en/text/maps/cinnabar_island.asm
new file mode 100644
index 00000000..352ab8ea
--- /dev/null
+++ b/en/text/maps/cinnabar_island.asm
@@ -0,0 +1,37 @@
+_CinnabarIslandText8::
+ text "The door is"
+ line "locked..."
+ done
+
+_CinnabarIslandText1::
+ text "CINNABAR GYM's"
+ line "BLAINE is an odd"
+ cont "man who has lived"
+ cont "here for decades."
+ done
+
+_CinnabarIslandText2::
+ text "Scientists conduct"
+ line "experiments in"
+ cont "the burned out"
+ cont "building."
+ done
+
+_CinnabarIslandText3::
+ text "CINNABAR ISLAND"
+ line "The Fiery Town of"
+ cont "Burning Desire"
+ done
+
+_CinnabarIslandText6::
+ text "#MON LAB"
+ done
+
+_CinnabarIslandText7::
+ text "CINNABAR ISLAND"
+ line "#MON GYM"
+ cont "LEADER: BLAINE"
+
+ para "The Hot-Headed"
+ line "Quiz Master!"
+ done
diff --git a/en/text/maps/cinnabar_lab.asm b/en/text/maps/cinnabar_lab.asm
new file mode 100644
index 00000000..a93a484d
--- /dev/null
+++ b/en/text/maps/cinnabar_lab.asm
@@ -0,0 +1,29 @@
+_Lab1Text1::
+ text "We study #MON"
+ line "extensively here."
+
+ para "People often bring"
+ line "us rare #MON"
+ cont "for examination."
+ done
+
+_Lab1Text2::
+ text "A photo of the"
+ line "LAB's founder,"
+ cont "DR.FUJI!"
+ done
+
+_Lab1Text3::
+ text "#MON LAB"
+ line "Meeting Room"
+ done
+
+_Lab1Text4::
+ text "#MON LAB"
+ line "R-and-D Room"
+ done
+
+_Lab1Text5::
+ text "#MON LAB"
+ line "Testing Room"
+ done
diff --git a/en/text/maps/cinnabar_lab_fossil_room.asm b/en/text/maps/cinnabar_lab_fossil_room.asm
new file mode 100644
index 00000000..3978814e
--- /dev/null
+++ b/en/text/maps/cinnabar_lab_fossil_room.asm
@@ -0,0 +1,78 @@
+_Lab4Text_75dc6::
+ text "Hiya!"
+
+ para "I am important"
+ line "doctor!"
+
+ para "I study here rare"
+ line "#MON fossils!"
+
+ para "You! Have you a"
+ line "fossil for me?"
+ prompt
+
+_Lab4Text_75dcb::
+ text "No! Is too bad!"
+ done
+
+_Lab4Text_75dd0::
+ text "I take a little"
+ line "time!"
+
+ para "You go for walk a"
+ line "little while!"
+ done
+
+_Lab4Text_75dd5::
+ text "Where were you?"
+
+ para "Your fossil is"
+ line "back to life!"
+
+ para "It was @"
+ TX_RAM wcf4b
+ db $0
+ line "like I think!"
+ prompt
+
+_Lab4Text_610ae::
+ text "Oh! That is"
+ line "@"
+ TX_RAM wcd6d
+ text "!"
+
+ para "It is fossil of"
+ line "@"
+ TX_RAM wcf4b
+ text ", a"
+ cont "#MON that is"
+ cont "already extinct!"
+
+ para "My Resurrection"
+ line "Machine will make"
+ cont "that #MON live"
+ cont "again!"
+ done
+
+_Lab4Text_610b3::
+ text "So! You hurry and"
+ line "give me that!"
+
+ para "<PLAYER> handed"
+ line "over @"
+ TX_RAM wcd6d
+ text "!"
+ prompt
+
+_Lab4Text_610b8::
+ text "I take a little"
+ line "time!"
+
+ para "You go for walk a"
+ line "little while!"
+ done
+
+_Lab4Text_610bd::
+ text "Aiyah! You come"
+ line "again!"
+ done
diff --git a/en/text/maps/cinnabar_lab_metronome_room.asm b/en/text/maps/cinnabar_lab_metronome_room.asm
new file mode 100644
index 00000000..fa04677f
--- /dev/null
+++ b/en/text/maps/cinnabar_lab_metronome_room.asm
@@ -0,0 +1,63 @@
+_TM35PreReceiveText::
+ text "Tch-tch-tch!"
+ line "I made a cool TM!"
+
+ para "It can cause all"
+ line "kinds of fun!"
+ prompt
+
+_ReceivedTM35Text::
+ text "<PLAYER> received "
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM35ExplanationText::
+ text "Tch-tch-tch!"
+ line "That's the sound"
+ cont "of a METRONOME!"
+
+ para "It tweaks your"
+ line "#MON's brain"
+ cont "into using moves"
+ cont "it doesn't know!"
+ done
+
+_TM35NoRoomText::
+ text "Your pack is"
+ line "crammed full!"
+ done
+
+_Lab3Text2::
+ text "EEVEE can evolve"
+ line "into 1 of 3 kinds"
+ cont "of #MON."
+ done
+
+_Lab3Text3::
+ text "There's an e-mail"
+ line "message!"
+
+ para "..."
+
+ para "The 3 legendary"
+ line "bird #MON are"
+ cont "ARTICUNO, ZAPDOS"
+ cont "and MOLTRES."
+
+ para "Their whereabouts"
+ line "are unknown."
+
+ para "We plan to explore"
+ line "the cavern close"
+ cont "to CERULEAN."
+
+ para "From: #MON"
+ line "RESEARCH TEAM"
+
+ para "..."
+ done
+
+_Lab3Text5::
+ text "An amber pipe!"
+ done
diff --git a/en/text/maps/cinnabar_lab_trade_room.asm b/en/text/maps/cinnabar_lab_trade_room.asm
new file mode 100644
index 00000000..196124e7
--- /dev/null
+++ b/en/text/maps/cinnabar_lab_trade_room.asm
@@ -0,0 +1,9 @@
+_Lab2Text1::
+ text "I found this very"
+ line "strange fossil in"
+ cont "MT.MOON!"
+
+ para "I think it's a"
+ line "rare, prehistoric"
+ cont "#MON!"
+ done
diff --git a/en/text/maps/cinnabar_mart.asm b/en/text/maps/cinnabar_mart.asm
new file mode 100644
index 00000000..42a41d06
--- /dev/null
+++ b/en/text/maps/cinnabar_mart.asm
@@ -0,0 +1,10 @@
+_CinnabarMartText2::
+ text "Don't they have X"
+ line "ATTACK? It's good"
+ cont "for battles!"
+ done
+
+_CinnabarMartText3::
+ text "It never hurts to"
+ line "have extra items!"
+ done
diff --git a/en/text/maps/cinnabar_pokecenter.asm b/en/text/maps/cinnabar_pokecenter.asm
new file mode 100644
index 00000000..cf481764
--- /dev/null
+++ b/en/text/maps/cinnabar_pokecenter.asm
@@ -0,0 +1,21 @@
+_CinnabarPokecenterText2::
+ text "You can cancel"
+ line "evolution."
+
+ para "When a #MON is"
+ line "evolving, you can"
+ cont "stop it and leave"
+ cont "it the way it is."
+ done
+
+_CinnabarPokecenterText3::
+ text "Do you have any"
+ line "friends?"
+
+ para "#MON you get"
+ line "in trades grow"
+ cont "very quickly."
+
+ para "I think it's"
+ line "worth a try!"
+ done
diff --git a/en/text/maps/copycats_house_1f.asm b/en/text/maps/copycats_house_1f.asm
new file mode 100644
index 00000000..3ec2b151
--- /dev/null
+++ b/en/text/maps/copycats_house_1f.asm
@@ -0,0 +1,20 @@
+_CopycatsHouse1FText1::
+ text "My daughter is so"
+ line "self-centered."
+ cont "She only has a"
+ cont "few friends."
+ done
+
+_CopycatsHouse1FText2::
+ text "My daughter likes"
+ line "to mimic people."
+
+ para "Her mimicry has"
+ line "earned her the"
+ cont "nickname COPYCAT"
+ cont "around here!"
+ done
+
+_CopycatsHouse1FText3::
+ text "CHANSEY: Chaan!"
+ line "Sii!@@"
diff --git a/en/text/maps/copycats_house_2f.asm b/en/text/maps/copycats_house_2f.asm
new file mode 100644
index 00000000..44988e58
--- /dev/null
+++ b/en/text/maps/copycats_house_2f.asm
@@ -0,0 +1,96 @@
+_CopycatsHouse2FText_5ccd4::
+ text "<PLAYER>: Hi! Do"
+ line "you like #MON?"
+
+ para "<PLAYER>: Uh no, I"
+ line "just asked you."
+
+ para "<PLAYER>: Huh?"
+ line "You're strange!"
+
+ para "COPYCAT: Hmm?"
+ line "Quit mimicking?"
+
+ para "But, that's my"
+ line "favorite hobby!"
+ prompt
+
+_TM31PreReceiveText::
+ text "Oh wow!"
+ line "A # DOLL!"
+
+ para "For me?"
+ line "Thank you!"
+
+ para "You can have"
+ line "this, then!"
+ prompt
+
+_ReceivedTM31Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM31ExplanationText1::
+ db $0
+ para "TM31 contains my"
+ line "favorite, MIMIC!"
+
+ para "Use it on a good"
+ line "#MON!@@"
+
+_TM31ExplanationText2::
+ text "<PLAYER>: Hi!"
+ line "Thanks for TM31!"
+
+ para "<PLAYER>: Pardon?"
+
+ para "<PLAYER>: Is it"
+ line "that fun to mimic"
+ cont "my every move?"
+
+ para "COPYCAT: You bet!"
+ line "It's a scream!"
+ done
+
+_TM31NoRoomText::
+ text "Don't you want"
+ line "this?@@"
+
+_CopycatsHouse2FText2::
+ text "DODUO: Giiih!"
+
+ para "MIRROR MIRROR ON"
+ line "THE WALL, WHO IS"
+ cont "THE FAIREST ONE"
+ cont "OF ALL?"
+ done
+
+_CopycatsHouse2FText3::
+ text "This is a rare"
+ line "#MON! Huh?"
+ cont "It's only a doll!"
+ done
+
+_CopycatsHouse2FText6::
+ text "A game with MARIO"
+ line "wearing a bucket"
+ cont "on his head!"
+ done
+
+_CopycatsHouse2FText_5cd17::
+ text "..."
+
+ para "My Secrets!"
+
+ para "Skill: Mimicry!"
+ line "Hobby: Collecting"
+ cont "dolls!"
+ cont "Favorite #MON:"
+ cont "CLEFAIRY!"
+ done
+
+_CopycatsHouse2FText_5cd1c::
+ text "Huh? Can't see!"
+ done
diff --git a/en/text/maps/daycare_1.asm b/en/text/maps/daycare_1.asm
new file mode 100644
index 00000000..f4cec10e
--- /dev/null
+++ b/en/text/maps/daycare_1.asm
@@ -0,0 +1,62 @@
+_DayCareIntroText::
+ text "I run a DAYCARE."
+ line "Would you like me"
+ cont "to raise one of"
+ cont "your #MON?"
+ done
+
+_DayCareWhichMonText::
+ text "Which #MON"
+ line "should I raise?"
+ prompt
+
+_DayCareWillLookAfterMonText::
+ text "Fine, I'll look"
+ line "after @"
+ TX_RAM wcd6d
+ db $0
+ cont "for a while."
+ prompt
+
+_DayCareComeSeeMeInAWhileText::
+ text "Come see me in"
+ line "a while."
+ done
+
+_DayCareMonHasGrownText::
+ text "Your @"
+ TX_RAM wcd6d
+ db $0
+ line "has grown a lot!"
+
+ para "By level, it's"
+ line "grown by @"
+ TX_NUM wDayCareNumLevelsGrown,$1,$3
+ text "!"
+
+ para "Aren't I great?"
+ prompt
+
+_DayCareOweMoneyText::
+ text "You owe me ¥@"
+ TX_BCD wDayCareTotalCost, $c2
+ db $0
+ line "for the return"
+ cont "of this #MON."
+ done
+
+_DayCareGotMonBackText::
+ text "<PLAYER> got"
+ line "@"
+ TX_RAM wDayCareMonName
+ text " back!"
+ done
+
+_DayCareMonNeedsMoreTimeText::
+ text "Back already?"
+ line "Your @"
+ TX_RAM wcd6d
+ db $0
+ cont "needs some more"
+ cont "time with me."
+ prompt
diff --git a/en/text/maps/daycare_2.asm b/en/text/maps/daycare_2.asm
new file mode 100644
index 00000000..20c0e5ad
--- /dev/null
+++ b/en/text/maps/daycare_2.asm
@@ -0,0 +1,33 @@
+_DayCareAllRightThenText::
+ text "All right then,"
+ line "@@"
+
+_DayCareComeAgainText::
+ text "come again."
+ done
+
+_DayCareNoRoomForMonText::
+ text "You have no room"
+ line "for this #MON!"
+ done
+
+_DayCareOnlyHaveOneMonText::
+ text "You only have one"
+ line "#MON with you."
+ done
+
+_DayCareCantAcceptMonWithHMText::
+ text "I can't accept a"
+ line "#MON that"
+ cont "knows an HM move."
+ done
+
+_DayCareHeresYourMonText::
+ text "Thank you! Here's"
+ line "your #MON!"
+ prompt
+
+_DayCareNotEnoughMoneyText::
+ text "Hey, you don't"
+ line "have enough ¥!"
+ done
diff --git a/en/text/maps/digletts_cave_route_11_entrance.asm b/en/text/maps/digletts_cave_route_11_entrance.asm
new file mode 100644
index 00000000..ecd3225e
--- /dev/null
+++ b/en/text/maps/digletts_cave_route_11_entrance.asm
@@ -0,0 +1,8 @@
+_DiglettsCaveEntRoute11Text1::
+ text "What a surprise!"
+ line "DIGLETTs dug this"
+ cont "long tunnel!"
+
+ para "It goes right to"
+ line "VIRIDIAN CITY!"
+ done
diff --git a/en/text/maps/digletts_cave_route_2_entrance.asm b/en/text/maps/digletts_cave_route_2_entrance.asm
new file mode 100644
index 00000000..a04bbef7
--- /dev/null
+++ b/en/text/maps/digletts_cave_route_2_entrance.asm
@@ -0,0 +1,9 @@
+_DiglettsCaveRoute2Text1::
+ text "I went to ROCK"
+ line "TUNNEL, but it's"
+ cont "dark and scary."
+
+ para "If a #MON's"
+ line "FLASH could light"
+ cont "it up..."
+ done
diff --git a/en/text/maps/fan_club.asm b/en/text/maps/fan_club.asm
new file mode 100644
index 00000000..4827f2e8
--- /dev/null
+++ b/en/text/maps/fan_club.asm
@@ -0,0 +1,143 @@
+PikachuFanText::
+ text "Won't you admire"
+ line "my PIKACHU's"
+ cont "adorable tail?"
+ done
+
+PikachuFanBetterText::
+ text "Humph! My PIKACHU"
+ line "is twice as cute"
+ cont "as that one!"
+ done
+
+SeelFanText::
+ text "I just love my"
+ line "SEEL!"
+
+ para "It squeals when I"
+ line "hug it!"
+ done
+
+SeelFanBetterText::
+ text "Oh dear!"
+
+ para "My SEEL is far"
+ line "more attractive!"
+ done
+
+FanClubPikachuText::
+ text "PIKACHU: Chu!"
+ line "Pikachu!"
+ done
+
+FanClubSeelText::
+ text "SEEL: Kyuoo!"
+ done
+
+FanClubMeetChairText::
+ text "I chair the"
+ line "#MON Fan Club!"
+
+ para "I have collected"
+ line "over 100 #MON!"
+
+ para "I'm very fussy"
+ line "when it comes to"
+ cont "#MON!"
+
+ para "So..."
+
+ para "Did you come"
+ line "visit to hear"
+ cont "about my #MON?"
+ done
+
+FanClubChairStoryText::
+ text "Good!"
+ line "Then listen up!"
+
+ para "My favorite"
+ line "RAPIDASH..."
+
+ para "It...cute..."
+ line "lovely...smart..."
+ cont "plus...amazing..."
+ cont "you think so?..."
+ cont "oh yes...it..."
+ cont "stunning..."
+ cont "kindly..."
+ cont "love it!"
+
+ para "Hug it...when..."
+ cont "sleeping...warm"
+ cont "and cuddly..."
+ cont "spectacular..."
+ cont "ravishing..."
+ cont "...Oops! Look at"
+ cont "the time! I kept"
+ cont "you too long!"
+
+ para "Thanks for hearing"
+ line "me out! I want"
+ cont "you to have this!"
+ prompt
+
+ReceivedBikeVoucherText::
+ text "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+ExplainBikeVoucherText::
+ text ""
+ para "Exchange that for"
+ line "a BICYCLE!"
+
+ para "Don't worry, my"
+ line "FEAROW will FLY"
+ cont "me anywhere!"
+
+ para "So, I don't need a"
+ line "BICYCLE!"
+
+ para "I hope you like"
+ line "cycling!"
+ done
+
+FanClubNoStoryText::
+ text "Oh. Come back"
+ line "when you want to"
+ cont "hear my story!"
+ done
+
+FanClubChairFinalText::
+ text "Hello, <PLAYER>!"
+
+ para "Did you come see"
+ line "me about my"
+ cont "#MON again?"
+
+ para "No? Too bad!"
+ done
+
+FanClubBagFullText::
+ text "Make room for"
+ line "this!"
+ done
+
+_FanClubText6::
+ text "Our Chairman is"
+ line "very vocal about"
+ cont "#MON."
+ done
+
+_FanClubText7::
+ text "Let's all listen"
+ line "politely to other"
+ cont "trainers!"
+ done
+
+_FanClubText8::
+ text "If someone brags,"
+ line "brag right back!"
+ done
diff --git a/en/text/maps/fighting_dojo.asm b/en/text/maps/fighting_dojo.asm
new file mode 100644
index 00000000..3df069c1
--- /dev/null
+++ b/en/text/maps/fighting_dojo.asm
@@ -0,0 +1,130 @@
+_FightingDojoText_5ce8e::
+ text "Grunt!"
+
+ para "I am the KARATE"
+ line "MASTER! I am the"
+ cont "LEADER here!"
+
+ para "You wish to"
+ line "challenge us?"
+ cont "Expect no mercy!"
+
+ para "Fwaaa!"
+ done
+
+_FightingDojoText_5ce93::
+ text "Hwa!"
+ line "Arrgh! Beaten!"
+ prompt
+
+_FightingDojoText_5ce98::
+ text "Indeed, I have"
+ line "lost!"
+
+ para "But, I beseech"
+ line "you, do not take"
+ cont "our emblem as"
+ cont "your trophy!"
+
+ para "In return, I will"
+ line "give you a prized"
+ cont "fighting #MON!"
+
+ para "Choose whichever"
+ line "one you like!"
+ done
+
+_FightingDojoText_5ce9d::
+ text "Ho!"
+
+ para "Stay and train at"
+ line "Karate with us!"
+ done
+
+_FightingDojoBattleText1::
+ text "Hoargh! Take your"
+ line "shoes off!"
+ done
+
+_FightingDojoEndBattleText1::
+ text "I give"
+ line "up!"
+ prompt
+
+_FightingDojoAfterBattleText1::
+ text "You wait 'til you"
+ line "see our Master!"
+
+ para "I'm a small fry"
+ line "compared to him!"
+ done
+
+_FightingDojoBattleText2::
+ text "I hear you're"
+ line "good! Show me!"
+ done
+
+_FightingDojoEndBattleText2::
+ text "Judge!"
+ line "1 point!"
+ prompt
+
+_FightingDojoAfterBattleText2::
+ text "Our Master is a"
+ line "pro fighter!"
+ done
+
+_FightingDojoBattleText3::
+ text "Nothing tough"
+ line "frightens me!"
+
+ para "I break boulders"
+ line "for training!"
+ done
+
+_FightingDojoEndBattleText3::
+ text "Yow!"
+ line "Stubbed fingers!"
+ prompt
+
+_FightingDojoAfterBattleText3::
+ text "The only thing"
+ line "that frightens us"
+ cont "is psychic power!"
+ done
+
+_FightingDojoBattleText4::
+ text "Hoohah!"
+
+ para "You're trespassing"
+ line "in our FIGHTING"
+ cont "DOJO!"
+ done
+
+_FightingDojoEndBattleText4::
+ text "Oof!"
+ line "I give up!"
+ prompt
+
+_FightingDojoAfterBattleText4::
+ text "The prime fighters"
+ line "across the land"
+ cont "train here."
+ done
+
+_WantHitmonleeText::
+ text "You want the"
+ line "hard kicking"
+ cont "HITMONLEE?"
+ done
+
+_WantHitmonchanText::
+ text "You want the"
+ line "piston punching"
+ cont "HITMONCHAN?"
+ done
+
+_OtherHitmonText::
+ text "Better not get"
+ line "greedy..."
+ done
diff --git a/en/text/maps/fuchsia_city.asm b/en/text/maps/fuchsia_city.asm
new file mode 100644
index 00000000..a90d0021
--- /dev/null
+++ b/en/text/maps/fuchsia_city.asm
@@ -0,0 +1,119 @@
+_FuchsiaCityText1::
+ text "Did you try the"
+ line "SAFARI GAME? Some"
+ cont "#MON can only"
+ cont "be caught there."
+ done
+
+_FuchsiaCityText2::
+ text "SAFARI ZONE has a"
+ line "zoo in front of"
+ cont "the entrance."
+
+ para "Out back is the"
+ line "SAFARI GAME for"
+ cont "catching #MON."
+ done
+
+_FuchsiaCityText3::
+ text "ERIK: Where's"
+ line "SARA? I said I'd"
+ cont "meet her here."
+ done
+
+_FuchsiaCityText4::
+ text "That item ball in"
+ line "there is really a"
+ cont "#MON."
+ done
+
+_FuchsiaCityText5::
+ text "!"
+ done
+
+_FuchsiaCityText11::
+ text "FUCHSIA CITY"
+ line "Behold! It's"
+ cont "Passion Pink!"
+ done
+
+_FuchsiaCityText13::
+ text "SAFARI GAME"
+ line "#MON-U-CATCH!"
+ done
+
+_FuchsiaCityText16::
+ text "SAFARI ZONE"
+ line "WARDEN's HOME"
+ done
+
+_FuchsiaCityText17::
+ text "#MON PARADISE"
+ line "SAFARI ZONE"
+ done
+
+_FuchsiaCityText18::
+ text "FUCHSIA CITY"
+ line "#MON GYM"
+ cont "LEADER: KOGA"
+
+ para "The Poisonous"
+ line "Ninja Master"
+ done
+
+_FuchsiaCityChanseyText::
+ text "Name: CHANSEY"
+
+ para "Catching one is"
+ line "all up to chance."
+ prompt
+
+_FuchsiaCityVoltorbText::
+ text "Name: VOLTORB"
+
+ para "The very image of"
+ line "a # BALL."
+ prompt
+
+_FuchsiaCityKangaskhanText::
+ text "Name: KANGASKHAN"
+
+ para "A maternal #MON"
+ line "that raises its"
+ cont "young in a pouch"
+ cont "on its belly."
+ prompt
+
+_FuchsiaCitySlowpokeText::
+ text "Name: SLOWPOKE"
+
+ para "Friendly and very"
+ line "slow moving."
+ prompt
+
+_FuchsiaCityLaprasText::
+ text "Name: LAPRAS"
+
+ para "A.K.A. the king"
+ line "of the seas."
+ prompt
+
+_FuchsiaCityOmanyteText::
+ text "Name: OMANYTE"
+
+ para "A #MON that"
+ line "was resurrected"
+ cont "from a fossil."
+ prompt
+
+_FuchsiaCityKabutoText::
+ text "Name: KABUTO"
+
+ para "A #MON that"
+ line "was resurrected"
+ cont "from a fossil."
+ prompt
+
+_FuchsiaCityText_19b2a::
+ text "..."
+ done
diff --git a/en/text/maps/fuchsia_fishing_house.asm b/en/text/maps/fuchsia_fishing_house.asm
new file mode 100644
index 00000000..b1b8b2f2
--- /dev/null
+++ b/en/text/maps/fuchsia_fishing_house.asm
@@ -0,0 +1,43 @@
+_FuchsiaHouse3Text_561bd::
+ text "I'm the FISHING"
+ line "GURU's older"
+ cont "brother!"
+
+ para "I simply Looove"
+ line "fishing!"
+
+ para "Do you like to"
+ line "fish?"
+ done
+
+_FuchsiaHouse3Text_561c2::
+ text "Grand! I like"
+ line "your style!"
+
+ para "Take this and"
+ line "fish, young one!"
+
+ para "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_FuchsiaHouse3Text_56212::
+ text "Oh... That's so"
+ line "disappointing..."
+ done
+
+_FuchsiaHouse3Text_56217::
+ text "Hello there,"
+ line "<PLAYER>!"
+
+ para "How are the fish"
+ line "biting?"
+ done
+
+_FuchsiaHouse3Text_5621c::
+ text "Oh no!"
+
+ para "You have no room"
+ line "for my gift!"
+ done
diff --git a/en/text/maps/fuchsia_gym_1.asm b/en/text/maps/fuchsia_gym_1.asm
new file mode 100644
index 00000000..9108fc79
--- /dev/null
+++ b/en/text/maps/fuchsia_gym_1.asm
@@ -0,0 +1,26 @@
+_KogaBeforeBattleText::
+ text "KOGA: Fwahahaha!"
+
+ para "A mere child like"
+ line "you dares to"
+ cont "challenge me?"
+
+ para "Very well, I"
+ line "shall show you"
+ cont "true terror as a"
+ cont "ninja master!"
+
+ para "You shall feel"
+ line "the despair of"
+ cont "poison and sleep"
+ cont "techniques!"
+ done
+
+_KogaAfterBattleText::
+ text "Humph!"
+ line "You have proven"
+ cont "your worth!"
+
+ para "Here! Take the"
+ line "SOULBADGE!"
+ prompt
diff --git a/en/text/maps/fuchsia_gym_2.asm b/en/text/maps/fuchsia_gym_2.asm
new file mode 100644
index 00000000..2913fb8f
--- /dev/null
+++ b/en/text/maps/fuchsia_gym_2.asm
@@ -0,0 +1,193 @@
+_KogaExplainToxicText::
+ text "When afflicted by"
+ line "TOXIC, #MON"
+ cont "suffer more and"
+ cont "more as battle"
+ cont "progresses!"
+
+ para "It will surely"
+ line "terrorize foes!"
+ done
+
+_FuchsiaGymText9::
+ text "Now that you have"
+ line "the SOULBADGE,"
+ cont "the DEFENSE of"
+ cont "your #MON"
+ cont "increases!"
+
+ para "It also lets you"
+ line "SURF outside of"
+ cont "battle!"
+
+ para "Ah! Take this"
+ line "too!"
+ done
+
+_ReceivedTM06Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM06ExplanationText::
+ db $0
+ para "TM06 contains"
+ line "TOXIC!"
+
+ para "It is a secret"
+ line "technique over"
+ cont "400 years old!"
+ done
+
+_TM06NoRoomText::
+ text "Make space for"
+ line "this, child!"
+ done
+
+_FuchsiaGymBattleText1::
+ text "Strength isn't"
+ line "the key for"
+ cont "#MON!"
+
+ para "It's strategy!"
+
+ para "I'll show you how"
+ line "strategy can beat"
+ cont "brute strength!"
+ done
+
+_FuchsiaGymEndBattleText1::
+ text "What?"
+ line "Extraordinary!"
+ prompt
+
+_FuchsiaGymAfterBattleText1::
+ text "So, you mix brawn"
+ line "with brains?"
+ cont "Good strategy!"
+ done
+
+_FuchsiaGymBattleText2::
+ text "I wanted to become"
+ line "a ninja, so I"
+ cont "joined this GYM!"
+ done
+
+_FuchsiaGymEndBattleText2::
+ text "I'm done"
+ line "for!"
+ prompt
+
+_FuchsiaGymAfterBattleText2::
+ text "I will keep on"
+ line "training under"
+ cont "KOGA, my ninja"
+ cont "master!"
+ done
+
+_FuchsiaGymBattleText3::
+ text "Let's see you"
+ line "beat my special"
+ cont "techniques!"
+ done
+
+_FuchsiaGymEndBattleText3::
+ text "You"
+ line "had me fooled!"
+ prompt
+
+_FuchsiaGymAfterBattleText3::
+ text "I like poison and"
+ line "sleep techniques,"
+ cont "as they linger"
+ cont "after battle!"
+ done
+
+_FuchsiaGymBattleText4::
+ text "Stop right there!"
+
+ para "Our invisible"
+ line "walls have you"
+ cont "frustrated?"
+ done
+
+_FuchsiaGymEndBattleText4::
+ text "Whoa!"
+ line "He's got it!"
+ prompt
+
+_FuchsiaGymAfterBattleText4::
+ text "You impressed me!"
+ line "Here's a hint!"
+
+ para "Look very closely"
+ line "for gaps in the"
+ cont "invisible walls!"
+ done
+
+_FuchsiaGymBattleText5::
+ text "I also study the"
+ line "way of the ninja"
+ cont "with master KOGA!"
+
+ para "Ninja have a long"
+ line "history of using"
+ cont "animals!"
+ done
+
+_FuchsiaGymEndBattleText5::
+ text "Awoo!"
+ prompt
+
+_FuchsiaGymAfterBattleText5::
+ text "I still have much"
+ line "to learn!"
+ done
+
+_FuchsiaGymBattleText6::
+ text "Master KOGA comes"
+ line "from a long line"
+ cont "of ninjas!"
+
+ para "What did you"
+ line "descend from?"
+ done
+
+_FuchsiaGymEndBattleText6::
+ text "Dropped"
+ line "my balls!"
+ prompt
+
+_FuchsiaGymAfterBattleText6::
+ text "Where there is"
+ line "light, there is"
+ cont "shadow!"
+
+ para "Light and shadow!"
+ line "Which do you"
+ cont "choose?"
+ done
+
+_FuchsiaGymText_7564e::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "FUCHSIA GYM is"
+ line "riddled with"
+ cont "invisible walls!"
+
+ para "KOGA might appear"
+ line "close, but he's"
+ cont "blocked off!"
+
+ para "You have to find"
+ line "gaps in the walls"
+ cont "to reach him!"
+ done
+
+_FuchsiaGymText_75653::
+ text "It's amazing how"
+ line "ninja can terrify"
+ cont "even now!"
+ done
diff --git a/en/text/maps/fuchsia_house.asm b/en/text/maps/fuchsia_house.asm
new file mode 100644
index 00000000..7b6556b1
--- /dev/null
+++ b/en/text/maps/fuchsia_house.asm
@@ -0,0 +1,27 @@
+_FuchsiaHouse1Text1::
+ text "SAFARI ZONE's"
+ line "WARDEN is old,"
+ cont "but still active!"
+
+ para "All his teeth are"
+ line "false, though."
+ done
+
+_FuchsiaHouse1Text2::
+ text "Hmm? You've met"
+ line "BILL?"
+
+ para "He's my grandson!"
+
+ para "He always liked"
+ line "collecting things"
+ cont "even as a child!"
+ done
+
+_FuchsiaHouse1Text3::
+ text "BILL files his"
+ line "own #MON data"
+ cont "on his PC!"
+
+ para "Did he show you?"
+ done
diff --git a/en/text/maps/fuchsia_mart.asm b/en/text/maps/fuchsia_mart.asm
new file mode 100644
index 00000000..574898ce
--- /dev/null
+++ b/en/text/maps/fuchsia_mart.asm
@@ -0,0 +1,14 @@
+_FuchsiaMartText2::
+ text "Do you have a"
+ line "SAFARI ZONE flag?"
+
+ para "What about cards"
+ line "or calendars?"
+ done
+
+_FuchsiaMartText3::
+ text "Did you try X"
+ line "SPEED? It speeds"
+ cont "up a #MON in"
+ cont "battle!"
+ done
diff --git a/en/text/maps/fuchsia_meeting_room.asm b/en/text/maps/fuchsia_meeting_room.asm
new file mode 100644
index 00000000..10675ead
--- /dev/null
+++ b/en/text/maps/fuchsia_meeting_room.asm
@@ -0,0 +1,26 @@
+_FuchsiaMeetingRoomText1::
+ text "We nicknamed the"
+ line "WARDEN SLOWPOKE."
+
+ para "He and SLOWPOKE"
+ line "both look vacant!"
+ done
+
+_FuchsiaMeetingRoomText2::
+ text "SLOWPOKE is very"
+ line "knowledgeable"
+ cont "about #MON!"
+
+ para "He even has some"
+ line "fossils of rare,"
+ cont "extinct #MON!"
+ done
+
+_FuchsiaMeetingRoomText3::
+ text "SLOWPOKE came in,"
+ line "but I couldn't"
+ cont "understand him."
+
+ para "I think he's got"
+ line "a speech problem!"
+ done
diff --git a/en/text/maps/fuchsia_pokecenter.asm b/en/text/maps/fuchsia_pokecenter.asm
new file mode 100644
index 00000000..a0def7eb
--- /dev/null
+++ b/en/text/maps/fuchsia_pokecenter.asm
@@ -0,0 +1,20 @@
+_FuchsiaPokecenterText1::
+ text "You can't win"
+ line "with just one"
+ cont "strong #MON."
+
+ para "It's tough, but"
+ line "you have to raise"
+ cont "them evenly."
+ done
+
+_FuchsiaPokecenterText3::
+ text "There's a narrow"
+ line "trail west of"
+ cont "VIRIDIAN CITY."
+
+ para "It goes to #MON"
+ line "LEAGUE HQ."
+ cont "The HQ governs"
+ cont "all trainers."
+ done
diff --git a/en/text/maps/fujis_house.asm b/en/text/maps/fujis_house.asm
new file mode 100644
index 00000000..86cade68
--- /dev/null
+++ b/en/text/maps/fujis_house.asm
@@ -0,0 +1,85 @@
+_LavenderHouse1Text_1d8d1::
+ text "That's odd, MR.FUJI"
+ line "isn't here."
+ cont "Where'd he go?"
+ done
+
+_LavenderHouse1Text_1d8d6::
+ text "MR.FUJI had been"
+ line "praying alone for"
+ cont "CUBONE's mother."
+ done
+
+_LavenderHouse1Text_1d8f4::
+ text "This is really"
+ line "MR.FUJI's house."
+
+ para "He's really kind!"
+
+ para "He looks after"
+ line "abandoned and"
+ cont "orphaned #MON!"
+ done
+
+_LavenderHouse1Text_1d8f9::
+ text "It's so warm!"
+ line "#MON are so"
+ cont "nice to hug!"
+ done
+
+_LavenderHouse1Text3::
+ text "PSYDUCK: Gwappa!@@"
+
+_LavenderHouse1Text4::
+ text "NIDORINO: Gaoo!@@"
+
+_LavenderHouse1Text_1d94c::
+ text "MR.FUJI: <PLAYER>."
+
+ para "Your #DEX quest"
+ line "may fail without"
+ cont "love for your"
+ cont "#MON."
+
+ para "I think this may"
+ line "help your quest."
+ prompt
+
+_ReceivedFluteText::
+ text "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_FluteExplanationText::
+ db $0
+ para "Upon hearing #"
+ line "FLUTE, sleeping"
+ cont "#MON will"
+ cont "spring awake."
+
+ para "It works on all"
+ line "sleeping #MON."
+ done
+
+_FluteNoRoomText::
+ text "You must make"
+ line "room for this!"
+ done
+
+_MrFujiAfterFluteText::
+ text "MR.FUJI: Has my"
+ line "FLUTE helped you?"
+ done
+
+_LavenderHouse1Text6::
+ text "#MON Monthly"
+ line "Grand Prize"
+ cont "Drawing!"
+
+ para "The application"
+ line "form is..."
+
+ para "Gone! It's been"
+ line "clipped out!"
+ done
diff --git a/en/text/maps/hall_of_fame.asm b/en/text/maps/hall_of_fame.asm
new file mode 100644
index 00000000..c799268b
--- /dev/null
+++ b/en/text/maps/hall_of_fame.asm
@@ -0,0 +1,28 @@
+_HallofFameRoomText1::
+ text "OAK: Er-hem!"
+ line "Congratulations"
+ cont "<PLAYER>!"
+
+ para "This floor is the"
+ line "#MON HALL OF"
+ cont "FAME!"
+
+ para "#MON LEAGUE"
+ line "champions are"
+ cont "honored for their"
+ cont "exploits here!"
+
+ para "Their #MON are"
+ line "also recorded in"
+ cont "the HALL OF FAME!"
+
+ para "<PLAYER>! You have"
+ line "endeavored hard"
+ cont "to become the new"
+ cont "LEAGUE champion!"
+
+ para "Congratulations,"
+ line "<PLAYER>, you and"
+ cont "your #MON are"
+ cont "HALL OF FAMERs!"
+ done
diff --git a/en/text/maps/indigo_plateau_lobby.asm b/en/text/maps/indigo_plateau_lobby.asm
new file mode 100644
index 00000000..8487e29a
--- /dev/null
+++ b/en/text/maps/indigo_plateau_lobby.asm
@@ -0,0 +1,25 @@
+_IndigoPlateauLobbyText2::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "At #MON LEAGUE,"
+ line "you have to face"
+ cont "the ELITE FOUR in"
+ cont "succession."
+
+ para "If you lose, you"
+ line "have to start all"
+ cont "over again! This"
+ cont "is it! Go for it!"
+ done
+
+_IndigoPlateauLobbyText3::
+ text "From here on, you"
+ line "face the ELITE"
+ cont "FOUR one by one!"
+
+ para "If you win, a"
+ line "door opens to the"
+ cont "next trainer!"
+ cont "Good luck!"
+ done
diff --git a/en/text/maps/lance.asm b/en/text/maps/lance.asm
new file mode 100644
index 00000000..ed3dcada
--- /dev/null
+++ b/en/text/maps/lance.asm
@@ -0,0 +1,63 @@
+_LanceBeforeBattleText::
+ text "Ah! I heard about"
+ line "you <PLAYER>!"
+
+ para "I lead the ELITE"
+ line "FOUR! You can"
+ cont "call me LANCE the"
+ cont "dragon trainer!"
+
+ para "You know that"
+ line "dragons are"
+ cont "mythical #MON!"
+
+ para "They're hard to"
+ line "catch and raise,"
+ cont "but their powers"
+ cont "are superior!"
+
+ para "They're virtually"
+ line "indestructible!"
+
+ para "Well, are you"
+ line "ready to lose?"
+
+ para "Your LEAGUE"
+ line "challenge ends"
+ cont "with me, <PLAYER>!"
+ done
+
+_LanceEndBattleText::
+ text "That's it!"
+
+ para "I hate to admit"
+ line "it, but you are a"
+ cont "#MON master!"
+ prompt
+
+_LanceAfterBattleText::
+ text "I still can't"
+ line "believe my"
+ cont "dragons lost to"
+ cont "you, <PLAYER>!"
+
+ para "You are now the"
+ line "#MON LEAGUE"
+ cont "champion!"
+
+ para "...Or, you would"
+ line "have been, but"
+ cont "you have one more"
+ cont "challenge ahead."
+
+ para "You have to face"
+ line "another trainer!"
+ cont "His name is..."
+
+ para "<RIVAL>!"
+ line "He beat the ELITE"
+ cont "FOUR before you!"
+
+ para "He is the real"
+ line "#MON LEAGUE"
+ cont "champion!@@"
diff --git a/en/text/maps/lavender_house.asm b/en/text/maps/lavender_house.asm
new file mode 100644
index 00000000..66cc85a5
--- /dev/null
+++ b/en/text/maps/lavender_house.asm
@@ -0,0 +1,24 @@
+_LavenderHouse2Text1::
+ text "CUBONE: Kyarugoo!@@"
+
+_LavenderHouse2Text_1d9dc::
+ text "I hate those"
+ line "horrible ROCKETs!"
+
+ para "That poor CUBONE's"
+ line "mother..."
+
+ para "It was killed"
+ line "trying to escape"
+ cont "from TEAM ROCKET!"
+ done
+
+_LavenderHouse2Text_1d9e1::
+ text "The GHOST of"
+ line "#MON TOWER is"
+ cont "gone!"
+
+ para "Someone must have"
+ line "soothed its"
+ cont "restless soul!"
+ done
diff --git a/en/text/maps/lavender_mart.asm b/en/text/maps/lavender_mart.asm
new file mode 100644
index 00000000..222712c6
--- /dev/null
+++ b/en/text/maps/lavender_mart.asm
@@ -0,0 +1,30 @@
+_LavenderMartText2::
+ text "I'm searching for"
+ line "items that raise"
+ cont "the abilities of"
+ cont "#MON during a"
+ cont "single battle."
+
+ para "X ATTACK, X"
+ line "DEFEND, X SPEED"
+ cont "and X SPECIAL are"
+ cont "what I'm after."
+
+ para "Do you know where"
+ line "I can get them?"
+ done
+
+_LavenderMartReviveText::
+ text "You know REVIVE?"
+ line "It revives any"
+ cont "fainted #MON!"
+ done
+
+_LavenderMartNuggetText::
+ text "I found a NUGGET"
+ line "in the mountains."
+
+ para "I thought it was"
+ line "useless, but it"
+ cont "sold for ¥5000!"
+ done
diff --git a/en/text/maps/lavender_pokecenter.asm b/en/text/maps/lavender_pokecenter.asm
new file mode 100644
index 00000000..3aa7b67d
--- /dev/null
+++ b/en/text/maps/lavender_pokecenter.asm
@@ -0,0 +1,12 @@
+_LavenderPokecenterText2::
+ text "TEAM ROCKET will"
+ line "do anything for"
+ cont "the sake of gold!"
+ done
+
+_LavenderPokecenterText3::
+ text "I saw CUBONE's"
+ line "mother die trying"
+ cont "to escape from"
+ cont "TEAM ROCKET!"
+ done
diff --git a/en/text/maps/lavender_town.asm b/en/text/maps/lavender_town.asm
new file mode 100644
index 00000000..19b6c8c8
--- /dev/null
+++ b/en/text/maps/lavender_town.asm
@@ -0,0 +1,64 @@
+_LavenderTownText_4413c::
+ text "Do you believe in"
+ line "GHOSTs?"
+ done
+
+_LavenderTownText_44141::
+ text "Really? So there"
+ line "are believers..."
+ done
+
+_LavenderTownText_44146::
+ text "Hahaha, I guess"
+ line "not."
+
+ para "That white hand"
+ line "on your shoulder,"
+ cont "it's not real."
+ done
+
+_LavenderTownText2::
+ text "This town is known"
+ line "as the grave site"
+ cont "of #MON."
+
+ para "Memorial services"
+ line "are held in"
+ cont "#MON TOWER."
+ done
+
+_LavenderTownText3::
+ text "GHOSTs appeared"
+ line "in #MON TOWER."
+
+ para "I think they're"
+ line "the spirits of"
+ cont "#MON that the"
+ cont "ROCKETs killed."
+ done
+
+_LavenderTownText4::
+ text "LAVENDER TOWN"
+ line "The Noble Purple"
+ cont "Town"
+ done
+
+_LavenderTownText5::
+ text "New SILPH SCOPE!"
+
+ para "Make the Invisible"
+ line "Plain to See!"
+
+ para "SILPH CO."
+ done
+
+_LavenderTownText8::
+ text "LAVENDER VOLUNTEER"
+ line "#MON HOUSE"
+ done
+
+_LavenderTownText9::
+ text "May the Souls of"
+ line "#MON Rest Easy"
+ cont "#MON TOWER"
+ done
diff --git a/en/text/maps/lorelei.asm b/en/text/maps/lorelei.asm
new file mode 100644
index 00000000..fdbb55b4
--- /dev/null
+++ b/en/text/maps/lorelei.asm
@@ -0,0 +1,42 @@
+_LoreleiBeforeBattleText::
+ text "Welcome to"
+ line "#MON LEAGUE!"
+
+ para "I am LORELEI of"
+ line "the ELITE FOUR!"
+
+ para "No one can best"
+ line "me when it comes"
+ cont "to icy #MON!"
+
+ para "Freezing moves"
+ line "are powerful!"
+
+ para "Your #MON will"
+ line "be at my mercy"
+ cont "when they are"
+ cont "frozen solid!"
+
+ para "Hahaha!"
+ line "Are you ready?"
+ done
+
+_LoreleiEndBattleText::
+ text "How"
+ line "dare you!"
+ prompt
+
+_LoreleiAfterBattleText::
+ text "You're better"
+ line "than I thought!"
+ cont "Go on ahead!"
+
+ para "You only got a"
+ line "taste of #MON"
+ cont "LEAGUE power!"
+ done
+
+_LoreleiDontRunAwayText::
+ text "Someone's voice:"
+ line "Don't run away!"
+ done
diff --git a/en/text/maps/mansion_1f.asm b/en/text/maps/mansion_1f.asm
new file mode 100644
index 00000000..a3c517fb
--- /dev/null
+++ b/en/text/maps/mansion_1f.asm
@@ -0,0 +1,29 @@
+_Mansion1BattleText2::
+ text "Who are you? There"
+ line "shouldn't be"
+ cont "anyone here."
+ done
+
+_Mansion1EndBattleText2::
+ text "Ouch!"
+ prompt
+
+_Mansion1AfterBattleText2::
+ text "A key? I don't"
+ line "know what you're"
+ cont "talking about."
+ done
+
+_MansionSwitchText::
+ text "A secret switch!"
+
+ para "Press it?"
+ done
+
+_MansionSwitchPressedText::
+ text "Who wouldn't?"
+ prompt
+
+_MansionSwitchNotPressedText::
+ text "Not quite yet!"
+ done
diff --git a/en/text/maps/mansion_2f.asm b/en/text/maps/mansion_2f.asm
new file mode 100644
index 00000000..378efb30
--- /dev/null
+++ b/en/text/maps/mansion_2f.asm
@@ -0,0 +1,47 @@
+_Mansion2BattleText1::
+ text "I can't get out!"
+ line "This old place is"
+ cont "one big puzzle!"
+ done
+
+_Mansion2EndBattleText1::
+ text "Oh no!"
+ line "My bag of loot!"
+ prompt
+
+_Mansion2AfterBattleText1::
+ text "Switches open and"
+ line "close alternating"
+ cont "sets of doors!"
+ done
+
+_Mansion2Text3::
+ text "Diary: July 5"
+ line "Guyana,"
+ cont "South America"
+
+ para "A new #MON was"
+ line "discovered deep"
+ cont "in the jungle."
+ done
+
+_Mansion2Text4::
+ text "Diary: July 10"
+ line "We christened the"
+ cont "newly discovered"
+ cont "#MON, MEW."
+ done
+
+_Mansion2Text_520c2::
+ text "A secret switch!"
+
+ para "Press it?"
+ done
+
+_Mansion2Text_520c7::
+ text "Who wouldn't?"
+ prompt
+
+_Mansion2Text_520cc::
+ text "Not quite yet!"
+ done
diff --git a/en/text/maps/mansion_3f.asm b/en/text/maps/mansion_3f.asm
new file mode 100644
index 00000000..70331fdf
--- /dev/null
+++ b/en/text/maps/mansion_3f.asm
@@ -0,0 +1,37 @@
+_Mansion3BattleText1::
+ text "This place is"
+ line "like, huge!"
+ done
+
+_Mansion3EndBattleText1::
+ text "Ayah!"
+ prompt
+
+_Mansion3AfterBattleText1::
+ text "I wonder where"
+ line "my partner went."
+ done
+
+_Mansion3BattleText2::
+ text "My mentor once"
+ line "lived here."
+ done
+
+_Mansion3EndBattleText2::
+ text "Whew!"
+ line "Overwhelming!"
+ prompt
+
+_Mansion3AfterBattleText2::
+ text "So, you're stuck?"
+ line "Try jumping off"
+ cont "over there!"
+ done
+
+_Mansion3Text5::
+ text "Diary: Feb. 6"
+ line "MEW gave birth."
+
+ para "We named the"
+ line "newborn MEWTWO."
+ done
diff --git a/en/text/maps/mansion_b1f.asm b/en/text/maps/mansion_b1f.asm
new file mode 100644
index 00000000..1bc1ef89
--- /dev/null
+++ b/en/text/maps/mansion_b1f.asm
@@ -0,0 +1,39 @@
+_Mansion4BattleText1::
+ text "Uh-oh. Where am"
+ line "I now?"
+ done
+
+_Mansion4EndBattleText1::
+ text "Awooh!"
+ prompt
+
+_Mansion4AfterBattleText1::
+ text "You can find stuff"
+ line "lying around."
+ done
+
+_Mansion4BattleText2::
+ text "This place is"
+ line "ideal for a lab."
+ done
+
+_Mansion4EndBattleText2::
+ text "What"
+ line "was that for?"
+ prompt
+
+_Mansion4AfterBattleText2::
+ text "I like it here!"
+ line "It's conducive to"
+ cont "my studies!"
+ done
+
+_Mansion4Text7::
+ text "Diary; Sept. 1"
+ line "MEWTWO is far too"
+ cont "powerful."
+
+ para "We have failed to"
+ line "curb its vicious"
+ cont "tendencies..."
+ done
diff --git a/en/text/maps/mr_psychics_house.asm b/en/text/maps/mr_psychics_house.asm
new file mode 100644
index 00000000..7be2e11e
--- /dev/null
+++ b/en/text/maps/mr_psychics_house.asm
@@ -0,0 +1,25 @@
+_TM29PreReceiveText::
+ text "...Wait! Don't"
+ line "say a word!"
+
+ para "You wanted this!"
+ prompt
+
+_ReceivedTM29Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM29ExplanationText::
+ text "TM29 is PSYCHIC!"
+
+ para "It can lower the"
+ line "target's SPECIAL"
+ cont "abilities."
+ done
+
+_TM29NoRoomText::
+ text "Where do you plan"
+ line "to put this?"
+ done
diff --git a/en/text/maps/mt_moon_1f.asm b/en/text/maps/mt_moon_1f.asm
new file mode 100644
index 00000000..761a5240
--- /dev/null
+++ b/en/text/maps/mt_moon_1f.asm
@@ -0,0 +1,119 @@
+_MtMoon1BattleText2::
+ text "WHOA! You shocked"
+ line "me! Oh, you're"
+ cont "just a kid!"
+ done
+
+_MtMoon1EndBattleText2::
+ text "Wow!"
+ line "Shocked again!"
+ prompt
+
+_MtMoon1AfterBattleText2::
+ text "Kids like you"
+ line "shouldn't be"
+ cont "here!"
+ done
+
+_MtMoon1BattleText3::
+ text "Did you come to"
+ line "explore too?"
+ done
+
+_MtMoon1EndBattleText3::
+ text "Losing"
+ line "stinks!"
+ prompt
+
+_MtMoon1AfterBattleText3::
+ text "I came down here"
+ line "to show off to"
+ cont "girls."
+ done
+
+_MtMoon1BattleText4::
+ text "Wow! It's way"
+ line "bigger in here"
+ cont "than I thought!"
+ done
+
+_MtMoon1EndBattleText4::
+ text "Oh!"
+ line "I lost it!"
+ prompt
+
+_MtMoon1AfterBattleText4::
+ text "How do you get"
+ line "out of here?"
+ done
+
+_MtMoon1BattleText5::
+ text "What! Don't sneak"
+ line "up on me!"
+ done
+
+_MtMoon1EndBattleText5::
+ text "My"
+ line "#MON won't do!"
+ prompt
+
+_MtMoon1AfterBattleText5::
+ text "I have to find"
+ line "stronger #MON."
+ done
+
+_MtMoon1BattleText6::
+ text "What? I'm waiting"
+ line "for my friends to"
+ cont "find me here."
+ done
+
+_MtMoon1EndBattleText6::
+ text "I lost?"
+ prompt
+
+_MtMoon1AfterBattleText6::
+ text "I heard there are"
+ line "some very rare"
+ cont "fossils here."
+ done
+
+_MtMoon1BattleText7::
+ text "Suspicious men"
+ line "are in the cave."
+ cont "What about you?"
+ done
+
+_MtMoon1EndBattleText7::
+ text "You"
+ line "got me!"
+ prompt
+
+_MtMoon1AfterBattleText7::
+ text "I saw them! I'm"
+ line "sure they're from"
+ cont "TEAM ROCKET!"
+ done
+
+_MtMoon1BattleText8::
+ text "Go through this"
+ line "cave to get to"
+ cont "CERULEAN CITY!"
+ done
+
+_MtMoon1EndBattleText8::
+ text "I"
+ line "lost."
+ prompt
+
+_MtMoon1AfterBattleText8::
+ text "ZUBAT is tough!"
+ line "But, it can be"
+ cont "useful if you"
+ cont "catch one."
+ done
+
+_MtMoon1Text14::
+ text "Beware! ZUBAT is"
+ line "a blood sucker!"
+ done
diff --git a/en/text/maps/mt_moon_b1f.asm b/en/text/maps/mt_moon_b1f.asm
new file mode 100644
index 00000000..cd995ed5
--- /dev/null
+++ b/en/text/maps/mt_moon_b1f.asm
@@ -0,0 +1,3 @@
+_MtMoonText1::
+ db $0
+ done
diff --git a/en/text/maps/mt_moon_b2f.asm b/en/text/maps/mt_moon_b2f.asm
new file mode 100644
index 00000000..472649b9
--- /dev/null
+++ b/en/text/maps/mt_moon_b2f.asm
@@ -0,0 +1,122 @@
+_MtMoon3Text_49f24::
+ text "You want the"
+ line "DOME FOSSIL?"
+ done
+
+_MtMoon3Text_49f64::
+ text "You want the"
+ line "HELIX FOSSIL?"
+ done
+
+_MtMoon3Text_49f6f::
+ text "<PLAYER> got the"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_MtMoon3Text_49f7f::
+ text "Look, you've got"
+ line "no room for this.@@"
+
+_MtMoon3Text_49f85::
+ text "Hey, stop!"
+
+ para "I found these"
+ line "fossils! They're"
+ cont "both mine!"
+ done
+
+_MtMoon3Text_49f8a::
+ text "OK!"
+ line "I'll share!"
+ prompt
+
+_MtMoon3Text_49f8f::
+ text "We'll each take"
+ line "one!"
+ cont "No being greedy!"
+ done
+
+_MtMoon3Text_49f94::
+ text "Far away, on"
+ line "CINNABAR ISLAND,"
+ cont "there's a #MON"
+ cont "LAB."
+
+ para "They do research"
+ line "on regenerating"
+ cont "fossils."
+ done
+
+_MtMoon3Text_49f99::
+ text "All right. Then"
+ line "this is mine!@@"
+
+_MtMoon3BattleText2::
+ text "TEAM ROCKET will"
+ line "find the fossils,"
+ cont "revive and sell"
+ cont "them for cash!"
+ done
+
+_MtMoon3EndBattleText2::
+ text "Urgh!"
+ line "Now I'm mad!"
+ prompt
+
+_MtMoon3AfterBattleText2::
+ text "You made me mad!"
+ line "TEAM ROCKET will"
+ cont "blacklist you!"
+ done
+
+_MtMoon3BattleText3::
+ text "We, TEAM ROCKET,"
+ line "are #MON"
+ cont "gangsters!"
+ done
+
+_MtMoon3EndBattleText3::
+ text "I blew"
+ line "it!"
+ prompt
+
+_MtMoon3AfterBattleText3::
+ text "Darn it all! My"
+ line "associates won't"
+ cont "stand for this!"
+ done
+
+_MtMoon3BattleText4::
+ text "We're pulling a"
+ line "big job here!"
+ cont "Get lost, kid!"
+ done
+
+_MtMoon3EndBattleText4::
+ text "So, you"
+ line "are good."
+ prompt
+
+_MtMoon3AfterBattleText4::
+ text "If you find a"
+ line "fossil, give it"
+ cont "to me and scram!"
+ done
+
+_MtMoon3BattleText5::
+ text "Little kids"
+ line "should leave"
+ cont "grown-ups alone!"
+ done
+
+_MtMoon3EndBattleText5::
+ text "I'm"
+ line "steamed!"
+ prompt
+
+_MtMoon3AfterBattleText5::
+ text "#MON lived"
+ line "here long before"
+ cont "people came."
+ done
diff --git a/en/text/maps/mt_moon_pokecenter.asm b/en/text/maps/mt_moon_pokecenter.asm
new file mode 100644
index 00000000..90fd811e
--- /dev/null
+++ b/en/text/maps/mt_moon_pokecenter.asm
@@ -0,0 +1,48 @@
+_MtMoonPokecenterText1::
+ text "I've 6 # BALLs"
+ line "set in my belt."
+
+ para "At most, you can"
+ line "carry 6 #MON."
+ done
+
+_MtMoonPokecenterText3::
+ text "TEAM ROCKET"
+ line "attacks CERULEAN"
+ cont "citizens..."
+
+ para "TEAM ROCKET is"
+ line "always in the"
+ cont "news!"
+ done
+
+_MagikarpSalesmanText1::
+ text "MAN: Hello, there!"
+ line "Have I got a deal"
+ cont "just for you!"
+
+ para "I'll let you have"
+ line "a swell MAGIKARP"
+ cont "for just ¥500!"
+ cont "What do you say?"
+ done
+
+_MagikarpSalesmanNoText::
+ text "No? I'm only"
+ line "doing this as a"
+ cont "favor to you!"
+ done
+
+_MagikarpSalesmanNoMoneyText::
+ text "You'll need more"
+ line "money than that!"
+ done
+
+_MagikarpSalesmanText2::
+ text "MAN: Well, I don't"
+ line "give refunds!"
+ done
+
+_MtMoonPokecenterText5::
+ db $0
+ done
diff --git a/en/text/maps/museum_1f.asm b/en/text/maps/museum_1f.asm
new file mode 100644
index 00000000..16431bda
--- /dev/null
+++ b/en/text/maps/museum_1f.asm
@@ -0,0 +1,107 @@
+_Museum1FText_5c21a::
+ text "Come again!"
+ done
+
+_Museum1FText_5c21f::
+ text "It's ¥50 for a"
+ line "child's ticket."
+
+ para "Would you like to"
+ line "come in?"
+ done
+
+_Museum1FText_5c224::
+ text "Right, ¥50!"
+ line "Thank you!"
+ done
+
+_Museum1FText_5c229::
+ text "You don't have"
+ line "enough money."
+ prompt
+
+_Museum1FText_5c22e::
+ text "You can't sneak"
+ line "in the back way!"
+
+ para "Oh, whatever!"
+ line "Do you know what"
+ cont "AMBER is?"
+ done
+
+_Museum1FText_5c233::
+ text "There's a lab"
+ line "somewhere trying"
+ cont "to resurrect"
+ cont "ancient #MON"
+ cont "from AMBER."
+ done
+
+_Museum1FText_5c238::
+ text "AMBER is fossil-"
+ line "ized tree sap."
+ done
+
+_Museum1FText_5c23d::
+ text "Please go to the"
+ line "other side!"
+ done
+
+_Museum1FText_5c242::
+ text "Take plenty of"
+ line "time to look!"
+ done
+
+_Museum1FText_5c251::
+ text "That is one"
+ line "magnificent"
+ cont "fossil!"
+ done
+
+_Museum1FText_5c28e::
+ text "Ssh! I think that"
+ line "this chunk of"
+ cont "AMBER contains"
+ cont "#MON DNA!"
+
+ para "It would be great"
+ line "if #MON could"
+ cont "be resurrected"
+ cont "from it!"
+
+ para "But, my colleagues"
+ line "just ignore me!"
+
+ para "So I have a favor"
+ line "to ask!"
+
+ para "Take this to a"
+ line "#MON LAB and"
+ cont "get it examined!"
+ prompt
+
+_ReceivedOldAmberText::
+ text "<PLAYER> received"
+ line "OLD AMBER!@@"
+
+_Museum1FText_5c299::
+ text "Ssh! Get the OLD"
+ line "AMBER checked!"
+ done
+
+_Museum1FText_5c29e::
+ text "You don't have"
+ line "space for this!"
+ done
+
+_Museum1FText_5c2ad::
+ text "We are proud of 2"
+ line "fossils of very"
+ cont "rare, prehistoric"
+ cont "#MON!"
+ done
+
+_Museum1FText_5c2bc::
+ text "The AMBER is"
+ line "clear and gold!"
+ done
diff --git a/en/text/maps/museum_2f.asm b/en/text/maps/museum_2f.asm
new file mode 100644
index 00000000..4f34a249
--- /dev/null
+++ b/en/text/maps/museum_2f.asm
@@ -0,0 +1,45 @@
+_Museum2FText1::
+ text "MOON STONE?"
+
+ para "What's so special"
+ line "about it?"
+ done
+
+_Museum2FText2::
+ text "July 20, 1969!"
+
+ para "The 1st lunar"
+ line "landing!"
+
+ para "I bought a color"
+ line "TV to watch it!"
+ done
+
+_Museum2FText3::
+ text "We have a space"
+ line "exhibit now."
+ done
+
+_Museum2FText4::
+ text "I want a PIKACHU!"
+ line "It's so cute!"
+
+ para "I asked my Daddy"
+ line "to catch me one!"
+ done
+
+_Museum2FText5::
+ text "Yeah, a PIKACHU"
+ line "soon, I promise!"
+ done
+
+_Museum2FText6::
+ text "SPACE SHUTTLE"
+ line "COLUMBIA"
+ done
+
+_Museum2FText7::
+ text "Meteorite that"
+ line "fell on MT.MOON."
+ cont "(MOON STONE?)"
+ done
diff --git a/en/text/maps/name_rater.asm b/en/text/maps/name_rater.asm
new file mode 100644
index 00000000..65d3e8a4
--- /dev/null
+++ b/en/text/maps/name_rater.asm
@@ -0,0 +1,60 @@
+_NameRaterText_1dab3::
+ text "Hello, hello!"
+ line "I am the official"
+ cont "NAME RATER!"
+
+ para "Want me to rate"
+ line "the nicknames of"
+ cont "your #MON?"
+ done
+
+_NameRaterText_1dab8::
+ text "Which #MON"
+ line "should I look at?"
+ prompt
+
+_NameRaterText_1dabd::
+ TX_RAM wcd6d
+ text ", is it?"
+ line "That is a decent"
+ cont "nickname!"
+
+ para "But, would you"
+ line "like me to give"
+ cont "it a nicer name?"
+
+ para "How about it?"
+ done
+
+_NameRaterText_1dac2::
+ text "Fine! What should"
+ line "we name it?"
+ prompt
+
+_NameRaterText_1dac7::
+ text "OK! This #MON"
+ line "has been renamed"
+ cont "@"
+ TX_RAM wBuffer
+ text "!"
+
+ para "That's a better"
+ line "name than before!"
+ done
+
+_NameRaterText_1dacc::
+ text "Fine! Come any"
+ line "time you like!"
+ done
+
+_NameRaterText_1dad1::
+ TX_RAM wcd6d
+ text ", is it?"
+ line "That is a truly"
+ cont "impeccable name!"
+
+ para "Take good care of"
+ line "@"
+ TX_RAM wcd6d
+ text "!"
+ done
diff --git a/en/text/maps/oaks_lab.asm b/en/text/maps/oaks_lab.asm
new file mode 100644
index 00000000..7a6f57b7
--- /dev/null
+++ b/en/text/maps/oaks_lab.asm
@@ -0,0 +1,477 @@
+_OaksLabGaryText1::
+ text "<RIVAL>: Yo"
+ line "<PLAYER>! Gramps"
+ cont "isn't around!"
+ done
+
+_OaksLabText40::
+ text "<RIVAL>: Heh, I"
+ line "don't need to be"
+ cont "greedy like you!"
+
+ para "Go ahead and"
+ line "choose, <PLAYER>!"
+ done
+
+_OaksLabText41::
+ text "<RIVAL>: My"
+ line "#MON looks a"
+ cont "lot stronger."
+ done
+
+_OaksLabText39::
+ text "Those are #"
+ line "BALLs. They"
+ cont "contain #MON!"
+ done
+
+_OaksLabCharmanderText::
+ text "So! You want the"
+ line "fire #MON,"
+ cont "CHARMANDER?"
+ done
+
+_OaksLabSquirtleText::
+ text "So! You want the"
+ line "water #MON,"
+ cont "SQUIRTLE?"
+ done
+
+_OaksLabBulbasaurText::
+ text "So! You want the"
+ line "plant #MON,"
+ cont "BULBASAUR?"
+ done
+
+_OaksLabMonEnergeticText::
+ text "This #MON is"
+ line "really energetic!"
+ prompt
+
+_OaksLabReceivedMonText::
+ text "<PLAYER> received"
+ line "a @"
+ TX_RAM wcd6d
+ text "!@@"
+
+_OaksLabLastMonText::
+ text "That's PROF.OAK's"
+ line "last #MON!"
+ done
+
+_OaksLabText_1d2f0::
+ text "OAK: Now, <PLAYER>,"
+ line "which #MON do"
+ cont "you want?"
+ done
+
+_OaksLabText_1d2f5::
+ text "OAK: If a wild"
+ line "#MON appears,"
+ cont "your #MON can"
+ cont "fight against it!"
+ done
+
+_OaksLabText_1d2fa::
+ text "OAK: <PLAYER>,"
+ line "raise your young"
+ cont "#MON by making"
+ cont "it fight!"
+ done
+
+_OaksLabDeliverParcelText1::
+ text "OAK: Oh, <PLAYER>!"
+
+ para "How is my old"
+ line "#MON?"
+
+ para "Well, it seems to"
+ line "like you a lot."
+
+ para "You must be"
+ line "talented as a"
+ cont "#MON trainer!"
+
+ para "What? You have"
+ line "something for me?"
+
+ para "<PLAYER> delivered"
+ line "OAK's PARCEL.@@"
+
+_OaksLabDeliverParcelText2::
+ text ""
+ para "Ah! This is the"
+ line "custom # BALL"
+ cont "I ordered!"
+ cont "Thank you!"
+ done
+
+_OaksLabAroundWorldText::
+ text "#MON around the"
+ line "world wait for"
+ cont "you, <PLAYER>!"
+ done
+
+_OaksLabGivePokeballsText1::
+ text "OAK: You can't get"
+ line "detailed data on"
+ cont "#MON by just"
+ cont "seeing them."
+
+ para "You must catch"
+ line "them! Use these"
+ cont "to capture wild"
+ cont "#MON."
+
+ para "<PLAYER> got 5"
+ line "# BALLs!@@"
+
+_OaksLabGivePokeballsText2::
+ text ""
+ para "When a wild"
+ line "#MON appears,"
+ cont "it's fair game."
+
+ para "Just throw a #"
+ line "BALL at it and try"
+ line "to catch it!"
+
+ para "This won't always"
+ line "work, though."
+
+ para "A healthy #MON"
+ line "could escape. You"
+ cont "have to be lucky!"
+ done
+
+_OaksLabPleaseVisitText::
+ text "OAK: Come see me"
+ line "sometimes."
+
+ para "I want to know how"
+ line "your #DEX is"
+ cont "coming along."
+ done
+
+_OaksLabText_1d31d::
+ text "OAK: Good to see "
+ line "you! How is your "
+ cont "#DEX coming? "
+ cont "Here, let me take"
+ cont "a look!"
+ prompt
+
+_OaksLabText_1d32c::
+ text "It's encyclopedia-"
+ line "like, but the"
+ cont "pages are blank!"
+ done
+
+_OaksLabText8::
+ text "?"
+ done
+
+_OaksLabText_1d340::
+ text "PROF.OAK is the"
+ line "authority on"
+ cont "#MON!"
+
+ para "Many #MON"
+ line "trainers hold him"
+ cont "in high regard!"
+ done
+
+_OaksLabRivalWaitingText::
+ text "<RIVAL>: Gramps!"
+ line "I'm fed up with"
+ cont "waiting!"
+ done
+
+_OaksLabChooseMonText::
+ text "OAK: <RIVAL>?"
+ line "Let me think..."
+
+ para "Oh, that's right,"
+ line "I told you to"
+ cont "come! Just wait!"
+
+ para "Here, <PLAYER>!"
+
+ para "There are 3"
+ line "#MON here!"
+
+ para "Haha!"
+
+ para "They are inside"
+ line "the # BALLs."
+
+ para "When I was young,"
+ line "I was a serious"
+ cont "#MON trainer!"
+
+ para "In my old age, I"
+ line "have only 3 left,"
+ cont "but you can have"
+ cont "one! Choose!"
+ done
+
+_OaksLabRivalInterjectionText::
+ text "<RIVAL>: Hey!"
+ line "Gramps! What"
+ cont "about me?"
+ done
+
+_OaksLabBePatientText::
+ text "OAK: Be patient!"
+ line "<RIVAL>, you can"
+ cont "have one too!"
+ done
+
+_OaksLabLeavingText::
+ text "OAK: Hey! Don't go"
+ line "away yet!"
+ done
+
+_OaksLabRivalPickingMonText::
+ text "<RIVAL>: I'll take"
+ line "this one, then!"
+ done
+
+_OaksLabRivalReceivedMonText::
+ text "<RIVAL> received"
+ line "a @"
+ TX_RAM wcd6d
+ text "!@@"
+
+_OaksLabRivalChallengeText::
+ text "<RIVAL>: Wait"
+ line "<PLAYER>!"
+ cont "Let's check out"
+ cont "our #MON!"
+
+ para "Come on, I'll take"
+ line "you on!"
+ done
+
+_OaksLabText_1d3be::
+ text "WHAT?"
+ line "Unbelievable!"
+ cont "I picked the"
+ cont "wrong #MON!"
+ prompt
+
+_OaksLabText_1d3c3::
+ text "<RIVAL>: Yeah! Am"
+ line "I great or what?"
+ prompt
+
+_OaksLabRivalToughenUpText::
+ text "<RIVAL>: Okay!"
+ line "I'll make my"
+ cont "#MON fight to"
+ cont "toughen it up!"
+
+ para "<PLAYER>! Gramps!"
+ line "Smell you later!"
+ done
+
+_OaksLabText21::
+ text "<RIVAL>: Gramps!"
+ done
+
+_OaksLabText22::
+ text "<RIVAL>: What did"
+ line "you call me for?"
+ done
+
+_OaksLabText23::
+ text "OAK: Oh right! I"
+ line "have a request"
+ cont "of you two."
+ done
+
+_OaksLabText24::
+ text "On the desk there"
+ line "is my invention,"
+ cont "#DEX!"
+
+ para "It automatically"
+ line "records data on"
+ cont "#MON you've"
+ cont "seen or caught!"
+
+ para "It's a hi-tech"
+ line "encyclopedia!"
+ done
+
+_OaksLabText25::
+ text "OAK: <PLAYER> and"
+ line "<RIVAL>! Take"
+ cont "these with you!"
+
+ para "<PLAYER> got"
+ line "#DEX from OAK!@@"
+
+_OaksLabText26::
+ text "To make a complete"
+ line "guide on all the"
+ cont "#MON in the"
+ cont "world..."
+
+ para "That was my dream!"
+
+ para "But, I'm too old!"
+ line "I can't do it!"
+
+ para "So, I want you two"
+ line "to fulfill my"
+ cont "dream for me!"
+
+ para "Get moving, you"
+ line "two!"
+
+ para "This is a great"
+ line "undertaking in"
+ cont "#MON history!"
+ done
+
+_OaksLabText27::
+ text "<RIVAL>: Alright"
+ line "Gramps! Leave it"
+ cont "all to me!"
+
+ para "<PLAYER>, I hate to"
+ line "say it, but I"
+ cont "don't need you!"
+
+ para "I know! I'll"
+ line "borrow a TOWN MAP"
+ cont "from my sis!"
+
+ para "I'll tell her not"
+ line "to lend you one,"
+ cont "<PLAYER>! Hahaha!"
+ done
+
+_OaksLabText_1d405::
+ text "I study #MON as"
+ line "PROF.OAK's AIDE."
+ done
+
+_OaksLabText_441cc::
+ text "#DEX comp-"
+ line "letion is:"
+
+ para "@"
+ TX_NUM hDexRatingNumMonsSeen, 1, 3
+ text " #MON seen"
+ line "@"
+ TX_NUM hDexRatingNumMonsOwned, 1, 3
+ text " #MON owned"
+
+ para "PROF.OAK's"
+ line "Rating:"
+ prompt
+
+_OaksLabText_44201::
+ text "You still have"
+ line "lots to do."
+ cont "Look for #MON"
+ cont "in grassy areas!"
+ done
+
+_OaksLabText_44206::
+ text "You're on the"
+ line "right track! "
+ cont "Get a FLASH HM"
+ cont "from my AIDE!"
+ done
+
+_OaksLabText_4420b::
+ text "You still need"
+ line "more #MON!"
+ cont "Try to catch"
+ cont "other species!"
+ done
+
+_OaksLabText_44210::
+ text "Good, you're"
+ line "trying hard!"
+ cont "Get an ITEMFINDER"
+ cont "from my AIDE!"
+ done
+
+_OaksLabText_44215::
+ text "Looking good!"
+ line "Go find my AIDE"
+ cont "when you get 50!"
+ done
+
+_OaksLabText_4421a::
+ text "You finally got at"
+ line "least 50 species!"
+ cont "Be sure to get"
+ cont "EXP.ALL from my"
+ cont "AIDE!"
+ done
+
+_OaksLabText_4421f::
+ text "Ho! This is geting"
+ line "even better!"
+ done
+
+_OaksLabText_44224::
+ text "Very good!"
+ line "Go fish for some"
+ cont "marine #MON!"
+ done
+
+_OaksLabText_44229::
+ text "Wonderful!"
+ line "Do you like to"
+ cont "collect things?"
+ done
+
+_OaksLabText_4422e::
+ text "I'm impressed!"
+ line "It must have been"
+ cont "difficult to do!"
+ done
+
+_OaksLabText_44233::
+ text "You finally got at"
+ line "least 100 species!"
+ cont "I can't believe"
+ cont "how good you are!"
+ done
+
+_OaksLabText_44238::
+ text "You even have the"
+ line "evolved forms of"
+ cont "#MON! Super!"
+ done
+
+_OaksLabText_4423d::
+ text "Excellent! Trade"
+ line "with friends to"
+ cont "get some more!"
+ done
+
+_OaksLabText_44242::
+ text "Outstanding!"
+ line "You've become a"
+ cont "real pro at this!"
+ done
+
+_OaksLabText_44247::
+ text "I have nothing"
+ line "left to say!"
+ cont "You're the"
+ cont "authority now!"
+ done
+
+_OaksLabText_4424c::
+ text "Your #DEX is"
+ line "entirely complete!"
+ cont "Congratulations!"
+ done
diff --git a/en/text/maps/pallet_town.asm b/en/text/maps/pallet_town.asm
new file mode 100644
index 00000000..d5eda74f
--- /dev/null
+++ b/en/text/maps/pallet_town.asm
@@ -0,0 +1,55 @@
+_OakAppearsText::
+ text "OAK: Hey! Wait!"
+ line "Don't go out!@@"
+
+_OakWalksUpText::
+ text "OAK: It's unsafe!"
+ line "Wild #MON live"
+ cont "in tall grass!"
+
+ para "You need your own"
+ line "#MON for your"
+ cont "protection."
+ cont "I know!"
+
+ para "Here, come with"
+ line "me!"
+ done
+
+_PalletTownText2::
+ text "I'm raising"
+ line "#MON too!"
+
+ para "When they get"
+ line "strong, they can"
+ cont "protect me!"
+ done
+
+_PalletTownText3::
+ text "Technology is"
+ line "incredible!"
+
+ para "You can now store"
+ line "and recall items"
+ cont "and #MON as"
+ cont "data via PC!"
+ done
+
+_PalletTownText4::
+ text "OAK #MON"
+ line "RESEARCH LAB"
+ done
+
+_PalletTownText5::
+ text "PALLET TOWN"
+ line "Shades of your"
+ cont "journey await!"
+ done
+
+_PalletTownText6::
+ text "<PLAYER>'s house "
+ done
+
+_PalletTownText7::
+ text "<RIVAL>'s house "
+ done
diff --git a/en/text/maps/pewter_city.asm b/en/text/maps/pewter_city.asm
new file mode 100644
index 00000000..14240c9e
--- /dev/null
+++ b/en/text/maps/pewter_city.asm
@@ -0,0 +1,117 @@
+_PewterCityText1::
+ text "It's rumored that"
+ line "CLEFAIRYs came"
+ cont "from the moon!"
+
+ para "They appeared "
+ line "after MOON STONE"
+ cont "fell on MT.MOON."
+ done
+
+_PewterCityText2::
+ text "There aren't many"
+ line "serious #MON"
+ cont "trainers here!"
+
+ para "They're all like"
+ line "BUG CATCHERs,"
+ cont "but PEWTER GYM's"
+ cont "BROCK is totally"
+ cont "into it!"
+ done
+
+_PewterCityText_193f1::
+ text "Did you check out"
+ line "the MUSEUM?"
+ done
+
+_PewterCityText_193f6::
+ text "Weren't those"
+ line "fossils from MT."
+ cont "MOON amazing?"
+ done
+
+_PewterCityText_193fb::
+ text "Really?"
+ line "You absolutely"
+ cont "have to go!"
+ done
+
+_PewterCityText13::
+ text "It's right here!"
+ line "You have to pay"
+ cont "to get in, but"
+ cont "it's worth it!"
+ cont "See you around!"
+ done
+
+_PewterCityText_19427::
+ text "Psssst!"
+ line "Do you know what"
+ cont "I'm doing?"
+ done
+
+_PewterCityText_1942c::
+ text "That's right!"
+ line "It's hard work!"
+ done
+
+_PewterCityText_19431::
+ text "I'm spraying REPEL"
+ line "to keep #MON"
+ cont "out of my garden!"
+ done
+
+_PewterCityText_1945d::
+ text "You're a trainer"
+ line "right? BROCK's"
+ cont "looking for new"
+ cont "challengers!"
+ cont "Follow me!"
+ done
+
+_PewterCityText14::
+ text "If you have the"
+ line "right stuff, go"
+ cont "take on BROCK!"
+ done
+
+_PewterCityText6::
+ text "TRAINER TIPS"
+
+ para "Any #MON that"
+ line "takes part in"
+ cont "battle, however"
+ cont "short, earns EXP!"
+ done
+
+_PewterCityText7::
+ text "NOTICE!"
+
+ para "Thieves have been"
+ line "stealing #MON"
+ cont "fossils at MT."
+ cont "MOON! Please call"
+ cont "PEWTER POLICE"
+ cont "with any info!"
+ done
+
+_PewterCityText10::
+ text "PEWTER MUSEUM"
+ line "OF SCIENCE"
+ done
+
+_PewterCityText11::
+ text "PEWTER CITY"
+ line "#MON GYM"
+ cont "LEADER: BROCK"
+
+ para "The Rock Solid"
+ line "#MON Trainer!"
+ done
+
+_PewterCityText12::
+ text "PEWTER CITY"
+ line "A Stone Gray"
+ cont "City"
+ done
diff --git a/en/text/maps/pewter_gym_1.asm b/en/text/maps/pewter_gym_1.asm
new file mode 100644
index 00000000..6426dd72
--- /dev/null
+++ b/en/text/maps/pewter_gym_1.asm
@@ -0,0 +1,18 @@
+_PewterGymText_5c49e::
+ text "I'm BROCK!"
+ line "I'm PEWTER's GYM"
+ cont "LEADER!"
+
+ para "I believe in rock"
+ line "hard defense and"
+ cont "determination!"
+
+ para "That's why my"
+ line "#MON are all"
+ cont "the rock-type!"
+
+ para "Do you still want"
+ line "to challenge me?"
+ cont "Fine then! Show"
+ cont "me your best!"
+ done
diff --git a/en/text/maps/pewter_gym_2.asm b/en/text/maps/pewter_gym_2.asm
new file mode 100644
index 00000000..86b97018
--- /dev/null
+++ b/en/text/maps/pewter_gym_2.asm
@@ -0,0 +1,142 @@
+_PewterGymText_5c4a3::
+ text "There are all"
+ line "kinds of trainers"
+ cont "in the world!"
+
+ para "You appear to be"
+ line "very gifted as a"
+ cont "#MON trainer!"
+
+ para "Go to the GYM in"
+ line "CERULEAN and test"
+ cont "your abilities!"
+ done
+
+_TM34PreReceiveText::
+ text "Wait! Take this"
+ line "with you!"
+ done
+
+_ReceivedTM34Text::
+ text "<PLAYER> received"
+ line "TM34!@@"
+
+_TM34ExplanationText::
+ db $0
+ para "A TM contains a"
+ line "technique that"
+ cont "can be taught to"
+ cont "#MON!"
+
+ para "A TM is good only"
+ line "once! So when you"
+ cont "use one to teach"
+ cont "a new technique,"
+ cont "pick the #MON"
+ cont "carefully!"
+
+ para "TM34 contains"
+ line "BIDE!"
+
+ para "Your #MON will"
+ line "absorb damage in"
+ cont "battle then pay"
+ cont "it back double!"
+ done
+
+_TM34NoRoomText::
+ text "You don't have"
+ line "room for this!"
+ done
+
+_PewterGymText_5c4bc::
+ text "I took"
+ line "you for granted."
+
+ para "As proof of your"
+ line "victory, here's"
+ cont "the BOULDERBADGE!"
+
+ para "<PLAYER> received"
+ line "the BOULDERBADGE!@@"
+
+_PewterGymText_5c4c1::
+ db $0
+ para "That's an official"
+ line "#MON LEAGUE"
+ cont "BADGE!"
+
+ para "Its bearer's"
+ line "#MON become"
+ cont "more powerful!"
+
+ para "The technique"
+ line "FLASH can now be"
+ cont "used any time!"
+ prompt
+
+_PewterGymBattleText1::
+ text "Stop right there,"
+ line "kid!"
+
+ para "You're still light"
+ line "years from facing"
+ cont "BROCK!"
+ done
+
+_PewterGymEndBattleText1::
+ text "Darn!"
+
+ para "Light years isn't"
+ line "time! It measures"
+ cont "distance!"
+ prompt
+
+_PewterGymAfterBattleText1::
+ text "You're pretty hot,"
+ line "but not as hot"
+ cont "as BROCK!"
+ done
+
+_PewterGymText_5c515::
+ text "Hiya! I can tell"
+ line "you have what it"
+ cont "takes to become a"
+ cont "#MON champ!"
+
+ para "I'm no trainer,"
+ line "but I can tell"
+ cont "you how to win!"
+
+ para "Let me take you"
+ line "to the top!"
+ done
+
+_PewterGymText_5c51a::
+ text "All right! Let's"
+ line "get happening!"
+ prompt
+
+_PewterGymText_5c51f::
+ text "The 1st #MON"
+ line "out in a match is"
+ cont "at the top of the"
+ cont "#MON LIST!"
+
+ para "By changing the"
+ line "order of #MON,"
+ cont "matches could be"
+ cont "made easier!"
+ done
+
+_PewterGymText_5c524::
+ text "It's a free"
+ line "service! Let's"
+ cont "get happening!"
+ prompt
+
+_PewterGymText_5c529::
+ text "Just as I thought!"
+ line "You're #MON"
+ cont "champ material!"
+ done
diff --git a/en/text/maps/pewter_house_1.asm b/en/text/maps/pewter_house_1.asm
new file mode 100644
index 00000000..450e8372
--- /dev/null
+++ b/en/text/maps/pewter_house_1.asm
@@ -0,0 +1,24 @@
+_PewterHouse1Text1::
+ text "NIDORAN: Bowbow!@@"
+
+_PewterHouse1Text2::
+ text "NIDORAN sit!"
+ done
+
+_PewterHouse1Text3::
+ text "Our #MON's an"
+ line "outsider, so it's"
+ cont "hard to handle."
+
+ para "An outsider is a"
+ line "#MON that you"
+ cont "get in a trade."
+
+ para "It grows fast, but"
+ line "it may ignore an"
+ cont "unskilled trainer"
+ cont "in battle!"
+
+ para "If only we had"
+ line "some BADGEs..."
+ done
diff --git a/en/text/maps/pewter_house_2.asm b/en/text/maps/pewter_house_2.asm
new file mode 100644
index 00000000..615536f7
--- /dev/null
+++ b/en/text/maps/pewter_house_2.asm
@@ -0,0 +1,19 @@
+_PewterHouse2Text1::
+ text "#MON learn new"
+ line "techniques as"
+ cont "they grow!"
+
+ para "But, some moves"
+ line "must be taught by"
+ cont "the trainer!"
+ done
+
+_PewterHouse2Text2::
+ text "#MON become"
+ line "easier to catch"
+ cont "when they are"
+ cont "hurt or asleep!"
+
+ para "But, it's not a"
+ line "sure thing!"
+ done
diff --git a/en/text/maps/pewter_mart.asm b/en/text/maps/pewter_mart.asm
new file mode 100644
index 00000000..0d5b07a2
--- /dev/null
+++ b/en/text/maps/pewter_mart.asm
@@ -0,0 +1,17 @@
+_PewterMartText2::
+ text "A shady, old man"
+ line "got me to buy"
+ cont "this really weird"
+ cont "fish #MON!"
+
+ para "It's totally weak"
+ line "and it cost ¥500!"
+ done
+
+_PewterMartText3::
+ text "Good things can"
+ line "happen if you"
+ cont "raise #MON"
+ cont "diligently, even"
+ cont "the weak ones!"
+ done
diff --git a/en/text/maps/pewter_pokecenter.asm b/en/text/maps/pewter_pokecenter.asm
new file mode 100644
index 00000000..6a1b373e
--- /dev/null
+++ b/en/text/maps/pewter_pokecenter.asm
@@ -0,0 +1,14 @@
+_PewterPokecenterText2::
+ text "What!?"
+
+ para "TEAM ROCKET is"
+ line "at MT.MOON? Huh?"
+ cont "I'm on the phone!"
+
+ para "Scram!"
+ done
+
+_PewterJigglypuffText::
+ text "JIGGLYPUFF: Puu"
+ line "pupuu!"
+ done
diff --git a/en/text/maps/pokemon_league_gate.asm b/en/text/maps/pokemon_league_gate.asm
new file mode 100644
index 00000000..ac92f4b0
--- /dev/null
+++ b/en/text/maps/pokemon_league_gate.asm
@@ -0,0 +1,19 @@
+_Route22GateText_1e704::
+ text "Only truly skilled"
+ line "trainers are"
+ cont "allowed through."
+
+ para "You don't have the"
+ line "BOULDERBADGE yet!@@"
+
+_Route22GateText_1e715::
+ db $0
+ para "The rules are"
+ line "rules. I can't"
+ cont "let you pass."
+ done
+
+_Route22GateText_1e71a::
+ text "Oh! That is the"
+ line "BOULDERBADGE!"
+ cont "Go right ahead!@@"
diff --git a/en/text/maps/pokemon_tower_1f.asm b/en/text/maps/pokemon_tower_1f.asm
new file mode 100644
index 00000000..50a2cd29
--- /dev/null
+++ b/en/text/maps/pokemon_tower_1f.asm
@@ -0,0 +1,31 @@
+_PokemonTower1Text1::
+ text "#MON TOWER was"
+ line "erected in the"
+ cont "memory of #MON"
+ cont "that had died."
+ done
+
+_PokemonTower1Text2::
+ text "Did you come to"
+ line "pay respects?"
+ cont "Bless you!"
+ done
+
+_PokemonTower1Text3::
+ text "I came to pray"
+ line "for my CLEFAIRY."
+
+ para "Sniff! I can't"
+ line "stop crying..."
+ done
+
+_PokemonTower1Text4::
+ text "My GROWLITHE..."
+ line "Why did you die?"
+ done
+
+_PokemonTower1Text5::
+ text "I am a CHANNELER!"
+ line "There are spirits"
+ cont "up to mischief!"
+ done
diff --git a/en/text/maps/pokemon_tower_2f.asm b/en/text/maps/pokemon_tower_2f.asm
new file mode 100644
index 00000000..79323001
--- /dev/null
+++ b/en/text/maps/pokemon_tower_2f.asm
@@ -0,0 +1,57 @@
+_PokemonTower2Text_6062d::
+ text "<RIVAL>: Hey,"
+ line "<PLAYER>! What"
+ cont "brings you here?"
+ cont "Your #MON"
+ cont "don't look dead!"
+
+ para "I can at least"
+ line "make them faint!"
+ cont "Let's go, pal!"
+ done
+
+_PokemonTower2Text_60632::
+ text "What?"
+ line "You stinker!"
+
+ para "I took it easy on"
+ line "you too!"
+ prompt
+
+_PokemonTower2Text_60637::
+ text "<RIVAL>: Well,"
+ line "look at all your"
+ cont "wimpy #MON!"
+
+ para "Toughen them up a"
+ line "bit more!"
+ prompt
+
+_PokemonTower2Text_6063c::
+ text "How's your #DEX"
+ line "coming, pal?"
+ cont "I just caught a"
+ cont "CUBONE!"
+
+ para "I can't find the"
+ line "grown-up MAROWAK"
+ cont "yet!"
+
+ para "I doubt there are"
+ line "any left! Well, I"
+ cont "better get going!"
+ cont "I've got a lot to"
+ cont "accomplish, pal!"
+
+ para "Smell ya later!"
+ done
+
+_PokemonTower2Text2::
+ text "Even we could not"
+ line "identify the"
+ cont "wayward GHOSTs!"
+
+ para "A SILPH SCOPE"
+ line "might be able to"
+ cont "unmask them."
+ done
diff --git a/en/text/maps/pokemon_tower_3f.asm b/en/text/maps/pokemon_tower_3f.asm
new file mode 100644
index 00000000..67098e6b
--- /dev/null
+++ b/en/text/maps/pokemon_tower_3f.asm
@@ -0,0 +1,45 @@
+_PokemonTower3BattleText1::
+ text "Urrg...Awaa..."
+ line "Huhu...graa.."
+ done
+
+_PokemonTower3EndBattleText1::
+ text "Hwa!"
+ line "I'm saved!"
+ prompt
+
+_PokemonTower3AfterBattleText1::
+ text "The GHOSTs can be"
+ line "identified by the"
+ cont "SILPH SCOPE."
+ done
+
+_PokemonTower3BattleText2::
+ text "Kekeke...."
+ line "Kwaaah!"
+ done
+
+_PokemonTower3EndBattleText2::
+ text "Hmm?"
+ line "What am I doing?"
+ prompt
+
+_PokemonTower3AfterBattleText2::
+ text "Sorry! I was"
+ line "possessed!"
+ done
+
+_PokemonTower3BattleText3::
+ text "Be gone!"
+ line "Evil spirit!"
+ done
+
+_PokemonTower3EndBattleText3::
+ text "Whew!"
+ line "The spirit left!"
+ prompt
+
+_PokemonTower3AfterBattleText3::
+ text "My friends were"
+ line "possessed too!"
+ done
diff --git a/en/text/maps/pokemon_tower_4f.asm b/en/text/maps/pokemon_tower_4f.asm
new file mode 100644
index 00000000..771325a0
--- /dev/null
+++ b/en/text/maps/pokemon_tower_4f.asm
@@ -0,0 +1,45 @@
+_PokemonTower4BattleText1::
+ text "GHOST! No!"
+ line "Kwaaah!"
+ done
+
+_PokemonTower4EndBattleText1::
+ text "Where"
+ line "is the GHOST?"
+ prompt
+
+_PokemonTower4AfterBattleText1::
+ text "I must have been"
+ line "dreaming..."
+ done
+
+_PokemonTower4BattleText2::
+ text "Be cursed with"
+ line "me! Kwaaah!"
+ done
+
+_PokemonTower4EndBattleText2::
+ text "What!"
+ prompt
+
+_PokemonTower4AfterBattleText2::
+ text "We can't crack"
+ line "the identity of"
+ cont "the GHOSTs."
+ done
+
+_PokemonTower4BattleText3::
+ text "Huhuhu..."
+ line "Beat me not!"
+ done
+
+_PokemonTower4EndBattleText3::
+ text "Huh?"
+ line "Who? What?"
+ prompt
+
+_PokemonTower4AfterBattleText3::
+ text "May the departed"
+ line "souls of #MON"
+ cont "rest in peace..."
+ done
diff --git a/en/text/maps/pokemon_tower_5f.asm b/en/text/maps/pokemon_tower_5f.asm
new file mode 100644
index 00000000..b329118d
--- /dev/null
+++ b/en/text/maps/pokemon_tower_5f.asm
@@ -0,0 +1,71 @@
+_PokemonTower5Text1::
+ text "Come, child! I"
+ line "sealed this space"
+ cont "with white magic!"
+
+ para "You can rest here!"
+ done
+
+_PokemonTower5BattleText1::
+ text "Give...me..."
+ line "your...soul..."
+ done
+
+_PokemonTower5EndBattleText1::
+ text "Gasp!"
+ prompt
+
+_PokemonTower5AfterBattleText1::
+ text "I was under"
+ line "possession!"
+ done
+
+_PokemonTower5BattleText2::
+ text "You...shall..."
+ line "join...us..."
+ done
+
+_PokemonTower5EndBattleText2::
+ text "What"
+ line "a nightmare!"
+ prompt
+
+_PokemonTower5AfterBattleText2::
+ text "I was possessed!"
+ done
+
+_PokemonTower5BattleText3::
+ text "Zombies!"
+ done
+
+_PokemonTower5EndBattleText3::
+ text "Ha?"
+ prompt
+
+_PokemonTower5AfterBattleText3::
+ text "I regained my"
+ line "senses!"
+ done
+
+_PokemonTower5BattleText4::
+ text "Urgah..."
+ line "Urff...."
+ done
+
+_PokemonTower5EndBattleText4::
+ text "Whoo!"
+ prompt
+
+_PokemonTower5AfterBattleText4::
+ text "I fell to evil"
+ line "spirits despite"
+ cont "my training!"
+ done
+
+_PokemonTower5Text7::
+ text "Entered purified,"
+ line "protected zone!"
+
+ para "<PLAYER>'s #MON"
+ line "are fully healed!"
+ done
diff --git a/en/text/maps/pokemon_tower_6f.asm b/en/text/maps/pokemon_tower_6f.asm
new file mode 100644
index 00000000..7532d56d
--- /dev/null
+++ b/en/text/maps/pokemon_tower_6f.asm
@@ -0,0 +1,61 @@
+_PokemonTower2Text_60c1f::
+ text "The GHOST was the"
+ line "restless soul of"
+ cont "CUBONE's mother!"
+ done
+
+_PokemonTower2Text_60c24::
+ text "The mother's soul"
+ line "was calmed."
+
+ para "It departed to"
+ line "the afterlife!"
+ done
+
+_PokemonTower6BattleText1::
+ text "Give...me..."
+ line "blood..."
+ done
+
+_PokemonTower6EndBattleText1::
+ text "Groan!"
+ prompt
+
+_PokemonTower6AfterBattleText1::
+ text "I feel anemic and"
+ line "weak..."
+ done
+
+_PokemonTower6BattleText2::
+ text "Urff... Kwaah!"
+ done
+
+_PokemonTower6EndBattleText2::
+ text "Some-"
+ line "thing fell out!"
+ prompt
+
+_PokemonTower6AfterBattleText2::
+ text "Hair didn't fall"
+ line "out! It was an"
+ cont "evil spirit!"
+ done
+
+_PokemonTower6BattleText3::
+ text "Ke..ke...ke..."
+ line "ke..ke...ke!!"
+ done
+
+_PokemonTower6EndBattleText3::
+ text "Keee!"
+ prompt
+
+_PokemonTower6AfterBattleText3::
+ text "What's going on"
+ line "here?"
+ done
+
+_PokemonTower6Text6::
+ text "Be gone..."
+ line "Intruders..."
+ done
diff --git a/en/text/maps/pokemon_tower_7f.asm b/en/text/maps/pokemon_tower_7f.asm
new file mode 100644
index 00000000..704a71eb
--- /dev/null
+++ b/en/text/maps/pokemon_tower_7f.asm
@@ -0,0 +1,78 @@
+_TowerRescueFujiText::
+ text "MR.FUJI: Heh? You"
+ line "came to save me?"
+
+ para "Thank you. But, I"
+ line "came here of my"
+ cont "own free will."
+
+ para "I came to calm"
+ line "the soul of"
+ cont "CUBONE's mother."
+
+ para "I think MAROWAK's"
+ line "spirit has gone"
+ cont "to the afterlife."
+
+ para "I must thank you"
+ line "for your kind"
+ cont "concern!"
+
+ para "Follow me to my"
+ line "home, #MON"
+ cont "HOUSE at the foot"
+ cont "of this tower."
+ done
+
+_PokemonTower7BattleText1::
+ text "What do you want?"
+ line "Why are you here?"
+ done
+
+_PokemonTower7EndBattleText1::
+ text "I give up!"
+ prompt
+
+_PokemonTower7AfterBattleText1::
+ text "I'm not going to"
+ line "forget this!"
+ done
+
+_PokemonTower7BattleText2::
+ text "This old guy came"
+ line "and complained"
+ cont "about us harming"
+ cont "useless #MON!"
+
+ para "We're talking it"
+ line "over as adults!"
+ done
+
+_PokemonTower7EndBattleText2::
+ text "Please!"
+ line "No more!"
+ prompt
+
+_PokemonTower7AfterBattleText2::
+ text "#MON are only"
+ line "good for making"
+ cont "money!"
+
+ para "Stay out of our"
+ line "business!"
+ done
+
+_PokemonTower7BattleText3::
+ text "You're not saving"
+ line "anyone, kid!"
+ done
+
+_PokemonTower7EndBattleText3::
+ text "Don't"
+ line "fight us ROCKETs!"
+ prompt
+
+_PokemonTower7AfterBattleText3::
+ text "You're not getting"
+ line "away with this!"
+ done
diff --git a/en/text/maps/power_plant.asm b/en/text/maps/power_plant.asm
new file mode 100644
index 00000000..e5df6674
--- /dev/null
+++ b/en/text/maps/power_plant.asm
@@ -0,0 +1,6 @@
+_VoltorbBattleText::
+ text "Bzzzt!"
+ done
+
+_ZapdosBattleText::
+ text "Gyaoo!@@"
diff --git a/en/text/maps/reds_house_1f.asm b/en/text/maps/reds_house_1f.asm
new file mode 100644
index 00000000..07768af9
--- /dev/null
+++ b/en/text/maps/reds_house_1f.asm
@@ -0,0 +1,37 @@
+_MomWakeUpText::
+ text "MOM: Right."
+ line "All boys leave"
+ cont "home some day."
+ cont "It said so on TV."
+
+ para "PROF.OAK, next"
+ line "door, is looking"
+ cont "for you."
+ done
+
+_MomHealText1::
+ text "MOM: <PLAYER>!"
+ line "You should take a"
+ cont "quick rest."
+ prompt
+
+_MomHealText2::
+ text "MOM: Oh good!"
+ line "You and your"
+ cont "#MON are"
+ cont "looking great!"
+ cont "Take care now!"
+ done
+
+_StandByMeText::
+ text "There's a movie"
+ line "on TV. Four boys"
+ cont "are walking on"
+ cont "railroad tracks."
+
+ para "I better go too."
+ done
+
+_TVWrongSideText::
+ text "Oops, wrong side."
+ done
diff --git a/en/text/maps/rock_tunnel_b1f.asm b/en/text/maps/rock_tunnel_b1f.asm
new file mode 100644
index 00000000..472c52f8
--- /dev/null
+++ b/en/text/maps/rock_tunnel_b1f.asm
@@ -0,0 +1,115 @@
+_RockTunnel1BattleText1::
+ text "This tunnel goes"
+ line "a long way, kid!"
+ done
+
+_RockTunnel1EndBattleText1::
+ text "Doh!"
+ line "You win!"
+ prompt
+
+_RockTunnel1AfterBattleText1::
+ text "Watch for ONIX!"
+ line "It can put the"
+ cont "squeeze on you!"
+ done
+
+_RockTunnel1BattleText2::
+ text "Hmm. Maybe I'm"
+ line "lost in here..."
+ done
+
+_RockTunnel1EndBattleText2::
+ text "Ease up!"
+ line "What am I doing?"
+ cont "Which way is out?"
+ prompt
+
+_RockTunnel1AfterBattleText2::
+ text "That sleeping"
+ line "#MON on ROUTE"
+ cont "12 forced me to"
+ cont "take this detour."
+ done
+
+_RockTunnel1BattleText3::
+ text "Outsiders like"
+ line "you need to show"
+ cont "me some respect!"
+ done
+
+_RockTunnel1EndBattleText3::
+ text "I give!"
+ prompt
+
+_RockTunnel1AfterBattleText3::
+ text "You're talented"
+ line "enough to hike!"
+ done
+
+_RockTunnel1BattleText4::
+ text "#MON fight!"
+ line "Ready, go!"
+ done
+
+_RockTunnel1EndBattleText4::
+ text "Game"
+ line "over!"
+ prompt
+
+_RockTunnel1AfterBattleText4::
+ text "Oh well, I'll get"
+ line "a ZUBAT as I go!"
+ done
+
+_RockTunnel1BattleText5::
+ text "Eek! Don't try"
+ line "anything funny in"
+ cont "the dark!"
+ done
+
+_RockTunnel1EndBattleText5::
+ text "It"
+ line "was too dark!"
+ prompt
+
+_RockTunnel1AfterBattleText5::
+ text "I saw a MACHOP"
+ line "in this tunnel!"
+ done
+
+_RockTunnel1BattleText6::
+ text "I came this far"
+ line "for #MON!"
+ done
+
+_RockTunnel1EndBattleText6::
+ text "I'm"
+ line "out of #MON!"
+ prompt
+
+_RockTunnel1AfterBattleText6::
+ text "You looked cute"
+ line "and harmless!"
+ done
+
+_RockTunnel1BattleText7::
+ text "You have #MON!"
+ line "Let's start!"
+ done
+
+_RockTunnel1EndBattleText7::
+ text "You"
+ line "play hard!"
+ prompt
+
+_RockTunnel1AfterBattleText7::
+ text "Whew! I'm all"
+ line "sweaty now!"
+ done
+
+_RockTunnel1Text8::
+ text "ROCK TUNNEL"
+ line "CERULEAN CITY -"
+ cont "LAVENDER TOWN"
+ done
diff --git a/en/text/maps/rock_tunnel_b2f_1.asm b/en/text/maps/rock_tunnel_b2f_1.asm
new file mode 100644
index 00000000..1a565eb3
--- /dev/null
+++ b/en/text/maps/rock_tunnel_b2f_1.asm
@@ -0,0 +1,108 @@
+_RockTunnel2BattleText2::
+ text "Hikers leave twigs"
+ line "as trail markers."
+ done
+
+_RockTunnel2EndBattleText2::
+ text "Ohhh!"
+ line "I did my best!"
+ prompt
+
+_RockTunnel2AfterBattleText2::
+ text "I want to go "
+ line "home!"
+ done
+
+_RockTunnel2BattleText3::
+ text "Hahaha! Can you"
+ line "beat my power?"
+ done
+
+_RockTunnel2EndBattleText3::
+ text "Oops!"
+ line "Out-muscled!"
+ prompt
+
+_RockTunnel2AfterBattleText3::
+ text "I go for power"
+ line "because I hate"
+ cont "thinking!"
+ done
+
+_RockTunnel2BattleText4::
+ text "You have a"
+ line "#DEX?"
+ cont "I want one too!"
+ done
+
+_RockTunnel2EndBattleText4::
+ text "Shoot!"
+ line "I'm so jealous!"
+ prompt
+
+_RockTunnel2AfterBattleText4::
+ text "When you finish"
+ line "your #DEX, can"
+ cont "I have it?"
+ done
+
+_RockTunnel2BattleText5::
+ text "Do you know about"
+ line "costume players?"
+ done
+
+_RockTunnel2EndBattleText5::
+ text "Well,"
+ line "that's that."
+ prompt
+
+_RockTunnel2AfterBattleText5::
+ text "Costume players"
+ line "dress up as"
+ cont "#MON for fun."
+ done
+
+_RockTunnel2BattleText6::
+ text "My #MON"
+ line "techniques will"
+ cont "leave you crying!"
+ done
+
+_RockTunnel2EndBattleText6::
+ text "I give!"
+ line "You're a better"
+ cont "technician!"
+ prompt
+
+_RockTunnel2AfterBattleText6::
+ text "In mountains,"
+ line "you'll often find"
+ cont "rock-type #MON."
+ done
+
+_RockTunnel2BattleText7::
+ text "I don't often"
+ line "come here, but I"
+ cont "will fight you."
+ done
+
+_RockTunnel2EndBattleText7::
+ text "Oh!"
+ line "I lost!"
+ prompt
+
+_RockTunnel2AfterBattleText7::
+ text "I like tiny"
+ line "#MON, big ones"
+ cont "are too scary!"
+ done
+
+_RockTunnel2BattleText8::
+ text "Hit me with your"
+ line "best shot!"
+ done
+
+_RockTunnel2EndBattleText8::
+ text "Fired"
+ line "away!"
+ prompt
diff --git a/en/text/maps/rock_tunnel_b2f_2.asm b/en/text/maps/rock_tunnel_b2f_2.asm
new file mode 100644
index 00000000..e8e45a7f
--- /dev/null
+++ b/en/text/maps/rock_tunnel_b2f_2.asm
@@ -0,0 +1,20 @@
+_RockTunnel2AfterBattleText8::
+ text "I'll raise my"
+ line "#MON to beat"
+ cont "yours, kid!"
+ done
+
+_RockTunnel2BattleText9::
+ text "I draw #MON"
+ line "when I'm home."
+ done
+
+_RockTunnel2EndBattleText9::
+ text "Whew!"
+ line "I'm exhausted!"
+ prompt
+
+_RockTunnel2AfterBattleText9::
+ text "I'm an artist,"
+ line "not a fighter."
+ done
diff --git a/en/text/maps/rock_tunnel_pokecenter.asm b/en/text/maps/rock_tunnel_pokecenter.asm
new file mode 100644
index 00000000..0fc249ff
--- /dev/null
+++ b/en/text/maps/rock_tunnel_pokecenter.asm
@@ -0,0 +1,13 @@
+_RockTunnelPokecenterText2::
+ text "The element types"
+ line "of #MON make"
+ cont "them stronger"
+ cont "than some types"
+ cont "and weaker than"
+ cont "others!"
+ done
+
+_RockTunnelPokecenterText3::
+ text "I sold a useless"
+ line "NUGGET for ¥5000!"
+ done
diff --git a/en/text/maps/rocket_hideout_b1f.asm b/en/text/maps/rocket_hideout_b1f.asm
new file mode 100644
index 00000000..36117804
--- /dev/null
+++ b/en/text/maps/rocket_hideout_b1f.asm
@@ -0,0 +1,73 @@
+_RocketHideout1EndBattleText6::
+ text "Why...?@@"
+
+_RocketHideout1BattleText2::
+ text "Who are you? How"
+ line "did you get here?"
+ done
+
+_RocketHideout1EndBattleText2::
+ text "Oww!"
+ line "Beaten!"
+ prompt
+
+_RocketHideout1AfterBattleTxt2::
+ text "Are you dissing"
+ line "TEAM ROCKET?"
+ done
+
+_RocketHideout1BattleText3::
+ text "You broke into"
+ line "our operation?"
+ done
+
+_RocketHideout1EndBattleText3::
+ text "Burnt!"
+ prompt
+
+_RocketHideout1AfterBattleTxt3::
+ text "You're not going"
+ line "to get away with"
+ cont "this, brat!"
+ done
+
+_RocketHideout1BattleText4::
+ text "Intruder alert!"
+ done
+
+_RocketHideout1EndBattleText4::
+ text "I"
+ line "can't do it!"
+ prompt
+
+_RocketHideout1AfterBattleTxt4::
+ text "SILPH SCOPE?"
+ line "I don't know"
+ cont "where it is!"
+ done
+
+_RocketHideout1BattleText5::
+ text "Why did you come"
+ line "here?"
+ done
+
+_RocketHideout1EndBattleText5::
+ text "This"
+ line "won't do!"
+ prompt
+
+_RocketHideout1AfterBattleTxt5::
+ text "OK, I'll talk!"
+ line "Take the elevator"
+ cont "to see my BOSS!"
+ done
+
+_RocketHideout1BattleText6::
+ text "Are you lost, you"
+ line "little rat?"
+ done
+
+_RocketHideout1AfterBattleTxt6::
+ text "Uh-oh, that fight"
+ line "opened the door!"
+ done
diff --git a/en/text/maps/rocket_hideout_b2f.asm b/en/text/maps/rocket_hideout_b2f.asm
new file mode 100644
index 00000000..c13c3593
--- /dev/null
+++ b/en/text/maps/rocket_hideout_b2f.asm
@@ -0,0 +1,17 @@
+_RocketHideout2BattleText2::
+ text "BOSS said you can"
+ line "see GHOSTs with"
+ cont "the SILPH SCOPE!"
+ done
+
+_RocketHideout2EndBattleText2::
+ text "I"
+ line "surrender!"
+ prompt
+
+_RocketHideout2AfterBattleTxt2::
+ text "The TEAM ROCKET"
+ line "HQ has 4 basement"
+ cont "floors. Can you"
+ cont "reach the BOSS?"
+ done
diff --git a/en/text/maps/rocket_hideout_b3f.asm b/en/text/maps/rocket_hideout_b3f.asm
new file mode 100644
index 00000000..a146a383
--- /dev/null
+++ b/en/text/maps/rocket_hideout_b3f.asm
@@ -0,0 +1,35 @@
+_RocketHideout3BattleText2::
+ text "Stop meddling in"
+ line "TEAM ROCKET's"
+ cont "affairs!"
+ done
+
+_RocketHideout3EndBattleText2::
+ text "Oof!"
+ line "Taken down!"
+ prompt
+
+_RocketHideout3AfterBattleTxt2::
+ text "SILPH SCOPE?"
+ line "The machine the"
+ cont "BOSS stole. It's"
+ cont "here somewhere."
+ done
+
+_RocketHideout3BattleTxt::
+ text "We got word from"
+ line "upstairs that you"
+ cont "were coming!"
+ done
+
+_RocketHideout3EndBattleText3::
+ text "What?"
+ line "I lost? No!"
+ prompt
+
+_RocketHide3AfterBattleText3::
+ text "Go ahead and go!"
+ line "But, you need the"
+ cont "LIFT KEY to run"
+ cont "the elevator!"
+ done
diff --git a/en/text/maps/rocket_hideout_b4f.asm b/en/text/maps/rocket_hideout_b4f.asm
new file mode 100644
index 00000000..f3ba43f3
--- /dev/null
+++ b/en/text/maps/rocket_hideout_b4f.asm
@@ -0,0 +1,74 @@
+_RocketHideout4Text_4557a::
+ text "So! I must say, I"
+ line "am impressed you"
+ cont "got here!"
+ done
+
+_RocketHideout4Text_4557f::
+ text "WHAT!"
+ line "This cannot be!"
+ prompt
+
+_RocketHideout4Text_45584::
+ text "I see that you"
+ line "raise #MON"
+ cont "with utmost care."
+
+ para "A child like you"
+ line "would never"
+ cont "understand what I"
+ cont "hope to achieve."
+
+ para "I shall step"
+ line "aside this time!"
+
+ para "I hope we meet"
+ line "again..."
+ done
+
+_RocketHideout4BattleText2::
+ text "I know you! You"
+ line "ruined our plans"
+ cont "at MT.MOON!"
+ done
+
+_RocketHideout4EndBattleText2::
+ text "Burned"
+ line "again!"
+ prompt
+
+_RocketHide4AfterBattleText2::
+ text "Do you have"
+ line "something against"
+ cont "TEAM ROCKET?"
+ done
+
+_RocketHideout4BattleText3::
+ text "How can you not"
+ line "see the beauty of"
+ cont "our evil?"
+ done
+
+_RocketHideout4EndBattleText3::
+ text "Ayaya!"
+ prompt
+
+_RocketHide4AfterBattleText3::
+ text "BOSS! I'm sorry I"
+ line "failed you!"
+ done
+
+_RocketHideout4BattleText4::
+ text "The elevator"
+ line "doesn't work? Who"
+ cont "has the LIFT KEY?"
+ done
+
+_RocketHideout4EndBattleText4::
+ text "No!"
+ prompt
+
+_RocketHideout4Text_455ec::
+ text "Oh no! I dropped"
+ line "the LIFT KEY!"
+ done
diff --git a/en/text/maps/rocket_hideout_elevator.asm b/en/text/maps/rocket_hideout_elevator.asm
new file mode 100644
index 00000000..6f2aa638
--- /dev/null
+++ b/en/text/maps/rocket_hideout_elevator.asm
@@ -0,0 +1,3 @@
+_RocketElevatorText_4578b::
+ text "It appears to"
+ line "need a key.@@"
diff --git a/en/text/maps/route_1.asm b/en/text/maps/route_1.asm
new file mode 100644
index 00000000..73188f09
--- /dev/null
+++ b/en/text/maps/route_1.asm
@@ -0,0 +1,49 @@
+_Route1ViridianMartSampleText::
+ text "Hi! I work at a"
+ line "#MON MART."
+
+ para "It's a convenient"
+ line "shop, so please"
+ cont "visit us in"
+ cont "VIRIDIAN CITY."
+
+ para "I know, I'll give"
+ line "you a sample!"
+ cont "Here you go!"
+ prompt
+
+_Route1Text_1cae8::
+ text "<PLAYER> got"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_Route1Text_1caee::
+ text "We also carry"
+ line "# BALLs for"
+ cont "catching #MON!"
+ done
+
+_Route1Text_1caf3::
+ text "You have too much"
+ line "stuff with you!"
+ done
+
+_Route1Text2::
+ text "See those ledges"
+ line "along the road?"
+
+ para "It's a bit scary,"
+ line "but you can jump"
+ cont "from them."
+
+ para "You can get back"
+ line "to PALLET TOWN"
+ cont "quicker that way."
+ done
+
+_Route1Text3::
+ text "ROUTE 1"
+ line "PALLET TOWN -"
+ cont "VIRIDIAN CITY"
+ done
diff --git a/en/text/maps/route_10.asm b/en/text/maps/route_10.asm
new file mode 100644
index 00000000..057ddcb5
--- /dev/null
+++ b/en/text/maps/route_10.asm
@@ -0,0 +1,109 @@
+_Route10BattleText1::
+ text "Wow, are you a"
+ line "#MANIAC too?"
+ cont "Want to see my"
+ cont "collection?"
+ done
+
+_Route10EndBattleText1::
+ text "Humph."
+ line "I'm not angry!"
+ prompt
+
+_Route10AfterBattleText1::
+ text "I have more rare"
+ line "#MON at home!"
+ done
+
+_Route10BattleText2::
+ text "Ha-hahah-ah-ha!"
+ done
+
+_Route10EndBattleText2::
+ text "Ha-haha!"
+ line "Not laughing!"
+ cont "Ha-hay fever!"
+ cont "Haha-ha-choo!"
+ prompt
+
+_Route10AfterBattleText2::
+ text "Haha-ha-choo!"
+ line "Ha-choo!"
+ cont "Snort! Snivel!"
+ done
+
+_Route10BattleText3::
+ text "Hi kid, want to"
+ line "see my #MON?"
+ done
+
+_Route10EndBattleText3::
+ text "Oh no!"
+ line "My #MON!"
+ prompt
+
+_Route10AfterBattleText3::
+ text "I don't like you"
+ line "for beating me!"
+ done
+
+_Route10BattleText4::
+ text "I've been to a"
+ line "#MON GYM a few"
+ cont "times. But, I"
+ cont "lost each time."
+ done
+
+_Route10EndBattleText4::
+ text "Ohh!"
+ line "Blew it again!"
+ prompt
+
+_Route10AfterBattleText4::
+ text "I noticed some"
+ line "#MANIACs"
+ cont "prowling around."
+ done
+
+_Route10BattleText5::
+ text "Ah! This mountain"
+ line "air is delicious!"
+ done
+
+_Route10EndBattleText5::
+ text "That"
+ line "cleared my head!"
+ prompt
+
+_Route10AfterBattleText5::
+ text "I feel bloated on"
+ line "mountain air!"
+ done
+
+_Route10BattleText6::
+ text "I'm feeling a bit"
+ line "faint from this"
+ cont "tough hike."
+ done
+
+_Route10EndBattleText6::
+ text "I'm"
+ line "not up to it!"
+ prompt
+
+_Route10AfterBattleText6::
+ text "The #MON here"
+ line "are so chunky!"
+ cont "There should be a"
+ cont "pink one with a"
+ cont "floral pattern!"
+ done
+
+_Route10Text9::
+_Route10Text7::
+ text "ROCK TUNNEL"
+ done
+
+_Route10Text10::
+ text "POWER PLANT"
+ done
diff --git a/en/text/maps/route_11_1.asm b/en/text/maps/route_11_1.asm
new file mode 100644
index 00000000..13e37bdf
--- /dev/null
+++ b/en/text/maps/route_11_1.asm
@@ -0,0 +1,133 @@
+_Route11BattleText1::
+ text "Win, lose or draw!"
+ done
+
+_Route11EndBattleText1::
+ text "Atcha!"
+ line "Didn't go my way!"
+ prompt
+
+_Route11AfterBattleText1::
+ text "#MON is life!"
+ line "And to live is to"
+ cont "gamble!"
+ done
+
+_Route11BattleText2::
+ text "Competition! I"
+ line "can't get enough!"
+ done
+
+_Route11EndBattleText2::
+ text "I had"
+ line "a chance!"
+ prompt
+
+_Route11AfterBattleText2::
+ text "You can't be a"
+ line "coward in the"
+ cont "world of #MON!"
+ done
+
+_Route11BattleText3::
+ text "Let's go, but"
+ line "don't cheat!"
+ done
+
+_Route11EndBattleText3::
+ text "Huh?"
+ line "That's not right!"
+ prompt
+
+_Route11AfterBattleText3::
+ text "I did my best! I"
+ line "have no regrets!"
+ done
+
+_Route11BattleText4::
+ text "Careful!"
+ line "I'm laying down"
+ cont "some cables!"
+ done
+
+_Route11EndBattleText4::
+ text "That"
+ line "was electric!"
+ prompt
+
+_Route11AfterBattleText4::
+ text "Spread the word"
+ line "to save energy!"
+ done
+
+_Route11BattleText5::
+ text "I just became a"
+ line "trainer! But, I"
+ cont "think I can win!"
+ done
+
+_Route11EndBattleText5::
+ text "My"
+ line "#MON couldn't!"
+ prompt
+
+_Route11AfterBattleText5::
+ text "What do you want?"
+ line "Leave me alone!"
+ done
+
+_Route11BattleText6::
+ text "Fwahaha! I have"
+ line "never lost!"
+ done
+
+_Route11EndBattleText6::
+ text "My"
+ line "first loss!"
+ prompt
+
+_Route11AfterBattleText6::
+ text "Luck of the draw!"
+ line "Just luck!"
+ done
+
+_Route11BattleText7::
+ text "I have never won"
+ line "before..."
+ done
+
+_Route11EndBattleText7::
+ text "I saw"
+ line "this coming..."
+ prompt
+
+_Route11AfterBattleText7::
+ text "It's just luck."
+ line "Luck of the draw."
+ done
+
+_Route11BattleText8::
+ text "I'm the best in"
+ line "my class!"
+ done
+
+_Route11EndBattleText8::
+ text "Darn!"
+ line "I need to make my"
+ cont "#MON stronger!"
+ prompt
+
+_Route11AfterBattleText8::
+ text "There's a fat"
+ line "#MON that"
+ cont "comes down from"
+ cont "the mountains."
+
+ para "It's strong if"
+ line "you can get it."
+ done
+
+_Route11BattleText9::
+ text "Watch out for"
+ line "live wires!"
+ done
diff --git a/en/text/maps/route_11_2.asm b/en/text/maps/route_11_2.asm
new file mode 100644
index 00000000..b9b68d6d
--- /dev/null
+++ b/en/text/maps/route_11_2.asm
@@ -0,0 +1,28 @@
+_Route11EndBattleText9::
+ text "Whoa!"
+ line "You spark plug!"
+ prompt
+
+_Route11AfterBattleText9::
+ text "Well, better get"
+ line "back to work."
+ done
+
+_Route11BattleText10::
+ text "My #MON should"
+ line "be ready by now!"
+ done
+
+_Route11EndBattleText10::
+ text "Too"
+ line "much, too young!"
+ prompt
+
+_Route11AfterBattleText10::
+ text "I better go find"
+ line "stronger ones!"
+ done
+
+_Route11Text11::
+ text "DIGLETT's CAVE"
+ done
diff --git a/en/text/maps/route_11_gate.asm b/en/text/maps/route_11_gate.asm
new file mode 100644
index 00000000..ef371d06
--- /dev/null
+++ b/en/text/maps/route_11_gate.asm
@@ -0,0 +1,14 @@
+_Route11GateText1::
+ text "When you catch"
+ line "lots of #MON,"
+ cont "isn't it hard to"
+ cont "think up names?"
+
+ para "In LAVENDER TOWN,"
+ line "there's a man who"
+ cont "rates #MON"
+ cont "nicknames."
+
+ para "He'll help you"
+ line "rename them too!"
+ done
diff --git a/en/text/maps/route_11_gate_upstairs.asm b/en/text/maps/route_11_gate_upstairs.asm
new file mode 100644
index 00000000..10236081
--- /dev/null
+++ b/en/text/maps/route_11_gate_upstairs.asm
@@ -0,0 +1,40 @@
+_Route11GateUpstairsText_494a3::
+ text "There are items on"
+ line "the ground that"
+ cont "can't be seen."
+
+ para "ITEMFINDER will"
+ line "detect an item"
+ cont "close to you."
+
+ para "It can't pinpoint"
+ line "it, so you have"
+ cont "to look yourself!"
+ done
+
+_BinocularsSnorlaxText::
+ text "Looked into the"
+ line "binoculars."
+
+ para "A big #MON is"
+ line "asleep on a road!"
+ done
+
+_BinocularsNoSnorlaxText::
+ text "Looked into the"
+ line "binoculars."
+
+ para "It's a beautiful"
+ line "view!"
+ done
+
+_Route11GateUpstairsText_494d5::
+ text "Looked into the"
+ line "binoculars."
+
+ para "The only way to"
+ line "get from CERULEAN"
+ cont "CITY to LAVENDER"
+ cont "is by way of the"
+ cont "ROCK TUNNEL."
+ done
diff --git a/en/text/maps/route_12.asm b/en/text/maps/route_12.asm
new file mode 100644
index 00000000..82696fda
--- /dev/null
+++ b/en/text/maps/route_12.asm
@@ -0,0 +1,139 @@
+_Route12Text1::
+ text "A sleeping #MON"
+ line "blocks the way!"
+ done
+
+_Route12Text13::
+ text "SNORLAX woke up!"
+
+ para "It attacked in a"
+ line "grumpy rage!"
+ done
+
+_Route12Text14::
+ text "SNORLAX calmed"
+ line "down! With a big"
+ cont "yawn, it returned"
+ cont "to the mountains!"
+ done
+
+_Route12BattleText1::
+ text "Yeah! I got a"
+ line "bite, here!"
+ done
+
+_Route12EndBattleText1::
+ text "Tch!"
+ line "Just a small fry!"
+ prompt
+
+_Route12AfterBattleText1::
+ text "Hang on! My line's"
+ line "snagged!"
+ done
+
+_Route12BattleText2::
+ text "Be patient!"
+ line "Fishing is a"
+ cont "waiting game!"
+ done
+
+_Route12EndBattleText2::
+ text "That"
+ line "one got away!"
+ prompt
+
+_Route12AfterBattleText2::
+ text "With a better ROD,"
+ line "I could catch"
+ cont "better #MON!"
+ done
+
+_Route12BattleText3::
+ text "Have you found a"
+ line "MOON STONE?"
+ done
+
+_Route12EndBattleText3::
+ text "Oww!"
+ prompt
+
+_Route12AfterBattleText3::
+ text "I could have made"
+ line "my #MON evolve"
+ cont "with MOON STONE!"
+ done
+
+_Route12BattleText4::
+ text "Electricity is my"
+ line "specialty!"
+ done
+
+_Route12EndBattleText4::
+ text "Unplugged!"
+ prompt
+
+_Route12AfterBattleText4::
+ text "Water conducts"
+ line "electricity, so"
+ cont "you should zap"
+ cont "sea #MON!"
+ done
+
+_Route12BattleText5::
+ text "The FISHING FOOL"
+ line "vs. #MON KID!"
+ done
+
+_Route12EndBattleText5::
+ text "Too"
+ line "much!"
+ prompt
+
+_Route12AfterBattleText5::
+ text "You beat me at"
+ line "#MON, but I'm"
+ cont "good at fishing!"
+ done
+
+_Route12BattleText6::
+ text "I'd rather be"
+ line "working!"
+ done
+
+_Route12EndBattleText6::
+ text "It's"
+ line "not easy..."
+ prompt
+
+_Route12AfterBattleText6::
+ text "It's all right."
+ line "Losing doesn't"
+ cont "bug me any more."
+ done
+
+_Route12BattleText7::
+ text "You never know"
+ line "what you could"
+ cont "catch!"
+ done
+
+_Route12EndBattleText7::
+ text "Lost"
+ line "it!"
+ prompt
+
+_Route12AfterBattleText7::
+ text "I catch MAGIKARP"
+ line "all the time, but"
+ cont "they're so weak!"
+ done
+
+_Route12Text11::
+ text "ROUTE 12 "
+ line "North to LAVENDER"
+ done
+
+_Route12Text12::
+ text "SPORT FISHING AREA"
+ done
diff --git a/en/text/maps/route_12_gate.asm b/en/text/maps/route_12_gate.asm
new file mode 100644
index 00000000..51d75539
--- /dev/null
+++ b/en/text/maps/route_12_gate.asm
@@ -0,0 +1,4 @@
+_Route12GateText1::
+ text "There's a lookout"
+ line "spot upstairs."
+ done
diff --git a/en/text/maps/route_12_gate_upstairs.asm b/en/text/maps/route_12_gate_upstairs.asm
new file mode 100644
index 00000000..95a89527
--- /dev/null
+++ b/en/text/maps/route_12_gate_upstairs.asm
@@ -0,0 +1,42 @@
+_TM39PreReceiveText::
+ text "My #MON's"
+ line "ashes are stored"
+ cont "in #MON TOWER."
+
+ para "You can have this"
+ line "TM. I don't need"
+ cont "it any more..."
+ prompt
+
+_ReceivedTM39Text::
+ text "<PLAYER> received"
+ line "TM39!@@"
+
+_TM39ExplanationText::
+ text "TM39 is a move"
+ line "called SWIFT."
+
+ para "It's very accurate,"
+ line "so use it during"
+ cont "battles you can't"
+ cont "afford to lose."
+ done
+
+_TM39NoRoomText::
+ text "You don't have"
+ line "room for this."
+ done
+
+_Route12GateUpstairsText_495b8::
+ text "Looked into the"
+ line "binoculars."
+
+ para "A man fishing!"
+ done
+
+_Route12GateUpstairsText_495c4::
+ text "Looked into the"
+ line "binoculars."
+
+ para "It's #MON TOWER!"
+ done
diff --git a/en/text/maps/route_12_house.asm b/en/text/maps/route_12_house.asm
new file mode 100644
index 00000000..e04ce5fb
--- /dev/null
+++ b/en/text/maps/route_12_house.asm
@@ -0,0 +1,60 @@
+_Route12HouseText_564c0::
+ text "I'm the FISHING"
+ line "GURU's brother!"
+
+ para "I simply Looove"
+ line "fishing!"
+
+ para "Do you like to"
+ line "fish?"
+ done
+
+_Route12HouseText_564c5::
+ text "Grand! I like"
+ line "your style!"
+
+ para "Take this and"
+ line "fish, young one!"
+
+ para "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_Route12HouseText_564ca::
+ db $0
+ para "Fishing is a way"
+ line "of life!"
+
+ para "From the seas to"
+ line "rivers, go out"
+ cont "and land the big"
+ cont "one!"
+ done
+
+_Route12HouseText_564cf::
+ text "Oh... That's so"
+ line "disappointing..."
+ done
+
+_Route12HouseText_564d4::
+ text "Hello there,"
+ line "<PLAYER>!"
+
+ para "Use the SUPER ROD"
+ line "in any water!"
+ cont "You can catch"
+ cont "different kinds"
+ cont "of #MON."
+
+ para "Try fishing"
+ line "wherever you can!"
+ done
+
+_Route12HouseText_564d9::
+ text "Oh no!"
+
+ para "I had a gift for"
+ line "you, but you have"
+ cont "no room for it!"
+ done
diff --git a/en/text/maps/route_13.asm b/en/text/maps/route_13.asm
new file mode 100644
index 00000000..e2718919
--- /dev/null
+++ b/en/text/maps/route_13.asm
@@ -0,0 +1,179 @@
+_Route13BattleText2::
+ text "My bird #MON"
+ line "want to scrap!"
+ done
+
+_Route13EndBattleText2::
+ text "My"
+ line "bird combo lost?"
+ prompt
+
+_Route13AfterBattleText2::
+ text "My #MON look"
+ line "happy even though"
+ cont "they lost."
+ done
+
+_Route13BattleText3::
+ text "I'm told I'm good"
+ line "for a kid!"
+ done
+
+_Route13EndBattleText3::
+ text "Ohh!"
+ line "I lost!"
+ prompt
+
+_Route13AfterBattleText3::
+ text "I want to become"
+ line "a good trainer."
+ cont "I'll train hard."
+ done
+
+_Route13BattleText4::
+ text "Wow! Your BADGEs"
+ line "are too cool!"
+ done
+
+_Route13EndBattleText4::
+ text "Not"
+ line "enough!"
+ prompt
+
+_Route13AfterBattleText4::
+ text "You got those"
+ line "BADGEs from GYM"
+ cont "LEADERs. I know!"
+ done
+
+_Route13BattleText5::
+ text "My cute #MON"
+ line "wish to make your"
+ cont "acquaintance."
+ done
+
+_Route13EndBattleText5::
+ text "Wow!"
+ line "You totally won!"
+ prompt
+
+_Route13AfterBattleText5::
+ text "You have to make"
+ line "#MON fight to"
+ cont "toughen them up!"
+ done
+
+_Route13BattleText6::
+ text "I found CARBOS in"
+ line "a cave once."
+ done
+
+_Route13EndBattleText6::
+ text "Just"
+ line "messed up!"
+ prompt
+
+_Route13AfterBattleText6::
+ text "CARBOS boosted"
+ line "the SPEED of my"
+ cont "#MON."
+ done
+
+_Route13BattleText7::
+ text "The wind's blowing"
+ line "my way!"
+ done
+
+_Route13EndBattleText7::
+ text "The"
+ line "wind turned!"
+ prompt
+
+_Route13AfterBattleText7::
+ text "I'm beat. I guess"
+ line "I'll FLY home."
+ done
+
+_Route13BattleText8::
+ text "Sure, I'll play"
+ line "with you!"
+ done
+
+_Route13EndBattleText8::
+ text "Oh!"
+ line "You little brute!"
+ prompt
+
+_Route13AfterBattleText8::
+ text "I wonder which is"
+ line "stronger, male or"
+ cont "female #MON?"
+ done
+
+_Route13BattleText9::
+ text "Do you want to"
+ line "#MON with me?"
+ done
+
+_Route13EndBattleText9::
+ text "It's over"
+ line "already?"
+ prompt
+
+_Route13AfterBattleText9::
+ text "I don't know"
+ line "anything about"
+ cont "#MON. I just"
+ cont "like cool ones!"
+ done
+
+_Route13BattleText10::
+ text "What're you"
+ line "lookin' at?"
+ done
+
+_Route13EndBattleText10::
+ text "Dang!"
+ line "Stripped gears!"
+ prompt
+
+_Route13AfterBattleText10::
+ text "Get lost!"
+ done
+
+_Route13BattleText11::
+ text "I always go with"
+ line "bird #MON!"
+ done
+
+_Route13EndBattleText11::
+ text "Out"
+ line "of power!"
+ prompt
+
+_Route13AfterBattleText11::
+ text "I wish I could"
+ line "fly like PIDGEY"
+ cont "and PIDGEOTTO..."
+ done
+
+_Route13Text11::
+ text "TRAINER TIPS"
+
+ para "Look to the left"
+ line "of that post!"
+ done
+
+_Route13Text12::
+ text "TRAINER TIPS"
+
+ para "Use SELECT to"
+ line "switch items in"
+ cont "the ITEM window!"
+ done
+
+_Route13Text13::
+ text "ROUTE 13"
+ line "North to SILENCE"
+ cont "BRIDGE"
+ done
diff --git a/en/text/maps/route_14.asm b/en/text/maps/route_14.asm
new file mode 100644
index 00000000..18e85ed4
--- /dev/null
+++ b/en/text/maps/route_14.asm
@@ -0,0 +1,173 @@
+_Route14BattleText1::
+ text "You need to use"
+ line "TMs to teach good"
+ cont "moves to #MON!"
+ done
+
+_Route14EndBattleText1::
+ text "Not"
+ line "good enough!"
+ prompt
+
+_Route14AfterBattleText1::
+ text "You have some HMs"
+ line "right? #MON"
+ cont "can't ever forget"
+ cont "those moves."
+ done
+
+_Route14BattleText2::
+ text "My bird #MON"
+ line "should be ready"
+ cont "for battle."
+ done
+
+_Route14EndBattleText2::
+ text "Not"
+ line "ready yet!"
+ prompt
+
+_Route14AfterBattleText2::
+ text "They need to learn"
+ line "better moves."
+ done
+
+_Route14BattleText3::
+ text "TMs are on sale"
+ line "in CELADON!"
+ cont "But, only a few"
+ cont "people have HMs!"
+ done
+
+_Route14EndBattleText3::
+ text "Aww,"
+ line "bummer!"
+ prompt
+
+_Route14AfterBattleText3::
+ text "Teach #MON"
+ line "moves of the same"
+ cont "element type for"
+ cont "more power."
+ done
+
+_Route14BattleText4::
+ text "Have you taught"
+ line "your bird #MON"
+ cont "how to FLY?"
+ done
+
+_Route14EndBattleText4::
+ text "Shot"
+ line "down in flames!"
+ prompt
+
+_Route14AfterBattleText4::
+ text "Bird #MON are"
+ line "my true love!"
+ done
+
+_Route14BattleText5::
+ text "Have you heard of"
+ line "the legendary"
+ cont "#MON?"
+ done
+
+_Route14EndBattleText5::
+ text "Why?"
+ line "Why'd I lose?"
+ prompt
+
+_Route14AfterBattleText5::
+ text "The 3 legendary"
+ line "#MON are all"
+ cont "birds of prey."
+ done
+
+_Route14BattleText6::
+ text "I'm not into it,"
+ line "but OK! Let's go!"
+ done
+
+_Route14EndBattleText6::
+ text "I"
+ line "knew it!"
+ prompt
+
+_Route14AfterBattleText6::
+ text "Winning, losing,"
+ line "it doesn't matter"
+ cont "in the long run!"
+ done
+
+_Route14BattleText7::
+ text "C'mon, c'mon."
+ line "Let's go, let's"
+ cont "go, let's go!"
+ done
+
+_Route14EndBattleText7::
+ text "Arrg!"
+ line "Lost! Get lost!"
+ prompt
+
+_Route14AfterBattleText7::
+ text "What, what, what?"
+ line "What do you want?"
+ done
+
+_Route14BattleText8::
+ text "Perfect! I need to"
+ line "burn some time!"
+ done
+
+_Route14EndBattleText8::
+ text "What?"
+ line "You!?"
+ prompt
+
+_Route14AfterBattleText8::
+ text "Raising #MON"
+ line "is a drag, man."
+ done
+
+_Route14BattleText9::
+ text "We ride out here"
+ line "because there's"
+ cont "more room!"
+ done
+
+_Route14EndBattleText9::
+ text "Wipe out!"
+ prompt
+
+_Route14AfterBattleText9::
+ text "It's cool you"
+ line "made your #MON"
+ cont "so strong!"
+
+ para "Might is right!"
+ line "And you know it!"
+ done
+
+_Route14BattleText10::
+ text "#MON fight?"
+ line "Cool! Rumble!"
+ done
+
+_Route14EndBattleText10::
+ text "Blown"
+ line "away!"
+ prompt
+
+_Route14AfterBattleText10::
+ text "You know who'd"
+ line "win, you and me"
+ cont "one on one!"
+ done
+
+_Route14Text11::
+ text "ROUTE 14"
+ line "West to FUCHSIA"
+ cont "CITY"
+ done
diff --git a/en/text/maps/route_15.asm b/en/text/maps/route_15.asm
new file mode 100644
index 00000000..a23b8500
--- /dev/null
+++ b/en/text/maps/route_15.asm
@@ -0,0 +1,171 @@
+_Route15BattleText1::
+ text "Let me try out the"
+ line "#MON I just"
+ cont "got in a trade!"
+ done
+
+_Route15EndBattleText1::
+ text "Not"
+ line "good enough!"
+ prompt
+
+_Route15AfterBattleText1::
+ text "You can't change"
+ line "the nickname of"
+ cont "any #MON you"
+ cont "get in a trade."
+
+ para "Only the Original"
+ line "Trainer can."
+ done
+
+_Route15BattleText2::
+ text "You look gentle,"
+ line "so I think I can"
+ cont "beat you!"
+ done
+
+_Route15EndBattleText2::
+ text "No,"
+ line "wrong!"
+ prompt
+
+_Route15AfterBattleText2::
+ text "I'm afraid of"
+ line "BIKERs, they look"
+ cont "so ugly and mean!"
+ done
+
+_Route15BattleText3::
+ text "When I whistle, I"
+ line "can summon bird"
+ cont "#MON!"
+ done
+
+_Route15EndBattleText3::
+ text "Ow!"
+ line "That's tragic!"
+ prompt
+
+_Route15AfterBattleText3::
+ text "Maybe I'm not cut"
+ line "out for battles."
+ done
+
+_Route15BattleText4::
+ text "Hmm? My birds are"
+ line "shivering! You're"
+ cont "good, aren't you?"
+ done
+
+_Route15EndBattleText4::
+ text "Just"
+ line "as I thought!"
+ prompt
+
+_Route15AfterBattleText4::
+ text "Did you know moves"
+ line "like EARTHQUAKE"
+ cont "don't have any"
+ cont "effect on birds?"
+ done
+
+_Route15BattleText5::
+ text "Oh, you're a"
+ line "little cutie!"
+ done
+
+_Route15EndBattleText5::
+ text "You looked"
+ line "so cute too!"
+ prompt
+
+_Route15AfterBattleText5::
+ text "I forgive you!"
+ line "I can take it!"
+ done
+
+_Route15BattleText6::
+ text "I raise #MON"
+ line "because I live"
+ cont "alone!"
+ done
+
+_Route15EndBattleText6::
+ text "I didn't"
+ line "ask for this!"
+ prompt
+
+_Route15AfterBattleText6::
+ text "I just like going"
+ line "home to be with"
+ cont "my #MON!"
+ done
+
+_Route15BattleText7::
+ text "Hey kid! C'mon!"
+ line "I just got these!"
+ done
+
+_Route15EndBattleText7::
+ text "Why"
+ line "not?"
+ prompt
+
+_Route15AfterBattleText7::
+ text "You only live"
+ line "once, so I live"
+ cont "as an outlaw!"
+ cont "TEAM ROCKET RULES!"
+ done
+
+_Route15BattleText8::
+ text "Fork over all your"
+ line "cash when you"
+ cont "lose to me, kid!"
+ done
+
+_Route15EndBattleText8::
+ text "That"
+ line "can't be true!"
+ prompt
+
+_Route15AfterBattleText8::
+ text "I was just joking"
+ line "about the money!"
+ done
+
+_Route15BattleText9::
+ text "What's cool?"
+ line "Trading #MON!"
+ done
+
+_Route15EndBattleText9::
+ text "I"
+ line "said trade!"
+ prompt
+
+_Route15AfterBattleText9::
+ text "I trade #MON"
+ line "with my friends!"
+ done
+
+_Route15BattleText10::
+ text "Want to play with"
+ line "my #MON?"
+ done
+
+_Route15EndBattleText10::
+ text "I was"
+ line "too impatient!"
+ prompt
+
+_Route15AfterBattleText10::
+ text "I'll go train with"
+ line "weaker people.@@"
+
+_Route15Text12::
+ text "ROUTE 15"
+ line "West to FUCHSIA"
+ cont "CITY"
+ done
diff --git a/en/text/maps/route_15_gate.asm b/en/text/maps/route_15_gate.asm
new file mode 100644
index 00000000..0a526142
--- /dev/null
+++ b/en/text/maps/route_15_gate.asm
@@ -0,0 +1,7 @@
+_Route15GateText1::
+ text "Are you working"
+ line "on a #DEX?"
+
+ para "PROF.OAK's AIDE"
+ line "came by here."
+ done
diff --git a/en/text/maps/route_15_gate_upstairs.asm b/en/text/maps/route_15_gate_upstairs.asm
new file mode 100644
index 00000000..ade4a358
--- /dev/null
+++ b/en/text/maps/route_15_gate_upstairs.asm
@@ -0,0 +1,24 @@
+_Route15GateUpstairsText_4968c::
+ text "EXP.ALL gives"
+ line "EXP points to all"
+ cont "the #MON with"
+ cont "you, even if they"
+ cont "don't fight."
+
+ para "It does, however,"
+ line "reduce the amount"
+ cont "of EXP for each"
+ cont "#MON."
+
+ para "If you don't need"
+ line "it, you should "
+ cont "store it via PC."
+ done
+
+_Route15GateUpstairsText_49698::
+ text "Looked into the"
+ line "binoculars."
+
+ para "It looks like a"
+ line "small island!"
+ done
diff --git a/en/text/maps/route_16.asm b/en/text/maps/route_16.asm
new file mode 100644
index 00000000..45265829
--- /dev/null
+++ b/en/text/maps/route_16.asm
@@ -0,0 +1,120 @@
+_Route16BattleText1::
+ text "What do you want?"
+ done
+
+_Route16EndBattleText1::
+ text "Don't you"
+ line "dare laugh!"
+ prompt
+
+_Route16AfterBattleText1::
+ text "We like just"
+ line "hanging here,"
+ cont "what's it to you?"
+ done
+
+_Route16BattleText2::
+ text "Nice BIKE!"
+ line "Hand it over!"
+ done
+
+_Route16EndBattleText2::
+ text "Knock"
+ line "out!"
+ prompt
+
+_Route16AfterBattleText2::
+ text "Forget it, who"
+ line "needs your BIKE!"
+ done
+
+_Route16BattleText3::
+ text "Come out and play,"
+ line "little mouse!"
+ done
+
+_Route16EndBattleText3::
+ text "You"
+ line "little rat!"
+ prompt
+
+_Route16AfterBattleText3::
+ text "I hate losing!"
+ line "Get away from me!"
+ done
+
+_Route16BattleText4::
+ text "Hey, you just"
+ line "bumped me!"
+ done
+
+_Route16EndBattleText4::
+ text "Kaboom!"
+ prompt
+
+_Route16AfterBattleText4::
+ text "You can also get"
+ line "to FUCHSIA from"
+ cont "VERMILION using a"
+ cont "coastal road."
+ done
+
+_Route16BattleText5::
+ text "I'm feeling"
+ line "hungry and mean!"
+ done
+
+_Route16EndBattleText5::
+ text "Bad,"
+ line "bad, bad!"
+ prompt
+
+_Route16AfterBattleText5::
+ text "I like my #MON"
+ line "ferocious! They"
+ cont "tear up enemies!"
+ done
+
+_Route16BattleText6::
+ text "Sure, I'll go!"
+ done
+
+_Route16EndBattleText6::
+ text "Don't make"
+ line "me mad!"
+ prompt
+
+_Route16AfterBattleText6::
+ text "I like harassing"
+ line "people with my"
+ cont "vicious #MON!"
+ done
+
+_Route16Text7::
+ text "A sleeping #MON"
+ line "blocks the way!"
+ done
+
+_Route16Text10::
+ text "SNORLAX woke up!"
+
+ para "It attacked in a"
+ line "grumpy rage!"
+ done
+
+_Route16Text11::
+ text "With a big yawn,"
+ line "SNORLAX returned"
+ cont "to the mountains!"
+ done
+
+_Route16Text8::
+ text "Enjoy the slope!"
+ line "CYCLING ROAD"
+ done
+
+_Route16Text9::
+ text "ROUTE 16"
+ line "CELADON CITY -"
+ cont "FUCHSIA CITY"
+ done
diff --git a/en/text/maps/route_16_gate.asm b/en/text/maps/route_16_gate.asm
new file mode 100644
index 00000000..f548977f
--- /dev/null
+++ b/en/text/maps/route_16_gate.asm
@@ -0,0 +1,22 @@
+_Route16GateText_49777::
+ text "No pedestrians"
+ line "are allowed on"
+ cont "CYCLING ROAD!"
+ done
+
+_Route16GateText_4977c::
+ text "CYCLING ROAD is a"
+ line "downhill course"
+ cont "by the sea. It's"
+ cont "a great ride."
+ done
+
+_Route16GateText_49781::
+ text "Excuse me! Wait"
+ line "up please!"
+ done
+
+_Route16GateText2::
+ text "How'd you get in?"
+ line "Good effort!"
+ done
diff --git a/en/text/maps/route_16_gate_upstairs.asm b/en/text/maps/route_16_gate_upstairs.asm
new file mode 100644
index 00000000..d76b70ca
--- /dev/null
+++ b/en/text/maps/route_16_gate_upstairs.asm
@@ -0,0 +1,26 @@
+_Route16GateUpstairsText_49820::
+ text "I'm going for a"
+ line "ride with my girl"
+ cont "friend!"
+ done
+
+_Route16GateUpstairsText_4982f::
+ text "We're going"
+ line "riding together!"
+ done
+
+_Route16GateUpstairsText_4983b::
+ text "Looked into the"
+ line "binoculars."
+
+ para "It's CELADON DEPT."
+ line "STORE!"
+ done
+
+_Route16GateUpstairsText_49847::
+ text "Looked into the"
+ line "binoculars."
+
+ para "There's a long"
+ line "path over water!"
+ done
diff --git a/en/text/maps/route_16_house.asm b/en/text/maps/route_16_house.asm
new file mode 100644
index 00000000..77efde87
--- /dev/null
+++ b/en/text/maps/route_16_house.asm
@@ -0,0 +1,31 @@
+_Route16HouseText3::
+ text "Oh, you found my"
+ line "secret retreat!"
+
+ para "Please don't tell"
+ line "anyone I'm here."
+ cont "I'll make it up"
+ cont "to you with this!"
+ prompt
+
+_ReceivedHM02Text::
+ text "<PLAYER> received"
+ line "HM02!@@"
+
+_HM02ExplanationText::
+ text "HM02 is FLY."
+ line "It will take you"
+ cont "back to any town."
+
+ para "Put it to good"
+ line "use!"
+ done
+
+_HM02NoRoomText::
+ text "You don't have any"
+ line "room for this."
+ done
+
+_Route16HouseText_1e652::
+ text "FEAROW: Kyueen!"
+ done
diff --git a/en/text/maps/route_17.asm b/en/text/maps/route_17.asm
new file mode 100644
index 00000000..a0affd90
--- /dev/null
+++ b/en/text/maps/route_17.asm
@@ -0,0 +1,195 @@
+_Route17BattleText1::
+ text "There's no money"
+ line "in fighting kids!"
+ done
+
+_Route17EndBattleText1::
+ text "Burned"
+ line "out!"
+ prompt
+
+_Route17AfterBattleText1::
+ text "Good stuff is"
+ line "lying around on"
+ cont "CYCLING ROAD!"
+ done
+
+_Route17BattleText2::
+ text "What do you want,"
+ line "kiddo?"
+ done
+
+_Route17EndBattleText2::
+ text "Whoo!"
+ prompt
+
+_Route17AfterBattleText2::
+ text "I could belly-"
+ line "bump you outta"
+ cont "here!"
+ done
+
+_Route17BattleText3::
+ text "You heading to"
+ line "FUCHSIA?"
+ done
+
+_Route17EndBattleText3::
+ text "Crash and"
+ line "burn!"
+ prompt
+
+_Route17AfterBattleText3::
+ text "I love racing"
+ line "downhill!"
+ done
+
+_Route17BattleText4::
+ text "We're BIKERs!"
+ line "Highway stars!"
+ done
+
+_Route17EndBattleText4::
+ text "Smoked!"
+ prompt
+
+_Route17AfterBattleText4::
+ text "Are you looking"
+ line "for adventure?"
+ done
+
+_Route17BattleText5::
+ text "Let VOLTORB"
+ line "electrify you!"
+ done
+
+_Route17EndBattleText5::
+ text "Grounded"
+ line "out!"
+ prompt
+
+_Route17AfterBattleText5::
+ text "I got my VOLTORB"
+ line "at the abandoned"
+ cont "POWER PLANT."
+ done
+
+_Route17BattleText6::
+ text "My #MON won't"
+ line "evolve! Why?"
+ done
+
+_Route17EndBattleText6::
+ text "Why,"
+ line "you!"
+ prompt
+
+_Route17AfterBattleText6::
+ text "Maybe some #MON"
+ line "need element"
+ cont "STONEs to evolve."
+ done
+
+_Route17BattleText7::
+ text "I need a little"
+ line "exercise!"
+ done
+
+_Route17EndBattleText7::
+ text "Whew!"
+ line "Good workout!"
+ prompt
+
+_Route17AfterBattleText7::
+ text "I'm sure I lost"
+ line "weight there!"
+ done
+
+_Route17BattleText8::
+ text "Be a rebel!"
+ done
+
+_Route17EndBattleText8::
+ text "Aaaargh!"
+ prompt
+
+_Route17AfterBattleText8::
+ text "Be ready to fight"
+ line "for your beliefs!"
+ done
+
+_Route17BattleText9::
+ text "Nice BIKE!"
+ line "How's it handle?"
+ done
+
+_Route17EndBattleText9::
+ text "Shoot!"
+ prompt
+
+_Route17AfterBattleText9::
+ text "The slope makes"
+ line "it hard to steer!"
+ done
+
+_Route17BattleText10::
+ text "Get lost kid!"
+ line "I'm bushed!"
+ done
+
+_Route17EndBattleText10::
+ text "Are you"
+ line "satisfied?"
+ prompt
+
+_Route17AfterBattleText10::
+ text "I need to catch"
+ line "a few Zs!"
+ done
+
+_Route17Text11::
+ text "It's a notice!"
+
+ para "Watch out for"
+ line "discarded items!"
+ done
+
+_Route17Text12::
+ text "TRAINER TIPS"
+
+ para "All #MON are"
+ line "unique."
+
+ para "Even #MON of"
+ line "the same type and"
+ cont "level grow at"
+ cont "different rates."
+ done
+
+_Route17Text13::
+ text "TRAINER TIPS"
+
+ para "Press the A or B"
+ line "Button to stay in"
+ cont "place while on a"
+ cont "slope."
+ done
+
+_Route17Text14::
+ text "ROUTE 17"
+ line "CELADON CITY -"
+ cont "FUCHSIA CITY"
+ done
+
+_Route17Text15::
+ text "It's a notice!"
+
+ para "Don't throw the"
+ line "game, throw #"
+ cont "BALLs instead!"
+ done
+
+_Route17Text16::
+ text "CYCLING ROAD"
+ line "Slope ends here!"
+ done
diff --git a/en/text/maps/route_18.asm b/en/text/maps/route_18.asm
new file mode 100644
index 00000000..d09caf82
--- /dev/null
+++ b/en/text/maps/route_18.asm
@@ -0,0 +1,58 @@
+_Route18BattleText1::
+ text "I always check"
+ line "every grassy area"
+ cont "for new #MON."
+ done
+
+_Route18EndBattleText1::
+ text "Tch!"
+ prompt
+
+_Route18AfterBattleText1::
+ text "I wish I had a"
+ line "BIKE!"
+ done
+
+_Route18BattleText2::
+ text "Kurukkoo!"
+ line "How do you like"
+ cont "my bird call?"
+ done
+
+_Route18EndBattleText2::
+ text "I"
+ line "had to bug you!"
+ prompt
+
+_Route18AfterBattleText2::
+ text "I also collect sea"
+ line "#MON on"
+ cont "weekends!"
+ done
+
+_Route18BattleText3::
+ text "This is my turf!"
+ line "Get out of here!"
+ done
+
+_Route18EndBattleText3::
+ text "Darn!"
+ prompt
+
+_Route18AfterBattleText3::
+ text "This is my fave"
+ line "#MON hunting"
+ cont "area!"
+ done
+
+_Route18Text4::
+ text "ROUTE 18"
+ line "CELADON CITY -"
+ cont "FUCHSIA CITY"
+ done
+
+_Route18Text5::
+ text "CYCLING ROAD"
+ line "No pedestrians"
+ cont "permitted!"
+ done
diff --git a/en/text/maps/route_18_gate.asm b/en/text/maps/route_18_gate.asm
new file mode 100644
index 00000000..f2f51039
--- /dev/null
+++ b/en/text/maps/route_18_gate.asm
@@ -0,0 +1,14 @@
+_Route18GateText_49928::
+ text "You need a BICYCLE"
+ line "for CYCLING ROAD!"
+ done
+
+_Route18GateText_4992d::
+ text "CYCLING ROAD is"
+ line "all uphill from"
+ cont "here."
+ done
+
+_Route18GateText_49932::
+ text "Excuse me!"
+ done
diff --git a/en/text/maps/route_18_gate_upstairs.asm b/en/text/maps/route_18_gate_upstairs.asm
new file mode 100644
index 00000000..0fd2de09
--- /dev/null
+++ b/en/text/maps/route_18_gate_upstairs.asm
@@ -0,0 +1,15 @@
+_Route18GateUpstairsText_49993::
+ text "Looked into the"
+ line "binoculars."
+
+ para "PALLET TOWN is in"
+ line "the west!"
+ done
+
+_Route18GateUpstairsText_4999f::
+ text "Looked into the"
+ line "binoculars."
+
+ para "There are people"
+ line "swimming!"
+ done
diff --git a/en/text/maps/route_19.asm b/en/text/maps/route_19.asm
new file mode 100644
index 00000000..244e31d0
--- /dev/null
+++ b/en/text/maps/route_19.asm
@@ -0,0 +1,157 @@
+_Route19BattleText1::
+ text "Have to warm up"
+ line "before my swim!"
+ done
+
+_Route19EndBattleText1::
+ text "All"
+ line "warmed up!"
+ prompt
+
+_Route19AfterBattleText1::
+ text "Thanks, kid! I'm"
+ line "ready for a swim!"
+ done
+
+_Route19BattleText2::
+ text "Wait! You'll have"
+ line "a heart attack!"
+ done
+
+_Route19EndBattleText2::
+ text "Ooh!"
+ line "That's chilly!"
+ prompt
+
+_Route19AfterBattleText2::
+ text "Watch out for"
+ line "TENTACOOL!"
+ done
+
+_Route19BattleText3::
+ text "I love swimming!"
+ line "What about you?"
+ done
+
+_Route19EndBattleText3::
+ text "Belly"
+ line "flop!"
+ prompt
+
+_Route19AfterBattleText3::
+ text "I can beat #MON"
+ line "at swimming!"
+ done
+
+_Route19BattleText4::
+ text "What's beyond the"
+ line "horizon?"
+ done
+
+_Route19EndBattleText4::
+ text "Glub!"
+ prompt
+
+_Route19AfterBattleText4::
+ text "I see a couple of"
+ line "islands!"
+ done
+
+_Route19BattleText5::
+ text "I tried diving"
+ line "for #MON, but"
+ cont "it was a no go!"
+ done
+
+_Route19EndBattleText5::
+ text "Help!"
+ prompt
+
+_Route19AfterBattleText5::
+ text "You have to fish"
+ line "for sea #MON!"
+ done
+
+_Route19BattleText6::
+ text "I look at the"
+ line "sea to forget!"
+ done
+
+_Route19EndBattleText6::
+ text "Ooh!"
+ line "Traumatic!"
+ prompt
+
+_Route19AfterBattleText6::
+ text "I'm looking at the"
+ line "sea to forget!"
+ done
+
+_Route19BattleText7::
+ text "Oh, I just love"
+ line "your ride! Can I"
+ cont "have it if I win?"
+ done
+
+_Route19EndBattleText7::
+ text "Oh!"
+ line "I lost!"
+ prompt
+
+_Route19AfterBattleText7::
+ text "It's still a long"
+ line "way to go to"
+ cont "SEAFOAM ISLANDS."
+ done
+
+_Route19BattleText8::
+ text "Swimming's great!"
+ line "Sunburns aren't!"
+ done
+
+_Route19EndBattleText8::
+ text "Shocker!"
+ prompt
+
+_Route19AfterBattleText8::
+ text "My boy friend"
+ line "wanted to swim to"
+ cont "SEAFOAM ISLANDS."
+ done
+
+_Route19BattleText9::
+ text "These waters are"
+ line "treacherous!"
+ done
+
+_Route19EndBattleText9::
+ text "Ooh!"
+ line "Dangerous!"
+ prompt
+
+_Route19AfterBattleText9::
+ text "I got a cramp!"
+ line "Glub, glub..."
+ done
+
+_Route19BattleText10::
+ text "I swam here, but"
+ line "I'm tired."
+ done
+
+_Route19EndBattleText10::
+ text "I'm"
+ line "exhausted..."
+ prompt
+
+_Route19AfterBattleText10::
+ text "LAPRAS is so big,"
+ line "it must keep you"
+ cont "dry on water."
+ done
+
+_Route19Text11::
+ text "SEA ROUTE 19"
+ line "FUCHSIA CITY -"
+ cont "SEAFOAM ISLANDS"
+ done
diff --git a/en/text/maps/route_2.asm b/en/text/maps/route_2.asm
new file mode 100644
index 00000000..dd7becc0
--- /dev/null
+++ b/en/text/maps/route_2.asm
@@ -0,0 +1,9 @@
+_Route2Text3::
+ text "ROUTE 2"
+ line "VIRIDIAN CITY -"
+ cont "PEWTER CITY"
+ done
+
+_Route2Text4::
+ text "DIGLETT's CAVE"
+ done
diff --git a/en/text/maps/route_20.asm b/en/text/maps/route_20.asm
new file mode 100644
index 00000000..1ccf0b6c
--- /dev/null
+++ b/en/text/maps/route_20.asm
@@ -0,0 +1,156 @@
+_Route20BattleText1::
+ text "The water is"
+ line "shallow here."
+ done
+
+_Route20EndBattleText1::
+ text "Splash!"
+ prompt
+
+_Route20AfterBattleText1::
+ text "I wish I could"
+ line "ride my #MON."
+ done
+
+_Route20BattleText2::
+ text "SEAFOAM is a"
+ line "quiet getaway!"
+ done
+
+_Route20EndBattleText2::
+ text "Quit it!"
+ prompt
+
+_Route20AfterBattleText2::
+ text "There's a huge"
+ line "cavern underneath"
+ cont "this island."
+ done
+
+_Route20BattleText3::
+ text "I love floating"
+ line "with the fishes!"
+ done
+
+_Route20EndBattleText3::
+ text "Yowch!"
+ prompt
+
+_Route20AfterBattleText3::
+ text "Want to float"
+ line "with me?"
+ done
+
+_Route20BattleText4::
+ text "Are you on"
+ line "vacation too?"
+ done
+
+_Route20EndBattleText4::
+ text "No"
+ line "mercy at all!"
+ prompt
+
+_Route20AfterBattleText4::
+ text "SEAFOAM used to"
+ line "be one island!"
+ done
+
+_Route20BattleText5::
+ text "Check out my buff"
+ line "physique!"
+ done
+
+_Route20EndBattleText5::
+ text "Wimpy!"
+ prompt
+
+_Route20AfterBattleText5::
+ text "I should've been"
+ line "buffing up my"
+ cont "#MON, not me!"
+ done
+
+_Route20BattleText6::
+ text "Why are you"
+ line "riding a #MON?"
+ cont "Can't you swim?"
+ done
+
+_Route20EndBattleText6::
+ text "Ouch!"
+ line "Torpedoed!"
+ prompt
+
+_Route20AfterBattleText6::
+ text "Riding a #MON"
+ line "sure looks fun!"
+ done
+
+_Route20BattleText7::
+ text "I rode my bird"
+ line "#MON here!"
+ done
+
+_Route20EndBattleText7::
+ text "Oh"
+ line "no!"
+ prompt
+
+_Route20AfterBattleText7::
+ text "My birds can't"
+ line "FLY me back!"
+ done
+
+_Route20BattleText8::
+ text "My boy friend gave"
+ line "me big pearls!"
+ done
+
+_Route20EndBattleText8::
+ text "Don't"
+ line "touch my pearls!"
+ prompt
+
+_Route20AfterBattleText8::
+ text "Will my pearls"
+ line "grow bigger"
+ cont "inside CLOYSTER?"
+ done
+
+_Route20BattleText9::
+ text "I swam here from"
+ line "CINNABAR ISLAND!"
+ done
+
+_Route20EndBattleText9::
+ text "I'm"
+ line "so disappointed!"
+ prompt
+
+_Route20AfterBattleText9::
+ text "#MON have"
+ line "taken over an"
+ cont "abandoned mansion"
+ cont "on CINNABAR!"
+ done
+
+_Route20BattleText10::
+ text "CINNABAR, in the"
+ line "west, has a LAB"
+ cont "for #MON."
+ done
+
+_Route20EndBattleText10::
+ text "Wait!"
+ prompt
+
+_Route20AfterBattleText10::
+ text "CINNABAR is a "
+ line "volcanic island!"
+ done
+
+_Route20Text12::
+_Route20Text11::
+ text "SEAFOAM ISLANDS"
+ done
diff --git a/en/text/maps/route_21.asm b/en/text/maps/route_21.asm
new file mode 100644
index 00000000..3451953f
--- /dev/null
+++ b/en/text/maps/route_21.asm
@@ -0,0 +1,137 @@
+_Route21BattleText1::
+ text "You want to know"
+ line "if the fish are"
+ cont "biting?"
+ done
+
+_Route21EndBattleText1::
+ text "Dang!"
+ prompt
+
+_Route21AfterBattleText1::
+ text "I can't catch"
+ line "anything good!"
+ done
+
+_Route21BattleText2::
+ text "I got a big haul!"
+ line "Wanna go for it?"
+ done
+
+_Route21EndBattleText2::
+ text "Darn"
+ line "MAGIKARP!"
+ prompt
+
+_Route21AfterBattleText2::
+ text "I seem to only"
+ line "catch MAGIKARP!"
+ done
+
+_Route21BattleText3::
+ text "The sea cleanses"
+ line "my body and soul!"
+ done
+
+_Route21EndBattleText3::
+ text "Ayah!"
+ prompt
+
+_Route21AfterBattleText3::
+ text "I like the"
+ line "mountains too!"
+ done
+
+_Route21BattleText4::
+ text "What's wrong with"
+ line "me swimming?"
+ done
+
+_Route21EndBattleText4::
+ text "Cheap"
+ line "shot!"
+ prompt
+
+_Route21AfterBattleText4::
+ text "I look like what?"
+ line "A studded inner"
+ cont "tube? Get lost!"
+ done
+
+_Route21BattleText5::
+ text "I caught all my"
+ line "#MON at sea!"
+ done
+
+_Route21EndBattleText5::
+ text "Diver!!"
+ line "Down!!"
+ prompt
+
+_Route21AfterBattleText5::
+ text "Where'd you catch"
+ line "your #MON?"
+ done
+
+_Route21BattleText6::
+ text "Right now, I'm in"
+ line "a triathlon meet!"
+ done
+
+_Route21EndBattleText6::
+ text "Pant..."
+ line "pant...pant..."
+ prompt
+
+_Route21AfterBattleText6::
+ text "I'm beat!"
+ line "But, I still have"
+ cont "the bike race and"
+ cont "marathon left!"
+ done
+
+_Route21BattleText7::
+ text "Ahh! Feel the sun"
+ line "and the wind!"
+ done
+
+_Route21EndBattleText7::
+ text "Yow!"
+ line "I lost!"
+ prompt
+
+_Route21AfterBattleText7::
+ text "I'm sunburnt to a"
+ line "crisp!"
+ done
+
+_Route21BattleText8::
+ text "Hey, don't scare"
+ line "away the fish!"
+ done
+
+_Route21EndBattleText8::
+ text "Sorry!"
+ line "I didn't mean it!"
+ prompt
+
+_Route21AfterBattleText8::
+ text "I was just angry"
+ line "that I couldn't"
+ cont "catch anything."
+ done
+
+_Route21BattleText9::
+ text "Keep me company"
+ line "'til I get a hit!"
+ done
+
+_Route21EndBattleText9::
+ text "That"
+ line "burned some time."
+ prompt
+
+_Route21AfterBattleText9::
+ text "Oh wait! I got a"
+ line "bite! Yeah!"
+ done
diff --git a/en/text/maps/route_22.asm b/en/text/maps/route_22.asm
new file mode 100644
index 00000000..3a1d28f0
--- /dev/null
+++ b/en/text/maps/route_22.asm
@@ -0,0 +1,104 @@
+_Route22RivalBeforeBattleText1::
+ text "<RIVAL>: Hey!"
+ line "<PLAYER>!"
+
+ para "You're going to"
+ line "#MON LEAGUE?"
+
+ para "Forget it! You"
+ line "probably don't"
+ cont "have any BADGEs!"
+
+ para "The guard won't"
+ line "let you through!"
+
+ para "By the way, did"
+ line "your #MON"
+ cont "get any stronger?"
+ done
+
+_Route22RivalAfterBattleText1::
+ text "I heard #MON"
+ line "LEAGUE has many"
+ cont "tough trainers!"
+
+ para "I have to figure"
+ line "out how to get"
+ cont "past them!"
+
+ para "You should quit"
+ line "dawdling and get"
+ cont "a move on!"
+ done
+
+_Route22RivalDefeatedText1::
+ text "Awww!"
+ line "You just lucked"
+ cont "out!"
+ prompt
+
+_Route22Text_511bc::
+ text "<RIVAL>: What?"
+ line "Why do I have 2"
+ cont "#MON?"
+
+ para "You should catch"
+ cont "some more too!"
+ prompt
+
+_Route22RivalBeforeBattleText2::
+ text "<RIVAL>: What?"
+ line "<PLAYER>! What a"
+ cont "surprise to see"
+ cont "you here!"
+
+ para "So you're going to"
+ line "#MON LEAGUE?"
+
+ para "You collected all"
+ line "the BADGEs too?"
+ cont "That's cool!"
+
+ para "Then I'll whip you"
+ line "<PLAYER> as a"
+ cont "warm up for"
+ cont "#MON LEAGUE!"
+
+ para "Come on!"
+ done
+
+_Route22RivalAfterBattleText2::
+ text "That loosened me"
+ line "up! I'm ready for"
+ cont "#MON LEAGUE!"
+
+ para "<PLAYER>, you need"
+ line "more practice!"
+
+ para "But hey, you know"
+ line "that! I'm out of"
+ cont "here. Smell ya!"
+ done
+
+_Route22RivalDefeatedText2::
+ text "What!?"
+
+ para "I was just"
+ line "careless!"
+ prompt
+
+_Route22Text_511d0::
+ text "<RIVAL>: Hahaha!"
+ line "<PLAYER>! That's"
+ cont "your best? You're"
+ cont "nowhere near as"
+ cont "good as me, pal!"
+
+ para "Go train some"
+ line "more! You loser!"
+ prompt
+
+_Route22FrontGateText::
+ text "#MON LEAGUE"
+ line "Front Gate"
+ done
diff --git a/en/text/maps/route_23.asm b/en/text/maps/route_23.asm
new file mode 100644
index 00000000..2ecb020e
--- /dev/null
+++ b/en/text/maps/route_23.asm
@@ -0,0 +1,38 @@
+_VictoryRoadGuardText1::
+ text "You can pass here"
+ line "only if you have"
+ cont "the @"
+ TX_RAM wcd6d
+ text "!"
+
+ para "You don't have the"
+ line "@"
+ TX_RAM wcd6d
+ text " yet!"
+
+ para "You have to have"
+ line "it to get to"
+ cont "#MON LEAGUE!@@"
+
+_VictoryRoadGuardText2::
+ text "You can pass here"
+ line "only if you have"
+ cont "the @"
+ TX_RAM wcd6d
+ text "!"
+
+ para "Oh! That is the"
+ line "@"
+ TX_RAM wcd6d
+ text "!@@"
+
+_VictoryRoadGuardText_513a3::
+ db $0
+ para "OK then! Please,"
+ line "go right ahead!"
+ done
+
+_Route23Text8::
+ text "VICTORY ROAD GATE"
+ line "- #MON LEAGUE"
+ done
diff --git a/en/text/maps/route_24_1.asm b/en/text/maps/route_24_1.asm
new file mode 100644
index 00000000..ae861eda
--- /dev/null
+++ b/en/text/maps/route_24_1.asm
@@ -0,0 +1,64 @@
+_Route24Text_51510::
+ text "Congratulations!"
+ line "You beat our 5"
+ cont "contest trainers!@@"
+
+_Route24Text_51515::
+ db $0
+ para "You just earned a"
+ line "fabulous prize!"
+ prompt
+
+_Route24Text_5151a::
+ text "<PLAYER> received"
+ line "a @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_Route24Text_51521::
+ text "You don't have"
+ line "any room!"
+ done
+
+_Route24Text_51526::
+ text "By the way, would"
+ line "you like to join"
+ cont "TEAM ROCKET?"
+
+ para "We're a group"
+ line "dedicated to evil"
+ cont "using #MON!"
+
+ para "Want to join?"
+
+ para "Are you sure?"
+
+ para "Come on, join us!"
+
+ para "I'm telling you"
+ line "to join!"
+
+ para "OK, you need"
+ line "convincing!"
+
+ para "I'll make you an"
+ line "offer you can't"
+ cont "refuse!"
+ done
+
+_Route24Text_5152b::
+ text "Arrgh!"
+ line "You are good!"
+ prompt
+
+_Route24Text_51530::
+ text "With your ability,"
+ line "you could become"
+ cont "a top leader in"
+ cont "TEAM ROCKET!"
+ done
+
+_Route24BattleText1::
+ text "I saw your feat"
+ line "from the grass!"
+ done
diff --git a/en/text/maps/route_24_2.asm b/en/text/maps/route_24_2.asm
new file mode 100644
index 00000000..325dea13
--- /dev/null
+++ b/en/text/maps/route_24_2.asm
@@ -0,0 +1,90 @@
+_Route24EndBattleText1::
+ text "I"
+ line "thought not!"
+ prompt
+
+_Route24AfterBattleText1::
+ text "I hid because the"
+ line "people on the"
+ cont "bridge scared me!"
+ done
+
+_Route24BattleText2::
+ text "OK! I'm No. 5!"
+ line "I'll stomp you!"
+ done
+
+_Route24EndBattleText2::
+ text "Whoa!"
+ line "Too much!"
+ prompt
+
+_Route24AfterBattleText2::
+ text "I did my best, I"
+ line "have no regrets!"
+ done
+
+_Route24BattleText3::
+ text "I'm No. 4!"
+ line "Getting tired?"
+ done
+
+_Route24EndBattleText3::
+ text "I lost"
+ line "too!"
+ prompt
+
+_Route24AfterBattleText3::
+ text "I did my best, so"
+ line "I've no regrets!"
+ done
+
+_Route24BattleText4::
+ text "Here's No. 3!"
+ line "I won't be easy!"
+ done
+
+_Route24EndBattleText4::
+ text "Ow!"
+ line "Stomped flat!"
+ prompt
+
+_Route24AfterBattleText4::
+ text "I did my best, I"
+ line "have no regrets!"
+ done
+
+_Route24BattleText5::
+ text "I'm second!"
+ line "Now it's serious!"
+ done
+
+_Route24EndBattleText5::
+ text "How could I"
+ line "lose?"
+ prompt
+
+_Route24AfterBattleText5::
+ text "I did my best, I"
+ line "have no regrets!"
+ done
+
+_Route24BattleText6::
+ text "This is NUGGET"
+ line "BRIDGE! Beat us 5"
+ cont "trainers and win"
+ cont "a fabulous prize!"
+
+ para "Think you got"
+ line "what it takes?"
+ done
+
+_Route24EndBattleText6::
+ text "Whoo!"
+ line "Good stuff!"
+ prompt
+
+_Route24AfterBattleText6::
+ text "I did my best, I"
+ line "have no regrets!"
+ done
diff --git a/en/text/maps/route_25.asm b/en/text/maps/route_25.asm
new file mode 100644
index 00000000..325ab348
--- /dev/null
+++ b/en/text/maps/route_25.asm
@@ -0,0 +1,156 @@
+_Route25BattleText1::
+ text "Local trainers"
+ line "come here to"
+ cont "practice!"
+ done
+
+_Route25EndBattleText1::
+ text "You're"
+ line "decent."
+ prompt
+
+_Route25AfterBattleText1::
+ text "All #MON have"
+ line "weaknesses. It's"
+ cont "best to raise"
+ cont "different kinds."
+ done
+
+_Route25BattleText2::
+ text "Dad took me to a"
+ line "great party on"
+ cont "S.S.ANNE at"
+ cont "VERMILION CITY!"
+ done
+
+_Route25EndBattleText2::
+ text "I'm"
+ line "not mad!"
+ prompt
+
+_Route25AfterBattleText2::
+ text "On S.S.ANNE, I"
+ line "saw trainers from"
+ cont "around the world."
+ done
+
+_Route25BattleText3::
+ text "I'm a cool guy."
+ line "I've got a girl"
+ cont "friend!"
+ done
+
+_Route25EndBattleText3::
+ text "Aww,"
+ line "darn..."
+ prompt
+
+_Route25AfterBattleText3::
+ text "Oh well. My girl"
+ line "will cheer me up."
+ done
+
+_Route25BattleText4::
+ text "Hi! My boy"
+ line "friend is cool!"
+ done
+
+_Route25EndBattleText4::
+ text "I was in"
+ line "bad condition!"
+ prompt
+
+_Route25AfterBattleText4::
+ text "I wish my guy was"
+ line "as good as you!"
+ done
+
+_Route25BattleText5::
+ text "I knew I had to"
+ line "fight you!"
+ done
+
+_Route25EndBattleText5::
+ text "I knew"
+ line "I'd lose too!"
+ prompt
+
+_Route25AfterBattleText5::
+ text "If your #MON"
+ line "gets confused or"
+ cont "falls asleep,"
+ cont "switch it!"
+ done
+
+_Route25BattleText6::
+ text "My friend has a"
+ line "cute #MON."
+ cont "I'm so jealous!"
+ done
+
+_Route25EndBattleText6::
+ text "I'm"
+ line "not so jealous!"
+ prompt
+
+_Route25AfterBattleText6::
+ text "You came from MT."
+ line "MOON? May I have"
+ cont "a CLEFAIRY?"
+ done
+
+_Route25BattleText7::
+ text "I just got down"
+ line "from MT.MOON,"
+ cont "but I'm ready!"
+ done
+
+_Route25EndBattleText7::
+ text "You"
+ line "worked hard!"
+ prompt
+
+_Route25AfterBattleText7::
+ text "Drat!"
+ line "A ZUBAT bit me"
+ cont "back in there."
+ done
+
+_Route25BattleText8::
+ text "I'm off to see a"
+ line "#MON collector"
+ cont "at the cape!"
+ done
+
+_Route25EndBattleText8::
+ text "You"
+ line "got me."
+ prompt
+
+_Route25AfterBattleText8::
+ text "The collector has"
+ line "many rare kinds"
+ cont "of #MON."
+ done
+
+_Route25BattleText9::
+ text "You're going to"
+ line "see BILL? First,"
+ cont "let's fight!"
+ done
+
+_Route25EndBattleText9::
+ text "You're"
+ line "something."
+ prompt
+
+_Route25AfterBattleText9::
+ text "The trail below"
+ line "is a shortcut to"
+ cont "CERULEAN CITY."
+ done
+
+_Route25Text11::
+ text "SEA COTTAGE"
+ line "BILL lives here!"
+ done
diff --git a/en/text/maps/route_2_gate.asm b/en/text/maps/route_2_gate.asm
new file mode 100644
index 00000000..566830f8
--- /dev/null
+++ b/en/text/maps/route_2_gate.asm
@@ -0,0 +1,12 @@
+_Route2GateText_5d616::
+ text "The HM FLASH"
+ line "lights even the"
+ cont "darkest dungeons."
+ done
+
+_Route2GateText2::
+ text "Once a #MON"
+ line "learns FLASH, you"
+ cont "can get through"
+ cont "ROCK TUNNEL."
+ done
diff --git a/en/text/maps/route_2_house.asm b/en/text/maps/route_2_house.asm
new file mode 100644
index 00000000..46fc1062
--- /dev/null
+++ b/en/text/maps/route_2_house.asm
@@ -0,0 +1,6 @@
+_Route2HouseText1::
+ text "A fainted #MON"
+ line "can't fight. But, "
+ cont "it can still use "
+ cont "moves like CUT!"
+ done
diff --git a/en/text/maps/route_3.asm b/en/text/maps/route_3.asm
new file mode 100644
index 00000000..966a0786
--- /dev/null
+++ b/en/text/maps/route_3.asm
@@ -0,0 +1,145 @@
+_Route3Text1::
+ text "Whew... I better"
+ line "take a rest..."
+ cont "Groan..."
+
+ para "That tunnel from"
+ line "CERULEAN takes a"
+ cont "lot out of you!"
+ done
+
+_Route3BattleText1::
+ text "Hey! I met you in"
+ line "VIRIDIAN FOREST!"
+ done
+
+_Route3EndBattleText1::
+ text "You"
+ line "beat me again!"
+ prompt
+
+_Route3AfterBattleText1::
+ text "There are other"
+ line "kinds of #MON"
+ cont "than those found"
+ cont "in the forest!"
+ done
+
+_Route3BattleText2::
+ text "Hi! I like shorts!"
+ line "They're comfy and"
+ cont "easy to wear!"
+ done
+
+_Route3EndBattleText2::
+ text "I don't"
+ line "believe it!"
+ prompt
+
+_Route3AfterBattleText2::
+ text "Are you storing"
+ line "your #MON on"
+ cont "PC? Each BOX can"
+ cont "hold 20 #MON!"
+ done
+
+_Route3BattleText3::
+ text "You looked at me,"
+ line "didn't you?"
+ done
+
+_Route3EndBattleText3::
+ text "You're"
+ line "mean!"
+ prompt
+
+_Route3AfterBattleText3::
+ text "Quit staring if"
+ line "you don't want to"
+ cont "fight!"
+ done
+
+_Route3BattleText4::
+ text "Are you a trainer?"
+ line "Let's fight!"
+ done
+
+_Route3EndBattleText4::
+ text "If I"
+ line "had new #MON I"
+ cont "would've won!"
+ prompt
+
+_Route3AfterBattleText4::
+ text "If a #MON BOX"
+ line "on the PC gets"
+ cont "full, just switch"
+ cont "to another BOX!"
+ done
+
+_Route3BattleText5::
+ text "That look you"
+ line "gave me, it's so"
+ cont "intriguing!"
+ done
+
+_Route3EndBattleText5::
+ text "Be nice!"
+ prompt
+
+_Route3AfterBattleText5::
+ text "Avoid fights by"
+ line "not letting"
+ cont "people see you!"
+ done
+
+_Route3BattleText6::
+ text "Hey! You're not"
+ line "wearing shorts!"
+ done
+
+_Route3EndBattleText6::
+ text "Lost!"
+ line "Lost! Lost!"
+ prompt
+
+_Route3AfterBattleText6::
+ text "I always wear"
+ line "shorts, even in"
+ cont "winter!"
+ done
+
+_Route3BattleText7::
+ text "You can fight my"
+ line "new #MON!"
+ done
+
+_Route3EndBattleText7::
+ text "Done"
+ line "like dinner!"
+ prompt
+
+_Route3AfterBattleText7::
+ text "Trained #MON"
+ line "are stronger than"
+ cont "the wild ones!"
+ done
+
+_Route3BattleText8::
+ text "Eek! Did you"
+ line "touch me?"
+ done
+
+_Route3EndBattleText8::
+ text "That's it?"
+ prompt
+
+_Route3AfterBattleText8::
+ text "ROUTE 4 is at the"
+ line "foot of MT.MOON."
+ done
+
+_Route3Text10::
+ text "ROUTE 3"
+ line "MT.MOON AHEAD"
+ done
diff --git a/en/text/maps/route_4.asm b/en/text/maps/route_4.asm
new file mode 100644
index 00000000..0a36f4cd
--- /dev/null
+++ b/en/text/maps/route_4.asm
@@ -0,0 +1,35 @@
+_Route4Text1::
+ text "Ouch! I tripped"
+ line "over a rocky"
+ cont "#MON, GEODUDE!"
+ done
+
+_Route4BattleText1::
+ text "I came to get my"
+ line "mushroom #MON!"
+ done
+
+_Route4EndBattleText1::
+ text "Oh! My cute"
+ line "mushroom #MON!"
+ prompt
+
+_Route4AfterBattleText1::
+ text "There might not"
+ line "be any more"
+ cont "mushrooms here."
+
+ para "I think I got"
+ line "them all."
+ done
+
+_Route4Text5::
+ text "MT.MOON"
+ line "Tunnel Entrance"
+ done
+
+_Route4Text6::
+ text "ROUTE 4"
+ line "MT.MOON -"
+ cont "CERULEAN CITY"
+ done
diff --git a/en/text/maps/route_5.asm b/en/text/maps/route_5.asm
new file mode 100644
index 00000000..54ff0f84
--- /dev/null
+++ b/en/text/maps/route_5.asm
@@ -0,0 +1,5 @@
+_Route5Text1::
+ text "UNDERGROUND PATH"
+ line "CERULEAN CITY -"
+ cont "VERMILION CITY"
+ done
diff --git a/en/text/maps/route_6.asm b/en/text/maps/route_6.asm
new file mode 100644
index 00000000..c48b5d3d
--- /dev/null
+++ b/en/text/maps/route_6.asm
@@ -0,0 +1,97 @@
+_Route6BattleText1::
+ text "Who's there?"
+ line "Quit listening in"
+ cont "on us!"
+ done
+
+_Route6EndBattleText1::
+ text "I"
+ line "just can't win!"
+ prompt
+
+_Route6AfterBattleText1::
+ text "Whisper..."
+ line "whisper..."
+ done
+
+_Route6BattleText2::
+ text "Excuse me! This"
+ line "is a private"
+ cont "conversation!"
+ done
+
+_Route6EndBattleText2::
+ text "Ugh!"
+ line "I hate losing!"
+ prompt
+
+_Route6BattleText3::
+ text "There aren't many"
+ line "bugs out here."
+ done
+
+_Route6EndBattleText3::
+ text "No!"
+ line "You're kidding!"
+ prompt
+
+_Route6AfterBattleText3::
+ text "I like bugs, so"
+ line "I'm going back to"
+ cont "VIRIDIAN FOREST."
+ done
+
+_Route6BattleText4::
+ text "Huh? You want"
+ line "to talk to me?"
+ done
+
+_Route6EndBattleText4::
+ text "I"
+ line "didn't start it!"
+ prompt
+
+_Route6AfterBattleText4::
+ text "I should carry"
+ line "more #MON with"
+ cont "me for safety."
+ done
+
+_Route6BattleText5::
+ text "Me? Well, OK."
+ line "I'll play!"
+ done
+
+_Route6EndBattleText5::
+ text "Just"
+ line "didn't work!"
+ prompt
+
+_Route6AfterBattleText5::
+ text "I want to get"
+ line "stronger! What's"
+ cont "your secret?"
+ done
+
+_Route6BattleText6::
+ text "I've never seen"
+ line "you around!"
+ cont "Are you good?"
+ done
+
+_Route6EndBattleText6::
+ text "You"
+ line "are too good!"
+ prompt
+
+_Route6AfterBattleText6::
+ text "Are my #MON"
+ line "weak? Or, am I"
+ cont "just bad?"
+ done
+
+_Route6Text7::
+ text "UNDERGROUND PATH"
+ line "CERULEAN CITY -"
+ cont "VERMILION CITY"
+ done
diff --git a/en/text/maps/route_7.asm b/en/text/maps/route_7.asm
new file mode 100644
index 00000000..6500be96
--- /dev/null
+++ b/en/text/maps/route_7.asm
@@ -0,0 +1,5 @@
+_Route7Text1::
+ text "UNDERGROUND PATH"
+ line "CELADON CITY -"
+ cont "LAVENDER TOWN"
+ done
diff --git a/en/text/maps/route_8.asm b/en/text/maps/route_8.asm
new file mode 100644
index 00000000..57a9a5f9
--- /dev/null
+++ b/en/text/maps/route_8.asm
@@ -0,0 +1,154 @@
+_Route8BattleText1::
+ text "You look good at"
+ line "#MON, but"
+ cont "how's your chem?"
+ done
+
+_Route8EndBattleText1::
+ text "Ow!"
+ line "Meltdown!"
+ prompt
+
+_Route8AfterBattleText1::
+ text "I am better at"
+ line "school than this!"
+ done
+
+_Route8BattleText2::
+ text "All right! Let's"
+ line "roll the dice!"
+ done
+
+_Route8EndBattleText2::
+ text "Drat!"
+ line "Came up short!"
+ prompt
+
+_Route8AfterBattleText2::
+ text "Lady Luck's not"
+ line "with me today!"
+ done
+
+_Route8BattleText3::
+ text "You need strategy"
+ line "to win at this!"
+ done
+
+_Route8EndBattleText3::
+ text "It's"
+ line "not logical!"
+ prompt
+
+_Route8AfterBattleText3::
+ text "Go with GRIMER"
+ line "first...and..."
+ cont "...and...then..."
+ done
+
+_Route8BattleText4::
+ text "I like NIDORAN, so"
+ line "I collect them!"
+ done
+
+_Route8EndBattleText4::
+ text "Why? Why??"
+ prompt
+
+_Route8AfterBattleText4::
+ text "When #MON grow"
+ line "up they get ugly!"
+ cont "They shouldn't"
+ cont "evolve!"
+ done
+
+_Route8BattleText5::
+ text "School is fun, but"
+ line "so are #MON."
+ done
+
+_Route8EndBattleText5::
+ text "I'll"
+ line "stay with school."
+ prompt
+
+_Route8AfterBattleText5::
+ text "We're stuck here"
+ line "because of the"
+ cont "gates at SAFFRON."
+ done
+
+_Route8BattleText6::
+ text "MEOWTH is so cute,"
+ line "meow, meow, meow!"
+ done
+
+_Route8EndBattleText6::
+ text "Meow!"
+ prompt
+
+_Route8AfterBattleText6::
+ text "I think PIDGEY"
+ line "and RATTATA"
+ cont "are cute too!"
+ done
+
+_Route8BattleText7::
+ text "We must look"
+ line "silly standing"
+ cont "here like this!"
+ done
+
+_Route8EndBattleText7::
+ text "Look what"
+ line "you did!"
+ prompt
+
+_Route8AfterBattleText7::
+ text "SAFFRON's gate"
+ line "keeper won't let"
+ cont "us through."
+ cont "He's so mean!"
+ done
+
+_Route8BattleText8::
+ text "I'm a rambling,"
+ line "gambling dude!"
+ done
+
+_Route8EndBattleText8::
+ text "Missed"
+ line "the big score!"
+ prompt
+
+_Route8AfterBattleText8::
+ text "Gambling and"
+ line "#MON are like"
+ cont "eating peanuts!"
+ cont "Just can't stop!"
+ done
+
+_Route8BattleText9::
+ text "What's a cute,"
+ line "round and fluffy"
+ cont "#MON?"
+ done
+
+_Route8EndBattleText9::
+ text "Stop!"
+
+ para "Don't be so mean"
+ line "to my CLEFAIRY!"
+ prompt
+
+_Route8AfterBattleText9::
+ text "I heard that"
+ line "CLEFAIRY evolves"
+ cont "when it's exposed"
+ cont "to a MOON STONE."
+ done
+
+_Route8Text10::
+ text "UNDERGROUND PATH"
+ line "CELADON CITY -"
+ cont "LAVENDER TOWN"
+ done
diff --git a/en/text/maps/route_9.asm b/en/text/maps/route_9.asm
new file mode 100644
index 00000000..9975000d
--- /dev/null
+++ b/en/text/maps/route_9.asm
@@ -0,0 +1,157 @@
+_Route9BattleText1::
+ text "You have #MON"
+ line "with you!"
+ cont "You're mine!"
+ done
+
+_Route9EndBattleText1::
+ text "You"
+ line "deceived me!"
+ prompt
+
+_Route9AfterBattleText1::
+ text "You need light to"
+ line "get through that"
+ cont "dark tunnel ahead."
+ done
+
+_Route9BattleText2::
+ text "Who's that walking"
+ line "with those good"
+ cont "looking #MON?"
+ done
+
+_Route9EndBattleText2::
+ text "Out"
+ line "like a light!"
+ prompt
+
+_Route9AfterBattleText2::
+ text "Keep walking!"
+ done
+
+_Route9BattleText3::
+ text "I'm taking ROCK"
+ line "TUNNEL to go to"
+ cont "LAVENDER..."
+ done
+
+_Route9EndBattleText3::
+ text "Can't"
+ line "measure up!"
+ prompt
+
+_Route9AfterBattleText3::
+ text "Are you off to"
+ line "ROCK TUNNEL too?"
+ done
+
+_Route9BattleText4::
+ text "Don't you dare"
+ line "condescend me!"
+ done
+
+_Route9EndBattleText4::
+ text "No!"
+ line "You're too much!"
+ prompt
+
+_Route9AfterBattleText4::
+ text "You're obviously"
+ line "talented! Good"
+ cont "luck to you!"
+ done
+
+_Route9BattleText5::
+ text "Bwahaha!"
+ line "Great! I was"
+ cont "bored, eh!"
+ done
+
+_Route9EndBattleText5::
+ text "Keep it"
+ line "coming, eh!"
+
+ para "Oh wait. I'm out"
+ line "of #MON!"
+ prompt
+
+_Route9AfterBattleText5::
+ text "You sure had guts"
+ line "standing up to me"
+ cont "there, eh?"
+ done
+
+_Route9BattleText6::
+ text "Hahaha!"
+ line "Aren't you a"
+ cont "little toughie!"
+ done
+
+_Route9EndBattleText6::
+ text "What's"
+ line "that?"
+ prompt
+
+_Route9AfterBattleText6::
+ text "Hahaha! Kids"
+ line "should be tough!"
+ done
+
+_Route9BattleText7::
+ text "I got up early"
+ line "every day to"
+ cont "raise my #MON"
+ cont "from cocoons!"
+ done
+
+_Route9EndBattleText7::
+ text "WHAT?"
+
+ para "What a total"
+ line "waste of time!"
+ prompt
+
+_Route9AfterBattleText7::
+ text "I have to collect"
+ line "more than bugs to"
+ cont "get stronger..."
+ done
+
+_Route9BattleText8::
+ text "Hahahaha!"
+ line "Come on, dude!"
+ done
+
+_Route9EndBattleText8::
+ text "Hahahaha!"
+ line "You beat me fair!"
+ prompt
+
+_Route9AfterBattleText8::
+ text "Hahahaha!"
+ line "Us hearty guys"
+ cont "always laugh!"
+ done
+
+_Route9BattleText9::
+ text "Go, my super bug"
+ line "#MON!"
+ done
+
+_Route9EndBattleText9::
+ text "My"
+ line "bugs..."
+ prompt
+
+_Route9AfterBattleText9::
+ text "If you don't like"
+ line "bug #MON, you"
+ cont "bug me!"
+ done
+
+_Route9Text11::
+ text "ROUTE 9"
+ line "CERULEAN CITY-"
+ cont "ROCK TUNNEL"
+ done
diff --git a/en/text/maps/safari_zone_center.asm b/en/text/maps/safari_zone_center.asm
new file mode 100644
index 00000000..09918f93
--- /dev/null
+++ b/en/text/maps/safari_zone_center.asm
@@ -0,0 +1,11 @@
+_SafariZoneCenterText2::
+ text "REST HOUSE"
+ done
+
+_SafariZoneCenterText3::
+ text "TRAINER TIPS"
+
+ para "Press the START"
+ line "Button to check"
+ cont "remaining time!"
+ done
diff --git a/en/text/maps/safari_zone_east.asm b/en/text/maps/safari_zone_east.asm
new file mode 100644
index 00000000..eebe5de7
--- /dev/null
+++ b/en/text/maps/safari_zone_east.asm
@@ -0,0 +1,16 @@
+_SafariZoneEastText5::
+ text "REST HOUSE"
+ done
+
+_SafariZoneEastText6::
+ text "TRAINER TIPS"
+
+ para "The remaining time"
+ line "declines only"
+ cont "while you walk!"
+ done
+
+_SafariZoneEastText7::
+ text "CENTER AREA"
+ line "NORTH: AREA 2"
+ done
diff --git a/en/text/maps/safari_zone_entrance.asm b/en/text/maps/safari_zone_entrance.asm
new file mode 100644
index 00000000..dcc1fd9b
--- /dev/null
+++ b/en/text/maps/safari_zone_entrance.asm
@@ -0,0 +1,93 @@
+_SafariZoneEntranceText1::
+ text "Welcome to the"
+ line "SAFARI ZONE!"
+ done
+
+SafariZoneEntranceText_9e6e4::
+ text "For just ¥500,"
+ line "you can catch all"
+ cont "the #MON you"
+ cont "want in the park!"
+
+ para "Would you like to"
+ line "join the hunt?@@"
+
+SafariZoneEntranceText_9e747::
+ text "That'll be ¥500"
+ line "please!"
+
+ para "We only use a"
+ line "special # BALL"
+ cont "here."
+
+ para "<PLAYER> received"
+ line "30 SAFARI BALLs!@@"
+
+_SafariZoneEntranceText_75360::
+ db $0
+ para "We'll call you on"
+ line "the PA when you"
+ cont "run out of time"
+ cont "or SAFARI BALLs!"
+ done
+
+_SafariZoneEntranceText_75365::
+ text "OK! Please come"
+ line "again!"
+ done
+
+_SafariZoneEntranceText_7536a::
+ text "Oops! Not enough"
+ line "money!"
+ done
+
+SafariZoneEntranceText_9e814::
+ text "Leaving early?@@"
+
+_SafariZoneEntranceText_753bb::
+ text "Please return any"
+ line "SAFARI BALLs you"
+ cont "have left."
+ done
+
+_SafariZoneEntranceText_753c0::
+ text "Good Luck!"
+ done
+
+_SafariZoneEntranceText_753c5::
+ text "Did you get a"
+ line "good haul?"
+ cont "Come again!"
+ done
+
+_SafariZoneEntranceText_753e6::
+ text "Hi! Is it your"
+ line "first time here?"
+ done
+
+_SafariZoneEntranceText_753eb::
+ text "SAFARI ZONE has 4"
+ line "zones in it."
+
+ para "Each zone has"
+ line "different kinds"
+ cont "of #MON. Use"
+ cont "SAFARI BALLs to"
+ cont "catch them!"
+
+ para "When you run out"
+ line "of time or SAFARI"
+ cont "BALLs, it's game"
+ cont "over for you!"
+
+ para "Before you go,"
+ line "open an unused"
+ cont "#MON BOX so"
+ cont "there's room for"
+ cont "new #MON!"
+ done
+
+_SafariZoneEntranceText_753f0::
+ text "Sorry, you're a"
+ line "regular here!"
+ done
diff --git a/en/text/maps/safari_zone_north.asm b/en/text/maps/safari_zone_north.asm
new file mode 100644
index 00000000..1e148f0b
--- /dev/null
+++ b/en/text/maps/safari_zone_north.asm
@@ -0,0 +1,33 @@
+_SafariZoneNorthText3::
+ text "REST HOUSE"
+ done
+
+_SafariZoneNorthText4::
+ text "TRAINER TIPS"
+
+ para "The SECRET HOUSE"
+ line "is still ahead!"
+ done
+
+_SafariZoneNorthText5::
+ text "AREA 2"
+ done
+
+_SafariZoneNorthText6::
+ text "TRAINER TIPS"
+
+ para "#MON hide in"
+ line "tall grass!"
+
+ para "Zigzag through"
+ line "grassy areas to"
+ cont "flush them out."
+ done
+
+_SafariZoneNorthText7::
+ text "TRAINER TIPS"
+
+ para "Win a free HM for"
+ line "finding the"
+ cont "SECRET HOUSE!"
+ done
diff --git a/en/text/maps/safari_zone_rest_house_1.asm b/en/text/maps/safari_zone_rest_house_1.asm
new file mode 100644
index 00000000..b6c87818
--- /dev/null
+++ b/en/text/maps/safari_zone_rest_house_1.asm
@@ -0,0 +1,11 @@
+_SafariZoneRestHouse1Text1::
+ text "SARA: Where did"
+ line "my boy friend,"
+ cont "ERIK, go?"
+ done
+
+_SafariZoneRestHouse1Text2::
+ text "I'm catching"
+ line "#MON to take"
+ cont "home as gifts!"
+ done
diff --git a/en/text/maps/safari_zone_rest_house_2.asm b/en/text/maps/safari_zone_rest_house_2.asm
new file mode 100644
index 00000000..94802b13
--- /dev/null
+++ b/en/text/maps/safari_zone_rest_house_2.asm
@@ -0,0 +1,19 @@
+_SafariZoneRestHouse2Text1::
+ text "Tossing ROCKs at"
+ line "#MON might"
+ cont "make them run,"
+ cont "but they'll be"
+ cont "easier to catch."
+ done
+
+_SafariZoneRestHouse2Text2::
+ text "Using BAIT will"
+ line "make #MON"
+ cont "easier to catch."
+ done
+
+_SafariZoneRestHouse2Text3::
+ text "I hiked a lot, but"
+ line "I didn't see any"
+ cont "#MON I wanted."
+ done
diff --git a/en/text/maps/safari_zone_rest_house_3.asm b/en/text/maps/safari_zone_rest_house_3.asm
new file mode 100644
index 00000000..d5f7abc8
--- /dev/null
+++ b/en/text/maps/safari_zone_rest_house_3.asm
@@ -0,0 +1,18 @@
+_SafariZoneRestHouse3Text1::
+ text "How many did you"
+ line "catch? I'm bushed"
+ cont "from the work!"
+ done
+
+_SafariZoneRestHouse3Text2::
+ text "I caught a"
+ line "CHANSEY!"
+
+ para "That makes this"
+ line "all worthwhile!"
+ done
+
+_SafariZoneRestHouse3Text3::
+ text "Whew! I'm tired"
+ line "from all the fun!"
+ done
diff --git a/en/text/maps/safari_zone_rest_house_4.asm b/en/text/maps/safari_zone_rest_house_4.asm
new file mode 100644
index 00000000..93f02c8f
--- /dev/null
+++ b/en/text/maps/safari_zone_rest_house_4.asm
@@ -0,0 +1,27 @@
+_SafariZoneRestHouse4Text1::
+ text "You can keep any"
+ line "item you find on"
+ cont "the ground here."
+
+ para "But, you'll run"
+ line "out of time if"
+ cont "you try for all"
+ cont "of them at once!"
+ done
+
+_SafariZoneRestHouse4Text2::
+ text "Go to the deepest"
+ line "part of the"
+ cont "SAFARI ZONE. You"
+ cont "will win a prize!"
+ done
+
+_SafariZoneRestHouse4Text3::
+ text "My EEVEE evolved"
+ line "into FLAREON!"
+
+ para "But, a friend's"
+ line "EEVEE turned into"
+ cont "a VAPOREON!"
+ cont "I wonder why?"
+ done
diff --git a/en/text/maps/safari_zone_secret_house.asm b/en/text/maps/safari_zone_secret_house.asm
new file mode 100644
index 00000000..3df79d90
--- /dev/null
+++ b/en/text/maps/safari_zone_secret_house.asm
@@ -0,0 +1,44 @@
+_SecretHouseText_4a350::
+ text "Ah! Finally!"
+
+ para "You're the first"
+ line "person to reach"
+ cont "the SECRET HOUSE!"
+
+ para "I was getting"
+ line "worried that no"
+ cont "one would win our"
+ cont "campaign prize."
+
+ para "Congratulations!"
+ line "You have won!"
+ prompt
+
+_ReceivedHM03Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_HM03ExplanationText::
+ text "HM03 is SURF!"
+
+ para "#MON will be"
+ line "able to ferry you"
+ cont "across water!"
+
+ para "And, this HM isn't"
+ line "disposable! You"
+ cont "can use it over"
+ cont "and over!"
+
+ para "You're super lucky"
+ line "for winning this"
+ cont "fabulous prize!"
+ done
+
+_HM03NoRoomText::
+ text "You don't have"
+ line "room for this"
+ cont "fabulous prize!"
+ done
diff --git a/en/text/maps/safari_zone_west.asm b/en/text/maps/safari_zone_west.asm
new file mode 100644
index 00000000..dcb2fe6c
--- /dev/null
+++ b/en/text/maps/safari_zone_west.asm
@@ -0,0 +1,31 @@
+_SafariZoneWestText5::
+ text "REST HOUSE"
+ done
+
+_SafariZoneWestText6::
+ text "REQUEST NOTICE"
+
+ para "Please find the"
+ line "SAFARI WARDEN's"
+ cont "lost GOLD TEETH."
+ cont "They're around"
+ cont "here somewhere."
+
+ para "Reward offered!"
+ line "Contact: WARDEN"
+ done
+
+_SafariZoneWestText7::
+ text "TRAINER TIPS"
+
+ para "Zone Exploration"
+ line "Campaign!"
+
+ para "The Search for"
+ line "the SECRET HOUSE!"
+ done
+
+_SafariZoneWestText8::
+ text "AREA 3"
+ line "EAST: CENTER AREA"
+ done
diff --git a/en/text/maps/saffron_city.asm b/en/text/maps/saffron_city.asm
new file mode 100644
index 00000000..a0422c8c
--- /dev/null
+++ b/en/text/maps/saffron_city.asm
@@ -0,0 +1,151 @@
+_SaffronCityText1::
+ text "What do you want?"
+ line "Get lost!"
+ done
+
+_SaffronCityText2::
+ text "BOSS said he'll"
+ line "take this town!"
+ done
+
+_SaffronCityText3::
+ text "Get out of the"
+ line "way!"
+ done
+
+_SaffronCityText4::
+ text "SAFFRON belongs"
+ line "to TEAM ROCKET!"
+ done
+
+_SaffronCityText5::
+ text "Being evil makes"
+ line "me feel so alive!"
+ done
+
+_SaffronCityText6::
+ text "Ow! Watch where"
+ line "you're walking!"
+ done
+
+_SaffronCityText7::
+ text "With SILPH under"
+ line "control, we can"
+ cont "exploit #MON"
+ cont "around the world!"
+ done
+
+_SaffronCityText8::
+ text "You beat TEAM"
+ line "ROCKET all alone?"
+ cont "That's amazing!"
+ done
+
+_SaffronCityText9::
+ text "Yeah! TEAM ROCKET"
+ line "is gone!"
+ cont "It's safe to go"
+ cont "out again!"
+ done
+
+_SaffronCityText10::
+ text "People should be"
+ line "flocking back to"
+ cont "SAFFRON now."
+ done
+
+_SaffronCityText11::
+ text "I flew here on my"
+ line "PIDGEOT when I"
+ cont "read about SILPH."
+
+ para "It's already over?"
+ line "I missed the"
+ cont "media action."
+ done
+
+_SaffronCityText12::
+ text "PIDGEOT: Bi bibii!@@"
+
+_SaffronCityText13::
+ text "I saw ROCKET"
+ line "BOSS escaping"
+ cont "SILPH's building."
+ done
+
+_SaffronCityText14::
+ text "I'm a security"
+ line "guard."
+
+ para "Suspicious kids I"
+ line "don't allow in!"
+ done
+
+_SaffronCityText15::
+ text "..."
+ line "Snore..."
+
+ para "Hah! He's taking"
+ line "a snooze!"
+ done
+
+_SaffronCityText16::
+ text "SAFFRON CITY"
+ line "Shining, Golden"
+ cont "Land of Commerce"
+ done
+
+_SaffronCityText17::
+ text "FIGHTING DOJO"
+ done
+
+_SaffronCityText18::
+ text "SAFFRON CITY"
+ line "#MON GYM"
+ cont "LEADER: SABRINA"
+
+ para "The Master of"
+ line "Psychic #MON!"
+ done
+
+_SaffronCityText20::
+ text "TRAINER TIPS"
+
+ para "FULL HEAL cures"
+ line "all ailments like"
+ cont "sleep and burns."
+
+ para "It costs a bit"
+ line "more, but it's"
+ cont "more convenient."
+ done
+
+_SaffronCityText21::
+ text "TRAINER TIPS"
+
+ para "New GREAT BALL"
+ line "offers improved"
+ cont "capture rates."
+
+ para "Try it on those"
+ line "hard-to-catch"
+ cont "#MON."
+ done
+
+_SaffronCityText22::
+ text "SILPH CO."
+ line "OFFICE BUILDING"
+ done
+
+_SaffronCityText24::
+ text "MR.PSYCHIC's"
+ line "HOUSE"
+ done
+
+_SaffronCityText25::
+ text "SILPH's latest"
+ line "product!"
+
+ para "Release to be"
+ line "determined..."
+ done
diff --git a/en/text/maps/saffron_gates.asm b/en/text/maps/saffron_gates.asm
new file mode 100644
index 00000000..c16e880e
--- /dev/null
+++ b/en/text/maps/saffron_gates.asm
@@ -0,0 +1,36 @@
+_SaffronGateText_1dfe7::
+ text "I'm on guard duty."
+ line "Gee, I'm thirsty,"
+ cont "though!"
+
+ para "Oh wait there,"
+ line "the road's closed."
+ done
+
+_SaffronGateText_8aaa9::
+ text "Whoa, boy!"
+ line "I'm parched!"
+ cont "..."
+ cont "Huh? I can have"
+ cont "this drink?"
+ cont "Gee, thanks!@@"
+
+_SaffronGateText_1dff1::
+ db $0
+ para "..."
+ line "Glug glug..."
+ cont "..."
+ cont "Gulp..."
+ cont "If you want to go"
+ cont "to SAFFRON CITY..."
+ cont "..."
+ cont "You can go on"
+ cont "through. I'll"
+ cont "share this with"
+ cont "the other guards!"
+ done
+
+_SaffronGateText_1dff6::
+ text "Hi, thanks for"
+ line "the cool drinks!"
+ done
diff --git a/en/text/maps/saffron_gym.asm b/en/text/maps/saffron_gym.asm
new file mode 100644
index 00000000..419b56ac
--- /dev/null
+++ b/en/text/maps/saffron_gym.asm
@@ -0,0 +1,236 @@
+_SaffronGymText_5d162::
+ text "I had a vision of"
+ line "your arrival!"
+
+ para "I have had psychic"
+ line "powers since I"
+ cont "was a child."
+
+ para "I first learned"
+ line "to bend spoons"
+ cont "with my mind."
+
+ para "I dislike fight-"
+ line "ing, but if you"
+ cont "wish, I will show"
+ cont "you my powers!"
+ done
+
+_SaffronGymText_5d167::
+ text "I'm"
+ line "shocked!"
+ cont "But, a loss is a"
+ cont "loss."
+
+ para "I admit I didn't"
+ line "work hard enough"
+ cont "to win!"
+
+ para "You earned the"
+ line "MARSHBADGE!@@"
+
+_SaffronGymText_5d16e::
+ text "Everyone has"
+ line "psychic power!"
+ cont "People just don't"
+ cont "realize it!"
+ done
+
+_SaffronGymText_5d173::
+ text "The MARSHBADGE"
+ line "makes #MON up"
+ cont "to L70 obey you!"
+
+ para "Stronger #MON"
+ line "will become wild,"
+ cont "ignoring your"
+ cont "orders in battle!"
+
+ para "Just don't raise"
+ line "your #MON too"
+ cont "much!"
+
+ para "Wait, please take"
+ line "this TM with you!"
+ done
+
+ReceivedTM46Text::
+ text "<PLAYER> received"
+ line "TM46!@@"
+
+_TM46ExplanationText::
+ db $0
+ para "TM46 is PSYWAVE!"
+ line "It uses powerful"
+ cont "psychic waves to"
+ cont "inflict damage!"
+ done
+
+_TM46NoRoomText::
+ text "Your pack is full"
+ line "of other items!"
+ done
+
+_SaffronGymText_5d1e6::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "SABRINA's #MON"
+ line "use psychic power"
+ cont "instead of force!"
+
+ para "Fighting #MON"
+ line "are weak against"
+ cont "psychic #MON!"
+
+ para "They get creamed"
+ line "before they can"
+ cont "even aim a punch!"
+ done
+
+_SaffronGymText_5d1eb::
+ text "Psychic power,"
+ line "huh?"
+
+ para "If I had that,"
+ line "I'd make a bundle"
+ cont "at the slots!"
+ done
+
+_SaffronGymBattleText1::
+ text "SABRINA is younger"
+ line "than I, but I"
+ cont "respect her!"
+ done
+
+_SaffronGymEndBattleText1::
+ text "Not"
+ line "good enough!"
+ prompt
+
+_SaffronGymAfterBattleText1::
+ text "In a battle of"
+ line "equals, the one"
+ cont "with the stronger"
+ cont "will wins!"
+
+ para "If you wish"
+ line "to beat SABRINA,"
+ cont "focus on winning!"
+ done
+
+_SaffronGymBattleText2::
+ text "Does our unseen"
+ line "power scare you?"
+ done
+
+_SaffronGymEndBattleText2::
+ text "I never"
+ line "foresaw this!"
+ prompt
+
+_SaffronGymAfterBattleText2::
+ text "Psychic #MON"
+ line "fear only ghosts"
+ cont "and bugs!"
+ done
+
+_SaffronGymBattleText3::
+ text "#MON take on"
+ line "the appearance of"
+ cont "their trainers."
+
+ para "Your #MON must"
+ line "be tough, then!"
+ done
+
+_SaffronGymEndBattleText3::
+ text "I knew"
+ line "it!"
+ prompt
+
+_SaffronGymAfterBattleText3::
+ text "I must teach"
+ line "better techniques"
+ cont "to my #MON!"
+ done
+
+_SaffronGymBattleText4::
+ text "You know that"
+ line "power alone isn't"
+ cont "enough!"
+ done
+
+_SaffronGymEndBattleText4::
+ text "I don't"
+ line "believe this!"
+ prompt
+
+_SaffronGymAfterBattleText4::
+ text "SABRINA just wiped"
+ line "out the KARATE"
+ cont "MASTER next door!"
+ done
+
+_SaffronGymBattleText5::
+ text "You and I, our"
+ line "#MON shall"
+ cont "fight!"
+ done
+
+_SaffronGymEndBattleText5::
+ text "I lost"
+ line "after all!"
+ prompt
+
+_SaffronGymAfterBattleText5::
+ text "I knew that this"
+ line "was going to take"
+ cont "place."
+ done
+
+_SaffronGymBattleText6::
+ text "SABRINA is young,"
+ line "but she's also"
+ cont "our LEADER!"
+
+ para "You won't reach"
+ line "her easily!"
+ done
+
+_SaffronGymEndBattleText6::
+ text "I lost"
+ line "my concentration!"
+ prompt
+
+_SaffronGymAfterBattleText6::
+ text "There used to be"
+ line "2 #MON GYMs in"
+ cont "SAFFRON."
+
+ para "The FIGHTING DOJO"
+ line "next door lost"
+ cont "its GYM status"
+ cont "when we went and"
+ cont "creamed them!"
+ done
+
+_SaffronGymBattleText7::
+ text "SAFFRON #MON"
+ line "GYM is famous for"
+ cont "its psychics!"
+
+ para "You want to see"
+ line "SABRINA!"
+ cont "I can tell!"
+ done
+
+_SaffronGymEndBattleText7::
+ text "Arrrgh!"
+ prompt
+
+_SaffronGymAfterBattleText7::
+ text "That's right! I"
+ line "used telepathy to"
+ cont "read your mind!"
+ done
diff --git a/en/text/maps/saffron_house.asm b/en/text/maps/saffron_house.asm
new file mode 100644
index 00000000..214bf089
--- /dev/null
+++ b/en/text/maps/saffron_house.asm
@@ -0,0 +1,26 @@
+_SaffronHouse1Text1::
+ text "Thank you for"
+ line "writing. I hope"
+ cont "to see you soon!"
+
+ para "Hey! Don't look"
+ line "at my letter!"
+ done
+
+_SaffronHouse1Text2::
+ text "PIDGEY: Kurukkoo!@@"
+
+_SaffronHouse1Text3::
+ text "The COPYCAT is"
+ line "cute! I'm getting"
+ cont "her a # DOLL!"
+ done
+
+_SaffronHouse1Text4::
+ text "I was given a PP"
+ line "UP as a gift."
+
+ para "It's used for"
+ line "increasing the PP"
+ cont "of techniques!"
+ done
diff --git a/en/text/maps/saffron_mart.asm b/en/text/maps/saffron_mart.asm
new file mode 100644
index 00000000..a43b0d94
--- /dev/null
+++ b/en/text/maps/saffron_mart.asm
@@ -0,0 +1,13 @@
+_SaffronMartText2::
+ text "MAX REPEL lasts"
+ line "longer than SUPER"
+ cont "REPEL for keeping"
+ cont "weaker #MON"
+ cont "away!"
+ done
+
+_SaffronMartText3::
+ text "REVIVE is costly,"
+ line "but it revives"
+ cont "fainted #MON!"
+ done
diff --git a/en/text/maps/saffron_pokecenter.asm b/en/text/maps/saffron_pokecenter.asm
new file mode 100644
index 00000000..6548aff8
--- /dev/null
+++ b/en/text/maps/saffron_pokecenter.asm
@@ -0,0 +1,12 @@
+_SaffronPokecenterText2::
+ text "#MON growth"
+ line "rates differ from"
+ cont "specie to specie."
+ done
+
+_SaffronPokecenterText3::
+ text "SILPH CO. is very"
+ line "famous. That's"
+ cont "why it attracted"
+ cont "TEAM ROCKET!"
+ done
diff --git a/en/text/maps/school.asm b/en/text/maps/school.asm
new file mode 100644
index 00000000..f6041e0d
--- /dev/null
+++ b/en/text/maps/school.asm
@@ -0,0 +1,13 @@
+_SchoolText1::
+ text "Whew! I'm trying"
+ line "to memorize all"
+ cont "my notes."
+ done
+
+_SchoolText2::
+ text "Okay!"
+
+ para "Be sure to read"
+ line "the blackboard"
+ cont "carefully!"
+ done
diff --git a/en/text/maps/seafoam_islands_b4f.asm b/en/text/maps/seafoam_islands_b4f.asm
new file mode 100644
index 00000000..608d165f
--- /dev/null
+++ b/en/text/maps/seafoam_islands_b4f.asm
@@ -0,0 +1,13 @@
+_ArticunoBattleText::
+ text "Gyaoo!@@"
+
+_SeafoamIslands5Text4::
+ text "Boulders might"
+ line "change the flow"
+ cont "of water!"
+ done
+
+_SeafoamIslands5Text5::
+ text "DANGER"
+ line "Fast current!"
+ done
diff --git a/en/text/maps/silph_co_10f.asm b/en/text/maps/silph_co_10f.asm
new file mode 100644
index 00000000..e916c64a
--- /dev/null
+++ b/en/text/maps/silph_co_10f.asm
@@ -0,0 +1,42 @@
+_SilphCo10Text_5a1d3::
+ text "Waaaaa!"
+ cont "I'm scared!"
+ done
+
+_SilphCo10Text_5a1d8::
+ text "Please keep quiet"
+ line "about my crying!"
+ done
+
+_SilphCo10BattleText1::
+ text "Welcome to the"
+ line "10F! So good of"
+ cont "you to join me!"
+ done
+
+_SilphCo10EndBattleText1::
+ text "I'm"
+ line "stunned!"
+ prompt
+
+_SilphCo10AfterBattleText1::
+ text "Nice try, but the"
+ line "boardroom is up"
+ cont "one more floor!"
+ done
+
+_SilphCo10BattleText2::
+ text "Enough of your"
+ line "silly games!"
+ done
+
+_SilphCo10EndBattleText2::
+ text "No"
+ line "continues left!"
+ prompt
+
+_SilphCo10AfterBattleText2::
+ text "Are you satisfied"
+ line "with beating me?"
+ cont "Then go on home!"
+ done
diff --git a/en/text/maps/silph_co_11f.asm b/en/text/maps/silph_co_11f.asm
new file mode 100644
index 00000000..fbaa6086
--- /dev/null
+++ b/en/text/maps/silph_co_11f.asm
@@ -0,0 +1,134 @@
+_SilphCoPresidentText::
+ text "PRESIDENT: Thank"
+ line "you for saving"
+ cont "SILPH!"
+
+ para "I will never"
+ line "forget you saved"
+ cont "us in our moment"
+ cont "of peril!"
+
+ para "I have to thank"
+ line "you in some way!"
+
+ para "Because I am rich,"
+ line "I can give you"
+ cont "anything!"
+
+ para "Here, maybe this"
+ line "will do!"
+ prompt
+
+_ReceivedSilphCoMasterBallText::
+ text "<PLAYER> got a"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_SilphCo10Text_6231c::
+ text "PRESIDENT: You"
+ line "can't buy that"
+ cont "anywhere!"
+
+ para "It's our secret"
+ line "prototype MASTER"
+ cont "BALL!"
+
+ para "It will catch any"
+ line "#MON without"
+ cont "fail!"
+
+ para "You should be"
+ line "quiet about using"
+ cont "it, though."
+ done
+
+_SilphCoMasterBallNoRoomText::
+ text "You have no"
+ line "room for this."
+ done
+
+_SilphCo11Text2::
+ text "SECRETARY: Thank"
+ line "you for rescuing"
+ cont "all of us!"
+
+ para "We admire your"
+ line "courage."
+ done
+
+_SilphCo11Text3::
+ text "Ah <PLAYER>!"
+ line "So we meet again!"
+
+ para "The PRESIDENT and"
+ line "I are discussing"
+ cont "a vital business"
+ cont "proposition."
+
+ para "Keep your nose"
+ line "out of grown-up"
+ cont "matters..."
+
+ para "Or, experience a"
+ line "world of pain!"
+ done
+
+_SilphCo10Text_62330::
+ text "Arrgh!!"
+ line "I lost again!?"
+ prompt
+
+_SilphCo10Text_62335::
+ text "Blast it all!"
+ line "You ruined our"
+ cont "plans for SILPH!"
+
+ para "But, TEAM ROCKET"
+ line "will never fall!"
+
+ para "<PLAYER>! Never"
+ line "forget that all"
+ cont "#MON exist"
+ cont "for TEAM ROCKET!"
+
+ para "I must go, but I"
+ line "shall return!"
+ done
+
+_SilphCo11BattleText1::
+ text "Stop right there!"
+ line "Don't you move!"
+ done
+
+_SilphCo11EndBattleText1::
+ text "Don't..."
+ line "Please!"
+ prompt
+
+_SilphCo11AfterBattleText1::
+ text "So, you want to"
+ line "see my BOSS?"
+ done
+
+_SilphCo11BattleText2::
+ text "Halt! Do you have"
+ line "an appointment"
+ cont "with my BOSS?"
+ done
+
+_SilphCo11EndBattleText2::
+ text "Gaah!"
+ line "Demolished!"
+ prompt
+
+_SilphCo11AfterBattleText2::
+ text "Watch your step,"
+ line "my BOSS likes his"
+ cont "#MON tough!"
+ done
+
+_SilphCo10Text_6237b::
+ text "The monitor has"
+ line "#MON on it!"
+ done
diff --git a/en/text/maps/silph_co_1f.asm b/en/text/maps/silph_co_1f.asm
new file mode 100644
index 00000000..1ef80189
--- /dev/null
+++ b/en/text/maps/silph_co_1f.asm
@@ -0,0 +1,7 @@
+_SilphCo1Text1::
+ text "Welcome!"
+
+ para "The PRESIDENT is"
+ line "in the boardroom"
+ cont "on 11F!"
+ done
diff --git a/en/text/maps/silph_co_2f.asm b/en/text/maps/silph_co_2f.asm
new file mode 100644
index 00000000..bd87630a
--- /dev/null
+++ b/en/text/maps/silph_co_2f.asm
@@ -0,0 +1,96 @@
+_SilphCo2Text_59ded::
+ text "Eeek!"
+ line "No! Stop! Help!"
+
+ para "Oh, you're not"
+ line "with TEAM ROCKET."
+ cont "I thought..."
+ cont "I'm sorry. Here,"
+ cont "please take this!"
+ prompt
+
+_ReceivedTM36Text::
+ text "<PLAYER> got"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM36ExplanationText::
+ text "TM36 is"
+ line "SELFDESTRUCT!"
+
+ para "It's powerful, but"
+ line "the #MON that"
+ cont "uses it faints!"
+ cont "Be careful."
+ done
+
+_TM36NoRoomText::
+ text "You don't have any"
+ line "room for this."
+ done
+
+_SilphCo2BattleText1::
+ text "Help! I'm a SILPH"
+ line "employee."
+ done
+
+_SilphCo2EndBattleText1::
+ text "How"
+ line "did you know I"
+ cont "was a ROCKET?"
+ prompt
+
+_SilphCo2AfterBattleText1::
+ text "I work for both"
+ line "SILPH and TEAM"
+ cont "ROCKET!"
+ done
+
+_SilphCo2BattleText2::
+ text "It's off limits"
+ line "here! Go home!"
+ done
+
+_SilphCo2EndBattleText2::
+ text "You're"
+ line "good."
+ prompt
+
+_SilphCo2AfterBattleText2::
+ text "Can you solve the"
+ line "maze in here?"
+ done
+
+_SilphCo2BattleText3::
+ text "No kids are"
+ line "allowed in here!"
+ done
+
+_SilphCo2EndBattleText3::
+ text "Tough!"
+ prompt
+
+_SilphCo2AfterBattleText3::
+ text "Diamond shaped"
+ line "tiles are"
+ cont "teleport blocks!"
+
+ para "They're hi-tech"
+ line "transporters!"
+ done
+
+_SilphCo2BattleText4::
+ text "Hey kid! What are"
+ line "you doing here?"
+ done
+
+_SilphCo2EndBattleText4::
+ text "I goofed!"
+ prompt
+
+_SilphCo2AfterBattleText4::
+ text "SILPH CO. will"
+ line "be merged with"
+ cont "TEAM ROCKET!"
+ done
diff --git a/en/text/maps/silph_co_3f.asm b/en/text/maps/silph_co_3f.asm
new file mode 100644
index 00000000..b6a023f9
--- /dev/null
+++ b/en/text/maps/silph_co_3f.asm
@@ -0,0 +1,46 @@
+_SilphCo3Text_59ff9::
+ text "I work for SILPH."
+ line "What should I do?"
+ done
+
+_SilphCo3Text_59ffe::
+ text "<PLAYER>! You and"
+ line "your #MON"
+ cont "saved us!"
+ done
+
+_SilphCo3BattleText1::
+ text "Quit messing with"
+ line "us, kid!"
+ done
+
+_SilphCo3EndBattleText1::
+ text "I give"
+ line "up!"
+ prompt
+
+_SilphCo3AfterBattleText1::
+ text "A hint? You can"
+ line "open doors with a"
+ cont "CARD KEY!"
+ done
+
+_SilphCo3BattleText2::
+ text "I support TEAM"
+ line "ROCKET more than"
+ cont "I support SILPH!"
+ done
+
+_SilphCo3EndBattleText2::
+ text "You"
+ line "really got me!"
+ prompt
+
+_SilphCo3AfterBattleText2::
+ text "Humph..."
+
+ para "TEAM ROCKET said"
+ line "that if I helped"
+ cont "them, they'd let"
+ cont "me study #MON!"
+ done
diff --git a/en/text/maps/silph_co_4f.asm b/en/text/maps/silph_co_4f.asm
new file mode 100644
index 00000000..5b484ec7
--- /dev/null
+++ b/en/text/maps/silph_co_4f.asm
@@ -0,0 +1,56 @@
+_SilphCo4Text_19de0::
+ text "Sssh! Can't you"
+ line "see I'm hiding?"
+ done
+
+_SilphCo4Text_19de5::
+ text "Huh? TEAM ROCKET"
+ line "is gone?"
+ done
+
+_SilphCo4BattleText2::
+ text "TEAM ROCKET has"
+ line "taken command of"
+ cont "SILPH CO.!"
+ done
+
+_SilphCo4EndBattleText2::
+ text "Arrgh!"
+ prompt
+
+_SilphCo4AfterBattleText2::
+ text "Fwahahaha!"
+ line "My BOSS has been"
+ cont "after this place!"
+ done
+
+_SilphCo4BattleText3::
+ text "My #MON are my"
+ line "loyal soldiers!"
+ done
+
+_SilphCo4EndBattleText3::
+ text "Darn!"
+ line "You weak #MON!"
+ prompt
+
+_SilphCo4AfterBattleText3::
+ text "The doors are"
+ line "electronically"
+ cont "locked! A CARD"
+ cont "KEY opens them!"
+ done
+
+_SilphCo4BattleText4::
+ text "Intruder spotted!"
+ done
+
+_SilphCo4EndBattleText4::
+ text "Who"
+ line "are you?"
+ prompt
+
+_SilphCo4AfterBattleText4::
+ text "I better tell the"
+ line "BOSS on 11F!"
+ done
diff --git a/en/text/maps/silph_co_5f_1.asm b/en/text/maps/silph_co_5f_1.asm
new file mode 100644
index 00000000..dab42539
--- /dev/null
+++ b/en/text/maps/silph_co_5f_1.asm
@@ -0,0 +1,51 @@
+_SilphCo5Text_1a010::
+ text "TEAM ROCKET is"
+ line "in an uproar over"
+ cont "some intruder."
+ cont "That's you right?"
+ done
+
+_SilphCo5Text_1a015::
+ text "TEAM ROCKET took"
+ line "off! You're our"
+ cont "hero! Thank you!"
+ done
+
+_SilphCo5BattleText2::
+ text "I heard a kid was"
+ line "wandering around."
+ done
+
+_SilphCo5EndBattleText2::
+ text "Boom!"
+ prompt
+
+_SilphCo5AfterBattleText2::
+ text "It's not smart"
+ line "to pick a fight"
+ cont "with TEAM ROCKET!"
+ done
+
+_SilphCo5BattleText3::
+ text "We study #"
+ line "BALL technology"
+ cont "on this floor!"
+ done
+
+_SilphCo5EndBattleText3::
+ text "Dang!"
+ line "Blast it!"
+ prompt
+
+_SilphCo5AfterBattleText3::
+ text "We worked on the"
+ line "ultimate #"
+ cont "BALL which would"
+ cont "catch anything!"
+ done
+
+_SilphCo5BattleText4::
+ text "Whaaat? There"
+ line "shouldn't be any"
+ cont "children here?"
+ done
diff --git a/en/text/maps/silph_co_5f_2.asm b/en/text/maps/silph_co_5f_2.asm
new file mode 100644
index 00000000..3c1b8ead
--- /dev/null
+++ b/en/text/maps/silph_co_5f_2.asm
@@ -0,0 +1,55 @@
+_SilphCo5EndBattleText4::
+ text "Oh"
+ line "goodness!"
+ prompt
+
+_SilphCo5AfterBattleText4::
+ text "You're only on 5F."
+ line "It's a long way"
+ cont "to my BOSS!"
+ done
+
+_SilphCo5BattleText5::
+ text "Show TEAM ROCKET"
+ line "a little respect!"
+ done
+
+_SilphCo5EndBattleText5::
+ text "Cough..."
+ line "Cough..."
+ prompt
+
+_SilphCo5AfterBattleText5::
+ text "Which reminds me."
+
+ para "KOFFING evolves"
+ line "into WEEZING!"
+ done
+
+_SilphCo5Text9::
+ text "It's a #MON"
+ line "REPORT!"
+
+ para "#MON LAB"
+ line "created PORYGON,"
+ cont "the first virtual"
+ cont "reality #MON."
+ done
+
+_SilphCo5Text10::
+ text "It's a #MON"
+ line "REPORT!"
+
+ para "Over 160 #MON"
+ line "techniques have"
+ cont "been confirmed."
+ done
+
+_SilphCo5Text11::
+ text "It's a #MON"
+ line "REPORT!"
+
+ para "4 #MON evolve"
+ line "only when traded"
+ cont "by link-cable."
+ done
diff --git a/en/text/maps/silph_co_6f.asm b/en/text/maps/silph_co_6f.asm
new file mode 100644
index 00000000..90456b5c
--- /dev/null
+++ b/en/text/maps/silph_co_6f.asm
@@ -0,0 +1,107 @@
+_SilphCo6Text_1a24a::
+ text "The ROCKETs came"
+ line "and took over the"
+ cont "building!"
+ done
+
+_SilphCo6Text_1a24f::
+ text "Well, better get"
+ line "back to work!"
+ done
+
+_SilphCo6Text_1a261::
+ text "Oh dear, oh dear."
+ line "Help me please!"
+ done
+
+_SilphCo6Text_1a266::
+ text "We got engaged!"
+ line "Heheh!"
+ done
+
+_SilphCo6Text_1a278::
+ text "Look at him! He's"
+ line "such a coward!"
+ done
+
+_SilphCo6Text_1a27d::
+ text "I feel so sorry"
+ line "for him, I have"
+ cont "to marry him!"
+ done
+
+_SilphCo6Text_1a28f::
+ text "TEAM ROCKET is"
+ line "trying to conquer"
+ cont "the world with"
+ cont "#MON!"
+ done
+
+_SilphCo6Text_1a294::
+ text "TEAM ROCKET ran"
+ line "because of you!"
+ done
+
+_SilphCo6Text_1a2a6::
+ text "They must have"
+ line "targeted SILPH"
+ cont "for our #MON"
+ cont "products."
+ done
+
+_SilphCo6Text_1a2ab::
+ text "Come work for"
+ line "SILPH when you"
+ cont "get older!"
+ done
+
+_SilphCo6BattleText2::
+ text "I am one of the 4"
+ line "ROCKET BROTHERS!"
+ done
+
+_SilphCo6EndBattleText2::
+ text "Flame"
+ line "out!"
+ prompt
+
+_SilphCo6AfterBattleText2::
+ text "No matter!"
+ line "My brothers will"
+ cont "avenge me!"
+ done
+
+_SilphCo6BattleText3::
+ text "That rotten"
+ line "PRESIDENT!"
+
+ para "He shouldn't have"
+ line "sent me to the"
+ cont "TIKSI BRANCH!"
+ done
+
+_SilphCo6EndBattleText3::
+ text "Shoot!"
+ prompt
+
+_SilphCo6AfterBattleText3::
+ text "TIKSI BRANCH?"
+ line "It's in Russian"
+ cont "no man's land!"
+ done
+
+_SilphCo6BattleText4::
+ text "You dare betray"
+ line "TEAM ROCKET?"
+ done
+
+_SilphCo6EndBattleText4::
+ text "You"
+ line "traitor!"
+ prompt
+
+_SilphCo6AfterBattleText4::
+ text "If you stand for"
+ line "justice, you"
+ cont "betray evil!"
+ done
diff --git a/en/text/maps/silph_co_7f.asm b/en/text/maps/silph_co_7f.asm
new file mode 100644
index 00000000..1cc2bc30
--- /dev/null
+++ b/en/text/maps/silph_co_7f.asm
@@ -0,0 +1,209 @@
+_MeetLaprasGuyText::
+ text "Oh! Hi! You're"
+ line "not a ROCKET! You"
+ cont "came to save us?"
+ cont "Why, thank you!"
+
+ para "I want you to"
+ line "have this #MON"
+ cont "for saving us."
+ prompt
+
+_HeresYourLaprasText::
+ text "It's LAPRAS. It's"
+ line "very intelligent."
+
+ para "We kept it in our"
+ line "lab, but it will"
+ cont "be much better"
+ cont "off with you!"
+
+ para "I think you will"
+ line "be a good trainer"
+ cont "for LAPRAS!"
+
+ para "It's a good"
+ line "swimmer. It'll"
+ cont "give you a lift!"
+ done
+
+_LaprasGuyText::
+ text "TEAM ROCKET's"
+ line "BOSS went to the"
+ cont "boardroom! Is our"
+ cont "PRESIDENT OK?"
+ done
+
+_LaprasGuySavedText::
+ text "Saved at last!"
+ line "Thank you!"
+ done
+
+_SilphCo7Text_51e00::
+ text "TEAM ROCKET was"
+ line "after the MASTER"
+ cont "BALL which will"
+ cont "catch any #MON!"
+ done
+
+_CanceledMasterBallText::
+ text "We canceled the"
+ line "MASTER BALL"
+ cont "project because"
+ cont "of TEAM ROCKET."
+ done
+
+_SilphCo7Text_51e23::
+ text "It would be bad"
+ line "if TEAM ROCKET"
+ cont "took over SILPH"
+ cont "or our #MON!"
+ done
+
+_SilphCo7Text_51e28::
+ text "Wow! You chased"
+ line "off TEAM ROCKET"
+ cont "all by yourself?"
+ done
+
+_SilphCo7Text_51e46::
+ text "You! It's really"
+ line "dangerous here!"
+ cont "You came to save"
+ cont "me? You can't!"
+ done
+
+_SilphCo7Text_51e4b::
+ text "Safe at last!"
+ line "Oh thank you!"
+ done
+
+_SilphCo7BattleText1::
+ text "Oh ho! I smell a"
+ line "little rat!"
+ done
+
+_SilphCo7EndBattleText1::
+ text "Lights"
+ line "out!"
+ prompt
+
+_SilphCo7AfterBattleText1::
+ text "You won't find my"
+ line "BOSS by just"
+ cont "scurrying around!"
+ done
+
+_SilphCo7BattleText2::
+ text "Heheh!"
+
+ para "You mistook me for"
+ line "a SILPH worker?"
+ done
+
+_SilphCo7EndBattleText2::
+ text "I'm"
+ line "done!"
+ prompt
+
+_SilphCo7AfterBattleText2::
+ text "Despite your age,"
+ line "you are a skilled"
+ cont "trainer!"
+ done
+
+_SilphCo7BattleText3::
+ text "I am one of the 4"
+ line "ROCKET BROTHERS!"
+ done
+
+_SilphCo7EndBattleText3::
+ text "Aack!"
+ line "Brothers, I lost!"
+ prompt
+
+_SilphCo7AfterBattleText3::
+ text "Doesn't matter."
+ line "My brothers will"
+ cont "repay the favor!"
+ done
+
+_SilphCo7BattleText4::
+ text "A child intruder?"
+ line "That must be you!"
+ done
+
+_SilphCo7EndBattleText4::
+ text "Fine!"
+ line "I lost!"
+ prompt
+
+_SilphCo7AfterBattleText4::
+ text "Go on home"
+ line "before my BOSS"
+ cont "gets ticked off!"
+ done
+
+_SilphCo7Text_51ebe::
+ text "<RIVAL>: What"
+ line "kept you <PLAYER>?"
+ done
+
+_SilphCo7Text_51ec3::
+ text "<RIVAL>: Hahaha!"
+ line "I thought you'd"
+ cont "turn up if I"
+ cont "waited here!"
+
+ para "I guess TEAM"
+ line "ROCKET slowed you"
+ cont "down! Not that I"
+ cont "care!"
+
+ para "I saw you in"
+ line "SAFFRON, so I"
+ cont "decided to see if"
+ cont "you got better!"
+ done
+
+_SilphCo7Text_51ec8::
+ text "Oh ho!"
+ line "So, you are ready"
+ cont "for BOSS ROCKET!"
+ prompt
+
+_SilphCo7Text_51ecd::
+ text "<RIVAL>: How can"
+ line "I put this?"
+
+ para "You're not good"
+ line "enough to play"
+ cont "with us big boys!"
+ prompt
+
+_SilphCo7Text_51ed2::
+ text "Well, <PLAYER>!"
+
+ para "I'm moving on up"
+ line "and ahead!"
+
+ para "By checking my"
+ line "#DEX, I'm"
+ cont "starting to see"
+ cont "what's strong and"
+ cont "how they evolve!"
+
+ para "I'm going to the"
+ line "#MON LEAGUE"
+ cont "to boot out the"
+ cont "ELITE FOUR!"
+
+ para "I'll become the"
+ line "world's most"
+ cont "powerful trainer!"
+
+ para "<PLAYER>, well"
+ line "good luck to you!"
+ cont "Don't sweat it!"
+ cont "Smell ya!"
+ done
diff --git a/en/text/maps/silph_co_8f.asm b/en/text/maps/silph_co_8f.asm
new file mode 100644
index 00000000..fabae5e6
--- /dev/null
+++ b/en/text/maps/silph_co_8f.asm
@@ -0,0 +1,56 @@
+_SilphCo8Text_565be::
+ text "I wonder if SILPH"
+ line "is finished..."
+ done
+
+_SilphCo8Text_565c3::
+ text "Thanks for saving"
+ line "us!"
+ done
+
+_SilphCo8BattleText1::
+ text "That's as far as"
+ line "you'll go!"
+ done
+
+_SilphCo8EndBattleText1::
+ text "Not"
+ line "enough grit!"
+ prompt
+
+_SilphCo8AfterBattleText1::
+ text "If you don't turn"
+ line "back, I'll call"
+ cont "for backup!"
+ done
+
+_SilphCo8BattleText2::
+ text "You're causing us"
+ line "problems!"
+ done
+
+_SilphCo8EndBattleText2::
+ text "Huh?"
+ line "I lost?"
+ prompt
+
+_SilphCo8AfterBattleText2::
+ text "So, what do you"
+ line "think of SILPH"
+ cont "BUILDING's maze?"
+ done
+
+_SilphCo8BattleText3::
+ text "I am one of the 4"
+ line "ROCKET BROTHERS!"
+ done
+
+_SilphCo8EndBattleText3::
+ text "Whoo!"
+ line "Oh brothers!"
+ prompt
+
+_SilphCo8AfterBattleText3::
+ text "I'll leave you up"
+ line "to my brothers!"
+ done
diff --git a/en/text/maps/silph_co_9f.asm b/en/text/maps/silph_co_9f.asm
new file mode 100644
index 00000000..fd1aa91c
--- /dev/null
+++ b/en/text/maps/silph_co_9f.asm
@@ -0,0 +1,62 @@
+_SilphCo9Text_5d8e5::
+ text "You look tired!"
+ line "You should take a"
+ cont "quick nap!"
+ prompt
+
+_SilphCo9Text_5d8ea::
+ text "Don't give up!"
+ done
+
+_SilphCo9Text_5d8ef::
+ text "Thank you so"
+ line "much!"
+ done
+
+_SilphCo9BattleText1::
+ text "Your #MON seem"
+ line "to adore you, kid!"
+ done
+
+_SilphCo9EndBattleText1::
+ text "Ghaaah!"
+ prompt
+
+_SilphCo9AfterBattleText1::
+ text "If I had started"
+ line "as a trainer at"
+ cont "your age..."
+ done
+
+_SilphCo9BattleText2::
+ text "Your #MON have"
+ line "weak points! I"
+ cont "can nail them!"
+ done
+
+_SilphCo9EndBattleText2::
+ text "You"
+ line "hammered me!"
+ prompt
+
+_SilphCo9AfterBattleText2::
+ text "Exploiting weak"
+ line "spots does work!"
+ cont "Think about"
+ cont "element types!"
+ done
+
+_SilphCo9BattleText3::
+ text "I am one of the 4"
+ line "ROCKET BROTHERS!"
+ done
+
+_SilphCo9EndBattleText3::
+ text "Warg!"
+ line "Brothers, I lost!"
+ prompt
+
+_SilphCo9AfterBattleText3::
+ text "My brothers will"
+ line "avenge me!"
+ done
diff --git a/en/text/maps/ss_anne_1.asm b/en/text/maps/ss_anne_1.asm
new file mode 100644
index 00000000..2bbdcbac
--- /dev/null
+++ b/en/text/maps/ss_anne_1.asm
@@ -0,0 +1,21 @@
+_SSAnne1Text1::
+ text "Bonjour!"
+ line "I am le waiter on"
+ cont "this ship!"
+
+ para "I will be happy"
+ line "to serve you any-"
+ cont "thing you please!"
+
+ para "Ah! Le strong"
+ line "silent type!"
+ done
+
+_SSAnne1Text2::
+ text "The passengers"
+ line "are restless!"
+
+ para "You might be"
+ line "challenged by the"
+ cont "more bored ones!"
+ done
diff --git a/en/text/maps/ss_anne_10.asm b/en/text/maps/ss_anne_10.asm
new file mode 100644
index 00000000..7df629b5
--- /dev/null
+++ b/en/text/maps/ss_anne_10.asm
@@ -0,0 +1,112 @@
+_SSAnne10Text8::
+ text "MACHOKE: Gwoh!"
+ line "Goggoh!@@"
+
+_SSAnne10BattleText1::
+ text "You know what they"
+ line "say about sailors"
+ cont "and fighting!"
+ done
+
+_SSAnne10EndBattleText1::
+ text "Right!"
+ line "Good fight, mate!"
+ prompt
+
+_SSAnne10AfterBattleText1::
+ text "Haha! Want to be"
+ line "a sailor, mate?"
+ done
+
+_SSAnne10BattleText2::
+ text "My sailor's pride"
+ line "is at stake!"
+ done
+
+_SSAnne10EndBattleText2::
+ text "Your"
+ line "spirit sank me!"
+ prompt
+
+_SSAnne10AfterBattleText2::
+ text "Did you see the"
+ line "FISHING GURU in"
+ cont "VERMILION CITY?"
+ done
+
+_SSAnne10BattleText3::
+ text "Us sailors have"
+ line "#MON too!"
+ done
+
+_SSAnne10EndBattleText3::
+ text "OK, "
+ line "you're not bad."
+ prompt
+
+_SSAnne10AfterBattleText3::
+ text "We caught all our"
+ line "#MON while"
+ cont "out at sea!"
+ done
+
+_SSAnne10BattleText4::
+ text "I like feisty"
+ line "kids like you!@@"
+
+_SSAnne10EndBattleText4::
+ text "Argh!"
+ line "Lost it!"
+ prompt
+
+_SSAnne10AfterBattleText4::
+ text "Sea #MON live"
+ line "in deep water."
+ cont "You'll need a ROD!"
+ done
+
+_SSAnne10BattleText5::
+ text "Matey, you're"
+ line "walking the plank"
+ cont "if you lose!"
+ done
+
+_SSAnne10EndBattleText5::
+ text "Argh!"
+ line "Beaten by a kid!"
+ prompt
+
+_SSAnne10AfterBattleText5::
+ text "Jellyfish some-"
+ line "times drift into"
+ cont "the ship."
+ done
+
+_SSAnne10BattleText6::
+ text "Hello stranger!"
+ line "Stop and chat!"
+
+ para "All my #MON"
+ line "are from the sea!"
+ done
+
+_SSAnne10EndBattleText6::
+ text "Darn!"
+ line "I let that one"
+ cont "get away!"
+ prompt
+
+_SSAnne10AfterBattleText6::
+ text "I was going to"
+ line "make you my"
+ cont "assistant too!"
+ done
+
+_SSAnne10Text7::
+ text "My buddy, MACHOKE,"
+ line "is super strong!"
+
+ para "He has enough"
+ line "STRENGTH to move"
+ cont "big rocks!"
+ done
diff --git a/en/text/maps/ss_anne_2.asm b/en/text/maps/ss_anne_2.asm
new file mode 100644
index 00000000..58d804ba
--- /dev/null
+++ b/en/text/maps/ss_anne_2.asm
@@ -0,0 +1,63 @@
+_SSAnne2Text1::
+ text "This ship, she is"
+ line "a luxury liner"
+ cont "for trainers!"
+
+ para "At every port, we"
+ line "hold parties with"
+ cont "invited trainers!"
+ done
+
+_SSAnneRivalBeforeBattleText::
+ text "<RIVAL>: Bonjour!"
+ line "<PLAYER>!"
+
+ para "Imagine seeing"
+ line "you here!"
+
+ para "<PLAYER>, were you"
+ line "really invited?"
+
+ para "So how's your"
+ line "#DEX coming?"
+
+ para "I already caught"
+ line "40 kinds, pal!"
+
+ para "Different kinds"
+ line "are everywhere!"
+
+ para "Crawl around in"
+ line "grassy areas!"
+ done
+
+_SSAnneRivalDefeatedText::
+ text "Humph!"
+
+ para "At least you're"
+ line "raising your"
+ cont "#MON!"
+ prompt
+
+_SSAnneRivalWonText::
+ text "<PLAYER>! What are"
+ line "you, seasick?"
+
+ para "You should shape"
+ line "up, pal!"
+ prompt
+
+_SSAnneRivalCaptainText::
+ text "<RIVAL>: I heard"
+ line "there was a CUT"
+ cont "master on board."
+
+ para "But, he was just a"
+ line "seasick, old man!"
+
+ para "But, CUT itself is"
+ line "really useful!"
+
+ para "You should go see"
+ line "him! Smell ya!"
+ done
diff --git a/en/text/maps/ss_anne_3.asm b/en/text/maps/ss_anne_3.asm
new file mode 100644
index 00000000..76490594
--- /dev/null
+++ b/en/text/maps/ss_anne_3.asm
@@ -0,0 +1,7 @@
+_SSAnne3Text1::
+ text "Our CAPTAIN is a"
+ line "sword master!"
+
+ para "He even teaches"
+ line "CUT to #MON!"
+ done
diff --git a/en/text/maps/ss_anne_5.asm b/en/text/maps/ss_anne_5.asm
new file mode 100644
index 00000000..76cd5631
--- /dev/null
+++ b/en/text/maps/ss_anne_5.asm
@@ -0,0 +1,52 @@
+_SSAnne5Text1::
+ text "The party's over."
+ line "The ship will be"
+ cont "departing soon."
+ done
+
+_SSAnne5Text2::
+ text "Scrubbing decks"
+ line "is hard work!"
+ done
+
+_SSAnne5Text3::
+ text "Urf. I feel ill."
+
+ para "I stepped out to"
+ line "get some air."
+ done
+
+_SSAnne5BattleText1::
+ text "Hey matey!"
+
+ para "Let's do a little"
+ line "jig!"
+ done
+
+_SSAnne5EndBattleText1::
+ text "You're"
+ line "impressive!"
+ prompt
+
+_SSAnne5AfterBattleText1::
+ text "How many kinds of"
+ line "#MON do you"
+ cont "think there are?"
+ done
+
+_SSAnne5BattleText2::
+ text "Ahoy there!"
+ line "Are you seasick?"
+ done
+
+_SSAnne5EndBattleText2::
+ text "I was"
+ line "just careless!"
+ prompt
+
+_SSAnne5AfterBattleText2::
+ text "My Pa said there"
+ line "are 100 kinds of"
+ cont "#MON. I think"
+ cont "there are more."
+ done
diff --git a/en/text/maps/ss_anne_6.asm b/en/text/maps/ss_anne_6.asm
new file mode 100644
index 00000000..7fcc9973
--- /dev/null
+++ b/en/text/maps/ss_anne_6.asm
@@ -0,0 +1,69 @@
+_SSAnne6Text1::
+ text "You, mon petit!"
+ line "We're busy here!"
+ cont "Out of the way!"
+ done
+
+_SSAnne6Text2::
+ text "I saw an odd ball"
+ line "in the trash."
+ done
+
+_SSAnne6Text3::
+ text "I'm so busy I'm"
+ line "getting dizzy!"
+ done
+
+_SSAnne6Text4::
+ text "Hum-de-hum-de-"
+ line "ho..."
+
+ para "I peel spuds"
+ line "every day!"
+ cont "Hum-hum..."
+ done
+
+_SSAnne6Text5::
+ text "Did you hear about"
+ line "SNORLAX?"
+
+ para "All it does is"
+ line "eat and sleep!"
+ done
+
+_SSAnne6Text6::
+ text "Snivel...Sniff..."
+
+ para "I only get to"
+ line "peel onions..."
+ cont "Snivel..."
+ done
+
+_SSAnne6Text_61807::
+ text "Er-hem! Indeed I"
+ line "am le CHEF!"
+
+ para "Le main course is"
+ prompt
+
+_SSAnne6Text_6180c::
+ text "Salmon du Salad!"
+
+ para "Les guests may"
+ line "gripe it's fish"
+ cont "again, however!"
+ done
+
+_SSAnne6Text_61811::
+ text "Eels au Barbecue!"
+
+ para "Les guests will"
+ line "mutiny, I fear."
+ done
+
+_SSAnne6Text_61816::
+ text "Prime Beef Steak!"
+
+ para "But, have I enough"
+ line "fillets du beef?"
+ done
diff --git a/en/text/maps/ss_anne_7.asm b/en/text/maps/ss_anne_7.asm
new file mode 100644
index 00000000..7bf004da
--- /dev/null
+++ b/en/text/maps/ss_anne_7.asm
@@ -0,0 +1,62 @@
+_SSAnne7RubText::
+ text "CAPTAIN: Ooargh..."
+ line "I feel hideous..."
+ cont "Urrp! Seasick..."
+
+ para "<PLAYER> rubbed"
+ line "the CAPTAIN's"
+ cont "back!"
+
+ para "Rub-rub..."
+ line "Rub-rub...@@"
+
+_ReceivingHM01Text::
+ text "CAPTAIN: Whew!"
+ line "Thank you! I"
+ cont "feel much better!"
+
+ para "You want to see"
+ line "my CUT technique?"
+
+ para "I could show you"
+ line "if I wasn't ill..."
+
+ para "I know! You can"
+ line "have this!"
+
+ para "Teach it to your"
+ line "#MON and you"
+ cont "can see it CUT"
+ cont "any time!"
+ prompt
+
+_ReceivedHM01Text::
+ text "<PLAYER> got"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_SSAnne7Text_61932::
+ text "CAPTAIN: Whew!"
+
+ para "Now that I'm not"
+ line "sick any more, I"
+ cont "guess it's time."
+ done
+
+_HM01NoRoomText::
+ text "Oh no! You have"
+ line "no room for this!"
+ done
+
+_SSAnne7Text2::
+ text "Yuck! Shouldn't"
+ line "have looked!"
+ done
+
+_SSAnne7Text3::
+ text "How to Conquer"
+ line "Seasickness..."
+ cont "The CAPTAIN's"
+ cont "reading this!"
+ done
diff --git a/en/text/maps/ss_anne_8.asm b/en/text/maps/ss_anne_8.asm
new file mode 100644
index 00000000..7a09303e
--- /dev/null
+++ b/en/text/maps/ss_anne_8.asm
@@ -0,0 +1,104 @@
+_SSAnne8Text8::
+ text "WIGGLYTUFF: Puup"
+ line "pupuu!@@"
+
+_SSAnne8BattleText1::
+ text "I travel alone"
+ line "on my journeys!"
+
+ para "My #MON are my"
+ line "only friends!"
+ done
+
+_SSAnne8EndBattleText1::
+ text "My, my"
+ line "friends..."
+ prompt
+
+_SSAnne8AfterBattleText1::
+ text "You should be"
+ line "nice to friends!"
+ done
+
+_SSAnne8BattleText2::
+ text "You pup! How dare"
+ line "you barge in!"
+ done
+
+_SSAnne8EndBattleText2::
+ text "Humph!"
+ line "You rude child!"
+ prompt
+
+_SSAnne8AfterBattleText2::
+ text "I wish to be left"
+ line "alone! Get out!"
+ done
+
+_SSAnne8BattleText3::
+ text "I love #MON!"
+ line "Do you?"
+ done
+
+_SSAnne8EndBattleText3::
+ text "Wow! "
+ line "You're great!"
+ prompt
+
+_SSAnne8AfterBattleText3::
+ text "Let me be your"
+ line "friend, OK?"
+
+ para "Then we can trade"
+ line "#MON!"
+ done
+
+_SSAnne8BattleText4::
+ text "I collected these"
+ line "#MON from all"
+ cont "around the world!"
+ done
+
+_SSAnne8EndBattleText4::
+ text "Oh no!"
+ line "I went around the"
+ cont "world for these!"
+ prompt
+
+_SSAnne8AfterBattleText4::
+ text "You hurt my poor"
+ line "worldly #MON!"
+
+ para "I demand that you"
+ line "heal them at a"
+ cont "#MON CENTER!"
+ done
+
+_SSAnne8Text5::
+ text "Waiter, I would"
+ line "like a cherry pie"
+ cont "please!"
+ done
+
+_SSAnne8Text6::
+ text "A cruise is so"
+ line "elegant yet cozy!"
+ done
+
+_SSAnne8Text7::
+ text "I always travel"
+ line "with WIGGLYTUFF!"
+ done
+
+_SSAnne8Text9::
+ text "We are cruising"
+ line "around the world."
+ done
+
+_SSAnne8Text11::
+ text "Ssh! I'm a GLOBAL"
+ line "POLICE agent!"
+
+ para "I'm on the trail"
+ line "of TEAM ROCKET!"
+ done
diff --git a/en/text/maps/ss_anne_9.asm b/en/text/maps/ss_anne_9.asm
new file mode 100644
index 00000000..a9be8cee
--- /dev/null
+++ b/en/text/maps/ss_anne_9.asm
@@ -0,0 +1,113 @@
+_SSAnne9Text_61bf2::
+ text "In all my travels"
+ line "I've never seen"
+ cont "any #MON sleep"
+ cont "like this one!"
+
+ para "It was something"
+ line "like this!"
+ prompt
+
+_SSAnne9Text_61c01::
+ text "Ah yes, I have"
+ line "seen some #MON"
+ cont "ferry people"
+ cont "across the water!"
+ done
+
+_SSAnne9Text_61c10::
+ text "#MON can CUT"
+ line "down small bushes."
+ done
+
+_SSAnne9Text_61c1f::
+ text "Have you gone to"
+ line "the SAFARI ZONE"
+ cont "in FUCHSIA CITY?"
+
+ para "It had many rare"
+ line "kinds of #MON!!"
+ done
+
+_SSAnne9Text_61c2e::
+ text "Me and my Daddy"
+ line "think the SAFARI"
+ cont "ZONE is awesome!"
+ done
+
+_SSAnne9Text_61c3d::
+ text "The CAPTAIN looked"
+ line "really sick and"
+ cont "pale!"
+ done
+
+_SSAnne9Text_61c4c::
+ text "I hear many people"
+ line "get seasick!"
+ done
+
+_SSAnne9BattleText1::
+ text "Competing against"
+ line "the young keeps"
+ cont "me youthful."
+ done
+
+_SSAnne9EndBattleText1::
+ text "Good"
+ line "fight! Ah, I feel"
+ cont "young again!"
+ prompt
+
+_SSAnne9AfterBattleText1::
+ text "15 years ago, I"
+ line "would have won!"
+ done
+
+_SSAnne9BattleText2::
+ text "Check out what I"
+ line "fished up!"
+ done
+
+_SSAnne9EndBattleText2::
+ text "I'm"
+ line "all out!"
+ prompt
+
+_SSAnne9AfterBattleText2::
+ text "Party?"
+
+ para "The cruise ship's"
+ line "party should be"
+ cont "over by now."
+ done
+
+_SSAnne9BattleText3::
+ text "Which do you like,"
+ line "a strong or a"
+ cont "rare #MON?"
+ done
+
+_SSAnne9EndBattleText3::
+ text "I must"
+ line "salute you!"
+ prompt
+
+_SSAnne9AfterBattleText3::
+ text "I prefer strong"
+ line "and rare #MON."
+ done
+
+_SSAnne9BattleText4::
+ text "I never saw you"
+ line "at the party."
+ done
+
+_SSAnne9EndBattleText4::
+ text "Take"
+ line "it easy!"
+ prompt
+
+_SSAnne9AfterBattleText4::
+ text "Oh, I adore your"
+ line "strong #MON!"
+ done
diff --git a/en/text/maps/underground_path_route_6_entrance.asm b/en/text/maps/underground_path_route_6_entrance.asm
new file mode 100644
index 00000000..dacc44f7
--- /dev/null
+++ b/en/text/maps/underground_path_route_6_entrance.asm
@@ -0,0 +1,5 @@
+_UndergrdTunnelEntRoute6Text1::
+ text "People often lose"
+ line "things in that"
+ cont "UNDERGROUND PATH."
+ done
diff --git a/en/text/maps/underground_path_route_7_entrance.asm b/en/text/maps/underground_path_route_7_entrance.asm
new file mode 100644
index 00000000..5cde3614
--- /dev/null
+++ b/en/text/maps/underground_path_route_7_entrance.asm
@@ -0,0 +1,5 @@
+_UndergroundPathEntRoute7Text1::
+ text "I heard a sleepy"
+ line "#MON appeared"
+ cont "near CELADON CITY."
+ done
diff --git a/en/text/maps/underground_path_route_7_entrance_unused.asm b/en/text/maps/underground_path_route_7_entrance_unused.asm
new file mode 100644
index 00000000..4e0dc3ca
--- /dev/null
+++ b/en/text/maps/underground_path_route_7_entrance_unused.asm
@@ -0,0 +1,35 @@
+_UGPathRoute7EntranceUnusedText_5d773::
+ text "I want to shop at"
+ line "the dept. store"
+ cont "in CELADON but..."
+
+ para "There are so many"
+ line "rough looking"
+ cont "people there."
+ done
+
+_UGPathRoute7EntranceUnusedText_5d778::
+ text "TEAM ROCKET had a"
+ line "secret hideout in"
+ cont "CELADON CITY?"
+ done
+
+_UGPathRoute7EntranceUnusedText_5d77d::
+ text "You're here to"
+ line "shop in CELADON?"
+
+ para "Just step outside"
+ line "and head west!"
+ done
+
+_UGPathRoute7EntranceUnusedText_5d782::
+ text "The UNDERGROUND"
+ line "PATH goes beneath"
+ cont "SAFFRON and leads"
+ cont "to LAVENDER."
+
+ para "If you're heading"
+ line "to CERULEAN, go"
+ cont "to the building"
+ cont "across the road."
+ done
diff --git a/en/text/maps/underground_path_route_8_entrance.asm b/en/text/maps/underground_path_route_8_entrance.asm
new file mode 100644
index 00000000..da785c8e
--- /dev/null
+++ b/en/text/maps/underground_path_route_8_entrance.asm
@@ -0,0 +1,5 @@
+_UndergroundPathEntRoute8Text1::
+ text "The dept. store"
+ line "in CELADON has a"
+ cont "great selection!"
+ done
diff --git a/en/text/maps/unknown_dungeon_b1f.asm b/en/text/maps/unknown_dungeon_b1f.asm
new file mode 100644
index 00000000..0918a3ce
--- /dev/null
+++ b/en/text/maps/unknown_dungeon_b1f.asm
@@ -0,0 +1,2 @@
+_MewtwoBattleText::
+ text "Mew!@@"
diff --git a/en/text/maps/vermilion_city.asm b/en/text/maps/vermilion_city.asm
new file mode 100644
index 00000000..b060a123
--- /dev/null
+++ b/en/text/maps/vermilion_city.asm
@@ -0,0 +1,126 @@
+_VermilionCityText1::
+ text "We're careful"
+ line "about pollution!"
+
+ para "We've heard GRIMER"
+ line "multiplies in"
+ cont "toxic sludge!"
+ done
+
+_VermilionCityText_198a7::
+ text "Did you see S.S."
+ line "ANNE moored in"
+ cont "the harbor?"
+ done
+
+_VermilionCityText_198ac::
+ text "So, S.S.ANNE has"
+ line "departed!"
+
+ para "She'll be back in"
+ line "about a year."
+ done
+
+_SSAnneWelcomeText4::
+ text "Welcome to S.S."
+ line "ANNE!"
+ done
+
+_SSAnneWelcomeText9::
+ text "Welcome to S.S."
+ line "ANNE!"
+
+ para "Excuse me, do you"
+ line "have a ticket?"
+ prompt
+
+_SSAnneFlashedTicketText::
+ text "<PLAYER> flashed"
+ line "the S.S.TICKET!"
+
+ para "Great! Welcome to"
+ line "S.S.ANNE!"
+ done
+
+_SSAnneNoTicketText::
+ text "<PLAYER> doesn't"
+ line "have the needed"
+ cont "S.S.TICKET."
+
+ para "Sorry!"
+
+ para "You need a ticket"
+ line "to get aboard."
+ done
+
+_SSAnneNotHereText::
+ text "The ship set sail."
+ done
+
+_VermilionCityText4::
+ text "I'm putting up a"
+ line "building on this"
+ cont "plot of land."
+
+ para "My #MON is"
+ line "tamping the land."
+ done
+
+_VermilionCityText5::
+ text "MACHOP: Guoh!"
+ line "Gogogoh!@@"
+
+_VermilionCityText14::
+ text ""
+ para "A MACHOP is"
+ line "stomping the land"
+ cont "flat."
+ done
+
+_VermilionCityText6::
+ text "S.S.ANNE is a"
+ line "famous luxury"
+ cont "cruise ship."
+
+ para "We visit VERMILION"
+ line "once a year."
+ done
+
+_VermilionCityText7::
+ text "VERMILION CITY"
+ line "The Port of"
+ cont "Exquisite Sunsets"
+ done
+
+_VermilionCityText8::
+ text "NOTICE!"
+
+ para "ROUTE 12 may be"
+ line "blocked off by a"
+ cont "sleeping #MON."
+
+ para "Detour through"
+ line "ROCK TUNNEL to"
+ cont "LAVENDER TOWN."
+
+ para "VERMILION POLICE"
+ done
+
+_VermilionCityText11::
+ text "#MON FAN CLUB"
+ line "All #MON fans"
+ cont "welcome!"
+ done
+
+_VermilionCityText12::
+ text "VERMILION CITY"
+ line "#MON GYM"
+ cont "LEADER: LT.SURGE"
+
+ para "The Lightning "
+ line "American!"
+ done
+
+_VermilionCityText13::
+ text "VERMILION HARBOR"
+ done
diff --git a/en/text/maps/vermilion_dock.asm b/en/text/maps/vermilion_dock.asm
new file mode 100644
index 00000000..5d998e82
--- /dev/null
+++ b/en/text/maps/vermilion_dock.asm
@@ -0,0 +1,3 @@
+_VermilionDockText1::
+ text ""
+ done
diff --git a/en/text/maps/vermilion_fishing_house.asm b/en/text/maps/vermilion_fishing_house.asm
new file mode 100644
index 00000000..6857bb5b
--- /dev/null
+++ b/en/text/maps/vermilion_fishing_house.asm
@@ -0,0 +1,53 @@
+_VermilionHouse2Text_560b1::
+ text "I'm the FISHING"
+ line "GURU!"
+
+ para "I simply Looove"
+ line "fishing!"
+
+ para "Do you like to"
+ line "fish?"
+ done
+
+_VermilionHouse2Text_560b6::
+ text "Grand! I like"
+ line "your style!"
+
+ para "Take this and"
+ line "fish, young one!"
+
+ para "<PLAYER> received"
+ line "an @"
+ TX_RAM wcf4b
+ text "!@@"
+
+_VermilionHouse2Text_560bb::
+ db $0
+ para "Fishing is a way"
+ line "of life!"
+
+ para "From the seas to"
+ line "rivers, go out"
+ cont "and land the big"
+ cont "one, young one!"
+ done
+
+_VermilionHouse2Text_560c0::
+ text "Oh... That's so"
+ line "disappointing..."
+ done
+
+_VermilionHouse2Text_560c5::
+ text "Hello there,"
+ line "<PLAYER>!"
+
+ para "How are the fish"
+ line "biting?"
+ done
+
+_VermilionHouse2Text_560ca::
+ text "Oh no!"
+
+ para "You have no room"
+ line "for my gift!"
+ done
diff --git a/en/text/maps/vermilion_gym_1.asm b/en/text/maps/vermilion_gym_1.asm
new file mode 100644
index 00000000..f718d899
--- /dev/null
+++ b/en/text/maps/vermilion_gym_1.asm
@@ -0,0 +1,21 @@
+_VermilionGymText_5cb6d::
+ text "Hey, kid! What do"
+ line "you think you're"
+ cont "doing here?"
+
+ para "You won't live"
+ line "long in combat!"
+ cont "That's for sure!"
+
+ para "I tell you kid,"
+ line "electric #MON"
+ cont "saved me during"
+ cont "the war!"
+
+ para "They zapped my"
+ line "enemies into"
+ cont "paralysis!"
+
+ para "The same as I'll"
+ line "do to you!"
+ done
diff --git a/en/text/maps/vermilion_gym_2.asm b/en/text/maps/vermilion_gym_2.asm
new file mode 100644
index 00000000..d0a01932
--- /dev/null
+++ b/en/text/maps/vermilion_gym_2.asm
@@ -0,0 +1,143 @@
+_VermilionGymText_5cb72::
+ text "A little word of"
+ line "advice, kid!"
+
+ para "Electricity is"
+ line "sure powerful!"
+
+ para "But, it's useless"
+ line "against ground-"
+ cont "type #MON!"
+ done
+
+_VermilionGymText_5cb77::
+ text "The THUNDERBADGE"
+ line "cranks up your"
+ cont "#MON's SPEED!"
+
+ para "It also lets your"
+ line "#MON FLY any"
+ cont "time, kid!"
+
+ para "You're special,"
+ line "kid! Take this!"
+ done
+
+_ReceivedTM24Text::
+ text "<PLAYER> received "
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_TM24ExplanationText::
+ db $0
+ para "TM24 contains"
+ line "THUNDERBOLT!"
+
+ para "Teach it to an"
+ line "electric #MON!"
+ done
+
+_TM24NoRoomText::
+ text "Yo kid, make room"
+ line "in your pack!"
+ done
+
+_ReceivedThunderbadgeText::
+ text "Whoa!"
+
+ para "You're the real"
+ line "deal, kid!"
+
+ para "Fine then, take"
+ line "the THUNDERBADGE!"
+ prompt
+
+_VermilionGymBattleText1::
+ text "When I was in the"
+ line "Army, LT.SURGE"
+ cont "was my strict CO!"
+ done
+
+_VermilionGymEndBattleText1::
+ text "Stop!"
+ line "You're very good!"
+ prompt
+
+_VermilionGymAfterBattleText1::
+ text "The door won't"
+ line "open?"
+
+ para "LT.SURGE always"
+ line "was cautious!"
+ done
+
+_VermilionGymBattleText2::
+ text "I'm a lightweight,"
+ line "but I'm good with"
+ cont "electricity!"
+ done
+
+_VermilionGymEndBattleText2::
+ text "Fried!"
+ prompt
+
+_VermilionGymAfterBattleText2::
+ text "OK, I'll talk!"
+
+ para "LT.SURGE said he"
+ line "hid door switches"
+ cont "inside something!"
+ done
+
+_VermilionGymBattleText3::
+ text "This is no place"
+ line "for kids!"
+ done
+
+_VermilionGymEndBattleText3::
+ text "Wow!"
+ line "Surprised me!"
+ prompt
+
+_VermilionGymAfterBattleText3::
+ text "LT.SURGE set up"
+ line "double locks!"
+ cont "Here's a hint!"
+
+ para "When you open the"
+ line "1st lock, the 2nd"
+ cont "lock is right"
+ cont "next to it!"
+ done
+
+_VermilionGymText_5cbf4::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "LT.SURGE has a"
+ line "nickname. People"
+ cont "refer to him as"
+ cont "the Lightning"
+ cont "American!"
+
+ para "He's an expert on"
+ line "electric #MON!"
+
+ para "Birds and water"
+ line "#MON are at"
+ cont "risk! Beware of"
+ cont "paralysis too!"
+
+ para "LT.SURGE is very"
+ line "cautious!"
+
+ para "You'll have to"
+ line "break a code to"
+ cont "get to him!"
+ done
+
+_VermilionGymText_5cbf9::
+ text "Whew! That match"
+ line "was electric!"
+ done
diff --git a/en/text/maps/vermilion_house.asm b/en/text/maps/vermilion_house.asm
new file mode 100644
index 00000000..91c18708
--- /dev/null
+++ b/en/text/maps/vermilion_house.asm
@@ -0,0 +1,21 @@
+_VermilionHouse1Text1::
+ text "I'm getting my"
+ line "PIDGEY to fly a"
+ cont "letter to SAFFRON"
+ cont "in the north!"
+ done
+
+_VermilionHouse1Text2::
+ text "PIDGEY: Kurukkoo!@@"
+
+_VermilionHouse1Text3::
+ text "Dear PIPPI, I hope"
+ line "to see you soon."
+
+ para "I heard SAFFRON"
+ line "has problems with"
+ cont "TEAM ROCKET."
+
+ para "VERMILION appears"
+ line "to be safe."
+ done
diff --git a/en/text/maps/vermilion_mart.asm b/en/text/maps/vermilion_mart.asm
new file mode 100644
index 00000000..10743989
--- /dev/null
+++ b/en/text/maps/vermilion_mart.asm
@@ -0,0 +1,23 @@
+_VermilionMartText2::
+ text "There are evil"
+ line "people who will"
+ cont "use #MON for"
+ cont "criminal acts."
+
+ para "TEAM ROCKET"
+ line "traffics in rare"
+ cont "#MON."
+
+ para "They also abandon"
+ line "#MON that they"
+ cont "consider not to"
+ cont "be popular or"
+ cont "useful."
+ done
+
+_VermilionMartText3::
+ text "I think #MON"
+ line "can be good or"
+ cont "evil. It depends"
+ cont "on the trainer."
+ done
diff --git a/en/text/maps/vermilion_pokecenter.asm b/en/text/maps/vermilion_pokecenter.asm
new file mode 100644
index 00000000..c9e9a581
--- /dev/null
+++ b/en/text/maps/vermilion_pokecenter.asm
@@ -0,0 +1,19 @@
+_VermilionPokecenterText2::
+ text "Even if they are"
+ line "the same level,"
+ cont "#MON can have"
+ cont "very different"
+ cont "abilities."
+
+ para "A #MON raised"
+ line "by a trainer is"
+ cont "stronger than one"
+ cont "in the wild."
+ done
+
+_VermilionPokecenterText3::
+ text "My #MON was"
+ line "poisoned! It"
+ cont "fainted while we"
+ cont "were walking!"
+ done
diff --git a/en/text/maps/victory_road_1f.asm b/en/text/maps/victory_road_1f.asm
new file mode 100644
index 00000000..1523db88
--- /dev/null
+++ b/en/text/maps/victory_road_1f.asm
@@ -0,0 +1,31 @@
+_VictoryRoad1BattleText1::
+ text "I wonder if you"
+ line "are good enough"
+ cont "for me!"
+ done
+
+_VictoryRoad1EndBattleText1::
+ text "I"
+ line "lost out!"
+ prompt
+
+_VictoryRoad1AfterBattleText1::
+ text "I never wanted to"
+ line "lose to anybody!"
+ done
+
+_VictoryRoad1BattleText2::
+ text "I can see you're"
+ line "good! Let me see"
+ cont "exactly how good!"
+ done
+
+_VictoryRoad1EndBattleText2::
+ text "I"
+ line "had a chance..."
+ prompt
+
+_VictoryRoad1AfterBattleText2::
+ text "I concede, you're"
+ line "better than me!"
+ done
diff --git a/en/text/maps/victory_road_2f.asm b/en/text/maps/victory_road_2f.asm
new file mode 100644
index 00000000..ec9dcf4f
--- /dev/null
+++ b/en/text/maps/victory_road_2f.asm
@@ -0,0 +1,85 @@
+_MoltresBattleText::
+ text "Gyaoo!@@"
+
+_VictoryRoad2BattleText1::
+ text "VICTORY ROAD is"
+ line "the final test"
+ cont "for trainers!"
+ done
+
+_VictoryRoad2EndBattleText1::
+ text "Aiyah!"
+ prompt
+
+_VictoryRoad2AfterBattleText1::
+ text "If you get stuck,"
+ line "try moving some"
+ cont "boulders around!"
+ done
+
+_VictoryRoad2BattleText2::
+ text "Ah, so you wish"
+ line "to challenge the"
+ cont "ELITE FOUR?"
+ done
+
+_VictoryRoad2EndBattleText2::
+ text "You"
+ line "got me!"
+ prompt
+
+_VictoryRoad2AfterBattleText2::
+ text "<RIVAL> also came"
+ line "through here!"
+ done
+
+_VictoryRoad2BattleText3::
+ text "Come on!"
+ line "I'll whip you!"
+ done
+
+_VictoryRoad2EndBattleText3::
+ text "I got"
+ line "whipped!"
+ prompt
+
+_VictoryRoad2AfterBattleText3::
+ text "You earned the"
+ line "right to be on"
+ cont "VICTORY ROAD!"
+ done
+
+_VictoryRoad2BattleText4::
+ text "If you can get"
+ line "through here, you"
+ cont "can go meet the"
+ cont "ELITE FOUR!"
+ done
+
+_VictoryRoad2EndBattleText4::
+ text "No!"
+ line "Unbelievable!"
+ prompt
+
+_VictoryRoad2AfterBattleText4::
+ text "I can beat you"
+ line "when it comes to"
+ cont "knowledge about"
+ cont "#MON!"
+ done
+
+_VictoryRoad2BattleText5::
+ text "Is VICTORY ROAD"
+ line "too tough?"
+ done
+
+_VictoryRoad2EndBattleText5::
+ text "Well"
+ line "done!"
+ prompt
+
+_VictoryRoad2AfterBattleText5::
+ text "Many trainers give"
+ line "up the challenge"
+ cont "here."
+ done
diff --git a/en/text/maps/victory_road_3f.asm b/en/text/maps/victory_road_3f.asm
new file mode 100644
index 00000000..07e0be70
--- /dev/null
+++ b/en/text/maps/victory_road_3f.asm
@@ -0,0 +1,63 @@
+_VictoryRoad3BattleText2::
+ text "I heard rumors of"
+ line "a child prodigy!"
+ done
+
+_VictoryRoad3EndBattleText2::
+ text "The"
+ line "rumors were true!"
+ prompt
+
+_VictoryRoad3AfterBattleText2::
+ text "You beat GIOVANNI"
+ line "of TEAM ROCKET?"
+ done
+
+_VictoryRoad3BattleText3::
+ text "I'll show you just"
+ line "how good you are!"
+ done
+
+_VictoryRoad3EndBattleText3::
+ text "I'm"
+ line "furious!"
+ prompt
+
+_VictoryRoad3AfterBattleText3::
+ text "You showed me just"
+ line "how good I was!"
+ done
+
+_VictoryRoad3BattleText4::
+ text "Only the chosen"
+ line "can pass here!"
+ done
+
+_VictoryRoad3EndBattleText4::
+ text "I"
+ line "don't believe it!"
+ prompt
+
+_VictoryRoad3AfterBattleText4::
+ text "All trainers here"
+ line "are headed to the"
+ cont "#MON LEAGUE!"
+ cont "Be careful!"
+ done
+
+_VictoryRoad3BattleText5::
+ text "Trainers live to"
+ line "seek stronger"
+ cont "opponents!"
+ done
+
+_VictoryRoad3EndBattleText5::
+ text "Oh!"
+ line "So strong!"
+ prompt
+
+_VictoryRoad3AfterBattleText5::
+ text "By fighting tough"
+ line "battles, you get"
+ cont "stronger!"
+ done
diff --git a/en/text/maps/viridian_city.asm b/en/text/maps/viridian_city.asm
new file mode 100644
index 00000000..67ab5c40
--- /dev/null
+++ b/en/text/maps/viridian_city.asm
@@ -0,0 +1,180 @@
+_ViridianCityText1::
+ text "Those # BALLs"
+ line "at your waist!"
+ cont "You have #MON!"
+
+ para "It's great that"
+ line "you can carry and"
+ cont "use #MON any"
+ cont "time, anywhere!"
+ done
+
+_ViridianCityText_19122::
+ text "This #MON GYM"
+ line "is always closed."
+
+ para "I wonder who the"
+ line "LEADER is?"
+ done
+
+_ViridianCityText_19127::
+ text "VIRIDIAN GYM's"
+ line "LEADER returned!"
+ done
+
+_ViridianCityText_1914d::
+ text "You want to know"
+ line "about the 2 kinds"
+ cont "of caterpillar"
+ cont "#MON?"
+ done
+
+_ViridianCityText_19152::
+ text "Oh, OK then!"
+ done
+
+_ViridianCityText_19157::
+ text "CATERPIE has no"
+ line "poison, but"
+ cont "WEEDLE does."
+
+ para "Watch out for its"
+ line "POISON STING!"
+ done
+
+_ViridianCityText_19175::
+ text "Oh Grandpa! Don't"
+ line "be so mean!"
+ cont "He hasn't had his"
+ cont "coffee yet."
+ done
+
+_ViridianCityText_1917a::
+ text "When I go shop in"
+ line "PEWTER CITY, I"
+ cont "have to take the"
+ cont "winding trail in"
+ cont "VIRIDIAN FOREST."
+ done
+
+_ViridianCityText_19191::
+ text "You can't go"
+ line "through here!"
+
+ para "This is private"
+ line "property!"
+ done
+
+_ViridianCityText_191ca::
+ text "Yawn!"
+ line "I must have dozed"
+ cont "off in the sun."
+
+ para "I had this dream"
+ line "about a DROWZEE"
+ cont "eating my dream."
+ cont "What's this?"
+ cont "Where did this TM"
+ cont "come from?"
+
+ para "This is spooky!"
+ line "Here, you can"
+ cont "have this TM."
+ prompt
+
+_ReceivedTM42Text::
+ text "<PLAYER> received"
+ line "TM42!@@"
+
+_TM42Explanation::
+ text "TM42 contains"
+ line "DREAM EATER..."
+ cont "...Snore..."
+ done
+
+_TM42NoRoomText::
+ text "You have too much"
+ line "stuff already."
+ done
+
+_ViridianCityText_1920a::
+ text "Ahh, I've had my"
+ line "coffee now and I"
+ cont "feel great!"
+
+ para "Sure you can go"
+ line "through!"
+
+ para "Are you in a"
+ line "hurry?"
+ done
+
+_ViridianCityText_1920f::
+ text "I see you're using"
+ line "a #DEX."
+
+ para "When you catch a"
+ line "#MON, #DEX"
+ cont "is automatically"
+ cont "updated."
+
+ para "What? Don't you"
+ line "know how to catch"
+ cont "#MON?"
+
+ para "I'll show you"
+ line "how to then."
+ done
+
+_ViridianCityText_19214::
+ text "Time is money..."
+ line "Go along then."
+ done
+
+_ViridianCityText_19219::
+ text "First, you need"
+ line "to weaken the"
+ cont "target #MON."
+ done
+
+_ViridianCityText8::
+ text "VIRIDIAN CITY "
+ line "The Eternally"
+ cont "Green Paradise"
+ done
+
+_ViridianCityText9::
+ text "TRAINER TIPS"
+
+ para "Catch #MON"
+ line "and expand your"
+ cont "collection!"
+
+ para "The more you have,"
+ line "the easier it is"
+ cont "to fight!"
+ done
+
+_ViridianCityText10::
+ text "TRAINER TIPS"
+
+ para "The battle moves"
+ line "of #MON are"
+ cont "limited by their"
+ cont "POWER POINTs, PP."
+
+ para "To replenish PP,"
+ line "rest your tired"
+ cont "#MON at a"
+ cont "#MON CENTER!"
+ done
+
+_ViridianCityText13::
+ text "VIRIDIAN CITY"
+ line "#MON GYM"
+ done
+
+_ViridianCityText14::
+ text "The GYM's doors"
+ line "are locked..."
+ done
diff --git a/en/text/maps/viridian_forest.asm b/en/text/maps/viridian_forest.asm
new file mode 100644
index 00000000..813b193a
--- /dev/null
+++ b/en/text/maps/viridian_forest.asm
@@ -0,0 +1,123 @@
+_ViridianForestText1::
+ text "I came here with"
+ line "some friends!"
+
+ para "They're out for"
+ line "#MON fights!"
+ done
+
+_ViridianForestBattleText1::
+ text "Hey! You have"
+ line "#MON! Come on!"
+ cont "Let's battle'em!"
+ done
+
+_ViridianForestEndBattleText1::
+ text "No!"
+ line "CATERPIE can't"
+ cont "cut it!"
+ prompt
+
+_ViridianFrstAfterBattleText1::
+ text "Ssh! You'll scare"
+ line "the bugs away!"
+ done
+
+_ViridianForestBattleText2::
+ text "Yo! You can't jam"
+ line "out if you're a"
+ cont "#MON trainer!"
+ done
+
+_ViridianForestEndBattleText2::
+ text "Huh?"
+ line "I ran out of"
+ cont "#MON!"
+ prompt
+
+_ViridianFrstAfterBattleText2::
+ text "Darn! I'm going"
+ line "to catch some"
+ cont "stronger ones!"
+ done
+
+_ViridianForestBattleText3::
+ text "Hey, wait up!"
+ line "What's the hurry?"
+ done
+
+_ViridianForestEndBattleText3::
+ text "I"
+ line "give! You're good"
+ cont "at this!"
+ prompt
+
+_ViridianFrstAfterBattleText3::
+ text "Sometimes, you"
+ line "can find stuff on"
+ cont "the ground!"
+
+ para "I'm looking for"
+ line "the stuff I"
+ cont "dropped!"
+ done
+
+_ViridianForestText8::
+ text "I ran out of #"
+ line "BALLs to catch"
+ cont "#MON with!"
+
+ para "You should carry"
+ line "extras!"
+ done
+
+_ViridianForestText9::
+ text "TRAINER TIPS"
+
+ para "If you want to"
+ line "avoid battles,"
+ cont "stay away from"
+ cont "grassy areas!"
+ done
+
+_ViridianForestText10::
+ text "For poison, use"
+ line "ANTIDOTE! Get it"
+ cont "at #MON MARTs!"
+ done
+
+_ViridianForestText11::
+ text "TRAINER TIPS"
+
+ para "Contact PROF.OAK"
+ line "via PC to get"
+ cont "your #DEX"
+ cont "evaluated!"
+ done
+
+_ViridianForestText12::
+ text "TRAINER TIPS"
+
+ para "No stealing of"
+ line "#MON from"
+ cont "other trainers!"
+ cont "Catch only wild"
+ cont "#MON!"
+ done
+
+_ViridianForestText13::
+ text "TRAINER TIPS"
+
+ para "Weaken #MON"
+ line "before attempting"
+ cont "capture!"
+
+ para "When healthy,"
+ line "they may escape!"
+ done
+
+_ViridianForestText14::
+ text "LEAVING"
+ line "VIRIDIAN FOREST"
+ cont "PEWTER CITY AHEAD"
+ done
diff --git a/en/text/maps/viridian_forest_entrance.asm b/en/text/maps/viridian_forest_entrance.asm
new file mode 100644
index 00000000..c1a8df22
--- /dev/null
+++ b/en/text/maps/viridian_forest_entrance.asm
@@ -0,0 +1,13 @@
+_ViridianForestEntranceText1::
+ text "Are you going to"
+ line "VIRIDIAN FOREST?"
+ cont "Be careful, it's"
+ cont "a natural maze!"
+ done
+
+_ViridianForestEntranceText2::
+ text "RATTATA may be"
+ line "small, but its"
+ cont "bite is wicked!"
+ cont "Did you get one?"
+ done
diff --git a/en/text/maps/viridian_forest_exit.asm b/en/text/maps/viridian_forest_exit.asm
new file mode 100644
index 00000000..ab6a5a1d
--- /dev/null
+++ b/en/text/maps/viridian_forest_exit.asm
@@ -0,0 +1,19 @@
+_ViridianForestExitText1::
+ text "Many #MON live"
+ line "only in forests "
+ cont "and caves."
+
+ para "You need to look"
+ line "everywhere to get"
+ cont "different kinds!"
+ done
+
+_ViridianForestExitText2::
+ text "Have you noticed"
+ line "the bushes on the"
+ cont "roadside?"
+
+ para "They can be cut"
+ line "down by a special"
+ cont "#MON move."
+ done
diff --git a/en/text/maps/viridian_gym.asm b/en/text/maps/viridian_gym.asm
new file mode 100644
index 00000000..f87d8d58
--- /dev/null
+++ b/en/text/maps/viridian_gym.asm
@@ -0,0 +1,236 @@
+_ViridianGymText_74ace::
+ text "Fwahahaha! This is"
+ line "my hideout!"
+
+ para "I planned to"
+ line "resurrect TEAM"
+ cont "ROCKET here!"
+
+ para "But, you have"
+ line "caught me again!"
+ cont "So be it! This"
+ cont "time, I'm not"
+ cont "holding back!"
+
+ para "Once more, you"
+ line "shall face"
+ cont "GIOVANNI, the"
+ cont "greatest trainer!"
+ done
+
+_ViridianGymText_74ad3::
+ text "Ha!"
+ line "That was a truly"
+ cont "intense fight!"
+ cont "You have won!"
+ cont "As proof, here is"
+ cont "the EARTHBADGE!@@"
+
+_ViridianGymText_74ad9::
+ text "Having lost, I"
+ line "cannot face my"
+ cont "underlings!"
+ cont "TEAM ROCKET is"
+ cont "finished forever!"
+
+ para "I will dedicate my"
+ line "life to the study"
+ cont "of #MON!"
+
+ para "Let us meet again"
+ line "some day!"
+ cont "Farewell!@@"
+
+_ViridianGymText12::
+ text "The EARTHBADGE"
+ line "makes #MON of"
+ cont "any level obey!"
+
+ para "It is evidence of"
+ line "your mastery as a"
+ cont "#MON trainer!"
+
+ para "With it, you can"
+ line "enter the #MON"
+ cont "LEAGUE!"
+
+ para "It is my gift for"
+ line "your #MON"
+ cont "LEAGUE challenge!"
+ done
+
+_ReceivedTM27Text::
+ text "<PLAYER> received"
+ line "TM27!@@"
+
+_TM27ExplanationText::
+ db $0
+ para "TM27 is FISSURE!"
+ line "It will take out"
+ cont "#MON with just"
+ cont "one hit!"
+
+ para "I made it when I"
+ line "ran the GYM here,"
+ cont "too long ago..."
+ done
+
+_TM27NoRoomText::
+ text "You do not have"
+ line "space for this!"
+ done
+
+_ViridianGymBattleText1::
+ text "Heh! You must be"
+ line "running out of"
+ cont "steam by now!"
+ done
+
+_ViridianGymEndBattleText1::
+ text "I"
+ line "ran out of gas!"
+ prompt
+
+_ViridianGymAfterBattleText1::
+ text "You need power to"
+ line "keep up with our"
+ cont "GYM LEADER!"
+ done
+
+_ViridianGymBattleText2::
+ text "Rrrroar! I'm"
+ line "working myself"
+ cont "into a rage!"
+ done
+
+_ViridianGymEndBattleText2::
+ text "Wargh!"
+ prompt
+
+_ViridianGymAfterBattleText2::
+ text "I'm still not"
+ line "worthy!"
+ done
+
+_ViridianGymBattleText3::
+ text "#MON and I, we"
+ line "make wonderful"
+ cont "music together!"
+ done
+
+_ViridianGymEndBattleText3::
+ text "You are in"
+ line "perfect harmony!"
+ prompt
+
+_ViridianGymAfterBattleText3::
+ text "Do you know the"
+ line "identity of our"
+ cont "GYM LEADER?"
+ done
+
+_ViridianGymBattleText4::
+ text "Karate is the"
+ line "ultimate form of"
+ cont "martial arts!"
+ done
+
+_ViridianGymEndBattleText4::
+ text "Atcho!"
+ prompt
+
+_ViridianGymAfterBattleText4::
+ text "If my #MON"
+ line "were as good at"
+ cont "Karate as I..."
+ done
+
+_ViridianGymBattleText5::
+ text "The truly talented"
+ line "win with style!"
+ done
+
+_ViridianGymEndBattleText5::
+ text "I"
+ line "lost my grip!"
+ prompt
+
+_ViridianGymAfterBattleText5::
+ text "The LEADER will"
+ line "scold me!"
+ done
+
+_ViridianGymBattleText6::
+ text "I'm the KARATE"
+ line "KING! Your fate"
+ cont "rests with me!"
+ done
+
+_ViridianGymEndBattleText6::
+ text "Ayah!"
+ prompt
+
+_ViridianGymAfterBattleText6::
+ text "#MON LEAGUE?"
+ line "You? Don't get"
+ cont "cocky!"
+ done
+
+_ViridianGymBattleText7::
+ text "Your #MON will"
+ line "cower at the"
+ cont "crack of my whip!"
+ done
+
+_ViridianGymEndBattleText7::
+ text "Yowch!"
+ line "Whiplash!"
+ prompt
+
+_ViridianGymAfterBattleText7::
+ text "Wait! I was just"
+ line "careless!"
+ done
+
+_ViridianGymBattleText8::
+ text "VIRIDIAN GYM was"
+ line "closed for a long"
+ cont "time, but now our"
+ cont "LEADER is back!"
+ done
+
+_ViridianGymEndBattleText8::
+ text "I"
+ line "was beaten?"
+ prompt
+
+_ViridianGymAfterBattleText8::
+ text "You can go onto"
+ line "#MON LEAGUE"
+ cont "only by defeating"
+ cont "our GYM LEADER!"
+ done
+
+_ViridianGymText_74bd4::
+ text "Yo! Champ in"
+ line "making!"
+
+ para "Even I don't know"
+ line "VIRIDIAN LEADER's"
+ cont "identity!"
+
+ para "This will be the"
+ line "toughest of all"
+ cont "the GYM LEADERs!"
+
+ para "I heard that the"
+ line "trainers here"
+ cont "like ground-type"
+ cont "#MON!"
+ done
+
+_ViridianGymText_74bd9::
+ text "Blow me away!"
+ line "GIOVANNI was the"
+ cont "GYM LEADER here?"
+ done
diff --git a/en/text/maps/viridian_house.asm b/en/text/maps/viridian_house.asm
new file mode 100644
index 00000000..757f597a
--- /dev/null
+++ b/en/text/maps/viridian_house.asm
@@ -0,0 +1,23 @@
+_ViridianHouseText1::
+ text "Coming up with"
+ line "nicknames is fun,"
+ cont "but hard."
+
+ para "Simple names are"
+ line "the easiest to"
+ cont "remember."
+ done
+
+_ViridianHouseText2::
+ text "My Daddy loves"
+ line "#MON too."
+ done
+
+_ViridianHouseText_1d5b1::
+ text "SPEARY: Tetweet!"
+ done
+
+_ViridianHouseText4::
+ text "SPEAROW"
+ line "Name: SPEARY"
+ done
diff --git a/en/text/maps/viridian_mart.asm b/en/text/maps/viridian_mart.asm
new file mode 100644
index 00000000..61750afe
--- /dev/null
+++ b/en/text/maps/viridian_mart.asm
@@ -0,0 +1,30 @@
+_ViridianMartText1::
+ text "Okay! Say hi to"
+ line "PROF.OAK for me!"
+ done
+
+_ViridianMartText4::
+ text "Hey! You came from"
+ line "PALLET TOWN?"
+ done
+
+ViridianMartParcelQuestText::
+ text "You know PROF."
+ line "OAK, right?"
+
+ para "His order came in."
+ line "Will you take it"
+ cont "to him?"
+
+ para "<PLAYER> got"
+ line "OAK's PARCEL!@@"
+
+_ViridianMartText2::
+ text "This shop sells"
+ line "many ANTIDOTEs."
+ done
+
+_ViridianMartText3::
+ text "No! POTIONs are"
+ line "all sold out."
+ done
diff --git a/en/text/maps/viridian_pokecenter.asm b/en/text/maps/viridian_pokecenter.asm
new file mode 100644
index 00000000..4ac18bf6
--- /dev/null
+++ b/en/text/maps/viridian_pokecenter.asm
@@ -0,0 +1,16 @@
+_ViridianPokeCenterText2::
+ text "You can use that"
+ line "PC in the corner."
+
+ para "The receptionist"
+ line "told me. So kind!"
+ done
+
+_ViridianPokeCenterText3::
+ text "There's a #MON"
+ line "CENTER in every"
+ cont "town ahead."
+
+ para "They don't charge"
+ line "any money either!"
+ done
diff --git a/en/text/maps/wardens_house.asm b/en/text/maps/wardens_house.asm
new file mode 100644
index 00000000..9d40cace
--- /dev/null
+++ b/en/text/maps/wardens_house.asm
@@ -0,0 +1,83 @@
+_WardenGibberishText1::
+ text "WARDEN: Hif fuff"
+ line "hefifoo!"
+
+ para "Ha lof ha feef ee"
+ line "hafahi ho. Heff"
+ cont "hee fwee!"
+ done
+
+_WardenGibberishText2::
+ text "Ah howhee ho hoo!"
+ line "Eef ee hafahi ho!"
+ done
+
+_WardenGibberishText3::
+ text "Ha? He ohay heh"
+ line "ha hoo ee haheh!"
+ done
+
+_WardenTeethText1::
+ text "<PLAYER> gave the"
+ line "GOLD TEETH to the"
+ cont "WARDEN!@@"
+
+_WardenTeethText2::
+ db $0
+ para "The WARDEN popped"
+ line "in his teeth!"
+ prompt
+
+_WardenThankYouText::
+ text "WARDEN: Thanks,"
+ line "kid! No one could"
+ cont "understand a word"
+ cont "that I said."
+
+ para "I couldn't work"
+ line "that way."
+ cont "Let me give you"
+ cont "something for"
+ cont "your trouble."
+ prompt
+
+_ReceivedHM04Text::
+ text "<PLAYER> received"
+ line "@"
+ TX_RAM wcf4b
+ text "!@@"
+
+_HM04ExplanationText::
+ text "WARDEN: HM04"
+ line "teaches STRENGTH!"
+
+ para "It lets #MON"
+ line "move boulders"
+ cont "when you're out-"
+ cont "side of battle."
+
+ para "Oh yes, did you"
+ line "find SECRET HOUSE"
+ cont "in SAFARI ZONE?"
+
+ para "If you do, you"
+ line "win an HM!"
+
+ para "I hear it's the"
+ line "rare SURF HM."
+ done
+
+_HM04NoRoomText::
+ text "Your pack is"
+ line "stuffed full!"
+ done
+
+_FuchsiaHouse2Text_75176::
+ text "#MON photos"
+ line "and fossils."
+ done
+
+_FuchsiaHouse2Text_7517b::
+ text "Old #MON"
+ line "merchandise."
+ done
diff --git a/en/text/monster_names.asm b/en/text/monster_names.asm
new file mode 100755
index 00000000..a62b1bd9
--- /dev/null
+++ b/en/text/monster_names.asm
@@ -0,0 +1,191 @@
+MonsterNames:
+ db "RHYDON@@@@"
+ db "KANGASKHAN"
+ db "NIDORAN♂@@"
+ db "CLEFAIRY@@"
+ db "SPEAROW@@@"
+ db "VOLTORB@@@"
+ db "NIDOKING@@"
+ db "SLOWBRO@@@"
+ db "IVYSAUR@@@"
+ db "EXEGGUTOR@"
+ db "LICKITUNG@"
+ db "EXEGGCUTE@"
+ db "GRIMER@@@@"
+ db "GENGAR@@@@"
+ db "NIDORAN♀@@"
+ db "NIDOQUEEN@"
+ db "CUBONE@@@@"
+ db "RHYHORN@@@"
+ db "LAPRAS@@@@"
+ db "ARCANINE@@"
+ db "MEW@@@@@@@"
+ db "GYARADOS@@"
+ db "SHELLDER@@"
+ db "TENTACOOL@"
+ db "GASTLY@@@@"
+ db "SCYTHER@@@"
+ db "STARYU@@@@"
+ db "BLASTOISE@"
+ db "PINSIR@@@@"
+ db "TANGELA@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "GROWLITHE@"
+ db "ONIX@@@@@@"
+ db "FEAROW@@@@"
+ db "PIDGEY@@@@"
+ db "SLOWPOKE@@"
+ db "KADABRA@@@"
+ db "GRAVELER@@"
+ db "CHANSEY@@@"
+ db "MACHOKE@@@"
+ db "MR.MIME@@@"
+ db "HITMONLEE@"
+ db "HITMONCHAN"
+ db "ARBOK@@@@@"
+ db "PARASECT@@"
+ db "PSYDUCK@@@"
+ db "DROWZEE@@@"
+ db "GOLEM@@@@@"
+ db "MISSINGNO."
+ db "MAGMAR@@@@"
+ db "MISSINGNO."
+ db "ELECTABUZZ"
+ db "MAGNETON@@"
+ db "KOFFING@@@"
+ db "MISSINGNO."
+ db "MANKEY@@@@"
+ db "SEEL@@@@@@"
+ db "DIGLETT@@@"
+ db "TAUROS@@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "FARFETCH'D"
+ db "VENONAT@@@"
+ db "DRAGONITE@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "DODUO@@@@@"
+ db "POLIWAG@@@"
+ db "JYNX@@@@@@"
+ db "MOLTRES@@@"
+ db "ARTICUNO@@"
+ db "ZAPDOS@@@@"
+ db "DITTO@@@@@"
+ db "MEOWTH@@@@"
+ db "KRABBY@@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "VULPIX@@@@"
+ db "NINETALES@"
+ db "PIKACHU@@@"
+ db "RAICHU@@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "DRATINI@@@"
+ db "DRAGONAIR@"
+ db "KABUTO@@@@"
+ db "KABUTOPS@@"
+ db "HORSEA@@@@"
+ db "SEADRA@@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "SANDSHREW@"
+ db "SANDSLASH@"
+ db "OMANYTE@@@"
+ db "OMASTAR@@@"
+ db "JIGGLYPUFF"
+ db "WIGGLYTUFF"
+ db "EEVEE@@@@@"
+ db "FLAREON@@@"
+ db "JOLTEON@@@"
+ db "VAPOREON@@"
+ db "MACHOP@@@@"
+ db "ZUBAT@@@@@"
+ db "EKANS@@@@@"
+ db "PARAS@@@@@"
+ db "POLIWHIRL@"
+ db "POLIWRATH@"
+ db "WEEDLE@@@@"
+ db "KAKUNA@@@@"
+ db "BEEDRILL@@"
+ db "MISSINGNO."
+ db "DODRIO@@@@"
+ db "PRIMEAPE@@"
+ db "DUGTRIO@@@"
+ db "VENOMOTH@@"
+ db "DEWGONG@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "CATERPIE@@"
+ db "METAPOD@@@"
+ db "BUTTERFREE"
+ db "MACHAMP@@@"
+ db "MISSINGNO."
+ db "GOLDUCK@@@"
+ db "HYPNO@@@@@"
+ db "GOLBAT@@@@"
+ db "MEWTWO@@@@"
+ db "SNORLAX@@@"
+ db "MAGIKARP@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MUK@@@@@@@"
+ db "MISSINGNO."
+ db "KINGLER@@@"
+ db "CLOYSTER@@"
+ db "MISSINGNO."
+ db "ELECTRODE@"
+ db "CLEFABLE@@"
+ db "WEEZING@@@"
+ db "PERSIAN@@@"
+ db "MAROWAK@@@"
+ db "MISSINGNO."
+ db "HAUNTER@@@"
+ db "ABRA@@@@@@"
+ db "ALAKAZAM@@"
+ db "PIDGEOTTO@"
+ db "PIDGEOT@@@"
+ db "STARMIE@@@"
+ db "BULBASAUR@"
+ db "VENUSAUR@@"
+ db "TENTACRUEL"
+ db "MISSINGNO."
+ db "GOLDEEN@@@"
+ db "SEAKING@@@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "PONYTA@@@@"
+ db "RAPIDASH@@"
+ db "RATTATA@@@"
+ db "RATICATE@@"
+ db "NIDORINO@@"
+ db "NIDORINA@@"
+ db "GEODUDE@@@"
+ db "PORYGON@@@"
+ db "AERODACTYL"
+ db "MISSINGNO."
+ db "MAGNEMITE@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "CHARMANDER"
+ db "SQUIRTLE@@"
+ db "CHARMELEON"
+ db "WARTORTLE@"
+ db "CHARIZARD@"
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "MISSINGNO."
+ db "ODDISH@@@@"
+ db "GLOOM@@@@@"
+ db "VILEPLUME@"
+ db "BELLSPROUT"
+ db "WEEPINBELL"
+ db "VICTREEBEL"
diff --git a/en/text/move_names.asm b/en/text/move_names.asm
index fb01d6fb..cbbe9c79 100644
--- a/en/text/move_names.asm
+++ b/en/text/move_names.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_bank_constants.asm"
SECTION "Move Names", ROMX, BANK[MOVE_NAMES]
diff --git a/en/text/oakspeech.asm b/en/text/oakspeech.asm
new file mode 100644
index 00000000..e006d16f
--- /dev/null
+++ b/en/text/oakspeech.asm
@@ -0,0 +1,55 @@
+_OakSpeechText1::
+ text "Hello there!"
+ line "Welcome to the"
+ cont "world of #MON!"
+
+ para "My name is OAK!"
+ line "People call me"
+ cont "the #MON PROF!"
+ prompt
+
+_OakSpeechText2A::
+ text "This world is"
+ line "inhabited by"
+ cont "creatures called"
+ cont "#MON!@@"
+
+_OakSpeechText2B::
+ text $51,"For some people,"
+ line "#MON are"
+ cont "pets. Others use"
+ cont "them for fights."
+
+ para "Myself..."
+
+ para "I study #MON"
+ line "as a profession."
+ prompt
+
+_IntroducePlayerText::
+ text "First, what is"
+ line "your name?"
+ prompt
+
+_IntroduceRivalText::
+ text "This is my grand-"
+ line "son. He's been"
+ cont "your rival since"
+ cont "you were a baby."
+
+ para "...Erm, what is"
+ line "his name again?"
+ prompt
+
+_OakSpeechText3::
+ text "<PLAYER>!"
+
+ para "Your very own"
+ line "#MON legend is"
+ cont "about to unfold!"
+
+ para "A world of dreams"
+ line "and adventures"
+ cont "with #MON"
+ cont "awaits! Let's go!"
+ done
diff --git a/en/text/pokedex_text.asm b/en/text/pokedex_text.asm
index 6bb43d94..83a686f7 100644
--- a/en/text/pokedex_text.asm
+++ b/en/text/pokedex_text.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
diff --git a/en/text/text1.asm b/en/text/text1.asm
index 6d56a899..e33ba17d 100644
--- a/en/text/text1.asm
+++ b/en/text/text1.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -152,26 +153,26 @@ _OaksAideNoRoomText::
text "."
done
-INCLUDE "text/maps/viridian_forest.asm"
-INCLUDE "text/maps/mt_moon_1f.asm"
-INCLUDE "text/maps/mt_moon_b1f.asm"
-INCLUDE "text/maps/mt_moon_b2f.asm"
-INCLUDE "text/maps/ss_anne_1.asm"
-INCLUDE "text/maps/ss_anne_2.asm"
-INCLUDE "text/maps/ss_anne_3.asm"
-INCLUDE "text/maps/ss_anne_5.asm"
-INCLUDE "text/maps/ss_anne_6.asm"
-INCLUDE "text/maps/ss_anne_7.asm"
-INCLUDE "text/maps/ss_anne_8.asm"
-INCLUDE "text/maps/ss_anne_9.asm"
-INCLUDE "text/maps/ss_anne_10.asm"
-INCLUDE "text/maps/victory_road_3f.asm"
-INCLUDE "text/maps/rocket_hideout_b1f.asm"
-INCLUDE "text/maps/rocket_hideout_b2f.asm"
-INCLUDE "text/maps/rocket_hideout_b3f.asm"
-INCLUDE "text/maps/rocket_hideout_b4f.asm"
-INCLUDE "text/maps/rocket_hideout_elevator.asm"
-INCLUDE "text/maps/silph_co_2f.asm"
-INCLUDE "text/maps/silph_co_3f.asm"
-INCLUDE "text/maps/silph_co_4f.asm"
-INCLUDE "text/maps/silph_co_5f_1.asm"
+ inclang text/maps/viridian_forest.asm
+ inclang text/maps/mt_moon_1f.asm
+ inclang text/maps/mt_moon_b1f.asm
+ inclang text/maps/mt_moon_b2f.asm
+ inclang text/maps/ss_anne_1.asm
+ inclang text/maps/ss_anne_2.asm
+ inclang text/maps/ss_anne_3.asm
+ inclang text/maps/ss_anne_5.asm
+ inclang text/maps/ss_anne_6.asm
+ inclang text/maps/ss_anne_7.asm
+ inclang text/maps/ss_anne_8.asm
+ inclang text/maps/ss_anne_9.asm
+ inclang text/maps/ss_anne_10.asm
+ inclang text/maps/victory_road_3f.asm
+ inclang text/maps/rocket_hideout_b1f.asm
+ inclang text/maps/rocket_hideout_b2f.asm
+ inclang text/maps/rocket_hideout_b3f.asm
+ inclang text/maps/rocket_hideout_b4f.asm
+ inclang text/maps/rocket_hideout_elevator.asm
+ inclang text/maps/silph_co_2f.asm
+ inclang text/maps/silph_co_3f.asm
+ inclang text/maps/silph_co_4f.asm
+ inclang text/maps/silph_co_5f_1.asm
diff --git a/en/text/text10.asm b/en/text/text10.asm
index d8ab5527..ec41e6ca 100644
--- a/en/text/text10.asm
+++ b/en/text/text10.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -109,16 +110,16 @@ _BoxIsFullText::
line "a #MON CENTER!"
done
-INCLUDE "text/maps/pallet_town.asm"
-INCLUDE "text/maps/viridian_city.asm"
-INCLUDE "text/maps/pewter_city.asm"
-INCLUDE "text/maps/cerulean_city.asm"
-INCLUDE "text/maps/lavender_town.asm"
-INCLUDE "text/maps/vermilion_city.asm"
-INCLUDE "text/maps/celadon_city.asm"
-INCLUDE "text/maps/fuchsia_city.asm"
-INCLUDE "text/maps/cinnabar_island.asm"
-INCLUDE "text/maps/saffron_city.asm"
+ inclang text/maps/pallet_town.asm
+ inclang text/maps/viridian_city.asm
+ inclang text/maps/pewter_city.asm
+ inclang text/maps/cerulean_city.asm
+ inclang text/maps/lavender_town.asm
+ inclang text/maps/vermilion_city.asm
+ inclang text/maps/celadon_city.asm
+ inclang text/maps/fuchsia_city.asm
+ inclang text/maps/cinnabar_island.asm
+ inclang text/maps/saffron_city.asm
_ItemUseBallText00::
text "It dodged the"
diff --git a/en/text/text11.asm b/en/text/text11.asm
index 4b5b8b01..21a1793a 100644
--- a/en/text/text11.asm
+++ b/en/text/text11.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
diff --git a/en/text/text2.asm b/en/text/text2.asm
index 78ca8bbf..b20dfa19 100644
--- a/en/text/text2.asm
+++ b/en/text/text2.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,31 +7,31 @@ INCLUDE "hram.asm"
SECTION "Text 2", ROMX, BANK[TEXT_2]
-INCLUDE "text/maps/silph_co_5f_2.asm"
-INCLUDE "text/maps/silph_co_6f.asm"
-INCLUDE "text/maps/silph_co_7f.asm"
-INCLUDE "text/maps/silph_co_8f.asm"
-INCLUDE "text/maps/silph_co_9f.asm"
-INCLUDE "text/maps/silph_co_10f.asm"
-INCLUDE "text/maps/silph_co_11f.asm"
-INCLUDE "text/maps/mansion_2f.asm"
-INCLUDE "text/maps/mansion_3f.asm"
-INCLUDE "text/maps/mansion_b1f.asm"
-INCLUDE "text/maps/safari_zone_east.asm"
-INCLUDE "text/maps/safari_zone_north.asm"
-INCLUDE "text/maps/safari_zone_west.asm"
-INCLUDE "text/maps/safari_zone_center.asm"
-INCLUDE "text/maps/safari_zone_rest_house_1.asm"
-INCLUDE "text/maps/safari_zone_secret_house.asm"
-INCLUDE "text/maps/safari_zone_rest_house_2.asm"
-INCLUDE "text/maps/safari_zone_rest_house_3.asm"
-INCLUDE "text/maps/safari_zone_rest_house_4.asm"
-INCLUDE "text/maps/unknown_dungeon_b1f.asm"
-INCLUDE "text/maps/victory_road_1f.asm"
-INCLUDE "text/maps/lance.asm"
-INCLUDE "text/maps/hall_of_fame.asm"
-INCLUDE "text/maps/champion.asm"
-INCLUDE "text/maps/lorelei.asm"
-INCLUDE "text/maps/bruno.asm"
-INCLUDE "text/maps/agatha.asm"
-INCLUDE "text/maps/rock_tunnel_b2f_1.asm"
+ inclang text/maps/silph_co_5f_2.asm
+ inclang text/maps/silph_co_6f.asm
+ inclang text/maps/silph_co_7f.asm
+ inclang text/maps/silph_co_8f.asm
+ inclang text/maps/silph_co_9f.asm
+ inclang text/maps/silph_co_10f.asm
+ inclang text/maps/silph_co_11f.asm
+ inclang text/maps/mansion_2f.asm
+ inclang text/maps/mansion_3f.asm
+ inclang text/maps/mansion_b1f.asm
+ inclang text/maps/safari_zone_east.asm
+ inclang text/maps/safari_zone_north.asm
+ inclang text/maps/safari_zone_west.asm
+ inclang text/maps/safari_zone_center.asm
+ inclang text/maps/safari_zone_rest_house_1.asm
+ inclang text/maps/safari_zone_secret_house.asm
+ inclang text/maps/safari_zone_rest_house_2.asm
+ inclang text/maps/safari_zone_rest_house_3.asm
+ inclang text/maps/safari_zone_rest_house_4.asm
+ inclang text/maps/unknown_dungeon_b1f.asm
+ inclang text/maps/victory_road_1f.asm
+ inclang text/maps/lance.asm
+ inclang text/maps/hall_of_fame.asm
+ inclang text/maps/champion.asm
+ inclang text/maps/lorelei.asm
+ inclang text/maps/bruno.asm
+ inclang text/maps/agatha.asm
+ inclang text/maps/rock_tunnel_b2f_1.asm
diff --git a/en/text/text3.asm b/en/text/text3.asm
index 66d79f77..9e2c752b 100644
--- a/en/text/text3.asm
+++ b/en/text/text3.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,8 +7,8 @@ INCLUDE "hram.asm"
SECTION "Text 3", ROMX, BANK[TEXT_3]
-INCLUDE "text/maps/rock_tunnel_b2f_2.asm"
-INCLUDE "text/maps/seafoam_islands_b4f.asm"
+ inclang text/maps/rock_tunnel_b2f_2.asm
+ inclang text/maps/seafoam_islands_b4f.asm
_AIBattleWithdrawText::
TX_RAM wTrainerName
@@ -1671,7 +1672,7 @@ _LinkCanceledText::
line "canceled."
done
-INCLUDE "text/oakspeech.asm"
+ inclang text/oakspeech.asm
_DoYouWantToNicknameText::
text "Do you want to"
@@ -1709,11 +1710,11 @@ _Char00Text::
_Char55Text::
text $4B,"@@"
-INCLUDE "text/maps/digletts_cave_route_2_entrance.asm"
-INCLUDE "text/maps/viridian_forest_exit.asm"
-INCLUDE "text/maps/route_2_house.asm"
-INCLUDE "text/maps/route_2_gate.asm"
-INCLUDE "text/maps/viridian_forest_entrance.asm"
-INCLUDE "text/maps/mt_moon_pokecenter.asm"
-INCLUDE "text/maps/saffron_gates.asm"
-INCLUDE "text/maps/daycare_1.asm"
+ inclang text/maps/digletts_cave_route_2_entrance.asm
+ inclang text/maps/viridian_forest_exit.asm
+ inclang text/maps/route_2_house.asm
+ inclang text/maps/route_2_gate.asm
+ inclang text/maps/viridian_forest_entrance.asm
+ inclang text/maps/mt_moon_pokecenter.asm
+ inclang text/maps/saffron_gates.asm
+ inclang text/maps/daycare_1.asm
diff --git a/en/text/text4.asm b/en/text/text4.asm
index 66adcf02..493981d9 100644
--- a/en/text/text4.asm
+++ b/en/text/text4.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,38 +7,38 @@ INCLUDE "hram.asm"
SECTION "Text 4", ROMX, BANK[TEXT_4]
-INCLUDE "text/maps/daycare_2.asm"
-INCLUDE "text/maps/underground_path_route_6_entrance.asm"
-INCLUDE "text/maps/underground_path_route_7_entrance.asm"
-INCLUDE "text/maps/underground_path_route_7_entrance_unused.asm"
-INCLUDE "text/maps/underground_path_route_8_entrance.asm"
-INCLUDE "text/maps/rock_tunnel_pokecenter.asm"
-INCLUDE "text/maps/rock_tunnel_b1f.asm"
-INCLUDE "text/maps/power_plant.asm"
-INCLUDE "text/maps/route_11_gate.asm"
-INCLUDE "text/maps/route_11_gate_upstairs.asm"
-INCLUDE "text/maps/digletts_cave_route_11_entrance.asm"
-INCLUDE "text/maps/route_12_gate.asm"
-INCLUDE "text/maps/route_12_gate_upstairs.asm"
-INCLUDE "text/maps/route_12_house.asm"
-INCLUDE "text/maps/route_15_gate.asm"
-INCLUDE "text/maps/route_15_gate_upstairs.asm"
-INCLUDE "text/maps/route_16_gate.asm"
-INCLUDE "text/maps/route_16_gate_upstairs.asm"
-INCLUDE "text/maps/route_16_house.asm"
-INCLUDE "text/maps/route_18_gate.asm"
-INCLUDE "text/maps/route_18_gate_upstairs.asm"
-INCLUDE "text/maps/pokemon_league_gate.asm"
-INCLUDE "text/maps/victory_road_2f.asm"
-INCLUDE "text/maps/bills_house.asm"
-INCLUDE "text/maps/route_1.asm"
-INCLUDE "text/maps/route_2.asm"
-INCLUDE "text/maps/route_3.asm"
-INCLUDE "text/maps/route_4.asm"
-INCLUDE "text/maps/route_5.asm"
-INCLUDE "text/maps/route_6.asm"
-INCLUDE "text/maps/route_7.asm"
-INCLUDE "text/maps/route_8.asm"
-INCLUDE "text/maps/route_9.asm"
-INCLUDE "text/maps/route_10.asm"
-INCLUDE "text/maps/route_11_1.asm"
+ inclang text/maps/daycare_2.asm
+ inclang text/maps/underground_path_route_6_entrance.asm
+ inclang text/maps/underground_path_route_7_entrance.asm
+ inclang text/maps/underground_path_route_7_entrance_unused.asm
+ inclang text/maps/underground_path_route_8_entrance.asm
+ inclang text/maps/rock_tunnel_pokecenter.asm
+ inclang text/maps/rock_tunnel_b1f.asm
+ inclang text/maps/power_plant.asm
+ inclang text/maps/route_11_gate.asm
+ inclang text/maps/route_11_gate_upstairs.asm
+ inclang text/maps/digletts_cave_route_11_entrance.asm
+ inclang text/maps/route_12_gate.asm
+ inclang text/maps/route_12_gate_upstairs.asm
+ inclang text/maps/route_12_house.asm
+ inclang text/maps/route_15_gate.asm
+ inclang text/maps/route_15_gate_upstairs.asm
+ inclang text/maps/route_16_gate.asm
+ inclang text/maps/route_16_gate_upstairs.asm
+ inclang text/maps/route_16_house.asm
+ inclang text/maps/route_18_gate.asm
+ inclang text/maps/route_18_gate_upstairs.asm
+ inclang text/maps/pokemon_league_gate.asm
+ inclang text/maps/victory_road_2f.asm
+ inclang text/maps/bills_house.asm
+ inclang text/maps/route_1.asm
+ inclang text/maps/route_2.asm
+ inclang text/maps/route_3.asm
+ inclang text/maps/route_4.asm
+ inclang text/maps/route_5.asm
+ inclang text/maps/route_6.asm
+ inclang text/maps/route_7.asm
+ inclang text/maps/route_8.asm
+ inclang text/maps/route_9.asm
+ inclang text/maps/route_10.asm
+ inclang text/maps/route_11_1.asm
diff --git a/en/text/text5.asm b/en/text/text5.asm
index c142986f..b2dab686 100644
--- a/en/text/text5.asm
+++ b/en/text/text5.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,17 +7,17 @@ INCLUDE "hram.asm"
SECTION "Text 5", ROMX, BANK[TEXT_5]
-INCLUDE "text/maps/route_11_2.asm"
-INCLUDE "text/maps/route_12.asm"
-INCLUDE "text/maps/route_13.asm"
-INCLUDE "text/maps/route_14.asm"
-INCLUDE "text/maps/route_15.asm"
-INCLUDE "text/maps/route_16.asm"
-INCLUDE "text/maps/route_17.asm"
-INCLUDE "text/maps/route_18.asm"
-INCLUDE "text/maps/route_19.asm"
-INCLUDE "text/maps/route_20.asm"
-INCLUDE "text/maps/route_21.asm"
-INCLUDE "text/maps/route_22.asm"
-INCLUDE "text/maps/route_23.asm"
-INCLUDE "text/maps/route_24_1.asm"
+ inclang text/maps/route_11_2.asm
+ inclang text/maps/route_12.asm
+ inclang text/maps/route_13.asm
+ inclang text/maps/route_14.asm
+ inclang text/maps/route_15.asm
+ inclang text/maps/route_16.asm
+ inclang text/maps/route_17.asm
+ inclang text/maps/route_18.asm
+ inclang text/maps/route_19.asm
+ inclang text/maps/route_20.asm
+ inclang text/maps/route_21.asm
+ inclang text/maps/route_22.asm
+ inclang text/maps/route_23.asm
+ inclang text/maps/route_24_1.asm
diff --git a/en/text/text6.asm b/en/text/text6.asm
index 4a1cce29..2df51713 100644
--- a/en/text/text6.asm
+++ b/en/text/text6.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,8 +7,8 @@ INCLUDE "hram.asm"
SECTION "Text 6", ROMX, BANK[TEXT_6]
-INCLUDE "text/maps/route_24_2.asm"
-INCLUDE "text/maps/route_25.asm"
+ inclang text/maps/route_24_2.asm
+ inclang text/maps/route_25.asm
_FileDataDestroyedText::
text "The file data is"
@@ -334,14 +335,14 @@ _ColosseumText1::
text "!"
done
-INCLUDE "text/maps/reds_house_1f.asm"
-INCLUDE "text/maps/blues_house.asm"
-INCLUDE "text/maps/oaks_lab.asm"
-INCLUDE "text/maps/viridian_pokecenter.asm"
-INCLUDE "text/maps/viridian_mart.asm"
-INCLUDE "text/maps/school.asm"
-INCLUDE "text/maps/viridian_house.asm"
-INCLUDE "text/maps/viridian_gym.asm"
-INCLUDE "text/maps/museum_1f.asm"
-INCLUDE "text/maps/museum_2f.asm"
-INCLUDE "text/maps/pewter_gym_1.asm"
+ inclang text/maps/reds_house_1f.asm
+ inclang text/maps/blues_house.asm
+ inclang text/maps/oaks_lab.asm
+ inclang text/maps/viridian_pokecenter.asm
+ inclang text/maps/viridian_mart.asm
+ inclang text/maps/school.asm
+ inclang text/maps/viridian_house.asm
+ inclang text/maps/viridian_gym.asm
+ inclang text/maps/museum_1f.asm
+ inclang text/maps/museum_2f.asm
+ inclang text/maps/pewter_gym_1.asm
diff --git a/en/text/text7.asm b/en/text/text7.asm
index 99a66234..d6a5509d 100644
--- a/en/text/text7.asm
+++ b/en/text/text7.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,31 +7,31 @@ INCLUDE "hram.asm"
SECTION "Text 7", ROMX, BANK[TEXT_7]
-INCLUDE "text/maps/pewter_gym_2.asm"
-INCLUDE "text/maps/pewter_house_1.asm"
-INCLUDE "text/maps/pewter_mart.asm"
-INCLUDE "text/maps/pewter_house_2.asm"
-INCLUDE "text/maps/pewter_pokecenter.asm"
-INCLUDE "text/maps/cerulean_trashed_house.asm"
-INCLUDE "text/maps/cerulean_trade_house.asm"
-INCLUDE "text/maps/cerulean_pokecenter.asm"
-INCLUDE "text/maps/cerulean_gym.asm"
-INCLUDE "text/maps/bike_shop.asm"
-INCLUDE "text/maps/cerulean_mart.asm"
-INCLUDE "text/maps/cerulean_badge_house.asm"
-INCLUDE "text/maps/lavender_pokecenter.asm"
-INCLUDE "text/maps/pokemon_tower_1f.asm"
-INCLUDE "text/maps/pokemon_tower_2f.asm"
-INCLUDE "text/maps/pokemon_tower_3f.asm"
-INCLUDE "text/maps/pokemon_tower_4f.asm"
-INCLUDE "text/maps/pokemon_tower_5f.asm"
-INCLUDE "text/maps/pokemon_tower_6f.asm"
-INCLUDE "text/maps/pokemon_tower_7f.asm"
-INCLUDE "text/maps/fujis_house.asm"
-INCLUDE "text/maps/lavender_mart.asm"
-INCLUDE "text/maps/lavender_house.asm"
-INCLUDE "text/maps/name_rater.asm"
-INCLUDE "text/maps/vermilion_pokecenter.asm"
-INCLUDE "text/maps/fan_club.asm"
-INCLUDE "text/maps/vermilion_mart.asm"
-INCLUDE "text/maps/vermilion_gym_1.asm"
+ inclang text/maps/pewter_gym_2.asm
+ inclang text/maps/pewter_house_1.asm
+ inclang text/maps/pewter_mart.asm
+ inclang text/maps/pewter_house_2.asm
+ inclang text/maps/pewter_pokecenter.asm
+ inclang text/maps/cerulean_trashed_house.asm
+ inclang text/maps/cerulean_trade_house.asm
+ inclang text/maps/cerulean_pokecenter.asm
+ inclang text/maps/cerulean_gym.asm
+ inclang text/maps/bike_shop.asm
+ inclang text/maps/cerulean_mart.asm
+ inclang text/maps/cerulean_badge_house.asm
+ inclang text/maps/lavender_pokecenter.asm
+ inclang text/maps/pokemon_tower_1f.asm
+ inclang text/maps/pokemon_tower_2f.asm
+ inclang text/maps/pokemon_tower_3f.asm
+ inclang text/maps/pokemon_tower_4f.asm
+ inclang text/maps/pokemon_tower_5f.asm
+ inclang text/maps/pokemon_tower_6f.asm
+ inclang text/maps/pokemon_tower_7f.asm
+ inclang text/maps/fujis_house.asm
+ inclang text/maps/lavender_mart.asm
+ inclang text/maps/lavender_house.asm
+ inclang text/maps/name_rater.asm
+ inclang text/maps/vermilion_pokecenter.asm
+ inclang text/maps/fan_club.asm
+ inclang text/maps/vermilion_mart.asm
+ inclang text/maps/vermilion_gym_1.asm
diff --git a/en/text/text8.asm b/en/text/text8.asm
index a18a8493..61ce6979 100644
--- a/en/text/text8.asm
+++ b/en/text/text8.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,31 +7,31 @@ INCLUDE "hram.asm"
SECTION "Text 8", ROMX, BANK[TEXT_8]
-INCLUDE "text/maps/vermilion_gym_2.asm"
-INCLUDE "text/maps/vermilion_house.asm"
-INCLUDE "text/maps/vermilion_dock.asm"
-INCLUDE "text/maps/vermilion_fishing_house.asm"
-INCLUDE "text/maps/celadon_dept_store_1f.asm"
-INCLUDE "text/maps/celadon_dept_store_2f.asm"
-INCLUDE "text/maps/celadon_dept_store_3f.asm"
-INCLUDE "text/maps/celadon_dept_store_4f.asm"
-INCLUDE "text/maps/celadon_dept_store_roof.asm"
-INCLUDE "text/maps/celadon_mansion_1f.asm"
-INCLUDE "text/maps/celadon_mansion_2f.asm"
-INCLUDE "text/maps/celadon_mansion_3f.asm"
-INCLUDE "text/maps/celadon_mansion_4f_outside.asm"
-INCLUDE "text/maps/celadon_mansion_4f_inside.asm"
-INCLUDE "text/maps/celadon_pokecenter.asm"
-INCLUDE "text/maps/celadon_gym.asm"
-INCLUDE "text/maps/celadon_game_corner.asm"
-INCLUDE "text/maps/celadon_dept_store_5f.asm"
-INCLUDE "text/maps/celadon_prize_room.asm"
-INCLUDE "text/maps/celadon_diner.asm"
-INCLUDE "text/maps/celadon_house.asm"
-INCLUDE "text/maps/celadon_hotel.asm"
-INCLUDE "text/maps/fuchsia_mart.asm"
-INCLUDE "text/maps/fuchsia_house.asm"
-INCLUDE "text/maps/fuchsia_pokecenter.asm"
-INCLUDE "text/maps/wardens_house.asm"
-INCLUDE "text/maps/safari_zone_entrance.asm"
-INCLUDE "text/maps/fuchsia_gym_1.asm"
+ inclang text/maps/vermilion_gym_2.asm
+ inclang text/maps/vermilion_house.asm
+ inclang text/maps/vermilion_dock.asm
+ inclang text/maps/vermilion_fishing_house.asm
+ inclang text/maps/celadon_dept_store_1f.asm
+ inclang text/maps/celadon_dept_store_2f.asm
+ inclang text/maps/celadon_dept_store_3f.asm
+ inclang text/maps/celadon_dept_store_4f.asm
+ inclang text/maps/celadon_dept_store_roof.asm
+ inclang text/maps/celadon_mansion_1f.asm
+ inclang text/maps/celadon_mansion_2f.asm
+ inclang text/maps/celadon_mansion_3f.asm
+ inclang text/maps/celadon_mansion_4f_outside.asm
+ inclang text/maps/celadon_mansion_4f_inside.asm
+ inclang text/maps/celadon_pokecenter.asm
+ inclang text/maps/celadon_gym.asm
+ inclang text/maps/celadon_game_corner.asm
+ inclang text/maps/celadon_dept_store_5f.asm
+ inclang text/maps/celadon_prize_room.asm
+ inclang text/maps/celadon_diner.asm
+ inclang text/maps/celadon_house.asm
+ inclang text/maps/celadon_hotel.asm
+ inclang text/maps/fuchsia_mart.asm
+ inclang text/maps/fuchsia_house.asm
+ inclang text/maps/fuchsia_pokecenter.asm
+ inclang text/maps/wardens_house.asm
+ inclang text/maps/safari_zone_entrance.asm
+ inclang text/maps/fuchsia_gym_1.asm
diff --git a/en/text/text9.asm b/en/text/text9.asm
index 9eba249d..c1aa303b 100644
--- a/en/text/text9.asm
+++ b/en/text/text9.asm
@@ -1,4 +1,5 @@
-INCLUDE "charmap.asm"
+INCLUDE "macros/inclang.asm"
+ inclang charmap.asm
INCLUDE "constants/text_constants.asm"
INCLUDE "constants/text_bank_constants.asm"
INCLUDE "macros/text_macros.asm"
@@ -6,27 +7,27 @@ INCLUDE "hram.asm"
SECTION "Text 9", ROMX, BANK[TEXT_9]
-INCLUDE "text/maps/fuchsia_gym_2.asm"
-INCLUDE "text/maps/fuchsia_meeting_room.asm"
-INCLUDE "text/maps/fuchsia_fishing_house.asm"
-INCLUDE "text/maps/mansion_1f.asm"
-INCLUDE "text/maps/cinnabar_gym.asm"
-INCLUDE "text/maps/cinnabar_lab.asm"
-INCLUDE "text/maps/cinnabar_lab_trade_room.asm"
-INCLUDE "text/maps/cinnabar_lab_metronome_room.asm"
-INCLUDE "text/maps/cinnabar_lab_fossil_room.asm"
-INCLUDE "text/maps/cinnabar_pokecenter.asm"
-INCLUDE "text/maps/cinnabar_mart.asm"
-INCLUDE "text/maps/indigo_plateau_lobby.asm"
-INCLUDE "text/maps/copycats_house_1f.asm"
-INCLUDE "text/maps/copycats_house_2f.asm"
-INCLUDE "text/maps/fighting_dojo.asm"
-INCLUDE "text/maps/saffron_gym.asm"
-INCLUDE "text/maps/saffron_house.asm"
-INCLUDE "text/maps/saffron_mart.asm"
-INCLUDE "text/maps/silph_co_1f.asm"
-INCLUDE "text/maps/saffron_pokecenter.asm"
-INCLUDE "text/maps/mr_psychics_house.asm"
+ inclang text/maps/fuchsia_gym_2.asm
+ inclang text/maps/fuchsia_meeting_room.asm
+ inclang text/maps/fuchsia_fishing_house.asm
+ inclang text/maps/mansion_1f.asm
+ inclang text/maps/cinnabar_gym.asm
+ inclang text/maps/cinnabar_lab.asm
+ inclang text/maps/cinnabar_lab_trade_room.asm
+ inclang text/maps/cinnabar_lab_metronome_room.asm
+ inclang text/maps/cinnabar_lab_fossil_room.asm
+ inclang text/maps/cinnabar_pokecenter.asm
+ inclang text/maps/cinnabar_mart.asm
+ inclang text/maps/indigo_plateau_lobby.asm
+ inclang text/maps/copycats_house_1f.asm
+ inclang text/maps/copycats_house_2f.asm
+ inclang text/maps/fighting_dojo.asm
+ inclang text/maps/saffron_gym.asm
+ inclang text/maps/saffron_house.asm
+ inclang text/maps/saffron_mart.asm
+ inclang text/maps/silph_co_1f.asm
+ inclang text/maps/saffron_pokecenter.asm
+ inclang text/maps/mr_psychics_house.asm
_PokemartGreetingText::
text "Hi there!"
diff --git a/en/text/trainer_names.asm b/en/text/trainer_names.asm
new file mode 100755
index 00000000..7736738b
--- /dev/null
+++ b/en/text/trainer_names.asm
@@ -0,0 +1,48 @@
+TrainerNames:
+ db "YOUNGSTER@"
+ db "BUG CATCHER@"
+ db "LASS@"
+ db "SAILOR@"
+ db "JR.TRAINER♂@"
+ db "JR.TRAINER♀@"
+ db "POKéMANIAC@"
+ db "SUPER NERD@"
+ db "HIKER@"
+ db "BIKER@"
+ db "BURGLAR@"
+ db "ENGINEER@"
+ db "JUGGLER@"
+ db "FISHERMAN@"
+ db "SWIMMER@"
+ db "CUE BALL@"
+ db "GAMBLER@"
+ db "BEAUTY@"
+ db "PSYCHIC@"
+ db "ROCKER@"
+ db "JUGGLER@"
+ db "TAMER@"
+ db "BIRD KEEPER@"
+ db "BLACKBELT@"
+ db "RIVAL1@"
+ db "PROF.OAK@"
+ db "CHIEF@"
+ db "SCIENTIST@"
+ db "GIOVANNI@"
+ db "ROCKET@"
+ db "COOLTRAINER♂@"
+ db "COOLTRAINER♀@"
+ db "BRUNO@"
+ db "BROCK@"
+ db "MISTY@"
+ db "LT.SURGE@"
+ db "ERIKA@"
+ db "KOGA@"
+ db "BLAINE@"
+ db "SABRINA@"
+ db "GENTLEMAN@"
+ db "RIVAL2@"
+ db "RIVAL3@"
+ db "LORELEI@"
+ db "CHANNELER@"
+ db "AGATHA@"
+ db "LANCE@"
diff --git a/en/text/type_names.asm b/en/text/type_names.asm
new file mode 100755
index 00000000..d94675b8
--- /dev/null
+++ b/en/text/type_names.asm
@@ -0,0 +1,48 @@
+TypeNames:
+
+ dw .Normal
+ dw .Fighting
+ dw .Flying
+ dw .Poison
+ dw .Ground
+ dw .Rock
+ dw .Bird
+ dw .Bug
+ dw .Ghost
+
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+ dw .Normal
+
+ dw .Fire
+ dw .Water
+ dw .Grass
+ dw .Electric
+ dw .Psychic
+ dw .Ice
+ dw .Dragon
+
+.Normal: db "NORMAL@"
+.Fighting: db "FIGHTING@"
+.Flying: db "FLYING@"
+.Poison: db "POISON@"
+.Fire: db "FIRE@"
+.Water: db "WATER@"
+.Grass: db "GRASS@"
+.Electric: db "ELECTRIC@"
+.Psychic: db "PSYCHIC@"
+.Ice: db "ICE@"
+.Ground: db "GROUND@"
+.Rock: db "ROCK@"
+.Bird: db "BIRD@"
+.Bug: db "BUG@"
+.Ghost: db "GHOST@"
+.Dragon: db "DRAGON@"