aboutsummaryrefslogtreecommitdiffstats
path: root/engine
diff options
context:
space:
mode:
authordannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
committerdannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
commit5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch)
treedde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /engine
parentMerge pull request #55 from Deokishisu/patch-1 (diff)
downloadpokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.tar.gz
pokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.tar.xz
pokeyellow-5647ca687b92954dcf37a6ea6bfbc9a341c32de4.zip
Sync with pokered
Diffstat (limited to '')
-rwxr-xr-xengine/HoF_room_pc.asm323
-rw-r--r--engine/bank3c.asm24
-rw-r--r--engine/bank3d.asm72
-rw-r--r--engine/bank3f.asm10
-rwxr-xr-xengine/battle/animations.asm794
-rw-r--r--engine/battle/bank3d_battle.asm111
-rw-r--r--engine/battle/battle_transitions.asm263
-rw-r--r--engine/battle/common_text.asm110
-rwxr-xr-xengine/battle/core.asm2836
-rw-r--r--engine/battle/decrement_pp.asm2
-rw-r--r--engine/battle/display_effectiveness.asm8
-rw-r--r--engine/battle/draw_hud_pokeball_gfx.asm8
-rw-r--r--engine/battle/effects.asm1551
-rwxr-xr-xengine/battle/end_of_battle.asm10
-rw-r--r--engine/battle/experience.asm64
-rw-r--r--engine/battle/get_trainer_name.asm8
-rw-r--r--engine/battle/ghost_marowak_anim.asm20
-rw-r--r--engine/battle/init_battle_variables.asm4
-rw-r--r--engine/battle/link_battle_versus_text.asm10
-rwxr-xr-xengine/battle/misc.asm (renamed from engine/battle/bank_e_misc.asm)0
-rw-r--r--engine/battle/moveEffects/conversion_effect.asm35
-rw-r--r--engine/battle/moveEffects/drain_hp_effect.asm104
-rw-r--r--engine/battle/moveEffects/focus_energy_effect.asm22
-rw-r--r--engine/battle/moveEffects/haze_effect.asm81
-rw-r--r--engine/battle/moveEffects/heal_effect.asm120
-rw-r--r--engine/battle/moveEffects/leech_seed_effect.asm40
-rw-r--r--engine/battle/moveEffects/mist_effect.asm19
-rw-r--r--engine/battle/moveEffects/one_hit_ko_effect.asm38
-rw-r--r--engine/battle/moveEffects/paralyze_effect.asm47
-rw-r--r--engine/battle/moveEffects/pay_day_effect.asm45
-rw-r--r--engine/battle/moveEffects/recoil_effect.asm70
-rw-r--r--engine/battle/moveEffects/reflect_light_screen_effect.asm45
-rw-r--r--engine/battle/moveEffects/substitute_effect.asm77
-rw-r--r--engine/battle/moveEffects/transform_effect.asm141
-rw-r--r--engine/battle/move_effects/conversion.asm35
-rw-r--r--engine/battle/move_effects/drain_hp.asm104
-rw-r--r--engine/battle/move_effects/focus_energy.asm22
-rw-r--r--engine/battle/move_effects/haze.asm81
-rw-r--r--engine/battle/move_effects/heal.asm120
-rw-r--r--engine/battle/move_effects/leech_seed.asm40
-rw-r--r--engine/battle/move_effects/mist.asm19
-rw-r--r--engine/battle/move_effects/one_hit_ko.asm38
-rw-r--r--engine/battle/move_effects/paralyze.asm47
-rw-r--r--engine/battle/move_effects/pay_day.asm45
-rw-r--r--engine/battle/move_effects/recoil.asm70
-rw-r--r--engine/battle/move_effects/reflect_light_screen.asm45
-rw-r--r--engine/battle/move_effects/substitute.asm77
-rw-r--r--engine/battle/move_effects/transform.asm141
-rw-r--r--engine/battle/print_type.asm2
-rwxr-xr-xengine/battle/read_trainer_party.asm2
-rwxr-xr-xengine/battle/safari_zone.asm8
-rw-r--r--engine/battle/save_trainer_name.asm95
-rw-r--r--engine/battle/scale_sprites.asm30
-rw-r--r--engine/battle/scroll_draw_trainer_pic.asm4
-rw-r--r--engine/battle/trainer_ai.asm151
-rwxr-xr-xengine/battle/trainer_pic_money_pointers.asm143
-rw-r--r--engine/battle/unused_stats_functions.asm4
-rw-r--r--engine/battle/wild_encounters.asm32
-rw-r--r--engine/bcd.asm218
-rw-r--r--engine/bg_map_attributes.asm40
-rw-r--r--engine/black_out.asm48
-rw-r--r--engine/debug/debug_menu.asm46
-rw-r--r--engine/debug/debug_party.asm24
-rw-r--r--engine/debug1.asm24
-rwxr-xr-xengine/diploma_3a.asm46
-rw-r--r--engine/display_text_id_init.asm75
-rw-r--r--engine/events/black_out.asm48
-rwxr-xr-xengine/events/card_key.asm102
-rwxr-xr-xengine/events/cinnabar_lab.asm (renamed from engine/overworld/cinnabar_lab.asm)34
-rw-r--r--engine/events/diploma.asm (renamed from engine/menu/diploma.asm)4
-rw-r--r--engine/events/display_pokedex.asm (renamed from engine/display_pokedex.asm)2
-rwxr-xr-xengine/events/elevator.asm54
-rwxr-xr-xengine/events/give_pokemon.asm (renamed from engine/give_pokemon.asm)26
-rw-r--r--engine/events/heal_party.asm (renamed from engine/heal_party.asm)0
-rwxr-xr-xengine/events/hidden_items.asm (renamed from engine/overworld/hidden_items.asm)54
-rw-r--r--engine/events/hidden_objects/bench_guys.asm98
-rw-r--r--engine/events/hidden_objects/bills_house_pc.asm131
-rw-r--r--engine/events/hidden_objects/blues_room.asm13
-rw-r--r--engine/events/hidden_objects/book_or_sculpture.asm21
-rw-r--r--engine/events/hidden_objects/bookshelves.asm39
-rw-r--r--engine/events/hidden_objects/cinnabar_gym_quiz.asm246
-rw-r--r--engine/events/hidden_objects/elevator.asm3
-rw-r--r--engine/events/hidden_objects/fanclub_pictures.asm23
-rw-r--r--engine/events/hidden_objects/fighting_dojo.asm23
-rw-r--r--engine/events/hidden_objects/gym_statues.asm39
-rw-r--r--engine/events/hidden_objects/indigo_plateau_hq.asm10
-rw-r--r--engine/events/hidden_objects/indigo_plateau_statues.asm24
-rw-r--r--engine/events/hidden_objects/magazines.asm8
-rw-r--r--engine/events/hidden_objects/museum_fossils.asm23
-rw-r--r--engine/events/hidden_objects/museum_fossils2.asm28
-rw-r--r--engine/events/hidden_objects/new_bike.asm7
-rw-r--r--engine/events/hidden_objects/oaks_lab_email.asm11
-rw-r--r--engine/events/hidden_objects/oaks_lab_posters.asm29
-rw-r--r--engine/events/hidden_objects/pokecenter_pc.asm11
-rw-r--r--engine/events/hidden_objects/pokemon_stuff.asm3
-rw-r--r--engine/events/hidden_objects/reds_room.asm14
-rw-r--r--engine/events/hidden_objects/route_15_binoculars.asm17
-rw-r--r--engine/events/hidden_objects/safari_game.asm78
-rw-r--r--engine/events/hidden_objects/school_blackboard.asm223
-rw-r--r--engine/events/hidden_objects/school_notebooks.asm65
-rw-r--r--engine/events/hidden_objects/town_map.asm22
-rw-r--r--engine/events/hidden_objects/vermilion_gym_trash.asm134
-rwxr-xr-xengine/events/in_game_trades.asm (renamed from engine/in_game_trades.asm)114
-rwxr-xr-xengine/events/oaks_aide.asm71
-rwxr-xr-xengine/events/pewter_guys.asm (renamed from engine/overworld/pewter_guys.asm)0
-rw-r--r--engine/events/pick_up_item.asm54
-rw-r--r--engine/events/poison.asm (renamed from engine/overworld/poison.asm)8
-rwxr-xr-xengine/events/pokecenter.asm149
-rwxr-xr-xengine/events/pokedex_rating.asm138
-rwxr-xr-xengine/events/pokemart.asm (renamed from engine/overworld/pokemart.asm)58
-rwxr-xr-xengine/events/prize_menu.asm (renamed from engine/menu/prize_menu.asm)90
-rwxr-xr-xengine/events/saffron_guards.asm15
-rw-r--r--engine/events/set_blackout_map.asm25
-rwxr-xr-xengine/events/starter_dex.asm9
-rwxr-xr-xengine/events/vending_machine.asm (renamed from engine/menu/vending_machine.asm)52
-rwxr-xr-xengine/evos_moves.asm668
-rwxr-xr-xengine/experience.asm160
-rwxr-xr-xengine/game_corner_slots.asm54
-rwxr-xr-xengine/game_corner_slots2.asm31
-rwxr-xr-xengine/gamefreak.asm263
-rwxr-xr-xengine/gfx/hp_bar.asm (renamed from engine/hp_bar.asm)16
-rwxr-xr-xengine/gfx/load_pokedex_tiles.asm (renamed from engine/load_pokedex_tiles.asm)6
-rwxr-xr-xengine/gfx/mon_icons.asm307
-rw-r--r--engine/gfx/oam_dma.asm28
-rwxr-xr-xengine/gfx/palettes.asm1117
-rw-r--r--engine/gfx/screen_effects.asm73
-rw-r--r--engine/gfx/sprite_oam.asm232
-rwxr-xr-xengine/hidden_object_functions14.asm100
-rwxr-xr-xengine/hidden_object_functions17.asm466
-rwxr-xr-xengine/hidden_object_functions18.asm204
-rwxr-xr-xengine/hidden_object_functions3.asm153
-rwxr-xr-xengine/hidden_object_functions7.asm510
-rw-r--r--engine/items/get_bag_item_quantity.asm (renamed from engine/get_bag_item_quantity.asm)0
-rw-r--r--engine/items/inventory.asm8
-rwxr-xr-xengine/items/item_effects.asm3186
-rwxr-xr-xengine/items/items.asm3235
-rw-r--r--engine/items/subtract_paid_money.asm (renamed from engine/subtract_paid_money.asm)4
-rwxr-xr-xengine/items/tm_prices.asm14
-rwxr-xr-xengine/items/tmhm.asm4
-rwxr-xr-xengine/items/tms.asm2
-rwxr-xr-xengine/items/town_map.asm629
-rw-r--r--engine/joypad.asm52
-rwxr-xr-xengine/link/cable_club.asm (renamed from engine/cable_club.asm)120
-rwxr-xr-xengine/link/cable_club_npc.asm (renamed from engine/overworld/cable_club_npc.asm)60
-rw-r--r--engine/link/print_waiting_text.asm (renamed from engine/print_waiting_text.asm)6
-rw-r--r--engine/math/bcd.asm218
-rwxr-xr-xengine/math/multiply_divide.asm143
-rwxr-xr-xengine/math/random.asm13
-rw-r--r--engine/menu/link_menu.asm910
-rwxr-xr-xengine/menu/oaks_pc.asm28
-rwxr-xr-xengine/menu/party_menu.asm333
-rw-r--r--engine/menu/text_box.asm739
-rw-r--r--engine/menus/display_text_id_init.asm76
-rw-r--r--engine/menus/draw_badges.asm (renamed from engine/menu/draw_badges.asm)14
-rw-r--r--engine/menus/draw_start_menu.asm (renamed from engine/menu/draw_start_menu.asm)10
-rwxr-xr-xengine/menus/league_pc.asm (renamed from engine/menu/league_pc.asm)24
-rw-r--r--engine/menus/link_menu.asm910
-rwxr-xr-xengine/menus/main_menu.asm (renamed from engine/menu/main_menu.asm)67
-rwxr-xr-xengine/menus/naming_screen.asm (renamed from engine/menu/naming_screen.asm)76
-rwxr-xr-xengine/menus/oaks_pc.asm28
-rw-r--r--engine/menus/options.asm (renamed from engine/menu/options.asm)40
-rwxr-xr-xengine/menus/party_menu.asm314
-rwxr-xr-xengine/menus/pc.asm (renamed from engine/menu/pc.asm)40
-rwxr-xr-xengine/menus/players_pc.asm (renamed from engine/menu/players_pc.asm)62
-rwxr-xr-xengine/menus/pokedex.asm (renamed from engine/menu/pokedex.asm)160
-rwxr-xr-xengine/menus/save.asm (renamed from engine/save.asm)76
-rwxr-xr-xengine/menus/start_sub_menus.asm (renamed from engine/menu/start_sub_menus.asm)210
-rw-r--r--engine/menus/swap_items.asm (renamed from engine/menu/swap_items.asm)10
-rw-r--r--engine/menus/text_box.asm533
-rwxr-xr-xengine/mon_party_sprites.asm445
-rwxr-xr-xengine/movie/credits.asm322
-rwxr-xr-xengine/movie/evolution.asm (renamed from engine/evolution.asm)18
-rwxr-xr-xengine/movie/hall_of_fame.asm (renamed from engine/hall_of_fame.asm)74
-rwxr-xr-xengine/movie/intro.asm (renamed from engine/intro.asm)41
-rwxr-xr-xengine/movie/oak_speech/clear_save.asm (renamed from engine/clear_save.asm)8
-rw-r--r--engine/movie/oak_speech/init_player_data.asm (renamed from engine/init_player_data.asm)8
-rwxr-xr-xengine/movie/oak_speech/oak_speech.asm (renamed from engine/oak_speech.asm)64
-rwxr-xr-xengine/movie/oak_speech/oak_speech2.asm (renamed from engine/oak_speech2.asm)76
-rwxr-xr-xengine/movie/splash.asm259
-rwxr-xr-xengine/movie/title.asm370
-rwxr-xr-xengine/movie/title2.asm122
-rwxr-xr-xengine/movie/trade.asm859
-rwxr-xr-xengine/movie/trade2.asm (renamed from engine/trade2.asm)25
-rwxr-xr-xengine/multiply_divide.asm144
-rw-r--r--engine/oam_dma.asm26
-rw-r--r--engine/overworld/advance_player_sprite.asm247
-rwxr-xr-xengine/overworld/auto_movement.asm270
-rwxr-xr-xengine/overworld/card_key.asm113
-rw-r--r--engine/overworld/clear_variables.asm16
-rwxr-xr-xengine/overworld/cut.asm66
-rwxr-xr-xengine/overworld/cut2.asm8
-rwxr-xr-xengine/overworld/doors.asm55
-rw-r--r--engine/overworld/dungeon_warps.asm2
-rwxr-xr-xengine/overworld/dust_smoke.asm95
-rwxr-xr-xengine/overworld/elevator.asm10
-rwxr-xr-xengine/overworld/emotion_bubbles.asm19
-rw-r--r--engine/overworld/field_move_messages.asm23
-rwxr-xr-xengine/overworld/healing_machine.asm43
-rwxr-xr-xengine/overworld/hidden_objects.asm20
-rw-r--r--engine/overworld/item.asm54
-rwxr-xr-xengine/overworld/ledges.asm26
-rw-r--r--engine/overworld/map_sprite_functions1.asm390
-rwxr-xr-xengine/overworld/map_sprites.asm32
-rw-r--r--engine/overworld/missable_objects.asm36
-rw-r--r--engine/overworld/movement.asm459
-rwxr-xr-xengine/overworld/npc_movement.asm270
-rwxr-xr-xengine/overworld/npc_movement_2.asm14
-rwxr-xr-xengine/overworld/oaks_aide.asm71
-rw-r--r--engine/overworld/oam.asm232
-rw-r--r--engine/overworld/pathfinding.asm201
-rwxr-xr-xengine/overworld/player_animations.asm118
-rw-r--r--engine/overworld/player_state.asm122
-rwxr-xr-xengine/overworld/pokecenter.asm149
-rw-r--r--engine/overworld/push_boulder.asm34
-rwxr-xr-xengine/overworld/saffron_guards.asm16
-rw-r--r--engine/overworld/set_blackout_map.asm29
-rw-r--r--engine/overworld/special_warps.asm149
-rw-r--r--engine/overworld/spinners.asm65
-rw-r--r--engine/overworld/sprite_collisions.asm392
-rwxr-xr-xengine/overworld/ssanne.asm95
-rw-r--r--engine/overworld/tileset_header.asm51
-rw-r--r--engine/overworld/tilesets.asm51
-rwxr-xr-xengine/overworld/trainer_sight.asm349
-rwxr-xr-xengine/overworld/trainers.asm349
-rw-r--r--engine/overworld/update_map.asm32
-rw-r--r--engine/overworld/wild_mons.asm10
-rwxr-xr-xengine/palettes.asm1116
-rw-r--r--engine/pathfinding.asm201
-rwxr-xr-xengine/pikachu_emotions.asm26
-rwxr-xr-xengine/pikachu_follow.asm16
-rwxr-xr-xengine/pikachu_movement.asm8
-rwxr-xr-xengine/pikachu_pcm.asm38
-rwxr-xr-xengine/pikachu_pic_animation.asm38
-rwxr-xr-xengine/pokedex_rating.asm154
-rw-r--r--engine/pokemon/add_mon.asm (renamed from engine/add_mon.asm)32
-rw-r--r--engine/pokemon/bills_pc.asm (renamed from engine/menu/bills_pc.asm)157
-rwxr-xr-xengine/pokemon/evos_moves.asm668
-rwxr-xr-xengine/pokemon/experience.asm149
-rwxr-xr-xengine/pokemon/learn_move.asm (renamed from engine/learn_move.asm)64
-rw-r--r--engine/pokemon/load_mon_data.asm (renamed from engine/load_mon_data.asm)2
-rw-r--r--engine/pokemon/remove_mon.asm95
-rwxr-xr-xengine/pokemon/set_types.asm (renamed from engine/predefs17_2.asm)0
-rwxr-xr-xengine/pokemon/status_ailments.asm (renamed from engine/status_ailments.asm)2
-rwxr-xr-xengine/pokemon/status_screen.asm (renamed from engine/menu/status_screen.asm)151
-rwxr-xr-xengine/predefs.asm113
-rwxr-xr-xengine/predefs17.asm9
-rwxr-xr-xengine/predefs7.asm54
-rw-r--r--engine/predefsA.asm73
-rw-r--r--engine/printer.asm208
-rwxr-xr-xengine/printer/serial.asm24
-rwxr-xr-xengine/random.asm13
-rw-r--r--engine/remove_pokemon.asm95
-rwxr-xr-xengine/slots/game_corner_slots.asm54
-rwxr-xr-xengine/slots/game_corner_slots2.asm31
-rwxr-xr-xengine/slots/slot_machine.asm (renamed from engine/slot_machine.asm)109
-rw-r--r--engine/special_warps.asm149
-rwxr-xr-xengine/surfing_minigame.asm218
-rw-r--r--engine/test_battle.asm45
-rwxr-xr-xengine/titlescreen.asm370
-rwxr-xr-xengine/titlescreen2.asm122
-rwxr-xr-xengine/town_map.asm628
-rwxr-xr-xengine/trade.asm857
-rwxr-xr-xengine/unknown_ea3ea.asm66
-rwxr-xr-xengine/vermilion_gym_trash_cans.asm2
-rwxr-xr-xengine/yellow_intro.asm164
-rwxr-xr-xhome/start_menu.asm (renamed from engine/menu/start_menu.asm)8
266 files changed, 20170 insertions, 21983 deletions
diff --git a/engine/HoF_room_pc.asm b/engine/HoF_room_pc.asm
deleted file mode 100755
index 71a98c59..00000000
--- a/engine/HoF_room_pc.asm
+++ /dev/null
@@ -1,323 +0,0 @@
-HallOfFamePC:
- callab AnimateHallOfFame
- call ClearScreen
- ld c, 100
- call DelayFrames
-
- call DisableLCD
- ld a, $a7
- ld [rWX], a
- xor a
- ld [rSCX], a
- ld [rSCY], a
- ld [hSCX], a
- ld [hSCY], a
- ld [hWY], a
- ld [rWY], a
- call CreditsLoadFont
- coord hl, 0, 0
- call FillFourRowsWithBlack
- coord hl, 0, 14
- call FillFourRowsWithBlack
- ld a, %11000000
- ld [rBGP], a
- call UpdateGBCPal_BGP
- call EnableLCD
- call StopAllMusic
- ld hl, vBGMap1
- call CreditsCopyTileMapToVRAM
- ld hl, vBGMap0
- call CreditsCopyTileMapToVRAM
- ld c, BANK(Music_Credits)
- ld a, MUSIC_CREDITS
- call PlayMusic
- ld c, 128
- call DelayFrames
- xor a
- ld [wHoFMonSpecies], a
- ld [wNumCreditsMonsDisplayed], a
- jp Credits
-
-FadeInCreditsText:
- ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
- ld hl, HoFGBPalettes
- ld b, 4
-.loop
- ld a, [hli]
- ld [rBGP], a
- call UpdateGBCPal_BGP
- ld c, 5
- call DelayFrames
- dec b
- jr nz, .loop
- ret
-
-HoFGBPalettes:
- db %11000000
- db %11010000
- db %11100000
- db %11110000
-
-DisplayCreditsMon:
- ld hl, vBGMap1
- call CreditsCopyTileMapToVRAM
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld hl, rLCDC
- set 3, [hl]
- call SaveScreenTilesToBuffer2
- call FillMiddleOfScreenWithWhite
- call GetNextCreditsMon
- ld hl, vBGMap0 + 12
- call CreditsCopyTileMapToVRAM
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- call LoadScreenTilesFromBuffer2DisableBGTransfer
- ld hl, vBGMap0
- call CreditsCopyTileMapToVRAM
- ld a, %11111100 ; make the mon a black silhouette
- ld [rBGP], a
- call UpdateGBCPal_BGP
- ld hl, rLCDC
- res 3, [hl]
- ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
- ld b, 0
- ld c, 10
- call ScrollCreditsMonLeft
- call FillLeftHalfOfScreenWithWhite
- ld c, 10
- call ScrollCreditsMonLeft
- call FillRightHalfOfScreenWithWhite
- ld c, 8
- call ScrollCreditsMonLeft
- ld a, %11000000
- ld [rBGP], a
- call UpdateGBCPal_BGP
- xor a
- ld [hSCX], a
- ret
-
-ScrollCreditsMonLeft:
- ld a, b
- ld [hSCX], a
- add 8
- ld b, a
- call DelayFrame
- dec c
- jr nz, ScrollCreditsMonLeft
- ret
-
-GetNextCreditsMon:
- ld hl, wNumCreditsMonsDisplayed
- ld c, [hl]
- inc [hl]
- ld b, 0
- ld hl, CreditsMons
- add hl, bc
- ld a, [hl]
- ld [wcf91], a
- ld [wd0b5], a
- coord hl, 8, 6
- call GetMonHeader
- call LoadFrontSpriteByMonIndex
- ret
-
-INCLUDE "data/credit_mons.asm"
-
-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
-
-CreditsLoadFont:
- call LoadFontTilePatterns
- ld hl, vChars1
- ld bc, $40 * $10
- call ZeroMemory
-
- call LoadTextBoxTilePatterns
- ld hl, vChars2 + $60 * $10
- ld bc, $10 * $10
- call ZeroMemory
-
- ld hl, vChars2 + $7e * $10
- ld bc, $1 * $10
- ld a, $ff
- call FillMemory
- ret
-
-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
-
-FillLeftHalfOfScreenWithWhite:
- coord hl, 0, 4
- push bc
- call FillHalfOfScreenWithWhite
- pop bc
- ret
-
-FillRightHalfOfScreenWithWhite:
- coord hl, 10, 4
- push bc
- call FillHalfOfScreenWithWhite
- pop bc
- ret
-
-FillHalfOfScreenWithWhite:
- ld b, 10
- ld c, 10
- ld a, " "
-.loop
- push bc
- push hl
-.innerLoop
- ld [hli], a
- dec c
- jr nz, .innerLoop
- pop hl
- ld bc, SCREEN_WIDTH
- add hl, bc
- pop bc
- dec b
- jr nz, .loop
- ret
-
-Credits: ; Roll 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
- call PlaceCreditsText
- pop de
- jr .nextCreditsCommand
-
-.showCopyrightText
- callba LoadCopyrightTiles
- pop de
- jr .nextCreditsCommand
-
-
-.fadeInTextAndShowMon
- call FadeInCreditsText
- ld c, 102
- jr .next1
-
-.showTextAndShowMon
- ld c, 122
-.next1
- call DelayFrames
- call DisplayCreditsMon
- jr .nextCreditsScreen
-
-.fadeInText
- call FadeInCreditsText
- ld c, 132
- jr .next2
-
-.showText
- ld c, 152
-.next2
- call DelayFrames
- jr .nextCreditsScreen
-
-.showTheEnd
- call ShowTheEndGFX
- pop de
- ret
-
-ShowTheEndGFX:
- ld c, 24
- call DelayFrames
- call FillMiddleOfScreenWithWhite
- 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, "@"
-
-PlaceCreditsText:
- push hl
- push hl
- ld hl, CreditsTextPointers
- ld c, a
- ld b, 0
- add hl, bc
- add hl, bc
- ld e, [hl]
- inc hl
- ld d, [hl]
- pop hl
- ld a, [de]
- inc de
- ld c, a
- ld b, $ff
- add hl, bc
- call PlaceString
- pop hl
- ld bc, SCREEN_WIDTH * 2
- add hl, bc
- ret
-
-INCLUDE "data/credits_order.asm"
-
-INCLUDE "text/credits_text.asm"
-
-TheEndGfx:
- INCBIN "gfx/theend.2bpp"
-TheEndGfxEnd:
diff --git a/engine/bank3c.asm b/engine/bank3c.asm
index 9c0e281f..8eb32837 100644
--- a/engine/bank3c.asm
+++ b/engine/bank3c.asm
@@ -1,9 +1,9 @@
INCLUDE "engine/pikachu_pcm.asm"
INCLUDE "engine/overworld/advance_player_sprite.asm"
-INCLUDE "engine/black_out.asm"
+INCLUDE "engine/events/black_out.asm"
-SetMapSpecificScriptFlagsOnMapReload:
+SetMapSpecificScriptFlagsOnMapReload::
ld a, [wCurMap]
cp VERMILION_GYM ; ??? new thing about verm gym?
jr z, .verm_gym
@@ -65,7 +65,7 @@ BeachHouse_Block:
Func_f0a54:
ret
-LoadUnusedBluesHouseMissableObjectData:
+LoadUnusedBluesHouseMissableObjectData::
; referenced in an unused function
ld hl, .MissableObjectsMaps
.loop
@@ -112,7 +112,7 @@ TryApplyPikachuMovementData:
ret nz
push hl
push bc
- callab GetPikachuFacingDirectionAndReturnToE
+ callfar GetPikachuFacingDirectionAndReturnToE
pop bc
pop hl
ld a, b
@@ -123,12 +123,12 @@ TryApplyPikachuMovementData:
push af
ld a, $ff
ld [wUpdateSpritesEnabled], a
- callab LoadPikachuShadowIntoVRAM
+ callfar LoadPikachuShadowIntoVRAM
pop af
ld [wUpdateSpritesEnabled], a
pop hl
call ApplyPikachuMovementData
- callab RefreshPikachuFollow
+ callfar RefreshPikachuFollow
ret
Pic_f0abf:
@@ -140,7 +140,7 @@ INCBIN "gfx/pikachu/unknown_f0cf4.pic"
GFX_f0d82:
INCBIN "gfx/pikachu/unknown_f0d82.2bpp"
-PokecenterChanseyText:
+PokecenterChanseyText::
ld hl, NurseChanseyText
call PrintText
ld a, CHANSEY
@@ -149,10 +149,10 @@ PokecenterChanseyText:
ret
NurseChanseyText:
- TX_FAR _NurseChanseyText
- db "@"
+ text_far _NurseChanseyText
+ text_end
-INCLUDE "engine/HoF_room_pc.asm"
+INCLUDE "engine/movie/credits.asm"
INCLUDE "scripts/ViridianCity2.asm"
INCLUDE "scripts/VermilionCity2.asm"
INCLUDE "scripts/CeladonCity2.asm"
@@ -173,11 +173,11 @@ INCLUDE "scripts/SafariZoneGate2.asm"
INCLUDE "scripts/CinnabarGym3.asm"
INCLUDE "scripts/MtMoonPokecenter2.asm"
-INCLUDE "data/mapHeaders/BeachHouse.asm"
+INCLUDE "data/maps/headers/BeachHouse.asm"
INCLUDE "scripts/BeachHouse.asm"
BeachHouse_Blocks:
INCBIN "maps/BeachHouse.blk"
-INCLUDE "data/mapObjects/BeachHouse.asm"
+INCLUDE "data/maps/objects/BeachHouse.asm"
INCLUDE "scripts/BeachHouse2.asm"
INCLUDE "scripts/BillsHouse2.asm"
diff --git a/engine/bank3d.asm b/engine/bank3d.asm
index 6d0b3a50..e929e44e 100644
--- a/engine/bank3d.asm
+++ b/engine/bank3d.asm
@@ -4,7 +4,7 @@ INCLUDE "engine/battle/unused_stats_functions.asm"
INCLUDE "engine/battle/scroll_draw_trainer_pic.asm"
StarterPikachuBattleEntranceAnimation:
- coord hl, 0, 5
+ hlcoord 0, 5
ld c, 0
.loop1
inc c
@@ -60,14 +60,14 @@ ModifyPikachuHappiness::
cp PIKAHAPPY_WALKING
jr z, .checkanywhereinparty
push de
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
pop de
ret nc
jr .proceed
.checkanywhereinparty
push de
- callab IsStarterPikachuInOurParty
+ callfar IsStarterPikachuInOurParty
pop de
ret nc
@@ -172,9 +172,9 @@ PikachuMoods:
db $6c ; Unknown (d = 10)
db $00 ; Unknown (d = 11)
-RedPicBack: INCBIN "pic/trainer/redb.pic"
-OldManPic: INCBIN "pic/trainer/oldman.pic"
-ProfOakPicBack: INCBIN "pic/ytrainer/prof.oakb.pic"
+RedPicBack: INCBIN "gfx/player/redb.pic"
+OldManPic: INCBIN "gfx/battle/oldman.pic"
+ProfOakPicBack: INCBIN "gfx/battle/prof.oakb.pic"
LoadYellowTitleScreenGFX:
ld hl, PokemonLogoGraphics
@@ -200,35 +200,35 @@ LoadYellowTitleScreenGFX:
ret
TitleScreen_PlacePokemonLogo:
- coord hl, 2, 1
+ hlcoord 2, 1
ld de, TitleScreenPokemonLogoTilemap
lb bc, 7, 16
call Bank3D_CopyBox
ret
TitleScreen_PlacePikaSpeechBubble:
- coord hl, 6, 4
+ hlcoord 6, 4
ld de, TitleScreenPikaBubbleTilemap
lb bc, 4, 7
call Bank3D_CopyBox
- coord hl, 9, 8
+ hlcoord 9, 8
ld [hl], $64
inc hl
ld [hl], $65
ret
TitleScreen_PlacePikachu:
- coord hl, 4, 8
+ hlcoord 4, 8
ld de, TitleScreenPikachuTilemap
lb bc, 9, 12
call Bank3D_CopyBox
- coord hl, 16, 10
+ hlcoord 16, 10
ld [hl], $96
- coord hl, 16, 11
+ hlcoord 16, 11
ld [hl], $9d
- coord hl, 16, 12
+ hlcoord 16, 12
ld [hl], $a7
- coord hl, 16, 13
+ hlcoord 16, 13
ld [hl], $b1
ld hl, TitleScreenPikachuEyesOAMData
ld de, wOAMBuffer
@@ -298,45 +298,45 @@ TitleScreenPikachuTilemap:
db $00, $b9, $ba, $8a, $8a, $8a, $8a, $8a, $8a, $bb, $bc, $00
db $00, $00, $bd, $8a, $8a, $8a, $8a, $8a, $8a, $be, $bf, $00
-PokemonLogoGraphics: INCBIN "gfx/pokemon_logo.2bpp"
+PokemonLogoGraphics: INCBIN "gfx/title/pokemon_logo.2bpp"
PokemonLogoGraphicsEnd:
YellowLogoGraphics: INCBIN "gfx/yellow_titlescreen.2bpp"
YellowLogoGraphicsEnd:
-INCLUDE "engine/menu/link_menu.asm"
+INCLUDE "engine/menus/link_menu.asm"
HandleMenuInputDouble:
xor a
ld [wPartyMenuAnimMonEnabled], a
HandleMenuInputPokemonSelectionDouble:
- ld a, [H_DOWNARROWBLINKCNT1]
+ ldh a, [hDownArrowBlinkCount1]
push af
- ld a, [H_DOWNARROWBLINKCNT2]
+ ldh a, [hDownArrowBlinkCount2]
push af ; save existing values on stack
xor a
- ld [H_DOWNARROWBLINKCNT1], a ; blinking down arrow timing value 1
+ ldh [hDownArrowBlinkCount1], a ; blinking down arrow timing value 1
ld a, $06
- ld [H_DOWNARROWBLINKCNT2], a ; blinking down arrow timing value 2
+ ldh [hDownArrowBlinkCount2], a ; blinking down arrow timing value 2
.loop1
xor a
ld [wAnimCounter], a ; counter for pokemon shaking animation
call .UpdateCursorTile
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and a ; was a key pressed?
jr nz, .keyPressed
pop af
- ld [H_DOWNARROWBLINKCNT2], a
+ ldh [hDownArrowBlinkCount2], a
pop af
- ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
+ ldh [hDownArrowBlinkCount1], a ; restore previous values
xor a
ld [wMenuWrappingEnabled], a ; disable menu wrapping
ret
.keyPressed
xor a
ld [wCheckFor180DegreeTurn], a
- ld a, [hJoy5]
+ ldh a, [hJoy5]
ld b, a
bit 6, a ; pressed Up key?
jr z, .checkIfDownPressed
@@ -365,7 +365,7 @@ HandleMenuInputPokemonSelectionDouble:
and b ; does the menu care about any of the pressed keys?
jp z, .loop1
.checkIfAButtonOrBButtonPressed
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and A_BUTTON | B_BUTTON
jr z, .skipPlayingSound
.AButtonOrBButtonPressed
@@ -373,17 +373,17 @@ HandleMenuInputPokemonSelectionDouble:
call PlaySound ; play sound
.skipPlayingSound
pop af
- ld [H_DOWNARROWBLINKCNT2], a
+ ldh [hDownArrowBlinkCount2], a
pop af
- ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
- ld a, [hJoy5]
+ ldh [hDownArrowBlinkCount1], a ; restore previous values
+ ldh a, [hJoy5]
ret
.UpdateCursorTile:
ld a, [wTopMenuItemY]
and a
jr z, .asm_f5ac0
- coord hl, 0, 0
+ hlcoord 0, 0
ld bc, SCREEN_WIDTH
.loop
add hl, bc
@@ -439,11 +439,7 @@ INCLUDE "engine/overworld/field_move_messages.asm"
INCLUDE "engine/items/inventory.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 "gfx/trainer_card.asm"
ReadSuperRodData:
ld a, [wCurMap]
@@ -485,11 +481,11 @@ GenerateRandomFishingEncounter:
ld d, [hl]
ret
-INCLUDE "data/super_rod.asm"
+INCLUDE "data/wild/super_rod.asm"
INCLUDE "engine/battle/bank3d_battle.asm"
INCLUDE "engine/items/tm_prices.asm"
-INCLUDE "engine/multiply_divide.asm"
-INCLUDE "engine/give_pokemon.asm"
+INCLUDE "engine/math/multiply_divide.asm"
+INCLUDE "engine/events/give_pokemon.asm"
INCLUDE "engine/battle/get_trainer_name.asm"
-INCLUDE "engine/random.asm"
+INCLUDE "engine/math/random.asm"
INCLUDE "engine/predefs.asm"
diff --git a/engine/bank3f.asm b/engine/bank3f.asm
index 23eadbb1..c26e9834 100644
--- a/engine/bank3f.asm
+++ b/engine/bank3f.asm
@@ -1,6 +1,6 @@
-INCLUDE "data/map_songs.asm"
-INCLUDE "data/map_header_pointers.asm"
-INCLUDE "data/map_header_banks.asm"
+INCLUDE "data/maps/songs.asm"
+INCLUDE "data/maps/map_header_pointers.asm"
+INCLUDE "data/maps/map_header_banks.asm"
INCLUDE "engine/pikachu_follow.asm"
INCLUDE "engine/pikachu_status.asm"
INCLUDE "engine/pikachu_emotions.asm"
@@ -16,8 +16,8 @@ SandshrewSprite: INCBIN "gfx/sprites/sandshrew.2bpp"
OddishSprite: INCBIN "gfx/sprites/oddish.2bpp"
BulbasaurSprite: INCBIN "gfx/sprites/bulbasaur.2bpp"
JigglypuffSprite: INCBIN "gfx/sprites/jigglypuff.2bpp"
-Clefairy2Sprite: INCBIN "gfx/sprites/clefairy2.2bpp"
+ClefairySprite: INCBIN "gfx/sprites/clefairy.2bpp"
ChanseySprite: INCBIN "gfx/sprites/chansey.2bpp"
-SurfingPikachuSprite: INCBIN "gfx/sprites/surfing_pikachu.2bpp"
+SurfingPikachuSprite:: INCBIN "gfx/sprites/surfing_pikachu.2bpp"
JessieSprite: INCBIN "gfx/sprites/jessie.2bpp"
JamesSprite: INCBIN "gfx/sprites/james.2bpp"
diff --git a/engine/battle/animations.asm b/engine/battle/animations.asm
index de1e67b9..4508dbaa 100755
--- a/engine/battle/animations.asm
+++ b/engine/battle/animations.asm
@@ -19,11 +19,11 @@ DrawFrameBlock:
ld [wdef5], a
ld a, [wSubAnimTransform]
dec a
- jr z, .flipHorizontalAndVertical ; 1
+ jr z, .flipHorizontalAndVertical ; SUBANIMTYPE_HVFLIP
dec a
- jp z, .flipHorizontalTranslateDown ; 2
+ jp z, .flipHorizontalTranslateDown ; SUBANIMTYPE_HFLIP
dec a
- jr z, .flipBaseCoords ; 3
+ jr z, .flipBaseCoords ; SUBANIMTYPE_COORDFLIP
.noTransformation
ld a, [wBaseCoordY]
add [hl]
@@ -45,7 +45,7 @@ DrawFrameBlock:
ld b, a
ld a, 168
sub b ; flip X base coordinate
-.finishCopying ; finish copying values to OAM (when [wSubAnimTransform] not 1 or 2)
+.finishCopying ; finish copying values to OAM (when subanimation not transformed)
add [hl] ; X offset
ld [de], a ; store X
cp 88
@@ -159,15 +159,15 @@ DrawFrameBlock:
jp nz, .loop ; go back up if there are more tiles to draw
.afterDrawingTiles
ld a, [wFBMode]
- cp 2
+ cp FRAMEBLOCKMODE_02
jr z, .advanceFrameBlockDestAddr; skip delay and don't clean OAM buffer
ld a, [wSubAnimFrameDelay]
ld c, a
call DelayFrames
ld a, [wFBMode]
- cp 3
+ cp FRAMEBLOCKMODE_03
jr z, .advanceFrameBlockDestAddr ; skip cleaning OAM buffer
- cp 4
+ cp FRAMEBLOCKMODE_04
jr z, .done ; skip cleaning OAM buffer and don't advance the frame block destination address
ld a, [wAnimationID]
cp GROWL
@@ -190,7 +190,7 @@ DrawFrameBlock:
PlayAnimation:
xor a
- ld [$FF8B], a ; it looks like nothing reads this
+ ldh [hROMBankTemp], a ; it looks like nothing reads this
ld [wSubAnimTransform], a
ld a, [wAnimationID] ; get animation number
dec a
@@ -204,9 +204,9 @@ PlayAnimation:
ld l, a
.animationLoop
ld a, [hli]
- cp $FF
+ cp -1
jr z, .AnimationOver
- cp $C0 ; is this subanimation or a special effect?
+ cp FIRST_SE_ID ; is this subanimation or a special effect?
jr c, .playSubanimation
.doSpecialEffect
ld c, a
@@ -221,7 +221,7 @@ PlayAnimation:
jr .searchSpecialEffectTableLoop
.foundMatch
ld a, [hli]
- cp $FF ; is there a sound to play?
+ cp NO_MOVE - 1 ; is there a sound to play?
jr z, .skipPlayingSound
ld [wAnimSoundID], a ; store sound
push hl
@@ -268,16 +268,16 @@ PlayAnimation:
ld l, c
ld h, b
push hl
- ld a, [rOBP0]
+ ldh a, [rOBP0]
push af
ld a, [wAnimPalette]
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
call LoadAnimationTileset
call LoadSubanimation
call PlaySubanimation
pop af
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
.nextAnimationCommand
pop hl
@@ -296,11 +296,11 @@ LoadSubanimation:
ld d, a ; de = address of subanimation
ld a, [de]
ld b, a
- and 31
+ and %00011111
ld [wSubAnimCounter], a ; number of frame blocks
ld a, b
and %11100000
- cp 5 << 5 ; is subanimation type 5?
+ cp SUBANIMTYPE_ENEMY << 5
jr nz, .isNotType5
.isType5
call GetSubanimationTransform2
@@ -312,7 +312,7 @@ LoadSubanimation:
srl a
swap a
ld [wSubAnimTransform], a
- cp 4 ; is the animation reversed?
+ cp SUBANIMTYPE_REVERSE
ld hl, 0
jr nz, .storeSubentryAddr
; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
@@ -332,27 +332,27 @@ LoadSubanimation:
ld [wSubAnimSubEntryAddr + 1], a
ret
-; called if the subanimation type is not 5
-; sets the transform to 0 (i.e. no transform) if it's the player's turn
+; called if the subanimation type is not SUBANIMTYPE_ENEMY
+; sets the transform to SUBANIMTYPE_NORMAL if it's the player's turn
; sets the transform to the subanimation type if it's the enemy's turn
GetSubanimationTransform1:
ld b, a
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, b
ret nz
- xor a
+ xor a ; SUBANIMTYPE_NORMAL << 5
ret
-; called if the subanimation type is 5
-; sets the transform to 2 (i.e. horizontal and vertical flip) if it's the player's turn
-; sets the transform to 0 (i.e. no transform) if it's the enemy's turn
+; called if the subanimation type is SUBANIMTYPE_ENEMY
+; sets the transform to SUBANIMTYPE_HFLIP if it's the player's turn
+; sets the transform to SUBANIMTYPE_NORMAL if it's the enemy's turn
GetSubanimationTransform2:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
- ld a, 2 << 5
+ ld a, SUBANIMTYPE_HFLIP << 5
ret z
- xor a
+ xor a ; SUBANIMTYPE_NORMAL << 5
ret
; loads tile patterns for battle animations
@@ -370,33 +370,33 @@ LoadAnimationTileset:
ld e, a
ld a, [hl]
ld d, a ; de = address of tileset
- ld hl, vSprites + $310
+ ld hl, vSprites tile $31
ld b, BANK(AnimationTileset1) ; ROM bank
ld a, [wTempTilesetNumTiles]
ld c, a ; number of tiles
jp CopyVideoData ; load tileset
-AnimationTilesetPointers:
- db 79 ; number of tiles
- dw AnimationTileset1
- db $FF
-
- db 79 ; number of tiles
- dw AnimationTileset2
- db $FF
+anim_tileset: MACRO
+ db \1
+ dw \2
+ db -1 ; padding
+ENDM
- db 64 ; number of tiles
- dw AnimationTileset1
- db $FF
+AnimationTilesetPointers:
+ ; number of tiles, gfx pointer
+ anim_tileset 79, AnimationTileset1
+ anim_tileset 79, AnimationTileset2
+ anim_tileset 64, AnimationTileset1
AnimationTileset1:
- INCBIN "gfx/attack_anim_1.2bpp"
+ INCBIN "gfx/battle/attack_anim_1.2bpp"
AnimationTileset2:
- INCBIN "gfx/attack_anim_2.2bpp"
+ INCBIN "gfx/battle/attack_anim_2.2bpp"
SlotMachineTiles2:
- INCBIN "gfx/slotmachine2.2bpp"
+ INCBIN "gfx/slots/slots_2.2bpp"
+SlotMachineTiles2End:
MoveAnimation:
push hl
@@ -435,7 +435,7 @@ MoveAnimation:
ld [wSubAnimSubEntryAddr], a
ld [wUnusedD09B], a
ld [wSubAnimTransform], a
- dec a
+ dec a ; NO_MOVE - 1
ld [wAnimSoundID], a
pop af
pop bc
@@ -445,11 +445,11 @@ MoveAnimation:
ShareMoveAnimations:
; some moves just reuse animations from status conditions
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ret z
- ; opponent’s turn
+ ; opponent's turn
ld a, [wAnimationID]
@@ -484,10 +484,10 @@ PlayApplyingAttackAnimation:
jp hl
AnimationTypePointerTable:
- dw ShakeScreenVertically ; enemy mon has used a damaging move without a side effect
+ dw ShakeScreenVertically ; enemy mon has used a damaging move without a side effect
dw ShakeScreenHorizontallyHeavy ; enemy mon has used a damaging move with a side effect
- dw ShakeScreenHorizontallySlow ; enemy mon has used a non-damaging move
- dw BlinkEnemyMonSprite ; player mon has used a damaging move without a side effect
+ dw ShakeScreenHorizontallySlow ; enemy mon has used a non-damaging move
+ dw BlinkEnemyMonSprite ; player mon has used a damaging move without a side effect
dw ShakeScreenHorizontallyLight ; player mon has used a damaging move with a side effect
dw ShakeScreenHorizontallySlow2 ; player mon has used a non-damaging move
@@ -521,18 +521,18 @@ AnimationShakeScreenHorizontallySlow:
push bc
push bc
.loop1
- ld a, [rWX]
+ ldh a, [rWX]
inc a
- ld [rWX], a
+ ldh [rWX], a
ld c, 2
call DelayFrames
dec b
jr nz, .loop1
pop bc
.loop2
- ld a, [rWX]
+ ldh a, [rWX]
dec a
- ld [rWX], a
+ ldh [rWX], a
ld c, 2
call DelayFrames
dec b
@@ -558,18 +558,18 @@ SetAnimationPalette:
ld b, $f0
.next
ld a, b
- ld [rOBP0], a
+ ldh [rOBP0], a
ld a, $6c
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
ret
.notSGB
ld a, $e4
ld [wAnimPalette], a
- ld [rOBP0], a
+ ldh [rOBP0], a
ld a, $6c
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
ret
@@ -577,13 +577,13 @@ SetAnimationPalette:
Func_78e98:
call SaveScreenTilesToBuffer2
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call ClearScreen
ld h, vBGMap0 / $100
call WriteLowerByteOfBGMapAndEnableBGTransfer
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call LoadScreenTilesFromBuffer2
ld h, vBGMap1 / $100
@@ -591,12 +591,12 @@ WriteLowerByteOfBGMapAndEnableBGTransfer:
ld l, vBGMap0 & $ff
call BattleAnimCopyTileMapToVRAM
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
PlaySubanimation:
ld a, [wAnimSoundID]
- cp $FF
+ cp NO_MOVE - 1
jr z, .skipPlayingSound
call GetMoveSound
call PlaySound
@@ -648,7 +648,7 @@ PlaySubanimation:
ld a, [wSubAnimSubEntryAddr]
ld l, a
ld a, [wSubAnimTransform]
- cp 4 ; is the animation reversed?
+ cp SUBANIMTYPE_REVERSE
ld bc, 3
jr nz, .nextSubanimationSubentry
ld bc, -3
@@ -697,90 +697,16 @@ DoSpecialEffectByAnimationId:
pop hl
ret
-; Format: Animation ID (1 byte), Address (2 bytes)
-AnimationIdSpecialEffects:
- db MEGA_PUNCH
- dw AnimationFlashScreen
-
- db GUILLOTINE
- dw AnimationFlashScreen
-
- db MEGA_KICK
- dw AnimationFlashScreen
-
- db HEADBUTT
- dw AnimationFlashScreen
-
- db TAIL_WHIP
- dw TailWhipAnimationUnused
-
- db GROWL
- dw DoGrowlSpecialEffects
-
- db DISABLE
- dw AnimationFlashScreen
-
- db BLIZZARD
- dw DoBlizzardSpecialEffects
-
- db BUBBLEBEAM
- dw AnimationFlashScreen
-
- db HYPER_BEAM
- dw FlashScreenEveryFourFrameBlocks
-
- db THUNDERBOLT
- dw FlashScreenEveryEightFrameBlocks
-
- db REFLECT
- dw AnimationFlashScreen
-
- db SELFDESTRUCT
- dw DoExplodeSpecialEffects
-
- db SPORE
- dw FlashScreenEveryFourFrameBlocks
-
- db EXPLOSION
- dw DoExplodeSpecialEffects
-
- db ROCK_SLIDE
- dw DoRockSlideSpecialEffects
-
- db TRADE_BALL_DROP_ANIM
- dw TradeHidePokemon
-
- db TRADE_BALL_SHAKE_ANIM
- dw TradeShakePokeball
-
- db TRADE_BALL_TILT_ANIM
- dw TradeJumpPokeball
-
- db TOSS_ANIM
- dw DoBallTossSpecialEffects
-
- db SHAKE_ANIM
- dw DoBallShakeSpecialEffects
-
- db POOF_ANIM
- dw DoPoofSpecialEffects
-
- db GREATTOSS_ANIM
- dw DoBallTossSpecialEffects
-
- db ULTRATOSS_ANIM
- dw DoBallTossSpecialEffects
-
- db $FF ; terminator
+INCLUDE "data/battle_anims/special_effects.asm"
DoBallTossSpecialEffects:
ld a, [wcf91]
cp 3 ; is it a Master Ball or Ultra Ball?
jr nc, .skipFlashingEffect
.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
- ld a, [rOBP0]
+ ldh a, [rOBP0]
xor %00111100 ; complement colors 1 and 2
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
.skipFlashingEffect
ld a, [wSubAnimCounter]
@@ -805,7 +731,7 @@ DoBallTossSpecialEffects:
cp 1
ret nz
.moveGhostMarowakLeft
- coord hl, 17, 0
+ hlcoord 17, 0
ld de, 20
lb bc, 7, 7
.loop
@@ -818,7 +744,7 @@ DoBallTossSpecialEffects:
dec b
jr nz, .loop
ld a, %00001000
- ld [rNR10], a ; Channel 1 sweep register
+ ldh [rNR10], a ; Channel 1 sweep register
ret
.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
ld a, [wSubAnimCounter]
@@ -904,7 +830,7 @@ DoExplodeSpecialEffects:
cp 1 ; is it the end of the subanimation?
jr nz, FlashScreenEveryFourFrameBlocks
; if it's the end of the subanimation, make the attacking pokemon disappear
- coord hl, 1, 5
+ hlcoord 1, 5
jp AnimationHideMonPic ; make pokemon disappear
; flashes the screen when subanimation counter is 1 modulo 4
@@ -972,7 +898,7 @@ TradeShakePokeball:
BallMoveDistances1:
db -12, -12, -8
- db $ff ; terminator
+ db -1 ; end
; function to make the pokeball jump up
TradeJumpPokeball:
@@ -1005,15 +931,15 @@ TradeJumpPokeball:
ld c, 5
call DelayFrames
pop bc
- ld a, [hSCX] ; background scroll X
+ ldh a, [hSCX] ; background scroll X
sub 8 ; scroll to the left
- ld [hSCX], a
+ ldh [hSCX], a
pop de
jr .loop
BallMoveDistances2:
db 11, 12, -12, -7, 7, 12, -8, 8
- db $ff ; terminator
+ db -1 ; end
; this function copies the current musical note graphic
; so that there are two musical notes flying towards the defending pokemon
@@ -1034,87 +960,7 @@ TailWhipAnimationUnused:
ld c, 20
jp DelayFrames
-; Format: Special Effect ID (1 byte), Address (2 bytes)
-SpecialEffectPointers:
- db SE_DARK_SCREEN_FLASH ; $FE
- dw AnimationFlashScreen
- db SE_DARK_SCREEN_PALETTE ; $FD
- dw AnimationDarkScreenPalette
- db SE_RESET_SCREEN_PALETTE ; $FC
- dw AnimationResetScreenPalette
- db SE_SHAKE_SCREEN ; $FB
- dw AnimationShakeScreen
- db SE_WATER_DROPLETS_EVERYWHERE ; $FA
- dw AnimationWaterDropletsEverywhere
- db SE_DARKEN_MON_PALETTE ; $F9
- dw AnimationDarkenMonPalette
- db SE_FLASH_SCREEN_LONG ; $F8
- dw AnimationFlashScreenLong
- db SE_SLIDE_MON_UP ; $F7
- dw AnimationSlideMonUp
- db SE_SLIDE_MON_DOWN ; $F6
- dw AnimationSlideMonDown
- db SE_FLASH_MON_PIC ; $F5
- dw AnimationFlashMonPic
- db SE_SLIDE_MON_OFF ; $F4
- dw AnimationSlideMonOff
- db SE_BLINK_MON ; $F3
- dw AnimationBlinkMon
- db SE_MOVE_MON_HORIZONTALLY ; $F2
- dw AnimationMoveMonHorizontally
- db SE_RESET_MON_POSITION ; $F1
- dw AnimationResetMonPosition
- db SE_LIGHT_SCREEN_PALETTE ; $F0
- dw AnimationLightScreenPalette
- db SE_HIDE_MON_PIC ; $EF
- dw AnimationHideMonPic
- db SE_SQUISH_MON_PIC ; $EE
- dw AnimationSquishMonPic
- db SE_SHOOT_BALLS_UPWARD ; $ED
- dw AnimationShootBallsUpward
- db SE_SHOOT_MANY_BALLS_UPWARD ; $EC
- dw AnimationShootManyBallsUpward
- db SE_BOUNCE_UP_AND_DOWN ; $EB
- dw AnimationBoundUpAndDown
- db SE_MINIMIZE_MON ; $EA
- dw AnimationMinimizeMon
- db SE_SLIDE_MON_DOWN_AND_HIDE ; $E9
- dw AnimationSlideMonDownAndHide
- db SE_TRANSFORM_MON ; $E8
- dw AnimationTransformMon
- db SE_LEAVES_FALLING ; $E7
- dw AnimationLeavesFalling
- db SE_PETALS_FALLING ; $E6
- dw AnimationPetalsFalling
- db SE_SLIDE_MON_HALF_OFF ; $E5
- dw AnimationSlideMonHalfOff
- db SE_SHAKE_ENEMY_HUD ; $E4
- dw AnimationShakeEnemyHUD
- db SE_SHAKE_ENEMY_HUD_2 ; unused--same pointer as SE_SHAKE_ENEMY_HUD ($E4)
- dw AnimationShakeEnemyHUD
- db SE_SPIRAL_BALLS_INWARD ; $E2
- dw AnimationSpiralBallsInward
- db SE_DELAY_ANIMATION_10 ; $E1
- dw AnimationDelay10
- db SE_FLASH_ENEMY_MON_PIC ; unused--same as SE_FLASH_MON_PIC ($F5), but for the enemy mon
- dw AnimationFlashEnemyMonPic
- db SE_HIDE_ENEMY_MON_PIC ; $DF
- dw AnimationHideEnemyMonPic
- db SE_BLINK_ENEMY_MON ; $DE
- dw AnimationBlinkEnemyMon
- db SE_SHOW_MON_PIC ; $DD
- dw AnimationShowMonPic
- db SE_SHOW_ENEMY_MON_PIC ; $DC
- dw AnimationShowEnemyMonPic
- db SE_SLIDE_ENEMY_MON_OFF ; $DB
- dw AnimationSlideEnemyMonOff
- db SE_SHAKE_BACK_AND_FORTH ; $DA
- dw AnimationShakeBackAndForth
- db SE_SUBSTITUTE_MON ; $D9
- dw AnimationSubstitute
- db SE_WAVY_SCREEN ; $D8
- dw AnimationWavyScreen
- db $FF
+INCLUDE "data/battle_anims/special_effect_pointers.asm"
AnimationDelay10:
ld c, 10
@@ -1123,16 +969,16 @@ AnimationDelay10:
; calls a function with the turn flipped from player to enemy or vice versa
; input - hl - address of function to call
CallWithTurnFlipped:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
push af
xor 1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld de, .returnAddress
push de
jp hl
.returnAddress
pop af
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ret
; flashes the screen for an extended period (48 frames)
@@ -1150,7 +996,7 @@ AnimationFlashScreenLong:
ld a, [hli]
cp $01 ; is it the end of the palettes?
jr z, .endOfPalettes
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
call FlashScreenLongDelay
jr .innerLoop
@@ -1210,20 +1056,20 @@ FlashScreenLongDelay:
jp DelayFrames
AnimationFlashScreen:
- ld a, [rBGP]
+ ldh a, [rBGP]
push af ; save initial palette
ld a, %00011011 ; 0, 1, 2, 3 (inverted colors)
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 2
call DelayFrames
xor a ; white out background
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 2
call DelayFrames
pop af
- ld [rBGP], a ; restore initial palette
+ ldh [rBGP], a ; restore initial palette
call UpdateGBCPal_BGP
ret
@@ -1269,7 +1115,7 @@ SetAnimationBGPalette:
jr z, .next
ld a, c
.next
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ret
@@ -1356,14 +1202,14 @@ _AnimationWaterDroplets:
AnimationSlideMonUp:
; Slides the mon's sprite upwards.
ld c, 7
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
- coord hl, 1, 6
- coord de, 1, 5
+ hlcoord 1, 6
+ decoord 1, 5
ld a, $30
jr z, .next
- coord hl, 12, 1
- coord de, 12, 0
+ hlcoord 12, 1
+ decoord 12, 0
ld a, $ff
.next
ld [wSlideMonUpBottomRowLeftTile], a
@@ -1371,7 +1217,7 @@ AnimationSlideMonUp:
AnimationSlideMonDown:
; Slides the mon's sprite down out of the screen.
- xor a
+ xor a ; TILEMAP_MON_PIC
call GetTileIDList
.loop
call GetMonSpriteTileMapPointerFromRowCount
@@ -1424,11 +1270,11 @@ _AnimationSlideMonUp:
jr nz, .slideLoop
; Fill in the bottom row of the mon pic with the next row's tile IDs.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
- coord hl, 1, 11
+ hlcoord 1, 11
jr z, .next
- coord hl, 12, 6
+ hlcoord 12, 6
.next
ld a, [wSlideMonUpBottomRowLeftTile]
inc a
@@ -1592,7 +1438,7 @@ AnimationFlashEnemyMonPic:
jp CallWithTurnFlipped
AnimationShowMonPic:
- xor a
+ xor a ; TILEMAP_MON_PIC
call GetTileIDList
call GetMonSpriteTileMapPointerFromRowCount
call CopyPicTiles
@@ -1607,16 +1453,16 @@ AnimationShowEnemyMonPic:
AnimationShakeBackAndForth:
; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
; The mon's sprite disappears after this animation.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
- coord hl, 0, 5
- coord de, 2, 5
+ hlcoord 0, 5
+ decoord 2, 5
jr z, .next
- coord hl, 11, 0
- coord de, 13, 0
+ hlcoord 11, 0
+ decoord 13, 0
.next
- xor a
+ xor a ; TILEMAP_MON_PIC
ld c, $10
.loop
push af
@@ -1655,13 +1501,13 @@ AnimationMoveMonHorizontally:
; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
; animations like Tackle/Body Slam.
call AnimationHideMonPic
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
- coord hl, 2, 5
+ hlcoord 2, 5
jr z, .next
- coord hl, 11, 0
+ hlcoord 11, 0
.next
- xor a
+ xor a ; TILEMAP_MON_PIC
push hl
call GetTileIDList
pop hl
@@ -1671,7 +1517,7 @@ AnimationMoveMonHorizontally:
AnimationResetMonPosition:
; Resets the mon's sprites to be located at the normal coordinates.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, 5 * SCREEN_WIDTH + 2
jr z, .next
@@ -1683,7 +1529,7 @@ AnimationResetMonPosition:
AnimationSpiralBallsInward:
; Creates an effect that looks like energy balls spiralling into the
; player mon's sprite. Used in Focus Energy, for example.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
ld a, -40
@@ -1772,7 +1618,7 @@ SpiralBallAnimationCoordinates:
db $58, $28
db $50, $30
db $50, $28
- db $FF ; list terminator
+ db -1 ; end
AnimationSquishMonPic:
; Squishes the mon's sprite horizontally making it
@@ -1780,15 +1626,15 @@ AnimationSquishMonPic:
ld c, 4
.loop
push bc
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
- coord hl, 16, 0
- coord de, 14, 0
+ hlcoord 16, 0
+ decoord 14, 0
jr .next
.playerTurn
- coord hl, 5, 5
- coord de, 3, 5
+ hlcoord 5, 5
+ decoord 3, 5
.next
push de
xor a ; left
@@ -1833,7 +1679,7 @@ _AnimationSquishMonPic:
AnimationShootBallsUpward:
; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
; animations.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
lb bc, 0, 16 * 8
@@ -1901,7 +1747,7 @@ _AnimationShootBallsUpward:
AnimationShootManyBallsUpward:
; Shoots several pillars of "energy" balls upward.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
ld a, $50 ; y coordinate for "energy" ball pillar
@@ -1927,13 +1773,13 @@ UpwardBallsAnimXCoordinatesPlayerTurn:
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
db $10, $40, $28, $18, $38, $30
- db $FF ; list terminator
+ db -1 ; end
UpwardBallsAnimXCoordinatesEnemyTurn:
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
db $60, $90, $78, $68, $88, $80
- db $FF ; list terminator
+ db -1 ; end
AnimationMinimizeMon:
; Changes the mon's sprite to a mini black sprite. Used by the
@@ -1960,13 +1806,13 @@ AnimationMinimizeMon:
jp AnimationShowMonPic
MinimizedMonSprite:
- INCBIN "gfx/minimized_mon_sprite.1bpp"
+ INCBIN "gfx/battle/minimize.1bpp"
MinimizedMonSpriteEnd:
AnimationSlideMonDownAndHide:
; Slides the mon's sprite down and disappears. Used in Acid Armor.
- ld a, $1
- ld c, $2
+ ld a, TILEMAP_SLIDE_DOWN_MON_PIC_7X5
+ ld c, 2
.loop
push bc
push af
@@ -1985,7 +1831,7 @@ AnimationSlideMonDownAndHide:
jr nz, .loop
call AnimationHideMonPic
ld hl, wTempPic
- ld bc, $0310
+ ld bc, 7 * 7 tiles
xor a
call FillMemory
jp CopyTempPicToMonPic
@@ -1993,13 +1839,13 @@ AnimationSlideMonDownAndHide:
_AnimationSlideMonOff:
; Slides the mon's sprite off the screen horizontally by e tiles and waits
; [wSlideMonDelay] V-blanks each time the pic is slid by one tile.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
- coord hl, 12, 0
+ hlcoord 12, 0
jr .next
.playerTurn
- coord hl, 0, 5
+ hlcoord 0, 5
.next
ld d, 8 ; d's value is unused
.slideLoop ; iterates once for each time the pic slides by one tile
@@ -2008,7 +1854,7 @@ _AnimationSlideMonOff:
.rowLoop ; iterates once for each row
ld c, 8
.tileLoop ; iterates once for each tile in the row
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn2
call .EnemyNextTile
@@ -2069,7 +1915,7 @@ AnimationSlideMonHalfOff:
jp Delay3
CopyTempPicToMonPic:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld hl, vBackPic ; player turn
jr z, .next
@@ -2085,18 +1931,18 @@ AnimationWavyScreen:
call BattleAnimCopyTileMapToVRAM
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
+ ldh [hAutoBGTransferEnabled], a
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
ld d, $80 ; terminator
- ld e, SCREEN_HEIGHT_PIXELS - 1
+ ld e, SCREEN_HEIGHT_PX - 1
ld c, $ff
ld hl, WavyScreenLineOffsets
.loop
push hl
.innerLoop
call WavyScreen_SetSCX
- ld a, [rLY]
+ ldh a, [rLY]
cp e ; is it the last visible line in the frame?
jr nz, .innerLoop ; keep going if not
pop hl
@@ -2109,11 +1955,11 @@ AnimationWavyScreen:
dec c
jr nz, .loop
xor a
- ld [hWY], a
+ ldh [hWY], a
call SaveScreenTilesToBuffer2
call ClearScreen
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call LoadScreenTilesFromBuffer2
ld hl, vBGMap1
@@ -2121,11 +1967,11 @@ AnimationWavyScreen:
ret
WavyScreen_SetSCX:
- ld a, [rSTAT]
+ ldh a, [rSTAT]
and $3 ; is it H-blank?
jr nz, WavyScreen_SetSCX ; wait until it's H-blank
ld a, [hl]
- ld [rSCX], a
+ ldh [rSCX], a
inc hl
ld a, [hl]
cp d ; have we reached the end?
@@ -2144,48 +1990,48 @@ AnimationSubstitute:
; Changes the pokemon's sprite to the mini sprite
ld hl, wTempPic
xor a
- ld bc, $0310
+ ld bc, $310
call FillMemory
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
- ld hl, SlowbroSprite ; facing down sprite
+ ld hl, MonsterSprite tile 0 ; facing down sprite
ld de, wTempPic + $120
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $10
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 1
ld de, wTempPic + $120 + $70
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $20
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 2
ld de, wTempPic + $120 + $10
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $30
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 3
ld de, wTempPic + $120 + $10 + $70
- call CopySlowbroSpriteData
+ call CopyMonsterSpriteData
jr .next
.playerTurn
- ld hl, SlowbroSprite + $40 ; facing up sprite
+ ld hl, MonsterSprite tile 4 ; facing up sprite
ld de, wTempPic + $120 + $70
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $50
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 5
ld de, wTempPic + $120 + $e0
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $60
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 6
ld de, wTempPic + $120 + $80
- call CopySlowbroSpriteData
- ld hl, SlowbroSprite + $70
+ call CopyMonsterSpriteData
+ ld hl, MonsterSprite tile 7
ld de, wTempPic + $120 + $f0
- call CopySlowbroSpriteData
+ call CopyMonsterSpriteData
.next
call CopyTempPicToMonPic
jp AnimationShowMonPic
-CopySlowbroSpriteData:
- ld bc, $0010
- ld a, BANK(SlowbroSprite)
+CopyMonsterSpriteData:
+ ld bc, 1 tiles
+ ld a, BANK(MonsterSprite)
jp FarCopyData
HideSubstituteShowMonAnim:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld hl, wPlayerMonMinimized
ld de, wPlayerBattleStatus1
@@ -2226,7 +2072,7 @@ HideSubstituteShowMonAnim:
call AnimationFlashMonPic
jp AnimationShowMonPic
.flyOrDig
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .enemy
ld a, [wPlayerMonMinimized]
@@ -2294,7 +2140,7 @@ AnimationTransformMon:
ld [wChangeMonPicEnemyTurnSpecies], a
ChangeMonPic:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
ld a, [wChangeMonPicEnemyTurnSpecies]
@@ -2303,7 +2149,7 @@ ChangeMonPic:
xor a
ld [wSpriteFlipped], a
call GetMonHeader
- coord hl, 12, 0
+ hlcoord 12, 0
call LoadFrontSpriteByMonIndex
jr .done
.playerTurn
@@ -2314,7 +2160,7 @@ ChangeMonPic:
ld [wd0b5], a
call GetMonHeader
predef LoadMonBackPic
- xor a
+ xor a ; TILEMAP_MON_PIC
call GetTileIDList
call GetMonSpriteTileMapPointerFromRowCount
call CopyPicTiles
@@ -2327,16 +2173,16 @@ ChangeMonPic:
AnimationHideEnemyMonPic:
; Hides the enemy mon's sprite
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld hl, AnimationHideMonPic
call CallWithTurnFlipped
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
jp Delay3
Func_79929:
ld hl, wPlayerMonMinimized
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
ld hl, wEnemyMonMinimized
@@ -2376,7 +2222,7 @@ InitMultipleObjectsOAM:
AnimationHideMonPic:
; Hides the mon's sprite.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
ld a, 12
@@ -2390,7 +2236,7 @@ ClearMonPicFromTileMap:
push bc
ld e, a
ld d, 0
- coord hl, 0, 0
+ hlcoord 0, 0
add hl, de
lb bc, 7, 7
call ClearScreenArea
@@ -2404,7 +2250,7 @@ ClearMonPicFromTileMap:
; in order to show only a portion of the mon sprite.
GetMonSpriteTileMapPointerFromRowCount:
push de
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .enemyTurn
ld a, 20 * 5 + 1
@@ -2412,7 +2258,7 @@ GetMonSpriteTileMapPointerFromRowCount:
.enemyTurn
ld a, 12
.next
- coord hl, 0, 0
+ hlcoord 0, 0
ld e, a
ld d, 0
add hl, de
@@ -2492,7 +2338,7 @@ GetMoveSound:
ld b, a
call IsCryMove
jr nc, .NotCryMove
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .next
ld a, [wBattleMonSpecies] ; get number of current monster
@@ -2534,184 +2380,17 @@ IsCryMove:
scf
ret
-MoveSoundTable:
- ; ID, pitch mod, tempo mod
- db SFX_POUND, $00, $80 ; POUND
- db SFX_BATTLE_0C, $10, $80 ; KARATE_CHOP
- db SFX_DOUBLESLAP, $00, $80 ; DOUBLESLAP
- db SFX_BATTLE_0B, $01, $80 ; COMET_PUNCH
- db SFX_BATTLE_0D, $00, $40 ; MEGA_PUNCH
- db SFX_SILPH_SCOPE, $00, $ff ; PAY_DAY
- db SFX_BATTLE_0D, $10, $60 ; FIRE_PUNCH
- db SFX_BATTLE_0D, $20, $80 ; ICE_PUNCH
- db SFX_BATTLE_0D, $00, $a0 ; THUNDERPUNCH
- db SFX_DAMAGE, $00, $80 ; SCRATCH
- db SFX_BATTLE_0F, $20, $40 ; VICEGRIP
- db SFX_BATTLE_0F, $00, $80 ; GUILLOTINE
- db SFX_BATTLE_0E, $00, $a0 ; RAZOR_WIND
- db SFX_NOT_VERY_EFFECTIVE, $10, $c0 ; SWORDS_DANCE
- db SFX_NOT_VERY_EFFECTIVE, $00, $a0 ; CUT
- db SFX_BATTLE_12, $00, $c0 ; GUST
- db SFX_BATTLE_12, $10, $a0 ; WING_ATTACK
- db SFX_BATTLE_13, $00, $e0 ; WHIRLWIND
- db SFX_NOT_VERY_EFFECTIVE, $20, $c0 ; FLY
- db SFX_BATTLE_14, $00, $80 ; BIND
- db SFX_BATTLE_22, $00, $80 ; SLAM
- db SFX_VINE_WHIP, $01, $80 ; VINE_WHIP
- db SFX_BATTLE_20, $00, $80 ; STOMP
- db SFX_BATTLE_17, $f0, $40 ; DOUBLE_KICK
- db SFX_SUPER_EFFECTIVE, $00, $80 ; MEGA_KICK
- db SFX_BATTLE_17, $00, $80 ; JUMP_KICK
- db SFX_BATTLE_21, $10, $80 ; ROLLING_KICK
- db SFX_BATTLE_1B, $01, $a0 ; SAND_ATTACK
- db SFX_BATTLE_18, $00, $80 ; HEADBUTT
- db SFX_BATTLE_1E, $00, $60 ; HORN_ATTACK
- db SFX_BATTLE_1E, $01, $40 ; FURY_ATTACK
- db SFX_HORN_DRILL, $00, $a0 ; HORN_DRILL
- db SFX_SUPER_EFFECTIVE, $10, $a0 ; TACKLE
- db SFX_BATTLE_20, $00, $c0 ; BODY_SLAM
- db SFX_BATTLE_14, $10, $60 ; WRAP
- db SFX_SUPER_EFFECTIVE, $00, $a0 ; TAKE_DOWN
- db SFX_BATTLE_22, $11, $c0 ; THRASH
- db SFX_SUPER_EFFECTIVE, $20, $c0 ; DOUBLE_EDGE
- db SFX_BATTLE_21, $00, $80 ; TAIL_WHIP
- db SFX_BATTLE_1B, $00, $80 ; POISON_STING
- db SFX_BATTLE_1B, $20, $c0 ; TWINEEDLE
- db SFX_BATTLE_19, $00, $80 ; PIN_MISSILE
- db SFX_BATTLE_31, $ff, $40 ; LEER
- db SFX_BATTLE_1E, $00, $80 ; BITE
- db SFX_BATTLE_0B, $00, $c0 ; GROWL
- db SFX_BATTLE_0B, $00, $40 ; ROAR
- db SFX_BATTLE_35, $00, $80 ; SING
- db SFX_BATTLE_27, $40, $60 ; SUPERSONIC
- db SFX_BATTLE_27, $00, $80 ; SONICBOOM
- db SFX_BATTLE_27, $ff, $40 ; DISABLE
- db SFX_BATTLE_2A, $80, $c0 ; ACID
- db SFX_BATTLE_19, $10, $a0 ; EMBER
- db SFX_BATTLE_19, $21, $e0 ; FLAMETHROWER
- db SFX_BATTLE_29, $00, $80 ; MIST
- db SFX_BATTLE_24, $20, $60 ; WATER_GUN
- db SFX_BATTLE_2A, $00, $80 ; HYDRO_PUMP
- db SFX_BATTLE_2C, $00, $80 ; SURF
- db SFX_BATTLE_28, $40, $80 ; ICE_BEAM
- db SFX_BATTLE_29, $f0, $e0 ; BLIZZARD
- db SFX_PSYBEAM, $00, $80 ; PSYBEAM
- db SFX_BATTLE_2A, $f0, $60 ; BUBBLEBEAM
- db SFX_BATTLE_28, $00, $80 ; AURORA_BEAM
- db SFX_BATTLE_36, $00, $80 ; HYPER_BEAM
- db SFX_PECK, $01, $a0 ; PECK
- db SFX_BATTLE_13, $f0, $20 ; DRILL_PECK
- db SFX_BATTLE_23, $01, $c0 ; SUBMISSION
- db SFX_BATTLE_23, $00, $80 ; LOW_KICK
- db SFX_SUPER_EFFECTIVE, $00, $e0 ; COUNTER
- db SFX_BATTLE_26, $01, $60 ; SEISMIC_TOSS
- db SFX_BATTLE_26, $20, $40 ; STRENGTH
- db SFX_BATTLE_24, $00, $80 ; ABSORB
- db SFX_BATTLE_24, $40, $c0 ; MEGA_DRAIN
- db SFX_BATTLE_1B, $03, $60 ; LEECH_SEED
- db SFX_BATTLE_25, $11, $e0 ; GROWTH
- db SFX_BATTLE_12, $20, $e0 ; RAZOR_LEAF
- db SFX_BATTLE_2E, $00, $80 ; SOLARBEAM
- db SFX_BATTLE_1C, $00, $80 ; POISONPOWDER
- db SFX_BATTLE_1C, $11, $a0 ; STUN_SPORE
- db SFX_BATTLE_1C, $01, $c0 ; SLEEP_POWDER
- db SFX_BATTLE_13, $14, $c0 ; PETAL_DANCE
- db SFX_BATTLE_1B, $02, $a0 ; STRING_SHOT
- db SFX_BATTLE_29, $f0, $80 ; DRAGON_RAGE
- db SFX_BATTLE_29, $20, $c0 ; FIRE_SPIN
- db SFX_BATTLE_2F, $00, $20 ; THUNDERSHOCK
- db SFX_BATTLE_2F, $20, $80 ; THUNDERBOLT
- db SFX_BATTLE_2E, $12, $60 ; THUNDER_WAVE
- db SFX_BATTLE_26, $00, $80 ; THUNDER
- db SFX_BATTLE_14, $01, $e0 ; ROCK_THROW
- db SFX_BATTLE_29, $0f, $e0 ; EARTHQUAKE
- db SFX_BATTLE_29, $11, $20 ; FISSURE
- db SFX_DAMAGE, $10, $40 ; DIG
- db SFX_BATTLE_0F, $10, $c0 ; TOXIC
- db SFX_BATTLE_14, $00, $20 ; CONFUSION
- db SFX_PSYCHIC_M, $00, $80 ; PSYCHIC_M
- db SFX_BATTLE_35, $11, $18 ; HYPNOSIS
- db SFX_BATTLE_09, $20, $c0 ; MEDITATE
- db SFX_FAINT_FALL, $20, $c0 ; AGILITY
- db SFX_BATTLE_25, $00, $10 ; QUICK_ATTACK
- db SFX_BATTLE_26, $f0, $20 ; RAGE
- db SFX_BATTLE_33, $f0, $c0 ; TELEPORT
- db SFX_NOT_VERY_EFFECTIVE, $f0, $e0 ; NIGHT_SHADE
- db SFX_BATTLE_09, $f0, $40 ; MIMIC
- db SFX_BATTLE_31, $00, $80 ; SCREECH
- db SFX_BATTLE_33, $80, $40 ; DOUBLE_TEAM
- db SFX_BATTLE_33, $00, $80 ; RECOVER
- db SFX_BATTLE_14, $11, $20 ; HARDEN
- db SFX_BATTLE_14, $22, $10 ; MINIMIZE
- db SFX_BATTLE_1B, $f1, $ff ; SMOKESCREEN
- db SFX_BATTLE_13, $f1, $ff ; CONFUSE_RAY
- db SFX_BATTLE_14, $33, $30 ; WITHDRAW
- db SFX_BATTLE_32, $40, $c0 ; DEFENSE_CURL
- db SFX_BATTLE_0E, $20, $20 ; BARRIER
- db SFX_BATTLE_0E, $f0, $10 ; LIGHT_SCREEN
- db SFX_BATTLE_0F, $f8, $10 ; HAZE
- db SFX_NOT_VERY_EFFECTIVE, $f0, $10 ; REFLECT
- db SFX_BATTLE_25, $00, $80 ; FOCUS_ENERGY
- db SFX_BATTLE_18, $00, $c0 ; BIDE
- db SFX_BATTLE_32, $c0, $ff ; METRONOME
- db SFX_BATTLE_09, $f2, $20 ; MIRROR_MOVE
- db SFX_BATTLE_34, $00, $80 ; SELFDESTRUCT
- db SFX_BATTLE_34, $00, $40 ; EGG_BOMB
- db SFX_BATTLE_09, $00, $40 ; LICK
- db SFX_NOT_VERY_EFFECTIVE, $10, $ff ; SMOG
- db SFX_BATTLE_2A, $20, $20 ; SLUDGE
- db SFX_BATTLE_32, $00, $80 ; BONE_CLUB
- db SFX_BATTLE_29, $1f, $20 ; FIRE_BLAST
- db SFX_BATTLE_25, $2f, $80 ; WATERFALL
- db SFX_BATTLE_0F, $1f, $ff ; CLAMP
- db SFX_BATTLE_2B, $1f, $60 ; SWIFT
- db SFX_BATTLE_26, $1e, $20 ; SKULL_BASH
- db SFX_BATTLE_26, $1f, $18 ; SPIKE_CANNON
- db SFX_BATTLE_14, $0f, $80 ; CONSTRICT
- db SFX_BATTLE_09, $f8, $10 ; AMNESIA
- db SFX_FAINT_FALL, $18, $20 ; KINESIS
- db SFX_BATTLE_32, $08, $40 ; SOFTBOILED
- db SFX_BATTLE_17, $01, $e0 ; HI_JUMP_KICK
- db SFX_NOT_VERY_EFFECTIVE, $09, $ff ; GLARE
- db SFX_BATTLE_35, $42, $01 ; DREAM_EATER
- db SFX_BATTLE_1C, $00, $ff ; POISON_GAS
- db SFX_BATTLE_32, $08, $e0 ; BARRAGE
- db SFX_BATTLE_24, $00, $80 ; LEECH_LIFE
- db SFX_BATTLE_09, $88, $10 ; LOVELY_KISS
- db SFX_BATTLE_25, $48, $ff ; SKY_ATTACK
- db SFX_FAINT_FALL, $ff, $ff ; TRANSFORM
- db SFX_BATTLE_24, $ff, $10 ; BUBBLE
- db SFX_FAINT_FALL, $ff, $04 ; DIZZY_PUNCH
- db SFX_BATTLE_1C, $01, $ff ; SPORE
- db SFX_BATTLE_13, $f8, $ff ; FLASH
- db SFX_BATTLE_0C, $f0, $f0 ; PSYWAVE
- db SFX_BATTLE_0F, $08, $10 ; SPLASH
- db SFX_BATTLE_0D, $f0, $ff ; ACID_ARMOR
- db SFX_SUPER_EFFECTIVE, $f0, $ff ; CRABHAMMER
- db SFX_BATTLE_34, $10, $ff ; EXPLOSION
- db SFX_BATTLE_0E, $f0, $20 ; FURY_SWIPES
- db SFX_BATTLE_2B, $f0, $60 ; BONEMERANG
- db SFX_BATTLE_21, $12, $10 ; REST
- db SFX_BATTLE_36, $f0, $20 ; ROCK_SLIDE
- db SFX_BATTLE_1E, $12, $ff ; HYPER_FANG
- db SFX_BATTLE_31, $80, $04 ; SHARPEN
- db SFX_BATTLE_33, $f0, $10 ; CONVERSION
- db SFX_BATTLE_29, $f8, $ff ; TRI_ATTACK
- db SFX_BATTLE_26, $f0, $ff ; SUPER_FANG
- db SFX_NOT_VERY_EFFECTIVE, $01, $ff ; SLASH
- db SFX_BATTLE_2C, $d8, $04 ; SUBSTITUTE
- db SFX_BATTLE_0B, $00, $80 ; STRUGGLE
- db SFX_BATTLE_0B, $00, $80
+INCLUDE "data/moves/sfx.asm"
CopyPicTiles:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, $31 ; base tile ID of player mon sprite
jr z, .next
; enemy turn
xor a ; base tile ID of enemy mon sprite
.next
- ld [hBaseTileID], a
+ ldh [hBaseTileID], a
jr CopyTileIDs_NoBGTransfer
; copy the tiles used when a mon is being sent out of or into a pokeball
@@ -2728,7 +2407,7 @@ CopyDownscaledMonTiles:
CopyTileIDs_NoBGTransfer:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
; fall through
; b = number of rows
@@ -2738,7 +2417,7 @@ CopyTileIDs:
.rowLoop
push bc
push hl
- ld a, [hBaseTileID]
+ ldh a, [hBaseTileID]
ld b, a
.columnLoop
ld a, [de]
@@ -2754,108 +2433,17 @@ CopyTileIDs:
dec b
jr nz, .rowLoop
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
pop hl
ret
-TileIDListPointerTable:
- dw DownscaledMonTiles_7x7
- dn 7, 7
- dw DownscaledMonTiles_5x7
- dn 5, 7
- dw DownscaledMonTiles_3x7
- dn 3, 7
- dw GengarIntroTiles1
- dn 7, 7
- dw GengarIntroTiles2
- dn 7, 7
- dw GengarIntroTiles3
- dn 7, 7
- dw DownscaledMonTiles_79d7c
- dn 8, 6
- dw DownscaledMonTiles_79dac
- dn 3, 12
-
-DownscaledMonTiles_5x5:
- db $31, $38, $46, $54, $5B
- db $32, $39, $47, $55, $5C
- db $34, $3B, $49, $57, $5E
- db $36, $3D, $4B, $59, $60
- db $37, $3E, $4C, $5A, $61
-
-DownscaledMonTiles_3x3:
- db $31, $46, $5B
- db $34, $49, $5E
- db $37, $4C, $61
-
-DownscaledMonTiles_7x7:
- db $00, $07, $0E, $15, $1C, $23, $2A
- db $01, $08, $0F, $16, $1D, $24, $2B
- db $02, $09, $10, $17, $1E, $25, $2C
- db $03, $0A, $11, $18, $1F, $26, $2D
- db $04, $0B, $12, $19, $20, $27, $2E
- db $05, $0C, $13, $1A, $21, $28, $2F
- db $06, $0D, $14, $1B, $22, $29, $30
-
-DownscaledMonTiles_5x7:
- db $00, $07, $0E, $15, $1C, $23, $2A
- db $01, $08, $0F, $16, $1D, $24, $2B
- db $03, $0A, $11, $18, $1F, $26, $2D
- db $04, $0B, $12, $19, $20, $27, $2E
- db $05, $0C, $13, $1A, $21, $28, $2F
-
-DownscaledMonTiles_3x7:
- db $00, $07, $0E, $15, $1C, $23, $2A
- db $02, $09, $10, $17, $1E, $25, $2C
- db $04, $0B, $12, $19, $20, $27, $2E
-
-GengarIntroTiles1:
- db $00, $00, $00, $00, $00, $00, $00
- db $00, $00, $00, $00, $00, $19, $00
- db $02, $06, $0B, $10, $14, $1A, $00
- db $00, $07, $0C, $11, $15, $1B, $00
- db $03, $08, $0D, $12, $16, $1C, $00
- db $04, $09, $0E, $13, $17, $1D, $1F
- db $05, $0A, $0F, $01, $18, $1E, $20
-
-GengarIntroTiles2:
- db $00, $00, $00, $30, $00, $37, $00
- db $00, $00, $2B, $31, $34, $38, $3D
- db $21, $26, $2C, $01, $35, $39, $3E
- db $22, $27, $2D, $32, $36, $01, $00
- db $23, $28, $2E, $33, $01, $3A, $00
- db $24, $29, $2F, $01, $01, $3B, $00
- db $25, $2A, $01, $01, $01, $3C, $00
-
-GengarIntroTiles3:
- db $00, $00, $00, $00, $00, $00, $00
- db $00, $00, $47, $4D, $00, $00, $00
- db $00, $00, $48, $4E, $52, $56, $5B
- db $3F, $43, $49, $4F, $53, $57, $5C
- db $40, $44, $4A, $50, $54, $58, $00
- db $41, $45, $4B, $51, $4C, $59, $5D
- db $42, $46, $4C, $4C, $55, $5A, $5E
-
-DownscaledMonTiles_79d7c:
- db $31, $32, $32, $32, $32, $33
- db $34, $35, $36, $36, $37, $38
- db $34, $39, $3A, $3A, $3B, $38
- db $3C, $3D, $3E, $3E, $3F, $40
- db $41, $42, $43, $43, $44, $45
- db $46, $47, $43, $48, $49, $4A
- db $41, $43, $4B, $4C, $4D, $4E
- db $4F, $50, $50, $50, $51, $52
-
-DownscaledMonTiles_79dac:
- db $43, $55, $56, $53, $53, $53, $53, $53, $53, $53, $53, $53
- db $43, $57, $58, $54, $54, $54, $54, $54, $54, $54, $54, $54
- db $43, $59, $5A, $43, $43, $43, $43, $43, $43, $43, $43, $43
+INCLUDE "data/tilemaps.asm"
AnimationLeavesFalling:
; Makes leaves float down from the top of the screen. This is used
; in Razor Leaf's animation.
ld a, [wAnimPalette]
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
ld d, $37 ; leaf tile
ld a, 3 ; number of leaves
@@ -3043,7 +2631,7 @@ AnimationShakeEnemyHUD:
call CopyVideoData
xor a
- ld [hSCX], a
+ ldh [hSCX], a
; Copy wTileMap to BG map 0. The regular BG (not the window) is set to use
; map 0 and can be scrolled with SCX, which allows a shaking effect.
@@ -3052,8 +2640,8 @@ AnimationShakeEnemyHUD:
; Now that the regular BG is showing the same thing the window was, move the
; window off the screen so that we can modify its contents below.
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
; Copy wTileMap to VRAM such that the row below the enemy HUD (in wTileMap) is
; lined up with row 0 of the window.
@@ -3061,11 +2649,11 @@ AnimationShakeEnemyHUD:
call BattleAnimCopyTileMapToVRAM
; update BGMap attributes
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC
ld c, 13
- callba LoadBGMapAttributes
+ farcall LoadBGMapAttributes
.notGBC
; Move the window so that the row below the enemy HUD (in BG map 0) lines up
@@ -3073,7 +2661,7 @@ AnimationShakeEnemyHUD:
; covers everything below the enemy HD with a copy that looks just like what
; was there before.
ld a, 7 * 8
- ld [hWY], a
+ ldh [hWY], a
; Write OAM entries so that the copy of the back pic from the top of this
; function shows up on screen. We need this because the back pic's Y coordinates
@@ -3097,19 +2685,19 @@ AnimationShakeEnemyHUD:
; Restore the original graphics.
call AnimationShowMonPic
call ClearSprites
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
ld hl, vBGMap1
call BattleAnimCopyTileMapToVRAM
; update BGMap attributes
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC2
ld c, 11
- callba LoadBGMapAttributes
+ farcall LoadBGMapAttributes
.notGBC2
xor a
- ld [hWY], a
+ ldh [hWY], a
call SaveScreenTilesToBuffer1
ld hl, vBGMap0
call BattleAnimCopyTileMapToVRAM
@@ -3122,7 +2710,7 @@ AnimationShakeEnemyHUD:
CopyTileIDsFromList:
call GetPredefRegisters
ld a, c
- ld [hBaseTileID], a
+ ldh [hBaseTileID], a
ld a, b
push hl
call GetTileIDList
@@ -3130,30 +2718,30 @@ CopyTileIDsFromList:
jp CopyTileIDs
ShakeEnemyHUD_ShakeBG:
- ld a, [hSCX]
+ ldh a, [hSCX]
ld [wTempSCX], a
.loop
ld a, [wTempSCX]
add d
- ld [hSCX], a
+ ldh [hSCX], a
ld c, 2
call DelayFrames
ld a, [wTempSCX]
sub d
- ld [hSCX], a
+ ldh [hSCX], a
ld c, 2
call DelayFrames
dec e
jr nz, .loop
ld a, [wTempSCX]
- ld [hSCX], a
+ ldh [hSCX], a
ret
BattleAnimCopyTileMapToVRAM:
ld a, h
- ld [H_AUTOBGTRANSFERDEST + 1], a
+ ldh [hAutoBGTransferDest + 1], a
ld a, l
- ld [H_AUTOBGTRANSFERDEST], a
+ ldh [hAutoBGTransferDest], a
jp Delay3
TossBallAnimation:
diff --git a/engine/battle/bank3d_battle.asm b/engine/battle/bank3d_battle.asm
index 5edc4571..48c3cde3 100644
--- a/engine/battle/bank3d_battle.asm
+++ b/engine/battle/bank3d_battle.asm
@@ -1,27 +1,28 @@
-InitBattle:
+InitBattle::
ld a, [wCurOpponent]
and a
- jr z, asm_f6003
+ jr z, DetermineWildOpponent
InitOpponent:
ld a, [wCurOpponent]
ld [wcf91], a
ld [wEnemyMonSpecies2], a
- jr asm_f601d
-asm_f6003:
+ jr InitBattleCommon
+
+DetermineWildOpponent:
ld a, [wd732]
bit 1, a
- jr z, .asm_f600f
- ld a, [hJoyHeld]
+ jr z, .asm_3ef2f
+ ldh a, [hJoyHeld]
bit 1, a ; B button pressed?
ret nz
-.asm_f600f
+.asm_3ef2f
ld a, [wNumberOfNoRandomBattleStepsLeft]
and a
ret nz
- callab TryDoWildEncounter
+ callfar TryDoWildEncounter
ret nz
-asm_f601d:
+InitBattleCommon:
ld a, [wMapPalOffset]
push af
ld hl, wLetterPrintingDelayFlags
@@ -34,37 +35,37 @@ asm_f601d:
jp c, InitWildBattle
ld [wTrainerClass], a
call GetTrainerInformation
- callab ReadTrainer
- callab DoBattleTransitionAndInitBattleVariables
+ callfar ReadTrainer
+ callfar DoBattleTransitionAndInitBattleVariables
call _LoadTrainerPic
xor a
ld [wEnemyMonSpecies2], a
- ld [$ffe1], a
+ ldh [hStartTileID], a
dec a
ld [wAICount], a
- coord hl, 12, 0
+ hlcoord 12, 0
predef CopyUncompressedPicToTilemap
ld a, $ff
ld [wEnemyMonPartyPos], a
ld a, $2
ld [wIsInBattle], a
- ; Is this a major story battle?
- ld a,[wLoneAttackNo]
+; Is this a major story battle?
+ ld a, [wLoneAttackNo]
and a
- jp z,InitBattle_Common
+ jp z, _InitBattleCommon
callabd_ModifyPikachuHappiness PIKAHAPPY_GYMLEADER ; useless since already in bank3d
- jp InitBattle_Common
+ jp _InitBattleCommon
InitWildBattle:
ld a, $1
ld [wIsInBattle], a
- callab LoadEnemyMonData
- callab DoBattleTransitionAndInitBattleVariables
+ callfar LoadEnemyMonData
+ callfar DoBattleTransitionAndInitBattleVariables
ld a, [wCurOpponent]
cp RESTLESS_SOUL
jr z, .isGhost
- callab IsGhostBattle
+ callfar IsGhostBattle
jr nz, .isNoGhost
.isGhost
ld hl, wMonHSpriteDim
@@ -101,49 +102,49 @@ InitWildBattle:
.spriteLoaded
xor a
ld [wTrainerClass], a
- ld [$ffe1], a
- coord hl, 12, 0
+ ldh [hStartTileID], a
+ hlcoord 12, 0
predef CopyUncompressedPicToTilemap
; common code that executes after init battle code specific to trainer or wild battles
-InitBattle_Common:
- ld b, $0
+_InitBattleCommon:
+ ld b, SET_PAL_BATTLE_BLACK
call RunPaletteCommand
- callab SlidePlayerAndEnemySilhouettesOnScreen
+ callfar SlidePlayerAndEnemySilhouettesOnScreen
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld hl, .emptyString
call PrintText
call SaveScreenTilesToBuffer1
call ClearScreen
ld a, $98
- ld [$ffbd], a
+ ldh [hAutoBGTransferDest + 1], a
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
ld a, $9c
- ld [$ffbd], a
+ ldh [hAutoBGTransferDest + 1], a
call LoadScreenTilesFromBuffer1
- coord hl, 9, 7
- ld bc, $50a
+ hlcoord 9, 7
+ lb bc, 5, 10
call ClearScreenArea
- coord hl, 1, 0
- ld bc, $40a
+ hlcoord 1, 0
+ lb bc, 4, 10
call ClearScreenArea
call ClearSprites
ld a, [wIsInBattle]
dec a ; is it a wild battle?
ld hl, DrawEnemyHUDAndHPBar
- ld b,BANK(DrawEnemyHUDAndHPBar)
+ ld b, BANK(DrawEnemyHUDAndHPBar)
call z, Bankswitch ; draw enemy HUD and HP bar if it's a wild battle
- callab StartBattle
- callab EndOfBattle
+ callfar StartBattle
+ callfar EndOfBattle
pop af
ld [wLetterPrintingDelayFlags], a
pop af
ld [wMapPalOffset], a
ld a, [wSavedTilesetType]
- ld [hTilesetType], a
+ ldh [hTilesetType], a
scf
ret
.emptyString
@@ -157,9 +158,9 @@ _LoadTrainerPic:
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)
+ ld a, BANK(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
jr z, .loadSprite
- ld a, Bank(RedPicFront)
+ ld a, BANK(RedPicFront)
.loadSprite
call UncompressSpriteFromDE
ld de, vFrontPic
@@ -172,8 +173,8 @@ LoadMonBackPic:
; been loaded with GetMonHeader.
ld a, [wBattleMonSpecies2]
ld [wcf91], a
- coord hl, 1, 5
- ld bc,$708
+ hlcoord 1, 5
+ lb bc, 7, 8
call ClearScreenArea
ld hl, wMonHBackSprite - wMonHeader
call UncompressMonSprite
@@ -183,7 +184,7 @@ LoadMonBackPic:
ld hl, vSprites
ld de, vBackPic
ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
ld b, a
jp CopyVideoData
@@ -192,8 +193,8 @@ AnimateSendingOutMon:
ld h, a
ld a, [wPredefRegisters + 1]
ld l, a
- ld a, [$ffe1]
- ld [H_DOWNARROWBLINKCNT1], a
+ ldh a, [hStartTileID]
+ ldh [hDownArrowBlinkCount1], a
ld b, $4c
ld a, [wIsInBattle]
and a
@@ -223,7 +224,7 @@ AnimateSendingOutMon:
ld bc, -123
.asm_f61f2
add hl, bc
- ld a, [H_DOWNARROWBLINKCNT1]
+ ldh a, [hDownArrowBlinkCount1]
add $31
jr CopyUncompressedPicToHL
@@ -232,8 +233,8 @@ CopyUncompressedPicToTilemap:
ld h, a
ld a, [wPredefRegisters + 1]
ld l, a
- ld a, [$ffe1]
-CopyUncompressedPicToHL:
+ ldh a, [hStartTileID]
+CopyUncompressedPicToHL::
ld bc, $707
ld de, $14
push af
@@ -281,11 +282,11 @@ CopyUncompressedPicToHL:
ret
INCLUDE "engine/battle/init_battle_variables.asm"
-INCLUDE "engine/battle/moveEffects/focus_energy_effect.asm"
-INCLUDE "engine/battle/moveEffects/heal_effect.asm"
-INCLUDE "engine/battle/moveEffects/transform_effect.asm"
-INCLUDE "engine/battle/moveEffects/reflect_light_screen_effect.asm"
-INCLUDE "engine/battle/moveEffects/mist_effect.asm"
-INCLUDE "engine/battle/moveEffects/one_hit_ko_effect.asm"
-INCLUDE "engine/battle/moveEffects/pay_day_effect.asm"
-INCLUDE "engine/battle/moveEffects/paralyze_effect.asm"
+INCLUDE "engine/battle/move_effects/focus_energy.asm"
+INCLUDE "engine/battle/move_effects/heal.asm"
+INCLUDE "engine/battle/move_effects/transform.asm"
+INCLUDE "engine/battle/move_effects/reflect_light_screen.asm"
+INCLUDE "engine/battle/move_effects/mist.asm"
+INCLUDE "engine/battle/move_effects/one_hit_ko.asm"
+INCLUDE "engine/battle/move_effects/pay_day.asm"
+INCLUDE "engine/battle/move_effects/paralyze.asm"
diff --git a/engine/battle/battle_transitions.asm b/engine/battle/battle_transitions.asm
index e4392a01..82c3318c 100644
--- a/engine/battle/battle_transitions.asm
+++ b/engine/battle/battle_transitions.asm
@@ -1,17 +1,17 @@
BattleTransition:
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
xor a
- ld [hWY], a
+ ldh [hWY], a
dec a
ld [wUpdateSpritesEnabled], a
call DelayFrame
; Determine which OAM block is being used by the enemy trainer sprite (if there
; is one).
- ld hl, wSpriteStateData1 + 2
- ld a, [hSpriteIndexOrTextID] ; enemy trainer sprite index (0 if wild battle)
+ ld hl, wSpritePlayerStateData1ImageIndex
+ ldh a, [hSpriteIndexOrTextID] ; enemy trainer sprite index (0 if wild battle)
ld c, a
ld b, 0
ld de, $10
@@ -118,9 +118,6 @@ GetBattleTransitionID_CompareLevels:
ld [wBattleTransitionSpiralDirection], a
ret
-; fails to recognize VICTORY_ROAD_2F, VICTORY_ROAD_3F, all ROCKET_HIDEOUT maps,
-; POKEMON_MANSION_1F, SEAFOAM_ISLANDS_[B1F-B4F], POWER_PLANT, DIGLETTS_CAVE
-; and SILPH_CO_[9-11]F as dungeon maps
GetBattleTransitionID_IsDungeonMap:
ld a, [wCurMap]
ld e, a
@@ -151,51 +148,21 @@ GetBattleTransitionID_IsDungeonMap:
res 2, c
ret
-; GetBattleTransitionID_IsDungeonMap checks if wCurMap
-; is equal to one of these maps
-DungeonMaps1:
- db VIRIDIAN_FOREST
- db ROCK_TUNNEL_1F
- db SEAFOAM_ISLANDS_1F
- db ROCK_TUNNEL_B1F
- db $FF
-
-; GetBattleTransitionID_IsDungeonMap checks if wCurMap
-; is in between or equal to each pair of maps
-DungeonMaps2:
- ; all MT_MOON maps
- db MT_MOON_1F
- db MT_MOON_B2F
-
- ; all SS_ANNE maps, VICTORY_ROAD_1F, LANCES_ROOM, and HALL_OF_FAME
- db SS_ANNE_1F
- db HALL_OF_FAME
-
- ; all POKEMON_TOWER maps and Lavender Town buildings
- db LAVENDER_POKECENTER
- db LAVENDER_CUBONE_HOUSE
-
- ; SILPH_CO_[2-8]F, POKEMON_MANSION[2F-B1F], SAFARI_ZONE, and
- ; CERULEAN_CAVE maps, except for SILPH_CO_1F
- db SILPH_CO_2F
- db CERULEAN_CAVE_1F
- db $FF
+INCLUDE "data/maps/dungeon_maps.asm"
LoadBattleTransitionTile:
- ld hl, vChars1 + $7f0
+ ld hl, vChars1 tile $7f
ld de, BattleTransitionTile
- lb bc, BANK(BattleTransitionTile), (BattleTransitionTileEnd - BattleTransitionTile) / $10
+ lb bc, BANK(BattleTransitionTile), 1
jp CopyVideoData
-BattleTransitionTile:
- INCBIN "gfx/battle_transition.2bpp"
-BattleTransitionTileEnd:
+BattleTransitionTile: INCBIN "gfx/overworld/battle_transition.2bpp"
BattleTransition_BlackScreen:
ld a, $ff
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -212,7 +179,7 @@ BattleTransition_Spiral:
call BattleTransition_InwardSpiral
jr .done
.outwardSpiral
- coord hl, 10, 10
+ hlcoord 10, 10
ld a, $3
ld [wOutwardSpiralCurrentDirection], a
ld a, l
@@ -241,7 +208,7 @@ BattleTransition_Spiral:
BattleTransition_InwardSpiral:
ld a, 7
ld [wInwardSpiralUpdateScreenCounter], a
- coord hl, 0, 0
+ hlcoord 0, 0
ld c, SCREEN_HEIGHT - 1
ld de, SCREEN_WIDTH
call BattleTransition_InwardSpiral_
@@ -359,9 +326,9 @@ BattleTransition_FlashScreen_:
ld hl, BattleTransition_FlashScreenPalettes
.loop
ld a, [hli]
- cp $1
+ cp 1
jr z, .done
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 2
call DelayFrames
@@ -372,8 +339,19 @@ BattleTransition_FlashScreen_:
ret
BattleTransition_FlashScreenPalettes:
- db $F9,$FE,$FF,$FE,$F9,$E4,$90,$40,$00,$40,$90,$E4
- db $01 ; terminator
+ db %11111001
+ db %11111110
+ db %11111111
+ db %11111110
+ db %11111001
+ db %11100100
+ db %10010000
+ db %01000000
+ db %00000000
+ db %01000000
+ db %10010000
+ db %11100100
+ db 1 ; end
; used for low level trainer dungeon battles
BattleTransition_Shrink:
@@ -381,25 +359,25 @@ BattleTransition_Shrink:
.loop
push bc
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 7
- coord de, 0, 8
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 0, 7
+ decoord 0, 8
ld bc, -SCREEN_WIDTH * 2
call BattleTransition_CopyTiles1
- coord hl, 0, 10
- coord de, 0, 9
+ hlcoord 0, 10
+ decoord 0, 9
ld bc, SCREEN_WIDTH * 2
call BattleTransition_CopyTiles1
- coord hl, 8, 0
- coord de, 9, 0
+ hlcoord 8, 0
+ decoord 9, 0
ld bc, -2
call BattleTransition_CopyTiles2
- coord hl, 11, 0
- coord de, 10, 0
+ hlcoord 11, 0
+ decoord 10, 0
ld bc, 2
call BattleTransition_CopyTiles2
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld c, 6
call DelayFrames
pop bc
@@ -413,23 +391,23 @@ BattleTransition_Shrink:
BattleTransition_Split:
ld c, 9
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
.loop
push bc
- coord hl, 0, 16
- coord de, 0, 17
+ hlcoord 0, 16
+ decoord 0, 17
ld bc, -SCREEN_WIDTH * 2
call BattleTransition_CopyTiles1
- coord hl, 0, 1
- coord de, 0, 0
+ hlcoord 0, 1
+ decoord 0, 0
ld bc, SCREEN_WIDTH * 2
call BattleTransition_CopyTiles1
- coord hl, 18, 0
- coord de, 19, 0
+ hlcoord 18, 0
+ decoord 19, 0
ld bc, -2
call BattleTransition_CopyTiles2
- coord hl, 1, 0
- coord de, 0, 0
+ hlcoord 1, 0
+ decoord 0, 0
ld bc, 2
call BattleTransition_CopyTiles2
call BattleTransition_TransferDelay3
@@ -525,10 +503,10 @@ BattleTransition_CopyTiles2:
; used for high level wild dungeon battles
BattleTransition_VerticalStripes:
ld c, SCREEN_HEIGHT
- coord hl, 0, 0
- coord de, 1, 17
+ hlcoord 0, 0
+ decoord 1, 17
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
.loop
push bc
push hl
@@ -564,10 +542,10 @@ BattleTransition_VerticalStripes_:
; used for low level wild dungeon battles
BattleTransition_HorizontalStripes:
ld c, SCREEN_WIDTH
- coord hl, 0, 0
- coord de, 19, 1
+ hlcoord 0, 0
+ decoord 19, 1
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
.loop
push bc
push hl
@@ -614,7 +592,7 @@ BattleTransition_FlashScreen:
ld b, $3
call BattleTransition_FlashScreen_
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
BattleTransition_Circle_Sub1:
@@ -633,10 +611,10 @@ BattleTransition_Circle_Sub1:
BattleTransition_TransferDelay3:
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
; used for low level wild non-dungeon battles
@@ -683,87 +661,41 @@ BattleTransition_Circle_Sub2:
ld l, a
jp BattleTransition_Circle_Sub3
-BattleTransition_HalfCircle1:
- db $01
- dw BattleTransition_CircleData1
- dwCoord 18, 6
-
- db $01
- dw BattleTransition_CircleData2
- dwCoord 19, 3
+; halves
+ const_def
+ const CIRCLE_LEFT
+ const CIRCLE_RIGHT
- db $01
- dw BattleTransition_CircleData3
- dwCoord 18, 0
+half_circle: MACRO
+ ; quadrant x, circle data, target coord
+ db \1
+ dw \2
+ dwcoord \3, \4
+ENDM
- db $01
- dw BattleTransition_CircleData4
- dwCoord 14, 0
-
- db $01
- dw BattleTransition_CircleData5
- dwCoord 10, 0
-
- db $00
- dw BattleTransition_CircleData5
- dwCoord 9, 0
-
- db $00
- dw BattleTransition_CircleData4
- dwCoord 5, 0
-
- db $00
- dw BattleTransition_CircleData3
- dwCoord 1, 0
-
- db $00
- dw BattleTransition_CircleData2
- dwCoord 0, 3
-
- db $00
- dw BattleTransition_CircleData1
- dwCoord 1, 6
+BattleTransition_HalfCircle1:
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData1, 18, 6
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData2, 19, 3
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData3, 18, 0
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData4, 14, 0
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData5, 10, 0
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData5, 9, 0
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData4, 5, 0
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData3, 1, 0
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData2, 0, 3
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData1, 1, 6
BattleTransition_HalfCircle2:
- db $00
- dw BattleTransition_CircleData1
- dwCoord 1, 11
-
- db $00
- dw BattleTransition_CircleData2
- dwCoord 0, 14
-
- db $00
- dw BattleTransition_CircleData3
- dwCoord 1, 17
-
- db $00
- dw BattleTransition_CircleData4
- dwCoord 5, 17
-
- db $00
- dw BattleTransition_CircleData5
- dwCoord 9, 17
-
- db $01
- dw BattleTransition_CircleData5
- dwCoord 10, 17
-
- db $01
- dw BattleTransition_CircleData4
- dwCoord 14, 17
-
- db $01
- dw BattleTransition_CircleData3
- dwCoord 18, 17
-
- db $01
- dw BattleTransition_CircleData2
- dwCoord 19, 14
-
- db $01
- dw BattleTransition_CircleData1
- dwCoord 18, 11
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData1, 1, 11
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData2, 0, 14
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData3, 1, 17
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData4, 5, 17
+ half_circle CIRCLE_LEFT, BattleTransition_CircleData5, 9, 17
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData5, 10, 17
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData4, 14, 17
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData3, 18, 17
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData2, 19, 14
+ half_circle CIRCLE_RIGHT, BattleTransition_CircleData1, 18, 11
BattleTransition_Circle_Sub3:
push hl
@@ -792,7 +724,7 @@ BattleTransition_Circle_Sub3:
add hl, bc
ld a, [de]
inc de
- cp $ff
+ cp -1
ret z
and a
jr z, BattleTransition_Circle_Sub3
@@ -810,17 +742,8 @@ BattleTransition_Circle_Sub3:
jr nz, .loop2
jr BattleTransition_Circle_Sub3
-BattleTransition_CircleData1:
- db $02,$03,$05,$04,$09,$FF
-
-BattleTransition_CircleData2:
- db $01,$01,$02,$02,$04,$02,$04,$02,$03,$FF
-
-BattleTransition_CircleData3:
- db $02,$01,$03,$01,$04,$01,$04,$01,$04,$01,$03,$01,$02,$01,$01,$01,$01,$FF
-
-BattleTransition_CircleData4:
- db $04,$01,$04,$00,$03,$01,$03,$00,$02,$01,$02,$00,$01,$FF
-
-BattleTransition_CircleData5:
- db $04,$00,$03,$00,$03,$00,$02,$00,$02,$00,$01,$00,$01,$00,$01,$FF
+BattleTransition_CircleData1: db 2, 3, 5, 4, 9, -1
+BattleTransition_CircleData2: db 1, 1, 2, 2, 4, 2, 4, 2, 3, -1
+BattleTransition_CircleData3: db 2, 1, 3, 1, 4, 1, 4, 1, 4, 1, 3, 1, 2, 1, 1, 1, 1, -1
+BattleTransition_CircleData4: db 4, 1, 4, 0, 3, 1, 3, 0, 2, 1, 2, 0, 1, -1
+BattleTransition_CircleData5: db 4, 0, 3, 0, 3, 0, 2, 0, 2, 0, 1, 0, 1, 0, 1, -1
diff --git a/engine/battle/common_text.asm b/engine/battle/common_text.asm
index 1c85efe9..95c06bf5 100644
--- a/engine/battle/common_text.asm
+++ b/engine/battle/common_text.asm
@@ -5,18 +5,18 @@ PrintBeginningBattleText:
ld a, [wCurMap]
cp POKEMON_TOWER_3F
jr c, .notPokemonTower
- cp MR_FUJIS_HOUSE
+ cp POKEMON_TOWER_7F + 1
jr c, .pokemonTower
.notPokemonTower
- ld a,[wBattleType]
+ ld a, [wBattleType]
cp BATTLE_TYPE_PIKACHU
- jr nz,.notPikachuBattle
- callab IsPlayerPikachuAsleepInParty
- ld e,$24
- jr c,.asm_f4026
- ld e,$a
+ jr nz, .notPikachuBattle
+ callfar IsPlayerPikachuAsleepInParty
+ ld e, $24
+ jr c, .asm_f4026
+ ld e, $a
.asm_f4026
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .continue
.notPikachuBattle
ld a, [wEnemyMonSpecies2]
@@ -39,7 +39,7 @@ PrintBeginningBattleText:
and a
jr nz, .doNotDrawPokeballs
push hl
- callab DrawAllPokeballs
+ callfar DrawAllPokeballs
pop hl
.doNotDrawPokeballs
call PrintText
@@ -54,7 +54,7 @@ PrintBeginningBattleText:
ld a, b
and a
jr z, .noSilphScope
- callab LoadEnemyMonData
+ callfar LoadEnemyMonData
jr .notPokemonTower
.noSilphScope
ld hl, EnemyAppearedText
@@ -70,8 +70,8 @@ PrintBeginningBattleText:
call PrintText
ld hl, UnveiledGhostText
call PrintText
- callab LoadEnemyMonData
- callab MarowakAnim
+ callfar LoadEnemyMonData
+ callfar MarowakAnim
ld hl, WildMonAppearedText
call PrintText
@@ -87,28 +87,28 @@ PrintBeginningBattleText:
ret
WildMonAppearedText:
- TX_FAR _WildMonAppearedText
- db "@"
+ text_far _WildMonAppearedText
+ text_end
HookedMonAttackedText:
- TX_FAR _HookedMonAttackedText
- db "@"
+ text_far _HookedMonAttackedText
+ text_end
EnemyAppearedText:
- TX_FAR _EnemyAppearedText
- db "@"
+ text_far _EnemyAppearedText
+ text_end
TrainerWantsToFightText:
- TX_FAR _TrainerWantsToFightText
- db "@"
+ text_far _TrainerWantsToFightText
+ text_end
UnveiledGhostText:
- TX_FAR _UnveiledGhostText
- db "@"
+ text_far _UnveiledGhostText
+ text_end
GhostCantBeIDdText:
- TX_FAR _GhostCantBeIDdText
- db "@"
+ text_far _GhostCantBeIDdText
+ text_end
PrintSendOutMonMessage:
ld hl, wEnemyMonHP
@@ -117,16 +117,16 @@ PrintSendOutMonMessage:
ld hl, GoText
jr z, .printText
xor a
- ld [H_MULTIPLICAND], a
+ ldh [hMultiplicand], a
ld hl, wEnemyMonHP
ld a, [hli]
ld [wLastSwitchInEnemyMonHP], a
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hl]
ld [wLastSwitchInEnemyMonHP + 1], a
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
ld a, 25
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
call Multiply
ld hl, wEnemyMonMaxHP
ld a, [hli]
@@ -137,9 +137,9 @@ PrintSendOutMonMessage:
rr b
ld a, b
ld b, 4
- ld [H_DIVISOR], a ; enemy mon max HP divided by 4
+ ldh [hDivisor], a ; enemy mon max HP divided by 4
call Divide
- ld a, [H_QUOTIENT + 3] ; a = (enemy mon current HP * 25) / (enemy max HP / 4); this approximates the current percentage of max HP
+ ldh a, [hQuotient + 3] ; a = (enemy mon current HP * 25) / (enemy max HP / 4); this approximates the current percentage of max HP
ld hl, GoText ; 70% or greater
cp 70
jr nc, .printText
@@ -154,39 +154,39 @@ PrintSendOutMonMessage:
jp PrintText
GoText:
- TX_FAR _GoText
- TX_ASM
+ text_far _GoText
+ text_asm
jr PrintPlayerMon1Text
DoItText:
- TX_FAR _DoItText
- TX_ASM
+ text_far _DoItText
+ text_asm
jr PrintPlayerMon1Text
GetmText:
- TX_FAR _GetmText
- TX_ASM
+ text_far _GetmText
+ text_asm
jr PrintPlayerMon1Text
EnemysWeakText:
- TX_FAR _EnemysWeakText
- TX_ASM
+ text_far _EnemysWeakText
+ text_asm
PrintPlayerMon1Text:
ld hl, PlayerMon1Text
ret
PlayerMon1Text:
- TX_FAR _PlayerMon1Text
- db "@"
+ text_far _PlayerMon1Text
+ text_end
RetreatMon:
ld hl, PlayerMon2Text
jp PrintText
PlayerMon2Text:
- TX_FAR _PlayerMon2Text
- TX_ASM
+ text_far _PlayerMon2Text
+ text_asm
push de
push bc
ld hl, wEnemyMonHP + 1
@@ -195,14 +195,14 @@ PlayerMon2Text:
dec hl
ld a, [de]
sub b
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
dec de
ld b, [hl]
ld a, [de]
sbc b
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, 25
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
call Multiply
ld hl, wEnemyMonMaxHP
ld a, [hli]
@@ -213,11 +213,11 @@ PlayerMon2Text:
rr b
ld a, b
ld b, 4
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
call Divide
pop bc
pop de
- ld a, [H_QUOTIENT + 3] ; a = ((LastSwitchInEnemyMonHP - CurrentEnemyMonHP) / 25) / (EnemyMonMaxHP / 4)
+ ldh a, [hQuotient + 3] ; a = ((LastSwitchInEnemyMonHP - CurrentEnemyMonHP) / 25) / (EnemyMonMaxHP / 4)
; Assuming that the enemy mon hasn't gained HP since the last switch in,
; a approximates the percentage that the enemy mon's total HP has decreased
; since the last switch in.
@@ -236,18 +236,18 @@ PlayerMon2Text:
ret
EnoughText:
- TX_FAR _EnoughText
- TX_ASM
+ text_far _EnoughText
+ text_asm
jr PrintComeBackText
OKExclamationText:
- TX_FAR _OKExclamationText
- TX_ASM
+ text_far _OKExclamationText
+ text_asm
jr PrintComeBackText
GoodText:
- TX_FAR _GoodText
- TX_ASM
+ text_far _GoodText
+ text_asm
jr PrintComeBackText
PrintComeBackText:
@@ -255,5 +255,5 @@ PrintComeBackText:
ret
ComeBackText:
- TX_FAR _ComeBackText
- db "@"
+ text_far _ComeBackText
+ text_end
diff --git a/engine/battle/core.asm b/engine/battle/core.asm
index 60146902..f66f509f 100755
--- a/engine/battle/core.asm
+++ b/engine/battle/core.asm
@@ -1,107 +1,17 @@
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
+INCLUDE "data/battle/residual_effects_1.asm"
+INCLUDE "data/battle/set_damage_effects.asm"
+INCLUDE "data/battle/residual_effects_2.asm"
+INCLUDE "data/battle/always_happen_effects.asm"
+INCLUDE "data/battle/special_effects.asm"
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
+ hlcoord 1, 5
lb bc, 3, 7
call ClearScreenArea
call DisableLCD
@@ -117,7 +27,7 @@ SlidePlayerAndEnemySilhouettesOnScreen:
or c
jr nz, .clearBackgroundLoop
; copy the work RAM tile map to VRAM
- coord hl, 0, 0
+ hlcoord 0, 0
ld de, vBGMap0
ld b, 18 ; number of rows
.copyRowLoop
@@ -138,25 +48,25 @@ SlidePlayerAndEnemySilhouettesOnScreen:
jr nz, .copyRowLoop
call EnableLCD
ld a, $90
- ld [hWY], a
- ld [rWY], a
+ ldh [hWY], a
+ ldh [rWY], a
xor a
- ld [hTilesetType], a
- ld [hSCY], a
+ ldh [hTilesetType], a
+ ldh [hSCY], a
dec a
ld [wUpdateSpritesEnabled], a
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld b, $70
ld c, $90
ld a, c
- ld [hSCX], a
+ ldh [hSCX], a
call DelayFrame
ld a, %11100100 ; inverted palette for silhouette effect
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -171,26 +81,26 @@ SlidePlayerAndEnemySilhouettesOnScreen:
call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60
call SlidePlayerHeadLeft
ld a, c
- ld [hSCX], a
+ ldh [hSCX], a
dec c
dec c
jr nz, .slideSilhouettesLoop
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, $31
- ld [hStartTileID], a
- coord hl, 1, 5
+ ldh [hStartTileID], a
+ hlcoord 1, 5
predef CopyUncompressedPicToTilemap
xor a
- ld [hWY], a
- ld [rWY], a
+ ldh [hWY], a
+ ldh [rWY], a
inc a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
ld b, SET_PAL_BATTLE
call RunPaletteCommand
call HideSprites
- jpab PrintBeginningBattleText
+ jpfar 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
@@ -211,13 +121,13 @@ SlidePlayerHeadLeft:
ret
SetScrollXForSlidingPlayerBodyLeft:
- ld a, [rLY]
+ ldh a, [rLY]
cp l
jr nz, SetScrollXForSlidingPlayerBodyLeft
ld a, h
- ld [rSCX], a
+ ldh [rSCX], a
.loop
- ld a, [rLY]
+ ldh a, [rLY]
cp h
jr z, .loop
ret
@@ -277,7 +187,7 @@ StartBattle:
ld hl, .outOfSafariBallsText
jp PrintText
.notOutOfSafariBalls
- callab PrintSafariZoneBattleText
+ callfar PrintSafariZoneBattleText
ld a, [wEnemyMonSpeed + 1]
add a
ld b, a ; init b (which is later compared with random value) to (enemy speed % 256) * 2
@@ -306,8 +216,8 @@ StartBattle:
jr EnemyRan ; if b was greater than the random value, the enemy runs
.outOfSafariBallsText
- TX_FAR _OutOfSafariBallsText
- db "@"
+ text_far _OutOfSafariBallsText
+ text_end
.playerSendOutFirstMon
xor a
@@ -331,7 +241,7 @@ StartBattle:
ld [wcf91], a
ld [wBattleMonSpecies2], a
call LoadScreenTilesFromBuffer1
- coord hl, 1, 5
+ hlcoord 1, 5
ld a, $9
call SlideTrainerPicOffScreen
call SaveScreenTilesToBuffer1
@@ -365,16 +275,16 @@ EnemyRan:
ld a, SFX_RUN
call PlaySoundWaitForCurrent
xor a
- ld [H_WHOSETURN], a
- jpab AnimationSlideEnemyMonOff
+ ldh [hWhoseTurn], a
+ jpfar AnimationSlideEnemyMonOff
WildRanText:
- TX_FAR _WildRanText
- db "@"
+ text_far _WildRanText
+ text_end
EnemyRanText:
- TX_FAR _EnemyRanText
- db "@"
+ text_far _EnemyRanText
+ text_end
MainInBattleLoop:
call ReadPlayerMonCurHPAndStatus
@@ -464,7 +374,7 @@ MainInBattleLoop:
jr nz, .specialMoveNotUsed
ld [wPlayerSelectedMove], a
.specialMoveNotUsed
- callab SwitchEnemyMon
+ callfar SwitchEnemyMon
.noLinkBattle
ld a, [wPlayerSelectedMove]
cp QUICK_ATTACK
@@ -497,7 +407,7 @@ MainInBattleLoop:
jr nc, .playerMovesFirst ; if player is faster
jr .enemyMovesFirst ; if enemy is faster
.speedEqual ; 50/50 chance for both players
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
jr z, .invertOutcome
call BattleRandom
@@ -511,8 +421,8 @@ MainInBattleLoop:
jr .playerMovesFirst
.enemyMovesFirst
ld a, $1
- ld [H_WHOSETURN], a
- callab TrainerAI
+ ldh [hWhoseTurn], a
+ callfar TrainerAI
jr c, .AIActionUsedEnemyFirst
call ExecuteEnemyMove
ld a, [wEscapedFromBattle]
@@ -549,8 +459,8 @@ MainInBattleLoop:
jp z, HandlePlayerMonFainted
call DrawHUDsAndHPBars
ld a, $1
- ld [H_WHOSETURN], a
- callab TrainerAI
+ ldh [hWhoseTurn], a
+ callfar TrainerAI
jr c, .AIActionUsedPlayerFirst
call ExecuteEnemyMove
ld a, [wEscapedFromBattle]
@@ -569,7 +479,7 @@ MainInBattleLoop:
HandlePoisonBurnLeechSeed:
ld hl, wBattleMonHP
ld de, wBattleMonStatus
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playersTurn
ld hl, wEnemyMonHP
@@ -594,7 +504,7 @@ HandlePoisonBurnLeechSeed:
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
.notBurnedOrPoisoned
ld de, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playersTurn2
ld de, wEnemyBattleStatus2
@@ -603,16 +513,16 @@ HandlePoisonBurnLeechSeed:
add a
jr nc, .notLeechSeeded
push hl
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
push af
xor $1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
xor a
ld [wAnimationType], a
ld a, ABSORB
call PlayMoveAnimation ; play leech seed animation (from opposing mon)
pop af
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
pop hl
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
@@ -631,16 +541,16 @@ HandlePoisonBurnLeechSeed:
ret
HurtByPoisonText:
- TX_FAR _HurtByPoisonText
- db "@"
+ text_far _HurtByPoisonText
+ text_end
HurtByBurnText:
- TX_FAR _HurtByBurnText
- db "@"
+ text_far _HurtByBurnText
+ text_end
HurtByLeechSeedText:
- TX_FAR _HurtByLeechSeedText
- db "@"
+ text_far _HurtByLeechSeedText
+ text_end
; 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)
@@ -670,7 +580,7 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP:
.nonZeroDamage
ld hl, wPlayerBattleStatus3
ld de, wPlayerToxicCounter
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playersTurn
ld hl, wEnemyBattleStatus3
@@ -681,7 +591,7 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP:
ld a, [de] ; increment toxic counter
inc a
ld [de], a
- ld hl, $0000
+ ld hl, 0
.toxicTicksLoop
add hl, bc
dec a
@@ -717,7 +627,7 @@ HandlePoisonBurnLeechSeed_DecreaseOwnHP:
HandlePoisonBurnLeechSeed_IncreaseEnemyHP:
push hl
ld hl, wEnemyMonMaxHP
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playersTurn
ld hl, wBattleMonMaxHP
@@ -754,23 +664,23 @@ HandlePoisonBurnLeechSeed_IncreaseEnemyHP:
ld [hl], a
ld [wHPBarNewHP], a
.noOverfullHeal
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
xor $1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
call UpdateCurMonHPBar
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
xor $1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
pop hl
ret
UpdateCurMonHPBar:
- coord hl, 10, 9 ; tile pointer to player HP bar
- ld a, [H_WHOSETURN]
+ hlcoord 10, 9 ; tile pointer to player HP bar
+ ldh a, [hWhoseTurn]
and a
ld a, $1
jr z, .playersTurn
- coord hl, 2, 2 ; tile pointer to enemy HP bar
+ hlcoord 2, 2 ; tile pointer to enemy HP bar
xor a
.playersTurn
push bc
@@ -866,10 +776,10 @@ FaintEnemyPokemon:
ld hl, wPlayerUsedMove
ld [hli], a
ld [hl], a
- coord hl, 12, 5
- coord de, 12, 6
+ hlcoord 12, 5
+ decoord 12, 6
call SlideDownFaintedMonPic
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 4, 11
call ClearScreenArea
ld a, [wIsInBattle]
@@ -936,7 +846,7 @@ FaintEnemyPokemon:
.giveExpToMonsThatFought
xor a
ld [wBoostExpByExpAll], a
- callab GainExperience
+ callfar GainExperience
pop af
ret z ; return if no exp all
@@ -954,11 +864,11 @@ FaintEnemyPokemon:
jr nz, .gainExpFlagsLoop
ld a, b
ld [wPartyGainExpFlags], a
- jpab GainExperience
+ jpfar GainExperience
EnemyMonFaintedText:
- TX_FAR _EnemyMonFaintedText
- db "@"
+ text_far _EnemyMonFaintedText
+ text_end
EndLowHealthAlarm:
; This function is called when the player has the won the battle. It turns off
@@ -993,11 +903,11 @@ ReplaceFaintedEnemyMon:
ld e, $30
call GetBattleHealthBarColor
setpal SHADE_BLACK, SHADE_DARK, SHADE_LIGHT, SHADE_WHITE
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
- callab DrawEnemyPokeballs
+ callfar DrawEnemyPokeballs
ld a, [wLinkState]
cp LINK_STATE_BATTLING
jr nz, .notLinkBattle
@@ -1025,7 +935,7 @@ TrainerBattleVictory:
ld b, MUSIC_DEFEATED_TRAINER
.gymleader
ld a, [wTrainerClass]
- cp SONY3 ; final battle against rival
+ cp RIVAL3 ; final battle against rival
jr nz, .notrival
ld b, MUSIC_DEFEATED_GYM_LEADER
ld hl, wFlags_D733
@@ -1053,12 +963,12 @@ TrainerBattleVictory:
predef_jump AddBCDPredef
MoneyForWinningText:
- TX_FAR _MoneyForWinningText
- db "@"
+ text_far _MoneyForWinningText
+ text_end
TrainerDefeatedText:
- TX_FAR _TrainerDefeatedText
- db "@"
+ text_far _TrainerDefeatedText
+ text_end
PlayBattleVictoryMusic:
push af
@@ -1124,11 +1034,11 @@ RemoveFaintedPlayerMon:
ld [hl], a
ld [wBattleMonStatus], a
call ReadPlayerMonCurHPAndStatus
- coord hl, 9, 7
+ hlcoord 9, 7
lb bc, 5, 11
call ClearScreenArea
- coord hl, 1, 10
- coord de, 1, 11
+ hlcoord 1, 10
+ decoord 1, 11
call SlideDownFaintedMonPic
ld a, $1
ld [wBattleResult], a
@@ -1143,10 +1053,10 @@ RemoveFaintedPlayerMon:
ld a, [wPlayerMonNumber]
ld [wWhichPokemon], a
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .notPlayerPikachu
ld e, $3
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .printText
.notPlayerPikachu
ld a, [wBattleMonSpecies]
@@ -1173,8 +1083,8 @@ RemoveFaintedPlayerMon:
ret
PlayerMonFaintedText:
- TX_FAR _PlayerMonFaintedText
- db "@"
+ text_far _PlayerMonFaintedText
+ text_end
; asks if you want to use next mon
; stores whether you ran in C flag
@@ -1188,7 +1098,7 @@ DoUseNextMonDialogue:
ld hl, UseNextMonText
call PrintText
.displayYesNoBox
- coord hl, 13, 9
+ hlcoord 13, 9
lb bc, 10, 14
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -1207,8 +1117,8 @@ DoUseNextMonDialogue:
jp TryRunningFromBattle
UseNextMonText:
- TX_FAR _UseNextMonText
- db "@"
+ text_far _UseNextMonText
+ text_end
; choose next player mon to send out
; stores whether enemy mon has no HP left in Z flag
@@ -1263,9 +1173,9 @@ HandlePlayerBlackOut:
cp LINK_STATE_BATTLING
jr z, .notSony1Battle
ld a, [wCurOpponent]
- cp OPP_SONY1
+ cp OPP_RIVAL1
jr nz, .notSony1Battle
- coord hl, 0, 0 ; sony 1 battle
+ hlcoord 0, 0 ; sony 1 battle
lb bc, 8, 21
call ClearScreenArea
call ScrollTrainerPicAfterBattle
@@ -1294,19 +1204,19 @@ HandlePlayerBlackOut:
ret
Sony1WinText:
- TX_FAR _Sony1WinText
- db "@"
+ text_far _Sony1WinText
+ text_end
PlayerBlackedOutText2:
- TX_FAR _PlayerBlackedOutText2
- db "@"
+ text_far _PlayerBlackedOutText2
+ text_end
LinkBattleLostText:
- TX_FAR _LinkBattleLostText
- db "@"
+ text_far _LinkBattleLostText
+ text_end
; slides pic of fainted mon downwards until it disappears
-; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
+; bug: when this is called, [hAutoBGTransferEnabled] is non-zero, so there is screen tearing
SlideDownFaintedMonPic:
ld a, [wd730]
push af
@@ -1359,9 +1269,9 @@ SevenSpacesText:
; 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
+; bug: when this is called, [hAutoBGTransferEnabled] is non-zero, so there is screen tearing
SlideTrainerPicOffScreen:
- ld [hSlideAmount], a
+ ldh [hSlideAmount], a
ld c, a
.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
push bc
@@ -1369,10 +1279,10 @@ SlideTrainerPicOffScreen:
ld b, 7 ; number of rows
.rowLoop
push hl
- ld a, [hSlideAmount]
+ ldh a, [hSlideAmount]
ld c, a
.columnLoop
- ld a, [hSlideAmount]
+ ldh a, [hSlideAmount]
cp 8
jr z, .slideRight
.slideLeft ; slide player sprite off screen
@@ -1435,7 +1345,7 @@ EnemySendOutFirstMon:
ld [wAICount], a
ld hl, wPlayerBattleStatus1
res 5, [hl]
- coord hl, 18, 0
+ hlcoord 18, 0
ld a, 8
call SlideTrainerPicOffScreen
call PrintEmptyString
@@ -1505,7 +1415,7 @@ EnemySendOutFirstMon:
jr nz, .next4
ld hl, TrainerAboutToUseText
call PrintText
- coord hl, 0, 7
+ hlcoord 0, 7
lb bc, 8, 1
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -1540,7 +1450,7 @@ EnemySendOutFirstMon:
call LoadScreenTilesFromBuffer1
.next4
call ClearSprites
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 4, 11
call ClearScreenArea
ld b, SET_PAL_BATTLE
@@ -1555,8 +1465,8 @@ EnemySendOutFirstMon:
ld de, vFrontPic
call LoadMonFrontSprite
ld a, -$31
- ld [hStartTileID], a
- coord hl, 15, 6
+ ldh [hStartTileID], a
+ hlcoord 15, 6
predef AnimateSendingOutMon
ld a, [wEnemyMonSpecies2]
call PlayCry
@@ -1571,16 +1481,16 @@ EnemySendOutFirstMon:
jp SwitchPlayerMon
TrainerAboutToUseText:
- TX_FAR _TrainerAboutToUseText
- db "@"
+ text_far _TrainerAboutToUseText
+ text_end
TrainerSentOutText:
- TX_FAR _TrainerSentOutText
- db "@"
+ text_far _TrainerSentOutText
+ text_end
; 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:
+AnyPartyAlive::
ld a, [wPartyCount]
ld e, a
xor a
@@ -1616,8 +1526,8 @@ HasMonFainted:
ret
NoWillText:
- TX_FAR _NoWillText
- db "@"
+ text_far _NoWillText
+ text_end
; try to run from battle (hl = player speed, de = enemy speed)
; stores whether the attempt was successful in carry flag
@@ -1639,32 +1549,32 @@ TryRunningFromBattle:
inc a
ld [wNumRunAttempts], a
ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hl]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
ld a, [de]
- ld [hEnemySpeed], a
+ ldh [hEnemySpeed], a
inc de
ld a, [de]
- ld [hEnemySpeed + 1], a
+ ldh [hEnemySpeed + 1], a
call LoadScreenTilesFromBuffer1
- ld de, H_MULTIPLICAND + 1
+ ld de, hMultiplicand + 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
+ ldh [hMultiplicand], a
ld a, 32
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], 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]
+ ldh a, [hProduct + 2]
+ ldh [hDividend], a
+ ldh a, [hProduct + 3]
+ ldh [hDividend + 1], a
+ ldh a, [hEnemySpeed]
ld b, a
- ld a, [hEnemySpeed + 1]
+ ldh a, [hEnemySpeed + 1]
; divide enemy speed by 4
srl b
rr a
@@ -1672,10 +1582,10 @@ TryRunningFromBattle:
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)
+ ldh [hDivisor], a ; ((enemy speed / 4) % 256)
ld b, $2
call Divide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
and a ; is the quotient greater than 256?
jr nz, .canEscape ; if so, the player can escape
ld a, [wNumRunAttempts]
@@ -1685,15 +1595,15 @@ TryRunningFromBattle:
dec c
jr z, .compareWithRandomValue
ld b, 30
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
add b
- ld [H_QUOTIENT + 3], a
+ ldh [hQuotient + 3], a
jr c, .canEscape
jr .loop
.compareWithRandomValue
call BattleRandom
ld b, a
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 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
@@ -1741,16 +1651,16 @@ TryRunningFromBattle:
ret
CantEscapeText:
- TX_FAR _CantEscapeText
- db "@"
+ text_far _CantEscapeText
+ text_end
NoRunningText:
- TX_FAR _NoRunningText
- db "@"
+ text_far _NoRunningText
+ text_end
GotAwayText:
- TX_FAR _GotAwayText
- db "@"
+ text_far _GotAwayText
+ text_end
; copies from party data to battle mon data when sending out a new player mon
LoadBattleMonFromParty:
@@ -1851,7 +1761,7 @@ LoadEnemyMonFromParty:
ret
SendOutMon:
- callab PrintSendOutMonMessage
+ callfar PrintSendOutMonMessage
ld hl, wEnemyMonHP
ld a, [hli]
or [hl] ; is enemy mon HP zero?
@@ -1861,7 +1771,7 @@ SendOutMon:
call DrawPlayerHUDAndHPBar
predef LoadMonBackPic
xor a
- ld [hStartTileID], a
+ ldh [hStartTileID], a
ld hl, wBattleAndStartSavedMenuItem
ld [hli], a
ld [hl], a
@@ -1884,27 +1794,27 @@ SendOutMon:
call RunPaletteCommand
ld hl, wEnemyBattleStatus1
res USING_TRAPPING_MOVE, [hl]
- callab IsThisPartymonStarterPikachu
+ callfar IsThisPartymonStarterPikachu
jr c, .starterPikachu
ld a, $1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld a, POOF_ANIM
call PlayMoveAnimation
- coord hl, 4, 11
+ hlcoord 4, 11
predef AnimateSendingOutMon
jr .playRegularCry
.starterPikachu
xor a
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- callab StarterPikachuBattleEntranceAnimation
- callab IsPlayerPikachuAsleepInParty
+ ldh [hAutoBGTransferEnabled], a
+ callfar StarterPikachuBattleEntranceAnimation
+ callfar IsPlayerPikachuAsleepInParty
ld e, $24
jr c, .asm_3cd81
ld e, $a
.asm_3cd81
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .done
.playRegularCry
ld a, [wcf91]
@@ -1919,42 +1829,42 @@ AnimateRetreatingPlayerMon:
push af
ld a, [wPlayerMonNumber]
ld [wWhichPokemon], a
- callab IsThisPartymonStarterPikachu
+ callfar IsThisPartymonStarterPikachu
pop bc
ld a, b
ld [wWhichPokemon], a
jr c, .starterPikachu
- coord hl, 1, 5
+ hlcoord 1, 5
lb bc, 7, 7
call ClearScreenArea
- coord hl, 3, 7
+ hlcoord 3, 7
lb bc, 5, 5
xor a
ld [wDownscaledMonSize], a
- ld [hBaseTileID], a
+ ldh [hBaseTileID], a
predef CopyDownscaledMonTiles
ld c, 4
call DelayFrames
call .clearScreenArea
- coord hl, 4, 9
+ hlcoord 4, 9
lb bc, 3, 3
ld a, 1
ld [wDownscaledMonSize], a
xor a
- ld [hBaseTileID], a
+ ldh [hBaseTileID], a
predef CopyDownscaledMonTiles
call Delay3
call .clearScreenArea
ld a, $4c
- Coorda 5, 11
+ ldcoord_a 5, 11
jr .clearScreenArea
.starterPikachu
xor a
- ld [H_WHOSETURN], a
- callab AnimationSlideMonOff
+ ldh [hWhoseTurn], a
+ callfar AnimationSlideMonOff
ret
.clearScreenArea
- coord hl, 1, 5
+ hlcoord 1, 5
lb bc, 7, 7
call ClearScreenArea
ret
@@ -1977,15 +1887,15 @@ DrawHUDsAndHPBars:
DrawPlayerHUDAndHPBar:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 9, 7
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 9, 7
lb bc, 5, 11
call ClearScreenArea
- callab PlacePlayerHUDTiles
- coord hl, 18, 9
+ callfar PlacePlayerHUDTiles
+ hlcoord 18, 9
ld [hl], $73
ld de, wBattleMonNick
- coord hl, 10, 7
+ hlcoord 10, 7
call CenterMonName
call PlaceString
ld hl, wBattleMonSpecies
@@ -1996,7 +1906,7 @@ DrawPlayerHUDAndHPBar:
ld de, wLoadedMonLevel
ld bc, wBattleMonPP - wBattleMonLevel
call CopyData
- coord hl, 14, 8
+ hlcoord 14, 8
push hl
inc hl
ld de, wLoadedMonStatus
@@ -2007,10 +1917,10 @@ DrawPlayerHUDAndHPBar:
.doNotPrintLevel
ld a, [wLoadedMonSpecies]
ld [wcf91], a
- coord hl, 10, 9
+ hlcoord 10, 9
predef DrawHP
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld hl, wPlayerHPBarColor
call GetBattleHealthBarColor
ld hl, wBattleMonHP
@@ -2038,16 +1948,16 @@ DrawPlayerHUDAndHPBar:
DrawEnemyHUDAndHPBar:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 0
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 0, 0
lb bc, 4, 12
call ClearScreenArea
- callab PlaceEnemyHUDTiles
+ callfar PlaceEnemyHUDTiles
ld de, wEnemyMonNick
- coord hl, 1, 0
+ hlcoord 1, 0
call CenterMonName
call PlaceString
- coord hl, 4, 1
+ hlcoord 4, 1
push hl
inc hl
ld de, wEnemyMonStatus
@@ -2060,9 +1970,9 @@ DrawEnemyHUDAndHPBar:
.skipPrintLevel
ld hl, wEnemyMonHP
ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hld]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
or [hl] ; is current HP zero?
jr nz, .hpNonzero
; current HP is 0
@@ -2073,45 +1983,45 @@ DrawEnemyHUDAndHPBar:
jp .drawHPBar
.hpNonzero
xor a
- ld [H_MULTIPLICAND], a
+ ldh [hMultiplicand], a
ld a, 48
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
call Multiply ; multiply current HP by 48
ld hl, wEnemyMonMaxHP
ld a, [hli]
ld b, a
ld a, [hl]
- ld [H_DIVISOR], a
+ ldh [hDivisor], 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]
+ ldh a, [hDivisor]
srl b
rr a
srl b
rr a
- ld [H_DIVISOR], a
- ld a, [H_PRODUCT + 2]
+ ldh [hDivisor], a
+ ldh a, [hProduct + 2]
ld b, a
srl b
- ld a, [H_PRODUCT + 3]
+ ldh a, [hProduct + 3]
rr a
srl b
rr a
- ld [H_PRODUCT + 3], a
+ ldh [hProduct + 3], a
ld a, b
- ld [H_PRODUCT + 2], a
+ ldh [hProduct + 2], a
.doDivide
- ld a, [H_PRODUCT + 2]
- ld [H_DIVIDEND], a
- ld a, [H_PRODUCT + 3]
- ld [H_DIVIDEND + 1], a
+ ldh a, [hProduct + 2]
+ ldh [hDividend], a
+ ldh a, [hProduct + 3]
+ ldh [hDividend + 1], a
ld a, $2
ld b, a
call Divide ; divide (current HP * 48) by max HP
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
; set variables for DrawHPBar
ld e, a
ld a, $6
@@ -2120,10 +2030,10 @@ DrawEnemyHUDAndHPBar:
.drawHPBar
xor a
ld [wHPBarType], a
- coord hl, 2, 2
+ hlcoord 2, 2
call DrawHPBar
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld hl, wEnemyHPBarColor
GetBattleHealthBarColor:
@@ -2161,7 +2071,7 @@ CenterMonName:
pop de
ret
-DisplayBattleMenu:
+DisplayBattleMenu::
call LoadScreenTilesFromBuffer1 ; restore saved screen
ld a, [wBattleType]
and a
@@ -2206,12 +2116,12 @@ DisplayBattleMenu:
ld bc, NAME_LENGTH
call CopyData
; the following simulates the keystrokes by drawing menus on screen
- coord hl, 9, 14
+ hlcoord 9, 14
ld [hl], "▶"
ld c, 20
call DelayFrames
ld [hl], " "
- coord hl, 9, 16
+ hlcoord 9, 16
ld [hl], "▶"
ld c, 20
call DelayFrames
@@ -2238,14 +2148,14 @@ DisplayBattleMenu:
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
+ ldcoord_a 15, 14 ; clear upper cursor position in right column
+ ldcoord_a 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
+ ldcoord_a 13, 14
+ ldcoord_a 13, 16
+ hlcoord 7, 14
ld de, wNumSafariBalls
lb bc, 1, 2
call PrintNumber
@@ -2271,14 +2181,14 @@ DisplayBattleMenu:
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
+ ldcoord_a 9, 14 ; clear upper cursor position in left column
+ ldcoord_a 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
+ ldcoord_a 1, 14 ; clear upper cursor position in left column
+ ldcoord_a 1, 16 ; clear lower cursor position in left column
+ hlcoord 7, 14
ld de, wNumSafariBalls
lb bc, 1, 2
call PrintNumber
@@ -2348,8 +2258,8 @@ DisplayBattleMenu:
jp DisplayBattleMenu
.RunAwayText
- TX_FAR _RunAwayText
- db "@"
+ text_far _RunAwayText
+ text_end
.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
cp $2
@@ -2485,8 +2395,8 @@ UseBagItem:
ret
ItemsCantBeUsedHereText:
- TX_FAR _ItemsCantBeUsedHereText
- db "@"
+ text_far _ItemsCantBeUsedHereText
+ text_end
PartyMenuOrRockOrRun:
dec a ; was Run selected?
@@ -2517,7 +2427,7 @@ PartyMenuOrRockOrRun:
call GBPalNormal
jp DisplayBattleMenu
.partyMonDeselected
- coord hl, 11, 11
+ hlcoord 11, 11
ld bc, 6 * SCREEN_WIDTH + 9
ld a, " "
call FillMemory
@@ -2562,7 +2472,7 @@ PartyMenuOrRockOrRun:
predef StatusScreen2
; now we need to reload the enemy mon pic
ld a, 1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld a, [wEnemyBattleStatus2]
bit HAS_SUBSTITUTE_UP, a ; does the enemy mon have a substitute?
ld hl, AnimationSubstitute
@@ -2609,7 +2519,7 @@ PartyMenuOrRockOrRun:
; fall through to SwitchPlayerMon
SwitchPlayerMon:
- callab RetreatMon
+ callfar RetreatMon
ld c, 50
call DelayFrames
call AnimateRetreatingPlayerMon
@@ -2632,8 +2542,8 @@ SwitchPlayerMon:
ret
AlreadyOutText:
- TX_FAR _AlreadyOutText
- db "@"
+ text_far _AlreadyOutText
+ text_end
BattleMenu_RunWasSelected:
call LoadScreenTilesFromBuffer1
@@ -2662,18 +2572,18 @@ MoveSelectionMenu:
ld de, wMoves
ld bc, NUM_MOVES
call CopyData
- callab FormatMovesString
+ callfar FormatMovesString
ret
.writemoves
ld de, wMovesString
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
set 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
call PlaceString
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
res 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
ret
.regularmenu
@@ -2681,17 +2591,17 @@ MoveSelectionMenu:
ret z
ld hl, wBattleMonMoves
call .loadmoves
- coord hl, 4, 12
+ hlcoord 4, 12
lb bc, 4, 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
+ hlcoord 4, 12
ld [hl], $7a
- coord hl, 10, 12
+ hlcoord 10, 12
ld [hl], $7e
ei
- coord hl, 6, 13
+ hlcoord 6, 13
call .writemoves
ld b, $5
ld a, $c
@@ -2699,10 +2609,10 @@ MoveSelectionMenu:
.mimicmenu
ld hl, wEnemyMonMoves
call .loadmoves
- coord hl, 0, 7
+ hlcoord 0, 7
lb bc, 4, 14
call TextBoxBorder
- coord hl, 2, 8
+ hlcoord 2, 8
call .writemoves
ld b, $1
ld a, $7
@@ -2713,10 +2623,10 @@ MoveSelectionMenu:
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
call .loadmoves
- coord hl, 4, 7
+ hlcoord 4, 7
lb bc, 4, 14
call TextBoxBorder
- coord hl, 6, 8
+ hlcoord 6, 8
call .writemoves
ld b, $5
ld a, $7
@@ -2770,7 +2680,7 @@ SelectMenuItem:
jr z, .battleselect
dec a
jr nz, .select
- coord hl, 1, 14
+ hlcoord 1, 14
ld de, WhichTechniqueString
call PlaceString
jr .select
@@ -2782,16 +2692,16 @@ SelectMenuItem:
ld a, [wMenuItemToSwap]
and a
jr z, .select
- coord hl, 5, 13
+ hlcoord 5, 13
dec a
ld bc, SCREEN_WIDTH
call AddNTimes
ld [hl], "▷"
.select
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 1, [hl]
bit 6, a
jp nz, SelectMenuItem_CursorUp ; up
@@ -2860,12 +2770,12 @@ SelectMenuItem:
jp MoveSelectionMenu
MoveNoPPText:
- TX_FAR _MoveNoPPText
- db "@"
+ text_far _MoveNoPPText
+ text_end
MoveDisabledText:
- TX_FAR _MoveDisabledText
- db "@"
+ text_far _MoveDisabledText
+ text_end
WhichTechniqueString:
db "WHICH TECHNIQUE?@"
@@ -2899,7 +2809,7 @@ Func_3d4f5:
jr nz, .asm_3d4fd
ld a, $1
.asm_3d4fd
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
call LoadScreenTilesFromBuffer1
call Func_3d536
ld a, [wTestBattlePlayerSelectedMove]
@@ -2909,7 +2819,7 @@ Func_3d4f5:
xor a
ld [wAnimationType], a
predef MoveAnimation
- callab Func_78e98
+ callfar Func_78e98
jp MoveSelectionMenu
Func_3d523:
@@ -2925,10 +2835,10 @@ asm_3d52d:
jp MoveSelectionMenu
Func_3d536:
- coord hl, 10, 16
+ hlcoord 10, 16
lb bc, 2, 10
call ClearScreenArea
- coord hl, 10, 17
+ hlcoord 10, 17
ld de, wTestBattlePlayerSelectedMove
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber
@@ -2939,7 +2849,7 @@ Func_3d536:
ret nc
ld [wd11e], a
call GetMoveName
- coord hl, 13, 17
+ hlcoord 13, 17
jp PlaceString
AnyMoveToSelect:
@@ -2989,8 +2899,8 @@ AnyMoveToSelect:
ret
NoMovesLeftText:
- TX_FAR _NoMovesLeftText
- db "@"
+ text_far _NoMovesLeftText
+ text_end
SwapMovesInMenu:
ld a, [wPlayerBattleStatus3]
@@ -3073,8 +2983,8 @@ SwapMovesInMenu:
PrintMenuItem:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 8
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 0, 8
lb bc, 3, 9
call TextBoxBorder
ld a, [wPlayerDisabledMove]
@@ -3086,7 +2996,7 @@ PrintMenuItem:
ld a, [wCurrentMenuItem]
cp b
jr nz, .notDisabled
- coord hl, 1, 10
+ hlcoord 1, 10
ld de, DisabledText
call PlaceString
jr .moveDisabled
@@ -3094,7 +3004,7 @@ PrintMenuItem:
ld hl, wCurrentMenuItem
dec [hl]
xor a
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld hl, wBattleMonMoves
ld a, [wCurrentMenuItem]
ld c, a
@@ -3107,7 +3017,7 @@ PrintMenuItem:
ld [wWhichPokemon], a
ld a, BATTLE_MON_DATA
ld [wMonDataLocation], a
- callab GetMaxPP
+ callfar GetMaxPP
ld hl, wCurrentMenuItem
ld c, [hl]
inc [hl]
@@ -3118,27 +3028,27 @@ PrintMenuItem:
and $3f
ld [wcd6d], a
; print TYPE/<type> and <curPP>/<maxPP>
- coord hl, 1, 9
+ hlcoord 1, 9
ld de, TypeText
call PlaceString
- coord hl, 7, 11
+ hlcoord 7, 11
ld [hl], "/"
- coord hl, 5, 9
+ hlcoord 5, 9
ld [hl], "/"
- coord hl, 5, 11
+ hlcoord 5, 11
ld de, wcd6d
lb bc, 1, 2
call PrintNumber
- coord hl, 8, 11
+ hlcoord 8, 11
ld de, wMaxPP
lb bc, 1, 2
call PrintNumber
call GetCurrentMove
- coord hl, 2, 10
+ hlcoord 2, 10
predef PrintMoveType
.moveDisabled
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
jp Delay3
DisabledText:
@@ -3202,7 +3112,7 @@ SelectEnemyMove:
ld a, [wIsInBattle]
dec a
jr z, .chooseRandomMove ; wild encounter
- callab AIEnemyTrainerChooseMoves
+ callfar AIEnemyTrainerChooseMoves
.chooseRandomMove
push hl
call BattleRandom
@@ -3267,7 +3177,7 @@ LinkBattleExchangeData:
ld a, b
.doExchange
ld [wSerialExchangeNybbleSendData], a
- callab PrintWaitingText
+ callfar PrintWaitingText
.syncLoop1
call Serial_ExchangeNybble
call DelayFrame
@@ -3290,7 +3200,7 @@ LinkBattleExchangeData:
ExecutePlayerMove:
xor a
- ld [H_WHOSETURN], a ; set player's turn
+ ldh [hWhoseTurn], a ; set player's turn
ld a, [wPlayerSelectedMove]
inc a
jp z, ExecutePlayerMoveDone ; for selected move = FF, skip most of player's turn
@@ -3443,7 +3353,7 @@ MirrorMoveCheck:
.moveDidNotMiss
call ApplyAttackToEnemyPokemon
call PrintCriticalOHKOText
- callab DisplayEffectiveness
+ callfar DisplayEffectiveness
ld a, 1
ld [wMoveDidntMiss], a
.notDone
@@ -3486,8 +3396,8 @@ MirrorMoveCheck:
jp ExecutePlayerMoveDone
MultiHitText:
- TX_FAR _MultiHitText
- db "@"
+ text_far _MultiHitText
+ text_end
ExecutePlayerMoveDone:
xor a
@@ -3499,29 +3409,29 @@ PrintGhostText:
; print the ghost battle messages
call IsGhostBattle
ret nz
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .Ghost
- ld a, [wBattleMonStatus] ; player’s turn
+ ld a, [wBattleMonStatus] ; player's turn
and SLP | (1 << FRZ)
ret nz
ld hl, ScaredText
call PrintText
xor a
ret
-.Ghost ; ghost’s turn
+.Ghost ; ghost's turn
ld hl, GetOutText
call PrintText
xor a
ret
ScaredText:
- TX_FAR _ScaredText
- db "@"
+ text_far _ScaredText
+ text_end
GetOutText:
- TX_FAR _GetOutText
- db "@"
+ text_far _GetOutText
+ text_end
IsGhostBattle:
ld a, [wIsInBattle]
@@ -3804,69 +3714,69 @@ CheckPlayerStatusConditions:
ret
FastAsleepText:
- TX_FAR _FastAsleepText
- db "@"
+ text_far _FastAsleepText
+ text_end
WokeUpText:
- TX_FAR _WokeUpText
- db "@"
+ text_far _WokeUpText
+ text_end
IsFrozenText:
- TX_FAR _IsFrozenText
- db "@"
+ text_far _IsFrozenText
+ text_end
FullyParalyzedText:
- TX_FAR _FullyParalyzedText
- db "@"
+ text_far _FullyParalyzedText
+ text_end
FlinchedText:
- TX_FAR _FlinchedText
- db "@"
+ text_far _FlinchedText
+ text_end
MustRechargeText:
- TX_FAR _MustRechargeText
- db "@"
+ text_far _MustRechargeText
+ text_end
DisabledNoMoreText:
- TX_FAR _DisabledNoMoreText
- db "@"
+ text_far _DisabledNoMoreText
+ text_end
IsConfusedText:
- TX_FAR _IsConfusedText
- db "@"
+ text_far _IsConfusedText
+ text_end
HurtItselfText:
- TX_FAR _HurtItselfText
- db "@"
+ text_far _HurtItselfText
+ text_end
ConfusedNoMoreText:
- TX_FAR _ConfusedNoMoreText
- db "@"
+ text_far _ConfusedNoMoreText
+ text_end
SavingEnergyText:
- TX_FAR _SavingEnergyText
- db "@"
+ text_far _SavingEnergyText
+ text_end
UnleashedEnergyText:
- TX_FAR _UnleashedEnergyText
- db "@"
+ text_far _UnleashedEnergyText
+ text_end
ThrashingAboutText:
- TX_FAR _ThrashingAboutText
- db "@"
+ text_far _ThrashingAboutText
+ text_end
AttackContinuesText:
- TX_FAR _AttackContinuesText
- db "@"
+ text_far _AttackContinuesText
+ text_end
CantMoveText:
- TX_FAR _CantMoveText
- db "@"
+ text_far _CantMoveText
+ text_end
PrintMoveIsDisabledText:
ld hl, wPlayerSelectedMove
ld de, wPlayerBattleStatus1
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .removeChargingUp
inc hl
@@ -3882,8 +3792,8 @@ PrintMoveIsDisabledText:
jp PrintText
MoveIsDisabledText:
- TX_FAR _MoveIsDisabledText
- db "@"
+ text_far _MoveIsDisabledText
+ text_end
HandleSelfConfusionDamage:
ld hl, HurtItselfText
@@ -3922,11 +3832,11 @@ HandleSelfConfusionDamage:
xor a
ld [wAnimationType], a
inc a
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
call PlayMoveAnimation
call DrawPlayerHUDAndHPBar
xor a
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
jp ApplyDamageToPlayerPokemon
PrintMonName1Text:
@@ -3939,9 +3849,9 @@ PrintMonName1Text:
; 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]
+ text_far _MonName1Text
+ text_asm
+ ldh a, [hWhoseTurn]
and a
ld a, [wPlayerMoveNum]
ld hl, wPlayerUsedMove
@@ -3964,13 +3874,13 @@ MonName1Text:
ret
Used1Text:
- TX_FAR _Used1Text
- TX_ASM
+ text_far _Used1Text
+ text_asm
jr PrintInsteadText
Used2Text:
- TX_FAR _Used2Text
- TX_ASM
+ text_far _Used2Text
+ text_asm
; fall through
PrintInsteadText:
@@ -3981,8 +3891,8 @@ PrintInsteadText:
ret
InsteadText:
- TX_FAR _InsteadText
- TX_ASM
+ text_far _InsteadText
+ text_asm
; fall through
PrintMoveName:
@@ -3990,8 +3900,8 @@ PrintMoveName:
ret
_PrintMoveName:
- TX_FAR _CF4BText
- TX_ASM
+ text_far _CF4BText
+ text_asm
ld hl, ExclamationPointPointerTable
ld a, [wd11e] ; exclamation point num
add a
@@ -4013,24 +3923,24 @@ ExclamationPointPointerTable:
dw ExclamationPoint5Text
ExclamationPoint1Text:
- TX_FAR _ExclamationPoint1Text
- db "@"
+ text_far _ExclamationPoint1Text
+ text_end
ExclamationPoint2Text:
- TX_FAR _ExclamationPoint2Text
- db "@"
+ text_far _ExclamationPoint2Text
+ text_end
ExclamationPoint3Text:
- TX_FAR _ExclamationPoint3Text
- db "@"
+ text_far _ExclamationPoint3Text
+ text_end
ExclamationPoint4Text:
- TX_FAR _ExclamationPoint4Text
- db "@"
+ text_far _ExclamationPoint4Text
+ text_end
ExclamationPoint5Text:
- TX_FAR _ExclamationPoint5Text
- db "@"
+ text_far _ExclamationPoint5Text
+ text_end
; this function does nothing useful
; if the move being used is in set [1-4] from ExclamationPointMoveSets,
@@ -4061,26 +3971,11 @@ DetermineExclamationPointTextNum:
pop bc
ret
-ExclamationPointMoveSets:
-; a grammar mistake was fixed (only concerning japanese)
-; BIDE is in category 3, moved from category 2
- db SWORDS_DANCE, GROWTH
- db $00
- db RECOVER, SELFDESTRUCT, AMNESIA
- db $00
- db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BIDE, 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
+INCLUDE "data/moves/grammar.asm"
PrintMoveFailureText:
ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playersTurn
ld de, wEnemyMoveEffect
@@ -4128,7 +4023,7 @@ PrintMoveFailureText:
call PrintText
ld b, $4
predef PredefShakeScreenHorizontally
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .enemyTurn
jp ApplyDamageToPlayerPokemon
@@ -4136,24 +4031,24 @@ PrintMoveFailureText:
jp ApplyDamageToEnemyPokemon
AttackMissedText:
- TX_FAR _AttackMissedText
- db "@"
+ text_far _AttackMissedText
+ text_end
KeptGoingAndCrashedText:
- TX_FAR _KeptGoingAndCrashedText
- db "@"
+ text_far _KeptGoingAndCrashedText
+ text_end
UnaffectedText:
- TX_FAR _UnaffectedText
- db "@"
+ text_far _UnaffectedText
+ text_end
PrintDoesntAffectText:
ld hl, DoesntAffectMonText
jp PrintText
DoesntAffectMonText:
- TX_FAR _DoesntAffectMonText
- db "@"
+ text_far _DoesntAffectMonText
+ text_end
; if there was a critical hit or an OHKO was successful, print the corresponding text
PrintCriticalOHKOText:
@@ -4181,12 +4076,12 @@ CriticalOHKOTextPointers:
dw OHKOText
CriticalHitText:
- TX_FAR _CriticalHitText
- db "@"
+ text_far _CriticalHitText
+ text_end
OHKOText:
- TX_FAR _OHKOText
- db "@"
+ text_far _OHKOText
+ text_end
; checks if a traded mon will disobey due to lack of badges
; stores whether the mon will use a move in Z flag
@@ -4216,16 +4111,16 @@ CheckForDisobedience:
.monIsTraded
; what level might disobey?
ld hl, wObtainedBadges
- bit 7, [hl]
+ bit BIT_EARTHBADGE, [hl]
ld a, 101
jr nz, .next
- bit 5, [hl]
+ bit BIT_MARSHBADGE, [hl]
ld a, 70
jr nz, .next
- bit 3, [hl]
+ bit BIT_RAINBOWBADGE, [hl]
ld a, 50
jr nz, .next
- bit 1, [hl]
+ bit BIT_CASCADEBADGE, [hl]
ld a, 30
jr nz, .next
ld a, 10
@@ -4370,24 +4265,24 @@ CheckForDisobedience:
ret
LoafingAroundText:
- TX_FAR _LoafingAroundText
- db "@"
+ text_far _LoafingAroundText
+ text_end
BeganToNapText:
- TX_FAR _BeganToNapText
- db "@"
+ text_far _BeganToNapText
+ text_end
WontObeyText:
- TX_FAR _WontObeyText
- db "@"
+ text_far _WontObeyText
+ text_end
TurnedAwayText:
- TX_FAR _TurnedAwayText
- db "@"
+ text_far _TurnedAwayText
+ text_end
IgnoredOrdersText:
- TX_FAR _IgnoredOrdersText
- db "@"
+ text_far _IgnoredOrdersText
+ text_end
; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the player mon
GetDamageVarsForPlayerAttack:
@@ -4401,7 +4296,7 @@ GetDamageVarsForPlayerAttack:
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
+ cp SPECIAL ; types >= SPECIAL are all special
jr nc, .specialAttack
.physicalAttack
ld hl, wEnemyMonDefense
@@ -4422,9 +4317,9 @@ GetDamageVarsForPlayerAttack:
; 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]
+ ldh a, [hProduct + 2]
ld b, a
- ld a, [H_PRODUCT + 3]
+ ldh a, [hProduct + 3]
ld c, a
push bc
ld hl, wPartyMon1Attack
@@ -4444,8 +4339,8 @@ GetDamageVarsForPlayerAttack:
; 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
+; reflect and light screen boosts do not cap the stat at MAX_STAT_VALUE, 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]
@@ -4454,9 +4349,9 @@ GetDamageVarsForPlayerAttack:
; 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]
+ ldh a, [hProduct + 2]
ld b, a
- ld a, [H_PRODUCT + 3]
+ ldh a, [hProduct + 3]
ld c, a
push bc
ld hl, wPartyMon1Special
@@ -4514,7 +4409,7 @@ GetDamageVarsForEnemyAttack:
and a
ret z ; return if move power is zero
ld a, [hl] ; a = [wEnemyMoveType]
- cp FIRE ; types >= FIRE are all special
+ cp SPECIAL ; types >= SPECIAL are all special
jr nc, .specialAttack
.physicalAttack
ld hl, wBattleMonDefense
@@ -4543,7 +4438,7 @@ GetDamageVarsForEnemyAttack:
push bc
ld c, 2 ; attack stat
call GetEnemyMonStat
- ld hl, H_PRODUCT + 2
+ ld hl, hProduct + 2
pop bc
jr .scaleStats
.specialAttack
@@ -4557,8 +4452,8 @@ GetDamageVarsForEnemyAttack:
; 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
+; reflect and light screen boosts do not cap the stat at MAX_STAT_VALUE, 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]
@@ -4575,7 +4470,7 @@ GetDamageVarsForEnemyAttack:
push bc
ld c, 5 ; special stat
call GetEnemyMonStat
- ld hl, H_PRODUCT + 2
+ ld hl, hProduct + 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
@@ -4633,9 +4528,9 @@ GetEnemyMonStat:
ld bc, wEnemyMon2 - wEnemyMon1
call AddNTimes
ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hl]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
pop bc
pop de
ret
@@ -4666,7 +4561,7 @@ CalculateDamage:
; d: base power
; e: level
- ld a, [H_WHOSETURN] ; whose turn?
+ ldh a, [hWhoseTurn] ; whose turn?
and a
ld a, [wPlayerMoveEffect]
jr z, .effect
@@ -4698,7 +4593,7 @@ CalculateDamage:
.skipbp
xor a
- ld hl, H_DIVIDEND
+ ld hl, hDividend
ldi [hl], a
ldi [hl], a
ld [hl], a
@@ -4747,76 +4642,82 @@ CalculateDamage:
ld b, 4
call Divide
+; Update wCurDamage.
+; Capped at MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE: 999 - 2 = 997.
ld hl, wDamage
ld b, [hl]
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
add b
- ld [H_QUOTIENT + 3], a
- jr nc, .asm_3e142
+ ldh [hQuotient + 3], a
+ jr nc, .dont_cap_1
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
inc a
- ld [H_QUOTIENT + 2], a
+ ldh [hQuotient + 2], a
and a
- jr z, .asm_3e176
+ jr z, .cap
-.asm_3e142
- ld a, [H_QUOTIENT]
+.dont_cap_1
+ ldh a, [hQuotient]
ld b, a
- ld a, [H_QUOTIENT + 1]
+ ldh a, [hQuotient + 1]
or a
- jr nz, .asm_3e176
+ jr nz, .cap
- ld a, [H_QUOTIENT + 2]
- cp 998 / $100
- jr c, .asm_3e15a
- cp 998 / $100 + 1
- jr nc, .asm_3e176
- ld a, [H_QUOTIENT + 3]
- cp 998 % $100
- jr nc, .asm_3e176
+ ldh a, [hQuotient + 2]
+ cp HIGH(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1)
+ jr c, .dont_cap_2
-.asm_3e15a
+ cp HIGH(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1) + 1
+ jr nc, .cap
+
+ ldh a, [hQuotient + 3]
+ cp LOW(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1)
+ jr nc, .cap
+
+.dont_cap_2
inc hl
- ld a, [H_QUOTIENT + 3]
+
+ ldh a, [hQuotient + 3]
ld b, [hl]
add b
ld [hld], a
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld b, [hl]
adc b
ld [hl], a
- jr c, .asm_3e176
+ jr c, .cap
ld a, [hl]
- cp 998 / $100
- jr c, .asm_3e17c
- cp 998 / $100 + 1
- jr nc, .asm_3e176
+ cp HIGH(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1)
+ jr c, .dont_cap_3
+
+ cp HIGH(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1) + 1
+ jr nc, .cap
+
inc hl
ld a, [hld]
- cp 998 % $100
- jr c, .asm_3e17c
+ cp LOW(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE + 1)
+ jr c, .dont_cap_3
-.asm_3e176
-; cap at 997
- ld a, 997 / $100
+.cap
+ ld a, HIGH(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE)
ld [hli], a
- ld a, 997 % $100
+ ld a, LOW(MAX_NEUTRAL_DAMAGE - MIN_NEUTRAL_DAMAGE)
ld [hld], a
-.asm_3e17c
-; add 2
+.dont_cap_3
+; Add back MIN_NEUTRAL_DAMAGE (capping at 999).
inc hl
ld a, [hl]
- add 2
+ add MIN_NEUTRAL_DAMAGE
ld [hld], a
- jr nc, .done
+ jr nc, .dont_floor
inc [hl]
+.dont_floor
-.done
-; minimum damage is 1
+; Returns nz and nc.
ld a, 1
and a
ret
@@ -4827,13 +4728,7 @@ JumpToOHKOMoveEffect:
dec a
ret
-
-UnusedHighCriticalMoves:
- db KARATE_CHOP
- db RAZOR_LEAF
- db CRABHAMMER
- db SLASH
- db $FF
+INCLUDE "data/battle/unused_critical_hit_moves.asm"
; determines if attack is a critical hit
; azure heights claims "the fastest pokémon (who are, not coincidentally,
@@ -4841,7 +4736,7 @@ UnusedHighCriticalMoves:
CriticalHitTest:
xor a
ld [wCriticalHitOrOHKO], a
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, [wEnemyMonSpecies]
jr nz, .handleEnemy
@@ -4852,7 +4747,7 @@ CriticalHitTest:
ld a, [wMonHBaseSpeed]
ld b, a
srl b ; (effective (base speed/2))
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld hl, wPlayerMovePower
ld de, wPlayerBattleStatus2
@@ -4904,14 +4799,7 @@ CriticalHitTest:
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
-
+INCLUDE "data/battle/critical_hit_moves.asm"
; function to determine if Counter hits and if so, how much damage it does
HandleCounterMove:
@@ -4921,7 +4809,7 @@ HandleCounterMove:
; 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
+ ldh a, [hWhoseTurn] ; whose turn
and a
; player's turn
ld hl, wEnemySelectedMove
@@ -5091,7 +4979,7 @@ ApplyDamageToEnemyPokemon:
ld [wHPBarNewHP+1], a
ld a, [hl]
ld [wHPBarNewHP], a
- coord hl, 2, 2
+ hlcoord 2, 2
xor a
ld [wHPBarType], a
predef UpdateHPBar2 ; animate the HP bar shortening
@@ -5209,7 +5097,7 @@ ApplyDamageToPlayerPokemon:
ld [wHPBarMaxHP+1], a
ld a, [hl]
ld [wHPBarMaxHP], a
- coord hl, 10, 9
+ hlcoord 10, 9
ld a, $01
ld [wHPBarType], a
predef UpdateHPBar2 ; animate the HP bar shortening
@@ -5229,7 +5117,7 @@ AttackSubstitute:
; values for player turn
ld de, wEnemySubstituteHP
ld bc, wEnemyBattleStatus2
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .applyDamageToSubstitute
; values for enemy turn
@@ -5254,14 +5142,14 @@ AttackSubstitute:
ld hl, SubstituteBrokeText
call PrintText
; flip whose turn it is for the next function call
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
xor $01
- ld [H_WHOSETURN], a
- callab Func_79929 ; animate the substitute breaking
+ ldh [hWhoseTurn], a
+ callfar Func_79929 ; animate the substitute breaking
; flip the turn back to the way it was
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
xor $01
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld hl, wPlayerMoveEffect ; value for player's turn
and a
jr z, .nullifyEffect
@@ -5272,12 +5160,12 @@ AttackSubstitute:
jp DrawHUDsAndHPBars
SubstituteTookDamageText:
- TX_FAR _SubstituteTookDamageText
- db "@"
+ text_far _SubstituteTookDamageText
+ text_end
SubstituteBrokeText:
- TX_FAR _SubstituteBrokeText
- db "@"
+ text_far _SubstituteBrokeText
+ text_end
; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
HandleBuildingRage:
@@ -5285,7 +5173,7 @@ HandleBuildingRage:
ld hl, wEnemyBattleStatus2
ld de, wEnemyMonStatMods
ld bc, wEnemyMoveNum
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .next
; values for the enemy turn
@@ -5298,9 +5186,9 @@ HandleBuildingRage:
ld a, [de]
cp $0d ; maximum stat modifier value
ret z ; return if attack modifier is already maxed
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
xor $01 ; flip turn for the stat modifier raising function
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], 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
@@ -5317,25 +5205,25 @@ HandleBuildingRage:
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]
+ ldh a, [hWhoseTurn]
xor $01 ; flip turn back to the way it was
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ret
BuildingRageText:
- TX_FAR _BuildingRageText
- db "@"
+ text_far _BuildingRageText
+ text_end
; 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,
+; Mirror Move makes use of wPlayerUsedMove and wEnemyUsedMove,
; 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.
+; wPlayerUsedMove is also set to 0 whenever the player is fast asleep or frozen solid.
+; wEnemyUsedMove is also set to 0 whenever the enemy is fast asleep or frozen solid.
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
; values for player turn
ld a, [wEnemyUsedMove]
@@ -5359,8 +5247,8 @@ MirrorMoveCopyMove:
ret
MirrorMoveFailedText:
- TX_FAR _MirrorMoveFailedText
- db "@"
+ text_far _MirrorMoveFailedText
+ text_end
; function used to reload move data for moves like Mirror Move and Metronome
ReloadMoveData:
@@ -5388,7 +5276,7 @@ MetronomePickMove:
; values for player turn
ld de, wPlayerMoveNum
ld hl, wPlayerSelectedMove
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .pickMoveLoop
; values for enemy turn
@@ -5410,7 +5298,7 @@ MetronomePickMove:
; 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]
+ ldh a, [hWhoseTurn]
and a
; values for player turn
ld hl, wBattleMonPP
@@ -5429,7 +5317,7 @@ IncrementMovePP:
ld h, d
ld l, e
add hl, bc
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, [wPlayerMonNumber] ; value for player turn
jr z, .updatePP
@@ -5453,7 +5341,7 @@ AdjustDamageForMoveType:
ld e, [hl] ; e = type 2 of defender
ld a, [wPlayerMoveType]
ld [wMoveType], a
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .next
; values for enemy turn
@@ -5517,25 +5405,25 @@ AdjustDamageForMoveType:
and $80
ld b, a
ld a, [hl] ; a = damage multiplier
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
add b
ld [wDamageMultipliers], a
xor a
- ld [H_MULTIPLICAND], a
+ ldh [hMultiplicand], a
ld hl, wDamage
ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hld]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
call Multiply
ld a, 10
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $04
call Divide
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld [hli], a
ld b, a
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld [hl], a
or b ; is damage 0?
jr nz, .skipTypeImmunity
@@ -5598,7 +5486,7 @@ AIGetTypeEffectiveness:
ld [wd11e], a ; store damage multiplier
ret
-INCLUDE "data/type_effects.asm"
+INCLUDE "data/types/type_matchups.asm"
; some tests that need to pass for a move to hit
MoveHitTest:
@@ -5606,7 +5494,7 @@ MoveHitTest:
ld hl, wEnemyBattleStatus1
ld de, wPlayerMoveEffect
ld bc, wEnemyMonStatus
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .dreamEaterCheck
; enemy's turn
@@ -5626,8 +5514,8 @@ MoveHitTest:
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.
+; This code is buggy. It's supposed to prevent HP draining moves from working on substitutes.
+; Since CheckTargetSubstitute overwrites a with either $00 or $01, it never works.
cp DRAIN_HP_EFFECT
jp z, .moveMissed
cp DREAM_EATER_EFFECT
@@ -5635,7 +5523,7 @@ MoveHitTest:
.checkForDigOrFlyStatus
bit INVULNERABLE, [hl]
jp nz, .moveMissed
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr nz, .enemyTurn
.playerTurn
@@ -5689,7 +5577,7 @@ MoveHitTest:
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]
+ ldh a, [hWhoseTurn]
and a
jr z, .doAccuracyCheck
ld a, [wEnemyMoveAccuracy]
@@ -5708,7 +5596,7 @@ MoveHitTest:
ld [hl], a
inc a
ld [wMoveMissed], a
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn2
.enemyTurn2
@@ -5723,7 +5611,7 @@ MoveHitTest:
; values for player turn
CalcHitChance:
ld hl, wPlayerMoveAccuracy
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, [wPlayerMonAccuracyMod]
ld b, a
@@ -5743,10 +5631,10 @@ CalcHitChance:
; 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
+ ldh [hMultiplicand], a
+ ldh [hMultiplicand + 1], a
ld a, [hl]
- ld [H_MULTIPLICAND + 2], a ; set multiplicand to move accuracy
+ ldh [hMultiplicand + 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
@@ -5761,29 +5649,29 @@ CalcHitChance:
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
+ ldh [hMultiplier], 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
+ ldh [hDivisor], 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]
+ ldh a, [hQuotient + 3]
ld b, a
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
or b
jp nz, .nextCalculation
; make sure the result is always at least one
- ld [H_QUOTIENT + 2], a
+ ldh [hQuotient + 2], a
ld a, $01
- ld [H_QUOTIENT + 3], a
+ ldh [hQuotient + 3], a
.nextCalculation
ld b, c
dec d
jr nz, .loop
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
and a ; is the calculated hit chance over 0xFF?
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
jr z, .storeAccuracy
; if calculated hit chance over 0xFF
ld a, $ff ; set the hit chance to 0xFF
@@ -5803,29 +5691,29 @@ RandomizeDamage:
ret c ; return if damage is equal to 0 or 1
.DamageGreaterThanOne
xor a
- ld [H_MULTIPLICAND], a
+ ldh [hMultiplicand], a
dec hl
ld a, [hli]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
ld a, [hl]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 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
+ ldh [hMultiplier], a
call Multiply ; multiply damage by the random number, which is in the range [217, 255]
ld a, 255
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $4
call Divide ; divide the result by 255
; store the modified damage
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld hl, wDamage
ld [hli], a
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld [hl], a
ret
@@ -6001,7 +5889,7 @@ EnemyCheckIfMirrorMoveEffect:
.moveDidNotMiss
call ApplyAttackToPlayerPokemon
call PrintCriticalOHKOText
- callab DisplayEffectiveness
+ callfar DisplayEffectiveness
ld a, 1
ld [wMoveDidntMiss], a
.handleExplosionMiss
@@ -6040,8 +5928,8 @@ EnemyCheckIfMirrorMoveEffect:
jr ExecuteEnemyMoveDone
HitXTimesText:
- TX_FAR _HitXTimesText
- db "@"
+ text_far _HitXTimesText
+ text_end
ExecuteEnemyMoveDone:
ld b, $1
@@ -6181,11 +6069,11 @@ CheckEnemyStatusConditions:
ld [hl], a
xor a
ld [wAnimationType], a
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
ld a, POUND
call PlayMoveAnimation
ld a, $1
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
call ApplyDamageToEnemyPokemon
jr .monHurtItselfOrFullyParalysed
.checkIfTriedToUseDisabledMove
@@ -6332,7 +6220,7 @@ CheckEnemyStatusConditions:
ret
GetCurrentMove:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jp z, .player
ld de, wEnemyMoveNum
@@ -6379,8 +6267,8 @@ LoadEnemyMonData:
ld a, [wIsInBattle]
cp $2 ; is it a trainer battle?
; fixed DVs for trainer mon
- ld a, $98
- ld b, $88
+ ld a, ATKDEFDV_TRAINER
+ ld b, SPDSPCDV_TRAINER
jr z, .storeDVs
; random DVs for wild mon
call BattleRandom
@@ -6529,25 +6417,25 @@ DoBattleTransitionAndInitBattleVariables:
; link battle
xor a
ld [wMenuJoypadPollCount], a
- callab DisplayLinkBattleVersusTextBox
+ callfar DisplayLinkBattleVersusTextBox
ld a, $1
ld [wUpdateSpritesEnabled], a
call ClearScreen
.next
call DelayFrame
predef BattleTransition
- callab LoadHudAndHpBarAndStatusTilePatterns
+ callfar LoadHudAndHpBarAndStatusTilePatterns
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], 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
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hWY], a
+ ldh [rWY], a
+ ldh [hTilesetType], a
ld hl, wPlayerStatsToDouble
ld [hli], a
ld [hli], a
@@ -6587,7 +6475,7 @@ LoadPlayerBackPic:
predef ScaleSpriteByTwo
ld hl, wOAMBuffer
xor a
- ld [hOAMTile], a ; initial tile number
+ ldh [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
@@ -6601,18 +6489,18 @@ LoadPlayerBackPic:
add d ; increase Y by height of tile
ld d, a
inc hl
- ld a, [hOAMTile]
+ ldh a, [hOAMTile]
ld [hli], a ; OAM tile number
inc a ; increment tile number
- ld [hOAMTile], a
+ ldh [hOAMTile], a
ld a, $2
ld [hl], a
inc hl
dec c
jr nz, .innerLoop
- ld a, [hOAMTile]
+ ldh a, [hOAMTile]
add $4 ; increase tile number by 4
- ld [hOAMTile], a
+ ldh [hOAMTile], a
ld a, $8 ; width of tile
add e ; increase X by width of tile
ld e, a
@@ -6624,23 +6512,23 @@ LoadPlayerBackPic:
call SwitchSRAMBankAndLatchClockData
ld hl, vSprites
ld de, sSpriteBuffer1
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
ld b, a
ld c, 7 * 7
call CopyVideoData
call PrepareRTCDataAndDisableSRAM
ld a, $31
- ld [hStartTileID], a
- coord hl, 1, 5
+ ldh [hStartTileID], a
+ hlcoord 1, 5
predef_jump CopyUncompressedPicToTilemap
; does nothing since no stats are ever selected (barring glitches)
DoubleOrHalveSelectedStats:
- callab DoubleSelectedStats
- jpab HalveSelectedStats
+ callfar DoubleSelectedStats
+ jpfar HalveSelectedStats
ScrollTrainerPicAfterBattle:
- jpab _ScrollTrainerPicAfterBattle
+ jpfar _ScrollTrainerPicAfterBattle
ApplyBurnAndParalysisPenaltiesToPlayer:
ld a, $1
@@ -6650,12 +6538,12 @@ ApplyBurnAndParalysisPenaltiesToEnemy:
xor a
ApplyBurnAndParalysisPenalties:
- ld [H_WHOSETURN], a
+ ldh [hWhoseTurn], a
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
QuarterSpeedDueToParalysis:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
.enemyTurn ; quarter the player's speed
@@ -6698,7 +6586,7 @@ QuarterSpeedDueToParalysis:
ret
HalveAttackDueToBurn:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
jr z, .playerTurn
.enemyTurn ; halve the player's attack
@@ -6788,35 +6676,35 @@ CalculateModifiedStat:
ld b, 0
add hl, bc
xor a
- ld [H_MULTIPLICAND], a
+ ldh [hMultiplicand], a
ld a, [de]
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand + 1], a
inc de
ld a, [de]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
ld a, [hli]
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
call Multiply
ld a, [hl]
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $4
call Divide
pop hl
- ld a, [H_DIVIDEND + 3]
- sub 999 % $100
- ld a, [H_DIVIDEND + 2]
- sbc 999 / $100
+ ldh a, [hDividend + 3]
+ sub LOW(MAX_STAT_VALUE)
+ ldh a, [hDividend + 2]
+ sbc HIGH(MAX_STAT_VALUE)
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
+; cap the stat at MAX_STAT_VALUE (999)
+ ld a, HIGH(MAX_STAT_VALUE)
+ ldh [hDividend + 2], a
+ ld a, LOW(MAX_STAT_VALUE)
+ ldh [hDividend + 3], a
.storeNewStatValue
- ld a, [H_DIVIDEND + 2]
+ ldh a, [hDividend + 2]
ld [hli], a
ld b, a
- ld a, [H_DIVIDEND + 3]
+ ldh a, [hDividend + 3]
ld [hl], a
or b
jr nz, .done
@@ -6850,7 +6738,7 @@ ApplyBadgeStatBoosts:
ret
; multiply stat at hl by 1.125
-; cap stat at 999
+; cap stat at MAX_STAT_VALUE
.applyBoostToStat
ld a, [hli]
ld d, a
@@ -6868,13 +6756,13 @@ ApplyBadgeStatBoosts:
adc d
ld [hli], a
ld a, [hld]
- sub 999 % $100
+ sub LOW(MAX_STAT_VALUE)
ld a, [hl]
- sbc 999 / $100
+ sbc HIGH(MAX_STAT_VALUE)
ret c
- ld a, 999 / $100
+ ld a, HIGH(MAX_STAT_VALUE)
ld [hli], a
- ld a, 999 % $100
+ ld a, LOW(MAX_STAT_VALUE)
ld [hld], a
ret
@@ -6882,33 +6770,34 @@ LoadHudAndHpBarAndStatusTilePatterns:
call LoadHpBarAndStatusTilePatterns
LoadHudTilePatterns:
- ld a, [rLCDC]
+ ldh a, [rLCDC]
add a ; is LCD disabled?
jr c, .lcdEnabled
.lcdDisabled
ld hl, BattleHudTiles1
- ld de, vChars2 + $6d0
+ ld de, vChars2 tile $6d
ld bc, BattleHudTiles1End - BattleHudTiles1
ld a, BANK(BattleHudTiles1)
call FarCopyDataDouble
ld hl, BattleHudTiles2
- ld de, vChars2 + $730
+ ld de, vChars2 tile $73
ld bc, BattleHudTiles3End - BattleHudTiles2
ld a, BANK(BattleHudTiles2)
jp FarCopyDataDouble
.lcdEnabled
ld de, BattleHudTiles1
- ld hl, vChars2 + $6d0
+ ld hl, vChars2 tile $6d
lb bc, BANK(BattleHudTiles1), (BattleHudTiles1End - BattleHudTiles1) / $8
call CopyVideoDataDouble
ld de, BattleHudTiles2
- ld hl, vChars2 + $730
+ ld hl, vChars2 tile $73
lb bc, BANK(BattleHudTiles2), (BattleHudTiles3End - BattleHudTiles2) / $8
jp CopyVideoDataDouble
PrintEmptyString:
ld hl, .emptyString
jp PrintText
+
.emptyString
db "@"
@@ -6966,7 +6855,7 @@ BattleRandom:
HandleExplodingAnimation:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld hl, wEnemyMonType1
ld de, wEnemyBattleStatus1
@@ -7000,1662 +6889,5 @@ PlayMoveAnimation:
ld [wAnimationID], a
call Delay3
predef MoveAnimation
- callab Func_78e98
- ret
-
-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 b, a
- ld a, [wUnknownSerialFlag_d499]
- and a
- jr z, .asm_3f1ba ; XXX stadium stuff?
- ld a, b
- and $3
- jr z, .setSleepCounter
- ld b, a
-.asm_3f1ba
- ld a, b
- 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 UNUSED_EFFECT_23 ; more stadium stuff
- jr nz, .asm_3f2c7
- ld a, [wUnknownSerialFlag_d499]
- and a
- ld a, FREEZE_SIDE_EFFECT
- ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
- jr z, .next1
- ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
- jr .next1
-.asm_3f2c7
- cp a, 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, .burn1
- cp FREEZE_SIDE_EFFECT
- jr z, .freeze1
-; .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
-.burn1
- 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
-.freeze1
- 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 UNUSED_EFFECT_23 ; more stadium stuff
- jr nz, .asm_3f341
- ld a, [wUnknownSerialFlag_d499]
- and a
- ld a, FREEZE_SIDE_EFFECT
- ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
- jr z, .next2
- ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
- jr .next2
-.asm_3f341
- cp a, PARALYZE_SIDE_EFFECT1 + 1
- ld b, $1a
- jr c, .next2
- ld b, $4d
- sub $1e
-.next2
- push af
- call BattleRandom
- cp b
- pop bc
- ret nc
- ld a, b
- cp BURN_SIDE_EFFECT1
- jr z, .burn2
- cp FREEZE_SIDE_EFFECT
- jr z, .freeze2
- ld a, 1 << PAR
- ld [wBattleMonStatus], a
- call QuarterSpeedDueToParalysis
- ld a, ANIM_C7
- call PlayBattleAnimation2
- jp PrintMayNotAttackText
-.burn2
- ld a, 1 << BRN
- ld [wBattleMonStatus], a
- call HalveAttackDueToBurn
- ld a, ANIM_C7
- call PlayBattleAnimation2
- ld hl, BurnedText
- jp PrintText
-.freeze2
-; hyper beam bits aren't reseted for opponent's side
- ld a, 1 << FRZ
- ld [wBattleMonStatus], a
- ld a, ANIM_C7
- call PlayBattleAnimation2
- 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, .playerTurn
- ld hl, wEnemyBattleStatus2
- ld de, wEnemyMoveNum
- ld bc, wEnemyMonMinimized
-.playerTurn
- ld a, [de]
- cp MINIMIZE
- jr nz, .notMinimize
- ; 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
- push de
- ld hl, HideSubstituteShowMonAnim
- ld b, BANK(HideSubstituteShowMonAnim)
- call nz, Bankswitch
- pop de
-.notMinimize
- 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, [wLinkState]
- cp LINK_STATE_BATTLING
- call z, ClearHyperBeam
- 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
- push de
- push bc
- inc hl ; battle status 2
- push hl
- ld a, [hl]
- bit HAS_SUBSTITUTE_UP, a
- ld hl, HideSubstituteShowMonAnim
- ld b, BANK(HideSubstituteShowMonAnim)
- call nz, Bankswitch
- pop hl
- pop bc
- xor a
- ld [wAnimationType], a
- ld a, b
- call PlayBattleAnimation
- ld a, [hl]
- bit HAS_SUBSTITUTE_UP, a
- ld hl, ReshowSubstituteAnim
- ld b, BANK(ReshowSubstituteAnim)
- call nz, Bankswitch
- pop de
- 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
- callab Func_78e98
- pop bc
- pop de
- pop hl
+ callfar Func_78e98
ret
diff --git a/engine/battle/decrement_pp.asm b/engine/battle/decrement_pp.asm
index b7c428f7..441bbb81 100644
--- a/engine/battle/decrement_pp.asm
+++ b/engine/battle/decrement_pp.asm
@@ -37,7 +37,7 @@ DecrementPP:
ld a, [wPlayerMoveListIndex] ; which move (0, 1, 2, 3) did we use?
ld c, a
ld b, 0
- add hl ,bc ; calculate the address in memory of the PP we need to decrement
+ add hl, bc ; calculate the address in memory of the PP we need to decrement
; based on the move chosen.
dec [hl] ; Decrement PP
ret
diff --git a/engine/battle/display_effectiveness.asm b/engine/battle/display_effectiveness.asm
index 1bf14460..b23695cf 100644
--- a/engine/battle/display_effectiveness.asm
+++ b/engine/battle/display_effectiveness.asm
@@ -10,9 +10,9 @@ DisplayEffectiveness:
jp PrintText
SuperEffectiveText:
- TX_FAR _SuperEffectiveText
- db "@"
+ text_far _SuperEffectiveText
+ text_end
NotVeryEffectiveText:
- TX_FAR _NotVeryEffectiveText
- db "@"
+ text_far _NotVeryEffectiveText
+ text_end
diff --git a/engine/battle/draw_hud_pokeball_gfx.asm b/engine/battle/draw_hud_pokeball_gfx.asm
index 96294774..6aed1d0a 100644
--- a/engine/battle/draw_hud_pokeball_gfx.asm
+++ b/engine/battle/draw_hud_pokeball_gfx.asm
@@ -12,7 +12,7 @@ DrawEnemyPokeballs:
LoadPartyPokeballGfx:
ld de, PokeballTileGraphics
- ld hl, vSprites + $310
+ ld hl, vSprites tile $31
lb bc, BANK(PokeballTileGraphics), (PokeballTileGraphicsEnd - PokeballTileGraphics) / $10
jp CopyVideoData
@@ -125,7 +125,7 @@ PlacePlayerHUDTiles:
ld de, wHUDGraphicsTiles
ld bc, $3
call CopyData
- coord hl, 18, 10
+ hlcoord 18, 10
ld de, -1
jr PlaceHUDTiles
@@ -140,7 +140,7 @@ PlaceEnemyHUDTiles:
ld de, wHUDGraphicsTiles
ld bc, $3
call CopyData
- coord hl, 1, 2
+ hlcoord 1, 2
ld de, $1
jr PlaceHUDTiles
@@ -196,5 +196,5 @@ SetupPlayerAndEnemyPokeballs:
; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (fainted) and pokeball slot (no mon)
PokeballTileGraphics::
- INCBIN "gfx/pokeball.2bpp"
+ INCBIN "gfx/battle/balls.2bpp"
PokeballTileGraphicsEnd:
diff --git a/engine/battle/effects.asm b/engine/battle/effects.asm
new file mode 100644
index 00000000..c4e81816
--- /dev/null
+++ b/engine/battle/effects.asm
@@ -0,0 +1,1551 @@
+JumpMoveEffect:
+ call _JumpMoveEffect
+ ld b, $1
+ ret
+
+_JumpMoveEffect:
+ ldh a, [hWhoseTurn]
+ 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
+
+INCLUDE "data/moves/effects_pointers.asm"
+
+SleepEffect:
+ ld de, wEnemyMonStatus
+ ld bc, wEnemyBattleStatus2
+ ldh a, [hWhoseTurn]
+ 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 b, a
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ jr z, .asm_3f1ba ; XXX stadium stuff?
+ ld a, b
+ and $3
+ jr z, .setSleepCounter
+ ld b, a
+.asm_3f1ba
+ ld a, b
+ ld [de], a
+ call PlayCurrentMoveAnimation2
+ ld hl, FellAsleepText
+ jp PrintText
+.didntAffect
+ jp PrintDidntAffectText
+
+FellAsleepText:
+ text_far _FellAsleepText
+ text_end
+
+AlreadyAsleepText:
+ text_far _AlreadyAsleepText
+ text_end
+
+PoisonEffect:
+ ld hl, wEnemyMonStatus
+ ld de, wPlayerMoveEffect
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _PoisonedText
+ text_end
+
+BadlyPoisonedText:
+ text_far _BadlyPoisonedText
+ text_end
+
+DrainHPEffect:
+ jpfar DrainHPEffect_
+
+ExplodeEffect:
+ ld hl, wBattleMonHP
+ ld de, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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 UNUSED_EFFECT_23 ; more stadium stuff
+ jr nz, .asm_3f2c7
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ ld a, FREEZE_SIDE_EFFECT
+ ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
+ jr z, .next1
+ ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
+ jr .next1
+.asm_3f2c7
+ cp a, 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, .burn1
+ cp FREEZE_SIDE_EFFECT
+ jr z, .freeze1
+; .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
+.burn1
+ 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
+.freeze1
+ 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 UNUSED_EFFECT_23 ; more stadium stuff
+ jr nz, .asm_3f341
+ ld a, [wUnknownSerialFlag_d499]
+ and a
+ ld a, FREEZE_SIDE_EFFECT
+ ld b, $4d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
+ jr z, .next2
+ ld b, $1a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
+ jr .next2
+.asm_3f341
+ cp a, PARALYZE_SIDE_EFFECT1 + 1
+ ld b, $1a
+ jr c, .next2
+ ld b, $4d
+ sub $1e
+.next2
+ push af
+ call BattleRandom
+ cp b
+ pop bc
+ ret nc
+ ld a, b
+ cp BURN_SIDE_EFFECT1
+ jr z, .burn2
+ cp FREEZE_SIDE_EFFECT
+ jr z, .freeze2
+ ld a, 1 << PAR
+ ld [wBattleMonStatus], a
+ call QuarterSpeedDueToParalysis
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
+ jp PrintMayNotAttackText
+.burn2
+ ld a, 1 << BRN
+ ld [wBattleMonStatus], a
+ call HalveAttackDueToBurn
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
+ ld hl, BurnedText
+ jp PrintText
+.freeze2
+; hyper beam bits aren't reseted for opponent's side
+ ld a, 1 << FRZ
+ ld [wBattleMonStatus], a
+ ld a, ANIM_C7
+ call PlayBattleAnimation2
+ ld hl, FrozenText
+ jp PrintText
+
+BurnedText:
+ text_far _BurnedText
+ text_end
+
+FrozenText:
+ text_far _FrozenText
+ text_end
+
+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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _FireDefrostedText
+ text_end
+
+StatModifierUpEffect:
+ ld hl, wPlayerMonStatMods
+ ld de, wPlayerMoveEffect
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ; check if stat is already 999
+ ld a, [hld]
+ sub LOW(MAX_STAT_VALUE)
+ jr nz, .recalculateStat
+ ld a, [hl]
+ sbc HIGH(MAX_STAT_VALUE)
+ 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
+ ldh [hMultiplicand], a
+ ld a, [de]
+ ldh [hMultiplicand + 1], a
+ inc de
+ ld a, [de]
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, [hl]
+ ldh [hDivisor], a
+ ld b, $4
+ call Divide
+ pop hl
+; cap at MAX_STAT_VALUE (999)
+ ldh a, [hProduct + 3]
+ sub LOW(MAX_STAT_VALUE)
+ ldh a, [hProduct + 2]
+ sbc HIGH(MAX_STAT_VALUE)
+ jp c, UpdateStat
+ ld a, HIGH(MAX_STAT_VALUE)
+ ldh [hMultiplicand + 1], a
+ ld a, LOW(MAX_STAT_VALUE)
+ ldh [hMultiplicand + 2], a
+
+UpdateStat:
+ ldh a, [hProduct + 2]
+ ld [hli], a
+ ldh a, [hProduct + 3]
+ ld [hl], a
+ pop hl
+UpdateStatDone:
+ ld b, c
+ inc b
+ call PrintStatText
+ ld hl, wPlayerBattleStatus2
+ ld de, wPlayerMoveNum
+ ld bc, wPlayerMonMinimized
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .playerTurn
+ ld hl, wEnemyBattleStatus2
+ ld de, wEnemyMoveNum
+ ld bc, wEnemyMonMinimized
+.playerTurn
+ ld a, [de]
+ cp MINIMIZE
+ jr nz, .notMinimize
+ ; 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
+ push de
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ pop de
+.notMinimize
+ 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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _MonsStatsRoseText
+ text_asm
+ ld hl, GreatlyRoseText
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .playerTurn
+ ld a, [wEnemyMoveEffect]
+.playerTurn
+ cp ATTACK_DOWN1_EFFECT
+ ret nc
+ ld hl, RoseText
+ ret
+
+GreatlyRoseText:
+ text_pause
+ text_far _GreatlyRoseText
+; fallthrough
+RoseText:
+ text_far _RoseText
+ text_end
+
+StatModifierDownEffect:
+ ld hl, wEnemyMonStatMods
+ ld de, wPlayerMoveEffect
+ ld bc, wEnemyBattleStatus1
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh [hMultiplicand], a
+ ld a, [de]
+ ldh [hMultiplicand + 1], a
+ inc de
+ ld a, [de]
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, [hl]
+ ldh [hDivisor], a
+ ld b, $4
+ call Divide
+ pop hl
+ ldh a, [hProduct + 3]
+ ld b, a
+ ldh a, [hProduct + 2]
+ or b
+ jp nz, UpdateLoweredStat
+ ldh [hMultiplicand + 1], a
+ ld a, $1
+ ldh [hMultiplicand + 2], a
+
+UpdateLoweredStat:
+ ldh a, [hProduct + 2]
+ ld [hli], a
+ ldh a, [hProduct + 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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _MonsStatsFellText
+ text_asm
+ ld hl, FellText
+ ldh a, [hWhoseTurn]
+ 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:
+ text_pause
+ text_far _GreatlyFellText
+; fallthrough
+FellText:
+ text_far _FellText
+ text_end
+
+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
+
+INCLUDE "data/battle/stat_names.asm"
+
+INCLUDE "data/battle/stat_modifiers.asm"
+
+BideEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerBideAccumulatedDamage
+ ld bc, wPlayerNumAttacksLeft
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ add XSTATITEM_ANIM
+ jp PlayBattleAnimation2
+
+ThrashPetalDanceEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ add ANIM_B0
+ jp PlayBattleAnimation2
+
+SwitchAndTeleportEffect:
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _RanFromBattleText
+ text_end
+
+RanAwayScaredText:
+ text_far _RanAwayScaredText
+ text_end
+
+WasBlownAwayText:
+ text_far _WasBlownAwayText
+ text_end
+
+TwoToFiveAttacksEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ld bc, wPlayerNumHits
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .flinchSideEffect
+ ld hl, wPlayerBattleStatus1
+ ld de, wEnemyMoveEffect
+.flinchSideEffect
+ ld a, [wLinkState]
+ cp LINK_STATE_BATTLING
+ call z, ClearHyperBeam
+ 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:
+ jpfar OneHitKOEffect_
+
+ChargeEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerMoveEffect
+ ldh a, [hWhoseTurn]
+ 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
+ push de
+ push bc
+ inc hl ; battle status 2
+ push hl
+ ld a, [hl]
+ bit HAS_SUBSTITUTE_UP, a
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ pop hl
+ pop bc
+ xor a
+ ld [wAnimationType], a
+ ld a, b
+ call PlayBattleAnimation
+ ld a, [hl]
+ bit HAS_SUBSTITUTE_UP, a
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ call nz, Bankswitch
+ pop de
+ ld a, [de]
+ ld [wChargeMoveNum], a
+ ld hl, ChargeMoveEffectText
+ jp PrintText
+
+ChargeMoveEffectText:
+ text_far _ChargeMoveEffectText
+ text_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:
+ text_far _MadeWhirlwindText
+ text_end
+
+TookInSunlightText:
+ text_far _TookInSunlightText
+ text_end
+
+LoweredItsHeadText:
+ text_far _LoweredItsHeadText
+ text_end
+
+SkyAttackGlowingText:
+ text_far _SkyAttackGlowingText
+ text_end
+
+FlewUpHighText:
+ text_far _FlewUpHighText
+ text_end
+
+DugAHoleText:
+ text_far _DugAHoleText
+ text_end
+
+TrappingEffect:
+ ld hl, wPlayerBattleStatus1
+ ld de, wPlayerNumAttacksLeft
+ ldh a, [hWhoseTurn]
+ 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:
+ jpfar MistEffect_
+
+FocusEnergyEffect:
+ jpfar FocusEnergyEffect_
+
+RecoilEffect:
+ jpfar 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:
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _BecameConfusedText
+ text_end
+
+ConfusionEffectFailed:
+ cp CONFUSION_SIDE_EFFECT
+ ret z
+ ld c, 50
+ call DelayFrames
+ jp ConditionalPrintButItFailed
+
+ParalyzeEffect:
+ jpfar ParalyzeEffect_
+
+SubstituteEffect:
+ jpfar SubstituteEffect_
+
+HyperBeamEffect:
+ ld hl, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _MimicLearnedMoveText
+ text_end
+
+LeechSeedEffect:
+ jpfar LeechSeedEffect_
+
+SplashEffect:
+ call PlayCurrentMoveAnimation
+ jp PrintNoEffectText
+
+DisableEffect:
+ call MoveHitTest
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .moveMissed
+ ld de, wEnemyDisabledMove
+ ld hl, wEnemyMonMoves
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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:
+ text_far _MoveWasDisabledText
+ text_end
+
+PayDayEffect:
+ jpfar PayDayEffect_
+
+ConversionEffect:
+ jpfar ConversionEffect_
+
+HazeEffect:
+ jpfar HazeEffect_
+
+HealEffect:
+ jpfar HealEffect_
+
+TransformEffect:
+ jpfar TransformEffect_
+
+ReflectLightScreenEffect:
+ jpfar ReflectLightScreenEffect_
+
+NothingHappenedText:
+ text_far _NothingHappenedText
+ text_end
+
+PrintNoEffectText:
+ ld hl, NoEffectText
+ jp PrintText
+
+NoEffectText:
+ text_far _NoEffectText
+ text_end
+
+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:
+ text_far _ButItFailedText
+ text_end
+
+PrintDidntAffectText:
+ ld hl, DidntAffectText
+ jp PrintText
+
+DidntAffectText:
+ text_far _DidntAffectText
+ text_end
+
+IsUnaffectedText:
+ text_far _IsUnaffectedText
+ text_end
+
+PrintMayNotAttackText:
+ ld hl, ParalyzedMayNotAttackText
+ jp PrintText
+
+ParalyzedMayNotAttackText:
+ text_far _ParalyzedMayNotAttackText
+ text_end
+
+CheckTargetSubstitute:
+ push hl
+ ld hl, wEnemyBattleStatus2
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ ldh a, [hWhoseTurn]
+ 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
+ callfar Func_78e98
+ pop bc
+ pop de
+ pop hl
+ ret
diff --git a/engine/battle/end_of_battle.asm b/engine/battle/end_of_battle.asm
index 5c0c3991..e64f54e7 100755
--- a/engine/battle/end_of_battle.asm
+++ b/engine/battle/end_of_battle.asm
@@ -12,7 +12,7 @@ EndOfBattle:
call ClearScreen
ld b, SET_PAL_OVERWORLD
call RunPaletteCommand
- callab DisplayLinkBattleVersusTextBox
+ callfar DisplayLinkBattleVersusTextBox
ld a, [wBattleResult]
cp $1
ld de, YouWinText
@@ -21,7 +21,7 @@ EndOfBattle:
jr z, .placeWinOrLoseString
ld de, DrawText
.placeWinOrLoseString
- coord hl, 6, 8
+ hlcoord 6, 8
call PlaceString
ld c, 200
call DelayFrames
@@ -46,7 +46,7 @@ EndOfBattle:
ld [wForceEvolution], a
predef EvolutionAfterBattle
ld d, $82
- callab UpdatePikachuMoodAfterBattle
+ callfar UpdatePikachuMoodAfterBattle
.resetVariables
xor a
ld [wLowHealthAlarm], a ;disable low health alarm
@@ -88,5 +88,5 @@ DrawText:
db " DRAW@"
PickUpPayDayMoneyText:
- TX_FAR _PickUpPayDayMoneyText
- db "@"
+ text_far _PickUpPayDayMoneyText
+ text_end
diff --git a/engine/battle/experience.asm b/engine/battle/experience.asm
index 722685c2..bab804bb 100644
--- a/engine/battle/experience.asm
+++ b/engine/battle/experience.asm
@@ -55,15 +55,15 @@ GainExperience:
jr .gainStatExpLoop
.statExpDone
xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
+ ldh [hMultiplicand], a
+ ldh [hMultiplicand + 1], a
ld a, [wEnemyMonBaseExp]
- ld [H_MULTIPLICAND + 2], a
+ ldh [hMultiplicand + 2], a
ld a, [wEnemyMonLevel]
- ld [H_MULTIPLIER], a
+ ldh [hMultiplier], a
call Multiply
ld a, 7
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, 4
call Divide
ld hl, wPartyMon1OTID - (wPartyMon1DVs - 1)
@@ -91,12 +91,12 @@ GainExperience:
inc hl
; add the gained exp to the party mon's exp
ld b, [hl]
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld [wExpAmountGained + 1], a
add b
ld [hld], a
ld b, [hl]
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld [wExpAmountGained], a
adc b
ld [hl], a
@@ -117,13 +117,13 @@ GainExperience:
ld [wd0b5], a
call GetMonHeader
ld d, MAX_LEVEL
- callab CalcExperience ; get max exp
+ callfar CalcExperience ; get max exp
; compare max exp with current exp
- ld a, [hExperience]
+ ldh a, [hExperience]
ld b, a
- ld a, [hExperience + 1]
+ ldh a, [hExperience + 1]
ld c, a
- ld a, [hExperience + 2]
+ ldh a, [hExperience + 2]
ld d, a
pop hl
ld a, [hld]
@@ -155,7 +155,7 @@ GainExperience:
ld bc, wPartyMon1Level - wPartyMon1Exp
add hl, bc
push hl
- callba CalcLevelFromExperience
+ farcall CalcLevelFromExperience
pop hl
ld a, [hl] ; current level
cp d
@@ -252,7 +252,7 @@ GainExperience:
ld [wMonDataLocation], a
call LoadMonData
ld d, $1
- callab PrintStatsBox
+ callfar PrintStatsBox
call WaitForTextScrollButtonPress
call LoadScreenTilesFromBuffer1
xor a ; PLAYER_PARTY_DATA
@@ -317,14 +317,14 @@ DivideExpDataByNumMonsGainingExp:
ld c, wEnemyMonBaseExp + 1 - wEnemyMonBaseStats
.divideLoop
xor a
- ld [H_DIVIDEND], a
+ ldh [hDividend], a
ld a, [hl]
- ld [H_DIVIDEND + 1], a
+ ldh [hDividend + 1], a
ld a, [wd11e]
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $2
call Divide ; divide value by number of mons gaining exp
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld [hli], a
dec c
jr nz, .divideLoop
@@ -332,17 +332,17 @@ DivideExpDataByNumMonsGainingExp:
; multiplies exp by 1.5
BoostExp:
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld b, a
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld c, a
srl b
rr c
add c
- ld [H_QUOTIENT + 3], a
- ld a, [H_QUOTIENT + 2]
+ ldh [hQuotient + 3], a
+ ldh a, [hQuotient + 2]
adc b
- ld [H_QUOTIENT + 2], a
+ ldh [hQuotient + 2], a
ret
Bankswitch15ToF:
@@ -350,8 +350,8 @@ Bankswitch15ToF:
jp Bankswitch
GainedText:
- TX_FAR _GainedText
- TX_ASM
+ text_far _GainedText
+ text_asm
ld a, [wBoostExpByExpAll]
ld hl, WithExpAllText
and a
@@ -364,19 +364,19 @@ GainedText:
ret
WithExpAllText:
- TX_FAR _WithExpAllText
- TX_ASM
+ text_far _WithExpAllText
+ text_asm
ld hl, ExpPointsText
ret
BoostedText:
- TX_FAR _BoostedText
+ text_far _BoostedText
ExpPointsText:
- TX_FAR _ExpPointsText
- db "@"
+ text_far _ExpPointsText
+ text_end
GrewLevelText:
- TX_FAR _GrewLevelText
- TX_SFX_LEVEL_UP
- db "@"
+ text_far _GrewLevelText
+ sound_level_up
+ text_end
diff --git a/engine/battle/get_trainer_name.asm b/engine/battle/get_trainer_name.asm
index 36ca019e..b2daebfe 100644
--- a/engine/battle/get_trainer_name.asm
+++ b/engine/battle/get_trainer_name.asm
@@ -1,15 +1,15 @@
-GetTrainerName_:
+GetTrainerName_::
ld hl, wGrassRate
ld a, [wLinkState]
and a
jr nz, .foundName
ld hl, wRivalName
ld a, [wTrainerClass]
- cp SONY1
+ cp RIVAL1
jr z, .foundName
- cp SONY2
+ cp RIVAL2
jr z, .foundName
- cp SONY3
+ cp RIVAL3
jr z, .foundName
ld [wd0b5], a
ld a, TRAINER_NAME
diff --git a/engine/battle/ghost_marowak_anim.asm b/engine/battle/ghost_marowak_anim.asm
index 972d5bf5..03059022 100644
--- a/engine/battle/ghost_marowak_anim.asm
+++ b/engine/battle/ghost_marowak_anim.asm
@@ -1,22 +1,22 @@
MarowakAnim:
; animate the ghost being unveiled as a Marowak
ld a, $e4
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
call CopyMonPicFromBGToSpriteVRAM ; cover the BG ghost pic with a sprite ghost pic that looks the same
; now that the ghost pic is being displayed using sprites, clear the ghost pic from the BG tilemap
- coord hl, 12, 0
+ hlcoord 12, 0
lb bc, 7, 7
call ClearScreenArea
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; disable BG transfer so we don't see the Marowak too soon
+ ldh [hAutoBGTransferEnabled], a ; disable BG transfer so we don't see the Marowak too soon
; replace ghost pic with Marowak in BG
ld a, RESTLESS_SOUL
ld [wChangeMonPicEnemyTurnSpecies], a
ld a, $1
- ld [H_WHOSETURN], a
- callab ChangeMonPic
+ ldh [hWhoseTurn], a
+ callfar ChangeMonPic
; alternate between black and light grey 8 times.
; this makes the ghost's body appear to flash
ld d, $80
@@ -24,10 +24,10 @@ MarowakAnim:
.fadeOutGhostLoop
ld c, 10
call DelayFrames
- ld a, [rOBP1]
+ ldh a, [rOBP1]
sla a
sla a
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
jr nz, .fadeOutGhostLoop
call ClearSprites
@@ -36,18 +36,18 @@ MarowakAnim:
.fadeInMarowakLoop
ld c, 10
call DelayFrames
- ld a, [rOBP1]
+ ldh a, [rOBP1]
srl b
rra
srl b
rra
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
ld a, b
and a
jr nz, .fadeInMarowakLoop
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a ; enable BG transfer so the BG Marowak pic will be visible after the sprite one is cleared
+ ldh [hAutoBGTransferEnabled], a ; enable BG transfer so the BG Marowak pic will be visible after the sprite one is cleared
call Delay3
jp ClearSprites
diff --git a/engine/battle/init_battle_variables.asm b/engine/battle/init_battle_variables.asm
index 7bc912d2..0d403b55 100644
--- a/engine/battle/init_battle_variables.asm
+++ b/engine/battle/init_battle_variables.asm
@@ -1,5 +1,5 @@
InitBattleVariables:
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
ld [wSavedTilesetType], a
xor a
ld [wActionResultOrTookBattleTurn], a
@@ -35,4 +35,4 @@ InitBattleVariables:
ld a, BATTLE_TYPE_SAFARI
ld [wBattleType], a
.notSafariBattle
- jpab PlayBattleMusic
+ jpfar PlayBattleMusic
diff --git a/engine/battle/link_battle_versus_text.asm b/engine/battle/link_battle_versus_text.asm
index 63142ba6..e55a0672 100644
--- a/engine/battle/link_battle_versus_text.asm
+++ b/engine/battle/link_battle_versus_text.asm
@@ -1,22 +1,22 @@
; display "[player] VS [enemy]" text box with pokeballs representing their parties next to the names
DisplayLinkBattleVersusTextBox:
call LoadTextBoxTilePatterns
- coord hl, 3, 4
+ hlcoord 3, 4
lb bc, 7, 12
call TextBoxBorder
- coord hl, 4, 5
+ hlcoord 4, 5
ld de, wPlayerName
call PlaceString
- coord hl, 4, 10
+ hlcoord 4, 10
ld de, wLinkEnemyTrainerName
call PlaceString
; place bold "VS" tiles between the names
- coord hl, 9, 8
+ hlcoord 9, 8
ld a, $69
ld [hli], a
ld [hl], $6a
xor a
ld [wUpdateSpritesEnabled], a
- callab SetupPlayerAndEnemyPokeballs
+ callfar SetupPlayerAndEnemyPokeballs
ld c, 150
jp DelayFrames
diff --git a/engine/battle/bank_e_misc.asm b/engine/battle/misc.asm
index df9145f2..df9145f2 100755
--- a/engine/battle/bank_e_misc.asm
+++ b/engine/battle/misc.asm
diff --git a/engine/battle/moveEffects/conversion_effect.asm b/engine/battle/moveEffects/conversion_effect.asm
deleted file mode 100644
index f23c3d70..00000000
--- a/engine/battle/moveEffects/conversion_effect.asm
+++ /dev/null
@@ -1,35 +0,0 @@
-ConversionEffect_:
- ld hl, wEnemyMonType1
- ld de, wBattleMonType1
- ld a, [H_WHOSETURN]
- and a
- ld a, [wEnemyBattleStatus1]
- jr z, .conversionEffect
- push hl
- ld h, d
- ld l, e
- pop de
- ld a, [wPlayerBattleStatus1]
-.conversionEffect
- bit INVULNERABLE, a ; is mon immune to typical attacks (dig/fly)
- jr nz, PrintButItFailedText
-; copy target's types to user
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hl]
- ld [de], a
- ld hl, PlayCurrentMoveAnimation
- call CallBankF
- ld hl, ConvertedTypeText
- jp PrintText
-
-ConvertedTypeText:
- TX_FAR _ConvertedTypeText
- db "@"
-
-PrintButItFailedText:
- ld hl, PrintButItFailedText_
-CallBankF:
- ld b, BANK(PrintButItFailedText_)
- jp Bankswitch
diff --git a/engine/battle/moveEffects/drain_hp_effect.asm b/engine/battle/moveEffects/drain_hp_effect.asm
deleted file mode 100644
index e5f4681a..00000000
--- a/engine/battle/moveEffects/drain_hp_effect.asm
+++ /dev/null
@@ -1,104 +0,0 @@
-DrainHPEffect_:
- ld hl, wDamage
- ld a, [hl]
- srl a ; divide damage by 2
- ld [hli], a
- ld a, [hl]
- rr a
- ld [hld], a
- or [hl] ; is damage 0?
- jr nz, .getAttackerHP
-; if damage is 0, increase to 1 so that the attacker gains at least 1 HP
- inc hl
- inc [hl]
-.getAttackerHP
- ld hl, wBattleMonHP
- ld de, wBattleMonMaxHP
- ld a, [H_WHOSETURN]
- and a
- jp z, .addDamageToAttackerHP
- ld hl, wEnemyMonHP
- ld de, wEnemyMonMaxHP
-.addDamageToAttackerHP
- ld bc, wHPBarOldHP+1
-; copy current HP to wHPBarOldHP
- ld a, [hli]
- ld [bc], a
- ld a, [hl]
- dec bc
- ld [bc], a
-; copy max HP to wHPBarMaxHP
- ld a, [de]
- dec bc
- ld [bc], a
- inc de
- ld a, [de]
- dec bc
- ld [bc], a
-; add damage to attacker's HP and copy new HP to wHPBarNewHP
- ld a, [wDamage + 1]
- ld b, [hl]
- add b
- ld [hld], a
- ld [wHPBarNewHP], a
- ld a, [wDamage]
- ld b, [hl]
- adc b
- ld [hli], a
- ld [wHPBarNewHP+1], a
- jr c, .capToMaxHP ; if HP > 65,535, cap to max HP
-; compare HP with max HP
- ld a, [hld]
- ld b, a
- ld a, [de]
- dec de
- sub b
- ld a, [hli]
- ld b, a
- ld a, [de]
- inc de
- sbc b
- jr nc, .next
-.capToMaxHP
- ld a, [de]
- ld [hld], a
- ld [wHPBarNewHP], a
- dec de
- ld a, [de]
- ld [hli], a
- ld [wHPBarNewHP+1], a
- inc de
-.next
- ld a, [H_WHOSETURN]
- and a
- coord hl, 10, 9
- ld a, $1
- jr z, .next2
- coord hl, 2, 2
- xor a
-.next2
- ld [wHPBarType], a
- predef UpdateHPBar2
- predef DrawPlayerHUDAndHPBar
- predef DrawEnemyHUDAndHPBar
- callab ReadPlayerMonCurHPAndStatus
- ld hl, SuckedHealthText
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveEffect]
- jr z, .next3
- ld a, [wEnemyMoveEffect]
-.next3
- cp DREAM_EATER_EFFECT
- jr nz, .printText
- ld hl, DreamWasEatenText
-.printText
- jp PrintText
-
-SuckedHealthText:
- TX_FAR _SuckedHealthText
- db "@"
-
-DreamWasEatenText:
- TX_FAR _DreamWasEatenText
- db "@"
diff --git a/engine/battle/moveEffects/focus_energy_effect.asm b/engine/battle/moveEffects/focus_energy_effect.asm
deleted file mode 100644
index 16dad7bb..00000000
--- a/engine/battle/moveEffects/focus_energy_effect.asm
+++ /dev/null
@@ -1,22 +0,0 @@
-FocusEnergyEffect_:
- ld hl, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .notEnemy
- ld hl, wEnemyBattleStatus2
-.notEnemy
- bit GETTING_PUMPED, [hl] ; is mon already using focus energy?
- jr nz, .alreadyUsing
- set GETTING_PUMPED, [hl] ; mon is now using focus energy
- callab PlayCurrentMoveAnimation
- ld hl, GettingPumpedText
- jp PrintText
-.alreadyUsing
- ld c, 50
- call DelayFrames
- jpab PrintButItFailedText_
-
-GettingPumpedText:
- TX_DELAY
- TX_FAR _GettingPumpedText
- db "@"
diff --git a/engine/battle/moveEffects/haze_effect.asm b/engine/battle/moveEffects/haze_effect.asm
deleted file mode 100644
index 47723ba2..00000000
--- a/engine/battle/moveEffects/haze_effect.asm
+++ /dev/null
@@ -1,81 +0,0 @@
-HazeEffect_:
- ld a, $7
-; store 7 on every stat mod
- ld hl, wPlayerMonAttackMod
- call ResetStatMods
- ld hl, wEnemyMonAttackMod
- call ResetStatMods
-; copy unmodified stats to battle stats
- ld hl, wPlayerMonUnmodifiedAttack
- ld de, wBattleMonAttack
- call ResetStats
- ld hl, wEnemyMonUnmodifiedAttack
- ld de, wEnemyMonAttack
- call ResetStats
-; cure non-volatile status, but only for the target
- ld hl, wEnemyMonStatus
- ld de, wEnemySelectedMove
- ld a, [H_WHOSETURN]
- and a
- jr z, .cureStatuses
- ld hl, wBattleMonStatus
- dec de ; wPlayerSelectedMove
-
-.cureStatuses
- ld a, [hl]
- ld [hl], $0
- and SLP | (1 << FRZ)
- jr z, .cureVolatileStatuses
-; prevent the Pokemon from executing a move if it was asleep or frozen
- ld a, $ff
- ld [de], a
-
-.cureVolatileStatuses
- xor a
- ld [wPlayerDisabledMove], a
- ld [wEnemyDisabledMove], a
- ld hl, wPlayerDisabledMoveNumber
- ld [hli], a
- ld [hl], a
- ld hl, wPlayerBattleStatus1
- call CureVolatileStatuses
- ld hl, wEnemyBattleStatus1
- call CureVolatileStatuses
- ld hl, PlayCurrentMoveAnimation
- call CallBankF
- ld hl, StatusChangesEliminatedText
- jp PrintText
-
-CureVolatileStatuses:
- res CONFUSED, [hl]
- inc hl ; BATTSTATUS2
- ld a, [hl]
- ; clear USING_X_ACCURACY, PROTECTED_BY_MIST, GETTING_PUMPED, and SEEDED statuses
- and $ff ^((1 << USING_X_ACCURACY) | (1 << PROTECTED_BY_MIST) | (1 << GETTING_PUMPED) | (1 << SEEDED))
- ld [hli], a ; BATTSTATUS3
- ld a, [hl]
- and %11110000 | (1 << TRANSFORMED) ; clear Bad Poison, Reflect and Light Screen statuses
- ld [hl], a
- ret
-
-ResetStatMods:
- ld b, $8
-.loop
- ld [hli], a
- dec b
- jr nz, .loop
- ret
-
-ResetStats:
- ld b, $8
-.loop
- ld a, [hli]
- ld [de], a
- inc de
- dec b
- jr nz, .loop
- ret
-
-StatusChangesEliminatedText:
- TX_FAR _StatusChangesEliminatedText
- db "@"
diff --git a/engine/battle/moveEffects/heal_effect.asm b/engine/battle/moveEffects/heal_effect.asm
deleted file mode 100644
index 97afa394..00000000
--- a/engine/battle/moveEffects/heal_effect.asm
+++ /dev/null
@@ -1,120 +0,0 @@
-HealEffect_:
- ld a, [H_WHOSETURN]
- and a
- ld de, wBattleMonHP
- ld hl, wBattleMonMaxHP
- ld a, [wPlayerMoveNum]
- jr z, .healEffect
- ld de, wEnemyMonHP
- ld hl, wEnemyMonMaxHP
- ld a, [wEnemyMoveNum]
-.healEffect
- ld b, a
- ld a, [de]
- cp [hl] ; most significant bytes comparison is ignored
- ; causes the move to miss if max HP is 255 or 511 points higher than the current HP
- inc de
- inc hl
- ld a, [de]
- sbc [hl]
- jp z, .failed ; no effect if user's HP is already at its maximum
- ld a, b
- cp REST
- jr nz, .healHP
- push hl
- push de
- push af
- ld c, 50
- call DelayFrames
- ld hl, wBattleMonStatus
- ld a, [H_WHOSETURN]
- and a
- jr z, .restEffect
- ld hl, wEnemyMonStatus
-.restEffect
- ld a, [hl]
- and a
- ld [hl], 2 ; clear status and set number of turns asleep to 2
- ld hl, StartedSleepingEffect ; if mon didn't have an status
- jr z, .printRestText
- ld hl, FellAsleepBecameHealthyText ; if mon had an status
-.printRestText
- call PrintText
- pop af
- pop de
- pop hl
-.healHP
- ld a, [hld]
- ld [wHPBarMaxHP], a
- ld c, a
- ld a, [hl]
- ld [wHPBarMaxHP+1], a
- ld b, a
- jr z, .gotHPAmountToHeal
-; Recover and Softboiled only heal for half the mon's max HP
- srl b
- rr c
-.gotHPAmountToHeal
-; update HP
- ld a, [de]
- ld [wHPBarOldHP], a
- add c
- ld [de], a
- ld [wHPBarNewHP], a
- dec de
- ld a, [de]
- ld [wHPBarOldHP+1], a
- adc b
- ld [de], a
- ld [wHPBarNewHP+1], a
- inc hl
- inc de
- ld a, [de]
- dec de
- sub [hl]
- dec hl
- ld a, [de]
- sbc [hl]
- jr c, .playAnim
-; copy max HP to current HP if an overflow occurred
- ld a, [hli]
- ld [de], a
- ld [wHPBarNewHP+1], a
- inc de
- ld a, [hl]
- ld [de], a
- ld [wHPBarNewHP], a
-.playAnim
- ld hl, PlayCurrentMoveAnimation
- call Bankswitch3DtoF
- ld a, [H_WHOSETURN]
- and a
- coord hl, 10, 9
- ld a, $1
- jr z, .updateHPBar
- coord hl, 2, 2
- xor a
-.updateHPBar
- ld [wHPBarType], a
- predef UpdateHPBar2
- ld hl, DrawHUDsAndHPBars
- call Bankswitch3DtoF
- ld hl, RegainedHealthText
- jp PrintText
-.failed
- ld c, 50
- call DelayFrames
- ld hl, PrintButItFailedText_
- jp Bankswitch3DtoF
-
-StartedSleepingEffect:
- TX_FAR _StartedSleepingEffect
- db "@"
-
-FellAsleepBecameHealthyText:
- TX_FAR _FellAsleepBecameHealthyText
- db "@"
-
-RegainedHealthText:
- TX_FAR _RegainedHealthText
- db "@"
diff --git a/engine/battle/moveEffects/leech_seed_effect.asm b/engine/battle/moveEffects/leech_seed_effect.asm
deleted file mode 100644
index f4d3ee9c..00000000
--- a/engine/battle/moveEffects/leech_seed_effect.asm
+++ /dev/null
@@ -1,40 +0,0 @@
-LeechSeedEffect_:
- callab MoveHitTest
- ld a, [wMoveMissed]
- and a
- jr nz, .moveMissed
- ld hl, wEnemyBattleStatus2
- ld de, wEnemyMonType1
- ld a, [H_WHOSETURN]
- and a
- jr z, .leechSeedEffect
- ld hl, wPlayerBattleStatus2
- ld de, wBattleMonType1
-.leechSeedEffect
-; miss if the target is grass-type or already seeded
- ld a, [de]
- cp GRASS
- jr z, .moveMissed
- inc de
- ld a, [de]
- cp GRASS
- jr z, .moveMissed
- bit SEEDED, [hl]
- jr nz, .moveMissed
- set SEEDED, [hl]
- callab PlayCurrentMoveAnimation
- ld hl, WasSeededText
- jp PrintText
-.moveMissed
- ld c, 50
- call DelayFrames
- ld hl, EvadedAttackText
- jp PrintText
-
-WasSeededText:
- TX_FAR _WasSeededText
- db "@"
-
-EvadedAttackText:
- TX_FAR _EvadedAttackText
- db "@"
diff --git a/engine/battle/moveEffects/mist_effect.asm b/engine/battle/moveEffects/mist_effect.asm
deleted file mode 100644
index 65070a3e..00000000
--- a/engine/battle/moveEffects/mist_effect.asm
+++ /dev/null
@@ -1,19 +0,0 @@
-MistEffect_:
- ld hl, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .mistEffect
- ld hl, wEnemyBattleStatus2
-.mistEffect
- bit PROTECTED_BY_MIST, [hl] ; is mon protected by mist?
- jr nz, .mistAlreadyInUse
- set PROTECTED_BY_MIST, [hl] ; mon is now protected by mist
- callab PlayCurrentMoveAnimation
- ld hl, ShroudedInMistText
- jp PrintText
-.mistAlreadyInUse
- jpab PrintButItFailedText_
-
-ShroudedInMistText:
- TX_FAR _ShroudedInMistText
- db "@"
diff --git a/engine/battle/moveEffects/one_hit_ko_effect.asm b/engine/battle/moveEffects/one_hit_ko_effect.asm
deleted file mode 100644
index 827e2197..00000000
--- a/engine/battle/moveEffects/one_hit_ko_effect.asm
+++ /dev/null
@@ -1,38 +0,0 @@
-OneHitKOEffect_:
- ld hl, wDamage
- xor a
- ld [hli], a
- ld [hl], a ; set the damage output to zero
- dec a
- ld [wCriticalHitOrOHKO], a
- ld hl, wBattleMonSpeed + 1
- ld de, wEnemyMonSpeed + 1
- ld a, [H_WHOSETURN]
- and a
- jr z, .compareSpeed
- ld hl, wEnemyMonSpeed + 1
- ld de, wBattleMonSpeed + 1
-.compareSpeed
-; set damage to 65535 and OHKO flag is the user's current speed is higher than the target's
- ld a, [de]
- dec de
- ld b, a
- ld a, [hld]
- sub b
- ld a, [de]
- ld b, a
- ld a, [hl]
- sbc b
- jr c, .userIsSlower
- ld hl, wDamage
- ld a, $ff
- ld [hli], a
- ld [hl], a
- ld a, $2
- ld [wCriticalHitOrOHKO], a
- ret
-.userIsSlower
-; keep damage at 0 and set move missed flag if target's current speed is higher instead
- ld a, $1
- ld [wMoveMissed], a
- ret
diff --git a/engine/battle/moveEffects/paralyze_effect.asm b/engine/battle/moveEffects/paralyze_effect.asm
deleted file mode 100644
index 95979ae6..00000000
--- a/engine/battle/moveEffects/paralyze_effect.asm
+++ /dev/null
@@ -1,47 +0,0 @@
-ParalyzeEffect_:
- ld hl, wEnemyMonStatus
- ld de, wPlayerMoveType
- ld a, [H_WHOSETURN]
- and a
- jp z, .next
- ld hl, wBattleMonStatus
- ld de, wEnemyMoveType
-.next
- ld a, [hl]
- and a ; does the target already have a status ailment?
- jr nz, .didntAffect
-; check if the target is immune due to types
- ld a, [de]
- cp ELECTRIC
- jr nz, .hitTest
- ld b, h
- ld c, l
- inc bc
- ld a, [bc]
- cp GROUND
- jr z, .doesntAffect
- inc bc
- ld a, [bc]
- cp GROUND
- jr z, .doesntAffect
-.hitTest
- push hl
- callab MoveHitTest
- pop hl
- ld a, [wMoveMissed]
- and a
- jr nz, .didntAffect
- set PAR, [hl]
- callab QuarterSpeedDueToParalysis
- ld c, 30
- call DelayFrames
- callab PlayCurrentMoveAnimation
- jpab PrintMayNotAttackText
-.didntAffect
- ld c, 50
- call DelayFrames
- jpab PrintDidntAffectText
-.doesntAffect
- ld c, 50
- call DelayFrames
- jpab PrintDoesntAffectText
diff --git a/engine/battle/moveEffects/pay_day_effect.asm b/engine/battle/moveEffects/pay_day_effect.asm
deleted file mode 100644
index e5daf014..00000000
--- a/engine/battle/moveEffects/pay_day_effect.asm
+++ /dev/null
@@ -1,45 +0,0 @@
-PayDayEffect_:
- xor a
- ld hl, wcd6d
- ld [hli], a
- ld a, [H_WHOSETURN]
- and a
- ld a, [wBattleMonLevel]
- jr z, .payDayEffect
- ld a, [wEnemyMonLevel]
-.payDayEffect
-; level * 2
- add a
- ld [H_DIVIDEND + 3], a
- xor a
- ld [H_DIVIDEND], a
- ld [H_DIVIDEND + 1], a
- ld [H_DIVIDEND + 2], a
-; convert to BCD
- ld a, 100
- ld [H_DIVISOR], a
- ld b, $4
- call Divide
- ld a, [H_QUOTIENT + 3]
- ld [hli], a
- ld a, [H_REMAINDER]
- ld [H_DIVIDEND + 3], a
- ld a, 10
- ld [H_DIVISOR], a
- ld b, $4
- call Divide
- ld a, [H_QUOTIENT + 3]
- swap a
- ld b, a
- ld a, [H_REMAINDER]
- add b
- ld [hl], a
- ld de, wTotalPayDayMoney + 2
- ld c, $3
- predef AddBCDPredef
- ld hl, CoinsScatteredText
- jp PrintText
-
-CoinsScatteredText:
- TX_FAR _CoinsScatteredText
- db "@"
diff --git a/engine/battle/moveEffects/recoil_effect.asm b/engine/battle/moveEffects/recoil_effect.asm
deleted file mode 100644
index 0f2f087b..00000000
--- a/engine/battle/moveEffects/recoil_effect.asm
+++ /dev/null
@@ -1,70 +0,0 @@
-RecoilEffect_:
- ld a, [H_WHOSETURN]
- and a
- ld a, [wPlayerMoveNum]
- ld hl, wBattleMonMaxHP
- jr z, .recoilEffect
- ld a, [wEnemyMoveNum]
- ld hl, wEnemyMonMaxHP
-.recoilEffect
- ld d, a
- ld a, [wDamage]
- ld b, a
- ld a, [wDamage + 1]
- ld c, a
- srl b
- rr c
- ld a, d
- cp STRUGGLE ; struggle deals 50% recoil damage
- jr z, .gotRecoilDamage
- srl b
- rr c
-.gotRecoilDamage
- ld a, b
- or c
- jr nz, .updateHP
- inc c ; minimum recoil damage is 1
-.updateHP
-; subtract HP from user due to the recoil damage
- ld a, [hli]
- ld [wHPBarMaxHP+1], a
- ld a, [hl]
- ld [wHPBarMaxHP], a
- push bc
- ld bc, wBattleMonHP - wBattleMonMaxHP
- add hl, bc
- pop bc
- ld a, [hl]
- 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, .getHPBarCoords
-; if recoil damage is higher than the Pokemon's HP, set its HP to 0
- xor a
- ld [hli], a
- ld [hl], a
- ld hl, wHPBarNewHP
- ld [hli], a
- ld [hl], a
-.getHPBarCoords
- coord hl, 10, 9
- ld a, [H_WHOSETURN]
- and a
- ld a, $1
- jr z, .updateHPBar
- coord hl, 2, 2
- xor a
-.updateHPBar
- ld [wHPBarType], a
- predef UpdateHPBar2
- ld hl, HitWithRecoilText
- jp PrintText
-HitWithRecoilText:
- TX_FAR _HitWithRecoilText
- db "@"
diff --git a/engine/battle/moveEffects/reflect_light_screen_effect.asm b/engine/battle/moveEffects/reflect_light_screen_effect.asm
deleted file mode 100644
index e5748b19..00000000
--- a/engine/battle/moveEffects/reflect_light_screen_effect.asm
+++ /dev/null
@@ -1,45 +0,0 @@
-ReflectLightScreenEffect_:
- ld hl, wPlayerBattleStatus3
- ld de, wPlayerMoveEffect
- ld a, [H_WHOSETURN]
- and a
- jr z, .reflectLightScreenEffect
- ld hl, wEnemyBattleStatus3
- ld de, wEnemyMoveEffect
-.reflectLightScreenEffect
- ld a, [de]
- cp LIGHT_SCREEN_EFFECT
- jr nz, .reflect
- bit HAS_LIGHT_SCREEN_UP, [hl] ; is mon already protected by light screen?
- jr nz, .moveFailed
- set HAS_LIGHT_SCREEN_UP, [hl] ; mon is now protected by light screen
- ld hl, LightScreenProtectedText
- jr .playAnim
-.reflect
- bit HAS_REFLECT_UP, [hl] ; is mon already protected by reflect?
- jr nz, .moveFailed
- set HAS_REFLECT_UP, [hl] ; mon is now protected by reflect
- ld hl, ReflectGainedArmorText
-.playAnim
- push hl
- ld hl, PlayCurrentMoveAnimation
- call Bankswitch3DtoF
- pop hl
- jp PrintText
-.moveFailed
- ld c, 50
- call DelayFrames
- ld hl, PrintButItFailedText_
- jp Bankswitch3DtoF
-
-LightScreenProtectedText:
- TX_FAR _LightScreenProtectedText
- db "@"
-
-ReflectGainedArmorText:
- TX_FAR _ReflectGainedArmorText
- db "@"
-
-Bankswitch3DtoF:
- ld b, BANK(BattleCore)
- jp Bankswitch
diff --git a/engine/battle/moveEffects/substitute_effect.asm b/engine/battle/moveEffects/substitute_effect.asm
deleted file mode 100644
index b5d006fc..00000000
--- a/engine/battle/moveEffects/substitute_effect.asm
+++ /dev/null
@@ -1,77 +0,0 @@
-SubstituteEffect_:
- ld c, 50
- call DelayFrames
- ld hl, wBattleMonMaxHP
- ld de, wPlayerSubstituteHP
- ld bc, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .notEnemy
- ld hl, wEnemyMonMaxHP
- ld de, wEnemySubstituteHP
- ld bc, wEnemyBattleStatus2
-.notEnemy
- ld a, [bc]
- bit HAS_SUBSTITUTE_UP, a ; user already has substitute?
- jr nz, .alreadyHasSubstitute
-; quarter health to remove from user
-; assumes max HP is 1023 or lower
- push bc
- ld a, [hli]
- ld b, [hl]
- srl a
- rr b
- srl a
- rr b ; max hp / 4
- push de
- ld de, wBattleMonHP - wBattleMonMaxHP
- add hl, de ; point hl to current HP low byte
- pop de
- ld a, b
- ld [de], a ; save copy of HP to subtract in ccd7/ccd8 [how much HP substitute has]
- ld a, [hld]
-; subtract [max hp / 4] to current HP
- sub b
- ld d, a
- ld a, [hl]
- sbc 0
- pop bc
- jr c, .notEnoughHP ; underflow means user would be left with negative health
- ; bug: since it only branches on carry, it will possibly leave user with 0 HP
-.userHasZeroOrMoreHP
- ldi [hl], a ; save resulting HP after subtraction into current HP
- ld [hl], d
- ld h, b
- ld l, c
- set HAS_SUBSTITUTE_UP, [hl]
- ld a, [wOptions]
- bit 7, a ; battle animation is enabled?
- ld hl, PlayCurrentMoveAnimation
- ld b, BANK(PlayCurrentMoveAnimation)
- jr z, .animationEnabled
- ld hl, AnimationSubstitute
- ld b, BANK(AnimationSubstitute)
-.animationEnabled
- call Bankswitch ; jump to routine depending on animation setting
- ld hl, SubstituteText
- call PrintText
- jpab DrawHUDsAndHPBars
-.alreadyHasSubstitute
- ld hl, HasSubstituteText
- jr .printText
-.notEnoughHP
- ld hl, TooWeakSubstituteText
-.printText
- jp PrintText
-
-SubstituteText:
- TX_FAR _SubstituteText
- db "@"
-
-HasSubstituteText:
- TX_FAR _HasSubstituteText
- db "@"
-
-TooWeakSubstituteText:
- TX_FAR _TooWeakSubstituteText
- db "@"
diff --git a/engine/battle/moveEffects/transform_effect.asm b/engine/battle/moveEffects/transform_effect.asm
deleted file mode 100644
index ec07b303..00000000
--- a/engine/battle/moveEffects/transform_effect.asm
+++ /dev/null
@@ -1,141 +0,0 @@
-TransformEffect_:
- ld hl, wBattleMonSpecies
- ld de, wEnemyMonSpecies
- ld bc, wEnemyBattleStatus3
- ld a, [wEnemyBattleStatus1]
- ld a, [H_WHOSETURN]
- and a
- jr nz, .hitTest
- ld hl, wEnemyMonSpecies
- ld de, wBattleMonSpecies
- ld bc, wPlayerBattleStatus3
- ld [wPlayerMoveListIndex], a
- ld a, [wPlayerBattleStatus1]
-.hitTest
- bit INVULNERABLE, a ; is mon invulnerable to typical attacks? (fly/dig)
- jp nz, .failed
- push hl
- push de
- push bc
- ld hl, wPlayerBattleStatus2
- ld a, [H_WHOSETURN]
- and a
- jr z, .transformEffect
- ld hl, wEnemyBattleStatus2
-.transformEffect
-; animation(s) played are different if target has Substitute up
- bit HAS_SUBSTITUTE_UP, [hl]
- push af
- ld hl, HideSubstituteShowMonAnim
- ld b, BANK(HideSubstituteShowMonAnim)
- call nz, Bankswitch
- ld a, [wOptions]
- add a
- ld hl, PlayCurrentMoveAnimation
- ld b, BANK(PlayCurrentMoveAnimation)
- jr nc, .gotAnimToPlay
- ld hl, AnimationTransformMon
- ld b, BANK(AnimationTransformMon)
-.gotAnimToPlay
- call Bankswitch
- ld hl, ReshowSubstituteAnim
- ld b, BANK(ReshowSubstituteAnim)
- pop af
- call nz, Bankswitch
- pop bc
- ld a, [bc]
- set TRANSFORMED, a ; mon is now transformed
- ld [bc], a
- pop de
- pop hl
- push hl
-; transform user into opposing Pokemon
-; species
- ld a, [hl]
- ld [de], a
-; type 1, type 2, catch rate, and moves
- ld bc, $5
- add hl, bc
- inc de
- inc de
- inc de
- inc de
- inc de
- inc bc
- inc bc
- call CopyData
- ld a, [H_WHOSETURN]
- and a
- jr z, .next
-; save enemy mon DVs at wTransformedEnemyMonOriginalDVs
- ld a, [de]
- ld [wTransformedEnemyMonOriginalDVs], a
- inc de
- ld a, [de]
- ld [wTransformedEnemyMonOriginalDVs + 1], a
- dec de
-.next
-; DVs
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- inc de
-; Attack, Defense, Speed, and Special stats
- inc hl
- inc hl
- inc hl
- inc de
- inc de
- inc de
- ld bc, $8
- call CopyData
- ld bc, wBattleMonMoves - wBattleMonPP
- add hl, bc ; ld hl, wBattleMonMoves
- ld b, NUM_MOVES
-.copyPPLoop
-; 5 PP for all moves
- ld a, [hli]
- and a
- jr z, .lessThanFourMoves
- ld a, $5
-.lessThanFourMoves
- ld [de], a
- inc de
- dec b
- jr nz, .copyPPLoop
-.copyStats
-; original (unmodified) stats and stat mods
- pop hl
- ld a, [hl]
- ld [wd11e], a
- call GetMonName
- ld hl, wEnemyMonUnmodifiedAttack
- ld de, wPlayerMonUnmodifiedAttack
- call .copyBasedOnTurn ; original (unmodified) stats
- ld hl, wEnemyMonStatMods
- ld de, wPlayerMonStatMods
- call .copyBasedOnTurn ; stat mods
- ld hl, TransformedText
- jp PrintText
-
-.copyBasedOnTurn
- ld a, [H_WHOSETURN]
- and a
- jr z, .gotStatsOrModsToCopy
- push hl
- ld h, d
- ld l, e
- pop de
-.gotStatsOrModsToCopy
- ld bc, $8
- jp CopyData
-
-.failed
- ld hl, PrintButItFailedText_
- jp Bankswitch3DtoF
-
-TransformedText:
- TX_FAR _TransformedText
- db "@"
diff --git a/engine/battle/move_effects/conversion.asm b/engine/battle/move_effects/conversion.asm
new file mode 100644
index 00000000..1f64ec5b
--- /dev/null
+++ b/engine/battle/move_effects/conversion.asm
@@ -0,0 +1,35 @@
+ConversionEffect_:
+ ld hl, wEnemyMonType1
+ ld de, wBattleMonType1
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wEnemyBattleStatus1]
+ jr z, .conversionEffect
+ push hl
+ ld h, d
+ ld l, e
+ pop de
+ ld a, [wPlayerBattleStatus1]
+.conversionEffect
+ bit INVULNERABLE, a ; is mon immune to typical attacks (dig/fly)
+ jr nz, PrintButItFailedText
+; copy target's types to user
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld hl, PlayCurrentMoveAnimation
+ call CallBankF
+ ld hl, ConvertedTypeText
+ jp PrintText
+
+ConvertedTypeText:
+ text_far _ConvertedTypeText
+ text_end
+
+PrintButItFailedText:
+ ld hl, PrintButItFailedText_
+CallBankF:
+ ld b, BANK(PrintButItFailedText_)
+ jp Bankswitch
diff --git a/engine/battle/move_effects/drain_hp.asm b/engine/battle/move_effects/drain_hp.asm
new file mode 100644
index 00000000..04a585cc
--- /dev/null
+++ b/engine/battle/move_effects/drain_hp.asm
@@ -0,0 +1,104 @@
+DrainHPEffect_:
+ ld hl, wDamage
+ ld a, [hl]
+ srl a ; divide damage by 2
+ ld [hli], a
+ ld a, [hl]
+ rr a
+ ld [hld], a
+ or [hl] ; is damage 0?
+ jr nz, .getAttackerHP
+; if damage is 0, increase to 1 so that the attacker gains at least 1 HP
+ inc hl
+ inc [hl]
+.getAttackerHP
+ ld hl, wBattleMonHP
+ ld de, wBattleMonMaxHP
+ ldh a, [hWhoseTurn]
+ and a
+ jp z, .addDamageToAttackerHP
+ ld hl, wEnemyMonHP
+ ld de, wEnemyMonMaxHP
+.addDamageToAttackerHP
+ ld bc, wHPBarOldHP+1
+; copy current HP to wHPBarOldHP
+ ld a, [hli]
+ ld [bc], a
+ ld a, [hl]
+ dec bc
+ ld [bc], a
+; copy max HP to wHPBarMaxHP
+ ld a, [de]
+ dec bc
+ ld [bc], a
+ inc de
+ ld a, [de]
+ dec bc
+ ld [bc], a
+; add damage to attacker's HP and copy new HP to wHPBarNewHP
+ ld a, [wDamage + 1]
+ ld b, [hl]
+ add b
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ld a, [wDamage]
+ ld b, [hl]
+ adc b
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ jr c, .capToMaxHP ; if HP > 65,535, cap to max HP
+; compare HP with max HP
+ ld a, [hld]
+ ld b, a
+ ld a, [de]
+ dec de
+ sub b
+ ld a, [hli]
+ ld b, a
+ ld a, [de]
+ inc de
+ sbc b
+ jr nc, .next
+.capToMaxHP
+ ld a, [de]
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ dec de
+ ld a, [de]
+ ld [hli], a
+ ld [wHPBarNewHP+1], a
+ inc de
+.next
+ ldh a, [hWhoseTurn]
+ and a
+ hlcoord 10, 9
+ ld a, $1
+ jr z, .next2
+ hlcoord 2, 2
+ xor a
+.next2
+ ld [wHPBarType], a
+ predef UpdateHPBar2
+ predef DrawPlayerHUDAndHPBar
+ predef DrawEnemyHUDAndHPBar
+ callfar ReadPlayerMonCurHPAndStatus
+ ld hl, SuckedHealthText
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wPlayerMoveEffect]
+ jr z, .next3
+ ld a, [wEnemyMoveEffect]
+.next3
+ cp DREAM_EATER_EFFECT
+ jr nz, .printText
+ ld hl, DreamWasEatenText
+.printText
+ jp PrintText
+
+SuckedHealthText:
+ text_far _SuckedHealthText
+ text_end
+
+DreamWasEatenText:
+ text_far _DreamWasEatenText
+ text_end
diff --git a/engine/battle/move_effects/focus_energy.asm b/engine/battle/move_effects/focus_energy.asm
new file mode 100644
index 00000000..1fafe920
--- /dev/null
+++ b/engine/battle/move_effects/focus_energy.asm
@@ -0,0 +1,22 @@
+FocusEnergyEffect_:
+ ld hl, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .notEnemy
+ ld hl, wEnemyBattleStatus2
+.notEnemy
+ bit GETTING_PUMPED, [hl] ; is mon already using focus energy?
+ jr nz, .alreadyUsing
+ set GETTING_PUMPED, [hl] ; mon is now using focus energy
+ callfar PlayCurrentMoveAnimation
+ ld hl, GettingPumpedText
+ jp PrintText
+.alreadyUsing
+ ld c, 50
+ call DelayFrames
+ jpfar PrintButItFailedText_
+
+GettingPumpedText:
+ text_pause
+ text_far _GettingPumpedText
+ text_end
diff --git a/engine/battle/move_effects/haze.asm b/engine/battle/move_effects/haze.asm
new file mode 100644
index 00000000..915eeed8
--- /dev/null
+++ b/engine/battle/move_effects/haze.asm
@@ -0,0 +1,81 @@
+HazeEffect_:
+ ld a, $7
+; store 7 on every stat mod
+ ld hl, wPlayerMonAttackMod
+ call ResetStatMods
+ ld hl, wEnemyMonAttackMod
+ call ResetStatMods
+; copy unmodified stats to battle stats
+ ld hl, wPlayerMonUnmodifiedAttack
+ ld de, wBattleMonAttack
+ call ResetStats
+ ld hl, wEnemyMonUnmodifiedAttack
+ ld de, wEnemyMonAttack
+ call ResetStats
+; cure non-volatile status, but only for the target
+ ld hl, wEnemyMonStatus
+ ld de, wEnemySelectedMove
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .cureStatuses
+ ld hl, wBattleMonStatus
+ dec de ; wPlayerSelectedMove
+
+.cureStatuses
+ ld a, [hl]
+ ld [hl], $0
+ and SLP | (1 << FRZ)
+ jr z, .cureVolatileStatuses
+; prevent the Pokemon from executing a move if it was asleep or frozen
+ ld a, $ff
+ ld [de], a
+
+.cureVolatileStatuses
+ xor a
+ ld [wPlayerDisabledMove], a
+ ld [wEnemyDisabledMove], a
+ ld hl, wPlayerDisabledMoveNumber
+ ld [hli], a
+ ld [hl], a
+ ld hl, wPlayerBattleStatus1
+ call CureVolatileStatuses
+ ld hl, wEnemyBattleStatus1
+ call CureVolatileStatuses
+ ld hl, PlayCurrentMoveAnimation
+ call CallBankF
+ ld hl, StatusChangesEliminatedText
+ jp PrintText
+
+CureVolatileStatuses:
+ res CONFUSED, [hl]
+ inc hl ; BATTSTATUS2
+ ld a, [hl]
+ ; clear USING_X_ACCURACY, PROTECTED_BY_MIST, GETTING_PUMPED, and SEEDED statuses
+ and $ff ^((1 << USING_X_ACCURACY) | (1 << PROTECTED_BY_MIST) | (1 << GETTING_PUMPED) | (1 << SEEDED))
+ ld [hli], a ; BATTSTATUS3
+ ld a, [hl]
+ and %11110000 | (1 << TRANSFORMED) ; clear Bad Poison, Reflect and Light Screen statuses
+ ld [hl], a
+ ret
+
+ResetStatMods:
+ ld b, $8
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+ResetStats:
+ ld b, $8
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .loop
+ ret
+
+StatusChangesEliminatedText:
+ text_far _StatusChangesEliminatedText
+ text_end
diff --git a/engine/battle/move_effects/heal.asm b/engine/battle/move_effects/heal.asm
new file mode 100644
index 00000000..80923a29
--- /dev/null
+++ b/engine/battle/move_effects/heal.asm
@@ -0,0 +1,120 @@
+HealEffect_:
+ ldh a, [hWhoseTurn]
+ and a
+ ld de, wBattleMonHP
+ ld hl, wBattleMonMaxHP
+ ld a, [wPlayerMoveNum]
+ jr z, .healEffect
+ ld de, wEnemyMonHP
+ ld hl, wEnemyMonMaxHP
+ ld a, [wEnemyMoveNum]
+.healEffect
+ ld b, a
+ ld a, [de]
+ cp [hl] ; most significant bytes comparison is ignored
+ ; causes the move to miss if max HP is 255 or 511 points higher than the current HP
+ inc de
+ inc hl
+ ld a, [de]
+ sbc [hl]
+ jp z, .failed ; no effect if user's HP is already at its maximum
+ ld a, b
+ cp REST
+ jr nz, .healHP
+ push hl
+ push de
+ push af
+ ld c, 50
+ call DelayFrames
+ ld hl, wBattleMonStatus
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .restEffect
+ ld hl, wEnemyMonStatus
+.restEffect
+ ld a, [hl]
+ and a
+ ld [hl], 2 ; clear status and set number of turns asleep to 2
+ ld hl, StartedSleepingEffect ; if mon didn't have an status
+ jr z, .printRestText
+ ld hl, FellAsleepBecameHealthyText ; if mon had an status
+.printRestText
+ call PrintText
+ pop af
+ pop de
+ pop hl
+.healHP
+ ld a, [hld]
+ ld [wHPBarMaxHP], a
+ ld c, a
+ ld a, [hl]
+ ld [wHPBarMaxHP+1], a
+ ld b, a
+ jr z, .gotHPAmountToHeal
+; Recover and Softboiled only heal for half the mon's max HP
+ srl b
+ rr c
+.gotHPAmountToHeal
+; update HP
+ ld a, [de]
+ ld [wHPBarOldHP], a
+ add c
+ ld [de], a
+ ld [wHPBarNewHP], a
+ dec de
+ ld a, [de]
+ ld [wHPBarOldHP+1], a
+ adc b
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ inc hl
+ inc de
+ ld a, [de]
+ dec de
+ sub [hl]
+ dec hl
+ ld a, [de]
+ sbc [hl]
+ jr c, .playAnim
+; copy max HP to current HP if an overflow occurred
+ ld a, [hli]
+ ld [de], a
+ ld [wHPBarNewHP+1], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ ld [wHPBarNewHP], a
+.playAnim
+ ld hl, PlayCurrentMoveAnimation
+ call Bankswitch3DtoF
+ ldh a, [hWhoseTurn]
+ and a
+ hlcoord 10, 9
+ ld a, $1
+ jr z, .updateHPBar
+ hlcoord 2, 2
+ xor a
+.updateHPBar
+ ld [wHPBarType], a
+ predef UpdateHPBar2
+ ld hl, DrawHUDsAndHPBars
+ call Bankswitch3DtoF
+ ld hl, RegainedHealthText
+ jp PrintText
+.failed
+ ld c, 50
+ call DelayFrames
+ ld hl, PrintButItFailedText_
+ jp Bankswitch3DtoF
+
+StartedSleepingEffect:
+ text_far _StartedSleepingEffect
+ text_end
+
+FellAsleepBecameHealthyText:
+ text_far _FellAsleepBecameHealthyText
+ text_end
+
+RegainedHealthText:
+ text_far _RegainedHealthText
+ text_end
diff --git a/engine/battle/move_effects/leech_seed.asm b/engine/battle/move_effects/leech_seed.asm
new file mode 100644
index 00000000..61bd982a
--- /dev/null
+++ b/engine/battle/move_effects/leech_seed.asm
@@ -0,0 +1,40 @@
+LeechSeedEffect_:
+ callfar MoveHitTest
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .moveMissed
+ ld hl, wEnemyBattleStatus2
+ ld de, wEnemyMonType1
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .leechSeedEffect
+ ld hl, wPlayerBattleStatus2
+ ld de, wBattleMonType1
+.leechSeedEffect
+; miss if the target is grass-type or already seeded
+ ld a, [de]
+ cp GRASS
+ jr z, .moveMissed
+ inc de
+ ld a, [de]
+ cp GRASS
+ jr z, .moveMissed
+ bit SEEDED, [hl]
+ jr nz, .moveMissed
+ set SEEDED, [hl]
+ callfar PlayCurrentMoveAnimation
+ ld hl, WasSeededText
+ jp PrintText
+.moveMissed
+ ld c, 50
+ call DelayFrames
+ ld hl, EvadedAttackText
+ jp PrintText
+
+WasSeededText:
+ text_far _WasSeededText
+ text_end
+
+EvadedAttackText:
+ text_far _EvadedAttackText
+ text_end
diff --git a/engine/battle/move_effects/mist.asm b/engine/battle/move_effects/mist.asm
new file mode 100644
index 00000000..163d386f
--- /dev/null
+++ b/engine/battle/move_effects/mist.asm
@@ -0,0 +1,19 @@
+MistEffect_:
+ ld hl, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .mistEffect
+ ld hl, wEnemyBattleStatus2
+.mistEffect
+ bit PROTECTED_BY_MIST, [hl] ; is mon protected by mist?
+ jr nz, .mistAlreadyInUse
+ set PROTECTED_BY_MIST, [hl] ; mon is now protected by mist
+ callfar PlayCurrentMoveAnimation
+ ld hl, ShroudedInMistText
+ jp PrintText
+.mistAlreadyInUse
+ jpfar PrintButItFailedText_
+
+ShroudedInMistText:
+ text_far _ShroudedInMistText
+ text_end
diff --git a/engine/battle/move_effects/one_hit_ko.asm b/engine/battle/move_effects/one_hit_ko.asm
new file mode 100644
index 00000000..7e5db0f7
--- /dev/null
+++ b/engine/battle/move_effects/one_hit_ko.asm
@@ -0,0 +1,38 @@
+OneHitKOEffect_:
+ ld hl, wDamage
+ xor a
+ ld [hli], a
+ ld [hl], a ; set the damage output to zero
+ dec a
+ ld [wCriticalHitOrOHKO], a
+ ld hl, wBattleMonSpeed + 1
+ ld de, wEnemyMonSpeed + 1
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .compareSpeed
+ ld hl, wEnemyMonSpeed + 1
+ ld de, wBattleMonSpeed + 1
+.compareSpeed
+; set damage to 65535 and OHKO flag is the user's current speed is higher than the target's
+ ld a, [de]
+ dec de
+ ld b, a
+ ld a, [hld]
+ sub b
+ ld a, [de]
+ ld b, a
+ ld a, [hl]
+ sbc b
+ jr c, .userIsSlower
+ ld hl, wDamage
+ ld a, $ff
+ ld [hli], a
+ ld [hl], a
+ ld a, $2
+ ld [wCriticalHitOrOHKO], a
+ ret
+.userIsSlower
+; keep damage at 0 and set move missed flag if target's current speed is higher instead
+ ld a, $1
+ ld [wMoveMissed], a
+ ret
diff --git a/engine/battle/move_effects/paralyze.asm b/engine/battle/move_effects/paralyze.asm
new file mode 100644
index 00000000..dbaa0fb8
--- /dev/null
+++ b/engine/battle/move_effects/paralyze.asm
@@ -0,0 +1,47 @@
+ParalyzeEffect_:
+ ld hl, wEnemyMonStatus
+ ld de, wPlayerMoveType
+ ldh a, [hWhoseTurn]
+ and a
+ jp z, .next
+ ld hl, wBattleMonStatus
+ ld de, wEnemyMoveType
+.next
+ ld a, [hl]
+ and a ; does the target already have a status ailment?
+ jr nz, .didntAffect
+; check if the target is immune due to types
+ ld a, [de]
+ cp ELECTRIC
+ jr nz, .hitTest
+ ld b, h
+ ld c, l
+ inc bc
+ ld a, [bc]
+ cp GROUND
+ jr z, .doesntAffect
+ inc bc
+ ld a, [bc]
+ cp GROUND
+ jr z, .doesntAffect
+.hitTest
+ push hl
+ callfar MoveHitTest
+ pop hl
+ ld a, [wMoveMissed]
+ and a
+ jr nz, .didntAffect
+ set PAR, [hl]
+ callfar QuarterSpeedDueToParalysis
+ ld c, 30
+ call DelayFrames
+ callfar PlayCurrentMoveAnimation
+ jpfar PrintMayNotAttackText
+.didntAffect
+ ld c, 50
+ call DelayFrames
+ jpfar PrintDidntAffectText
+.doesntAffect
+ ld c, 50
+ call DelayFrames
+ jpfar PrintDoesntAffectText
diff --git a/engine/battle/move_effects/pay_day.asm b/engine/battle/move_effects/pay_day.asm
new file mode 100644
index 00000000..fa373038
--- /dev/null
+++ b/engine/battle/move_effects/pay_day.asm
@@ -0,0 +1,45 @@
+PayDayEffect_:
+ xor a
+ ld hl, wcd6d
+ ld [hli], a
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wBattleMonLevel]
+ jr z, .payDayEffect
+ ld a, [wEnemyMonLevel]
+.payDayEffect
+; level * 2
+ add a
+ ldh [hDividend + 3], a
+ xor a
+ ldh [hDividend], a
+ ldh [hDividend + 1], a
+ ldh [hDividend + 2], a
+; convert to BCD
+ ld a, 100
+ ldh [hDivisor], a
+ ld b, $4
+ call Divide
+ ldh a, [hQuotient + 3]
+ ld [hli], a
+ ldh a, [hRemainder]
+ ldh [hDividend + 3], a
+ ld a, 10
+ ldh [hDivisor], a
+ ld b, $4
+ call Divide
+ ldh a, [hQuotient + 3]
+ swap a
+ ld b, a
+ ldh a, [hRemainder]
+ add b
+ ld [hl], a
+ ld de, wTotalPayDayMoney + 2
+ ld c, $3
+ predef AddBCDPredef
+ ld hl, CoinsScatteredText
+ jp PrintText
+
+CoinsScatteredText:
+ text_far _CoinsScatteredText
+ text_end
diff --git a/engine/battle/move_effects/recoil.asm b/engine/battle/move_effects/recoil.asm
new file mode 100644
index 00000000..85110d50
--- /dev/null
+++ b/engine/battle/move_effects/recoil.asm
@@ -0,0 +1,70 @@
+RecoilEffect_:
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, [wPlayerMoveNum]
+ ld hl, wBattleMonMaxHP
+ jr z, .recoilEffect
+ ld a, [wEnemyMoveNum]
+ ld hl, wEnemyMonMaxHP
+.recoilEffect
+ ld d, a
+ ld a, [wDamage]
+ ld b, a
+ ld a, [wDamage + 1]
+ ld c, a
+ srl b
+ rr c
+ ld a, d
+ cp STRUGGLE ; struggle deals 50% recoil damage
+ jr z, .gotRecoilDamage
+ srl b
+ rr c
+.gotRecoilDamage
+ ld a, b
+ or c
+ jr nz, .updateHP
+ inc c ; minimum recoil damage is 1
+.updateHP
+; subtract HP from user due to the recoil damage
+ ld a, [hli]
+ ld [wHPBarMaxHP+1], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ push bc
+ ld bc, wBattleMonHP - wBattleMonMaxHP
+ add hl, bc
+ pop bc
+ ld a, [hl]
+ 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, .getHPBarCoords
+; if recoil damage is higher than the Pokemon's HP, set its HP to 0
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wHPBarNewHP
+ ld [hli], a
+ ld [hl], a
+.getHPBarCoords
+ hlcoord 10, 9
+ ldh a, [hWhoseTurn]
+ and a
+ ld a, $1
+ jr z, .updateHPBar
+ hlcoord 2, 2
+ xor a
+.updateHPBar
+ ld [wHPBarType], a
+ predef UpdateHPBar2
+ ld hl, HitWithRecoilText
+ jp PrintText
+HitWithRecoilText:
+ text_far _HitWithRecoilText
+ text_end
diff --git a/engine/battle/move_effects/reflect_light_screen.asm b/engine/battle/move_effects/reflect_light_screen.asm
new file mode 100644
index 00000000..c05055fa
--- /dev/null
+++ b/engine/battle/move_effects/reflect_light_screen.asm
@@ -0,0 +1,45 @@
+ReflectLightScreenEffect_:
+ ld hl, wPlayerBattleStatus3
+ ld de, wPlayerMoveEffect
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .reflectLightScreenEffect
+ ld hl, wEnemyBattleStatus3
+ ld de, wEnemyMoveEffect
+.reflectLightScreenEffect
+ ld a, [de]
+ cp LIGHT_SCREEN_EFFECT
+ jr nz, .reflect
+ bit HAS_LIGHT_SCREEN_UP, [hl] ; is mon already protected by light screen?
+ jr nz, .moveFailed
+ set HAS_LIGHT_SCREEN_UP, [hl] ; mon is now protected by light screen
+ ld hl, LightScreenProtectedText
+ jr .playAnim
+.reflect
+ bit HAS_REFLECT_UP, [hl] ; is mon already protected by reflect?
+ jr nz, .moveFailed
+ set HAS_REFLECT_UP, [hl] ; mon is now protected by reflect
+ ld hl, ReflectGainedArmorText
+.playAnim
+ push hl
+ ld hl, PlayCurrentMoveAnimation
+ call Bankswitch3DtoF
+ pop hl
+ jp PrintText
+.moveFailed
+ ld c, 50
+ call DelayFrames
+ ld hl, PrintButItFailedText_
+ jp Bankswitch3DtoF
+
+LightScreenProtectedText:
+ text_far _LightScreenProtectedText
+ text_end
+
+ReflectGainedArmorText:
+ text_far _ReflectGainedArmorText
+ text_end
+
+Bankswitch3DtoF:
+ ld b, BANK(BattleCore)
+ jp Bankswitch
diff --git a/engine/battle/move_effects/substitute.asm b/engine/battle/move_effects/substitute.asm
new file mode 100644
index 00000000..860b76b6
--- /dev/null
+++ b/engine/battle/move_effects/substitute.asm
@@ -0,0 +1,77 @@
+SubstituteEffect_:
+ ld c, 50
+ call DelayFrames
+ ld hl, wBattleMonMaxHP
+ ld de, wPlayerSubstituteHP
+ ld bc, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .notEnemy
+ ld hl, wEnemyMonMaxHP
+ ld de, wEnemySubstituteHP
+ ld bc, wEnemyBattleStatus2
+.notEnemy
+ ld a, [bc]
+ bit HAS_SUBSTITUTE_UP, a ; user already has substitute?
+ jr nz, .alreadyHasSubstitute
+; quarter health to remove from user
+; assumes max HP is 1023 or lower
+ push bc
+ ld a, [hli]
+ ld b, [hl]
+ srl a
+ rr b
+ srl a
+ rr b ; max hp / 4
+ push de
+ ld de, wBattleMonHP - wBattleMonMaxHP
+ add hl, de ; point hl to current HP low byte
+ pop de
+ ld a, b
+ ld [de], a ; save copy of HP to subtract in wPlayerSubstituteHP/wEnemySubstituteHP
+ ld a, [hld]
+; subtract [max hp / 4] to current HP
+ sub b
+ ld d, a
+ ld a, [hl]
+ sbc 0
+ pop bc
+ jr c, .notEnoughHP ; underflow means user would be left with negative health
+ ; bug: since it only branches on carry, it will possibly leave user with 0 HP
+.userHasZeroOrMoreHP
+ ldi [hl], a ; save resulting HP after subtraction into current HP
+ ld [hl], d
+ ld h, b
+ ld l, c
+ set HAS_SUBSTITUTE_UP, [hl]
+ ld a, [wOptions]
+ bit 7, a ; battle animation is enabled?
+ ld hl, PlayCurrentMoveAnimation
+ ld b, BANK(PlayCurrentMoveAnimation)
+ jr z, .animationEnabled
+ ld hl, AnimationSubstitute
+ ld b, BANK(AnimationSubstitute)
+.animationEnabled
+ call Bankswitch ; jump to routine depending on animation setting
+ ld hl, SubstituteText
+ call PrintText
+ jpfar DrawHUDsAndHPBars
+.alreadyHasSubstitute
+ ld hl, HasSubstituteText
+ jr .printText
+.notEnoughHP
+ ld hl, TooWeakSubstituteText
+.printText
+ jp PrintText
+
+SubstituteText:
+ text_far _SubstituteText
+ text_end
+
+HasSubstituteText:
+ text_far _HasSubstituteText
+ text_end
+
+TooWeakSubstituteText:
+ text_far _TooWeakSubstituteText
+ text_end
diff --git a/engine/battle/move_effects/transform.asm b/engine/battle/move_effects/transform.asm
new file mode 100644
index 00000000..d37bd94d
--- /dev/null
+++ b/engine/battle/move_effects/transform.asm
@@ -0,0 +1,141 @@
+TransformEffect_:
+ ld hl, wBattleMonSpecies
+ ld de, wEnemyMonSpecies
+ ld bc, wEnemyBattleStatus3
+ ld a, [wEnemyBattleStatus1]
+ ldh a, [hWhoseTurn]
+ and a
+ jr nz, .hitTest
+ ld hl, wEnemyMonSpecies
+ ld de, wBattleMonSpecies
+ ld bc, wPlayerBattleStatus3
+ ld [wPlayerMoveListIndex], a
+ ld a, [wPlayerBattleStatus1]
+.hitTest
+ bit INVULNERABLE, a ; is mon invulnerable to typical attacks? (fly/dig)
+ jp nz, .failed
+ push hl
+ push de
+ push bc
+ ld hl, wPlayerBattleStatus2
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .transformEffect
+ ld hl, wEnemyBattleStatus2
+.transformEffect
+; animation(s) played are different if target has Substitute up
+ bit HAS_SUBSTITUTE_UP, [hl]
+ push af
+ ld hl, HideSubstituteShowMonAnim
+ ld b, BANK(HideSubstituteShowMonAnim)
+ call nz, Bankswitch
+ ld a, [wOptions]
+ add a
+ ld hl, PlayCurrentMoveAnimation
+ ld b, BANK(PlayCurrentMoveAnimation)
+ jr nc, .gotAnimToPlay
+ ld hl, AnimationTransformMon
+ ld b, BANK(AnimationTransformMon)
+.gotAnimToPlay
+ call Bankswitch
+ ld hl, ReshowSubstituteAnim
+ ld b, BANK(ReshowSubstituteAnim)
+ pop af
+ call nz, Bankswitch
+ pop bc
+ ld a, [bc]
+ set TRANSFORMED, a ; mon is now transformed
+ ld [bc], a
+ pop de
+ pop hl
+ push hl
+; transform user into opposing Pokemon
+; species
+ ld a, [hl]
+ ld [de], a
+; type 1, type 2, catch rate, and moves
+ ld bc, $5
+ add hl, bc
+ inc de
+ inc de
+ inc de
+ inc de
+ inc de
+ inc bc
+ inc bc
+ call CopyData
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .next
+; save enemy mon DVs at wTransformedEnemyMonOriginalDVs
+ ld a, [de]
+ ld [wTransformedEnemyMonOriginalDVs], a
+ inc de
+ ld a, [de]
+ ld [wTransformedEnemyMonOriginalDVs + 1], a
+ dec de
+.next
+; DVs
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hli]
+ ld [de], a
+ inc de
+; Attack, Defense, Speed, and Special stats
+ inc hl
+ inc hl
+ inc hl
+ inc de
+ inc de
+ inc de
+ ld bc, $8
+ call CopyData
+ ld bc, wBattleMonMoves - wBattleMonPP
+ add hl, bc ; ld hl, wBattleMonMoves
+ ld b, NUM_MOVES
+.copyPPLoop
+; 5 PP for all moves
+ ld a, [hli]
+ and a
+ jr z, .lessThanFourMoves
+ ld a, $5
+.lessThanFourMoves
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .copyPPLoop
+.copyStats
+; original (unmodified) stats and stat mods
+ pop hl
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, wEnemyMonUnmodifiedAttack
+ ld de, wPlayerMonUnmodifiedAttack
+ call .copyBasedOnTurn ; original (unmodified) stats
+ ld hl, wEnemyMonStatMods
+ ld de, wPlayerMonStatMods
+ call .copyBasedOnTurn ; stat mods
+ ld hl, TransformedText
+ jp PrintText
+
+.copyBasedOnTurn
+ ldh a, [hWhoseTurn]
+ and a
+ jr z, .gotStatsOrModsToCopy
+ push hl
+ ld h, d
+ ld l, e
+ pop de
+.gotStatsOrModsToCopy
+ ld bc, $8
+ jp CopyData
+
+.failed
+ ld hl, PrintButItFailedText_
+ jp Bankswitch3DtoF
+
+TransformedText:
+ text_far _TransformedText
+ text_end
diff --git a/engine/battle/print_type.asm b/engine/battle/print_type.asm
index f717f871..7da0dc8c 100644
--- a/engine/battle/print_type.asm
+++ b/engine/battle/print_type.asm
@@ -49,4 +49,4 @@ PrintType_:
pop hl
jp PlaceString
-INCLUDE "text/type_names.asm"
+INCLUDE "data/types/names.asm"
diff --git a/engine/battle/read_trainer_party.asm b/engine/battle/read_trainer_party.asm
index b4ee46a0..02fbfeda 100755
--- a/engine/battle/read_trainer_party.asm
+++ b/engine/battle/read_trainer_party.asm
@@ -110,7 +110,7 @@ ReadTrainer:
dec a
ld c, a
ld b, 0
- add hl,bc
+ add hl, bc
ld a, [de]
inc de
ld [hl], a
diff --git a/engine/battle/safari_zone.asm b/engine/battle/safari_zone.asm
index 88064f9a..9362cc3a 100755
--- a/engine/battle/safari_zone.asm
+++ b/engine/battle/safari_zone.asm
@@ -28,9 +28,9 @@ PrintSafariZoneBattleText:
jp PrintText
SafariZoneEatingText:
- TX_FAR _SafariZoneEatingText
- db "@"
+ text_far _SafariZoneEatingText
+ text_end
SafariZoneAngryText:
- TX_FAR _SafariZoneAngryText
- db "@"
+ text_far _SafariZoneAngryText
+ text_end
diff --git a/engine/battle/save_trainer_name.asm b/engine/battle/save_trainer_name.asm
index 49d0429f..4d40fd82 100644
--- a/engine/battle/save_trainer_name.asm
+++ b/engine/battle/save_trainer_name.asm
@@ -1,4 +1,4 @@
-SaveTrainerName:
+SaveTrainerName::
ld hl, TrainerNamePointers
ld a, [wTrainerClass]
dec a
@@ -18,95 +18,4 @@ SaveTrainerName:
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♀@"
+INCLUDE "data/trainers/name_pointers.asm"
diff --git a/engine/battle/scale_sprites.asm b/engine/battle/scale_sprites.asm
index c614d638..794a65ab 100644
--- a/engine/battle/scale_sprites.asm
+++ b/engine/battle/scale_sprites.asm
@@ -24,7 +24,7 @@ ScaleFirstThreeSpriteColumnsByTwo:
.columnInnerLoop
push bc
ld a, [de]
- ld bc, -(7*8)+1 ; $ffc9, scale lower nybble and seek to previous output column
+ ld bc, -(7*8)+1 ; -$37, scale lower nybble and seek to previous output column
call ScalePixelsByTwo
ld a, [de]
dec de
@@ -39,7 +39,7 @@ ScaleFirstThreeSpriteColumnsByTwo:
dec de
dec de
ld a, b
- ld bc, -7*8 ; $ffc8, skip one output column (which has already been written along with the current one)
+ ld bc, -7*8 ; -$38, skip one output column (which has already been written along with the current one)
add hl, bc
ld b, a
dec b
@@ -48,16 +48,16 @@ ScaleFirstThreeSpriteColumnsByTwo:
ScaleLastSpriteColumnByTwo:
ld a, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows
- ld [H_SPRITEINTERLACECOUNTER], a
+ ldh [hSpriteInterlaceCounter], a
ld bc, -1
.columnInnerLoop
ld a, [de]
dec de
swap a ; only high nybble contains information
call ScalePixelsByTwo
- ld a, [H_SPRITEINTERLACECOUNTER]
+ ldh a, [hSpriteInterlaceCounter]
dec a
- ld [H_SPRITEINTERLACECOUNTER], a
+ ldh [hSpriteInterlaceCounter], a
jr nz, .columnInnerLoop
dec de ; skip last 4 rows of new column
dec de
@@ -86,7 +86,19 @@ ScalePixelsByTwo:
; repeats each input bit twice
DuplicateBitsTable:
- db $00, $03, $0c, $0f
- db $30, $33, $3c, $3f
- db $c0, $c3, $cc, $cf
- db $f0, $f3, $fc, $ff
+ db %00000000
+ db %00000011
+ db %00001100
+ db %00001111
+ db %00110000
+ db %00110011
+ db %00111100
+ db %00111111
+ db %11000000
+ db %11000011
+ db %11001100
+ db %11001111
+ db %11110000
+ db %11110011
+ db %11111100
+ db %11111111
diff --git a/engine/battle/scroll_draw_trainer_pic.asm b/engine/battle/scroll_draw_trainer_pic.asm
index 98893dcf..e19d681a 100644
--- a/engine/battle/scroll_draw_trainer_pic.asm
+++ b/engine/battle/scroll_draw_trainer_pic.asm
@@ -5,8 +5,8 @@ _ScrollTrainerPicAfterBattle:
ld [wEnemyMonSpecies2], a
ld b, SET_PAL_BATTLE
call RunPaletteCommand
- callab _LoadTrainerPic
- coord hl, 19, 0
+ callfar _LoadTrainerPic
+ hlcoord 19, 0
ld c, $0
.scrollLoop
inc c
diff --git a/engine/battle/trainer_ai.asm b/engine/battle/trainer_ai.asm
index c8fdfb29..17e68e75 100644
--- a/engine/battle/trainer_ai.asm
+++ b/engine/battle/trainer_ai.asm
@@ -134,7 +134,7 @@ AIMoveChoiceModification1:
push de
push bc
ld hl, StatusAilmentMoveEffects
- ld de, $0001
+ ld de, 1
call IsInArray
pop bc
pop de
@@ -146,11 +146,11 @@ AIMoveChoiceModification1:
jr .nextMove
StatusAilmentMoveEffects:
- db $01 ; unused sleep effect
+ db EFFECT_01 ; unused sleep effect
db SLEEP_EFFECT
db POISON_EFFECT
db PARALYZE_EFFECT
- db $FF
+ db -1 ; end
; slightly encourage moves with specific effects.
; in particular, stat-modifying moves and other move effects
@@ -204,7 +204,7 @@ AIMoveChoiceModification3:
push hl
push bc
push de
- callab AIGetTypeEffectiveness
+ callfar AIGetTypeEffectiveness
pop de
pop bc
pop hl
@@ -273,68 +273,19 @@ ReadMove:
pop hl
ret
-; move choice modification methods that are applied for each trainer class
-; 0 is sentinel value
-TrainerClassMoveChoiceModifications:
- db 0 ; YOUNGSTER
- db 1,0 ; BUG CATCHER
- db 1,0 ; LASS
- db 1,3,0 ; SAILOR
- db 1,0 ; JR_TRAINER_M
- db 1,0 ; JR_TRAINER_F
- db 1,2,3,0; POKEMANIAC
- db 1,2,0 ; SUPER_NERD
- db 1,0 ; HIKER
- db 1,0 ; BIKER
- db 1,3,0 ; BURGLAR
- db 1,0 ; ENGINEER
- db 1,2,0 ; JUGGLER_X
- db 1,3,0 ; FISHER
- db 1,3,0 ; SWIMMER
- db 0 ; CUE_BALL
- db 1,0 ; GAMBLER
- db 1,3,0 ; BEAUTY
- db 1,2,0 ; PSYCHIC_TR
- db 1,0 ; ROCKER
- db 1,0 ; JUGGLER
- db 1,0 ; TAMER
- db 1,0 ; BIRD_KEEPER
- db 1,0 ; BLACKBELT
- db 1,0 ; SONY1
- db 1,3,0 ; PROF_OAK
- db 1,2,0 ; CHIEF
- db 1,2,0 ; SCIENTIST
- db 1,3,0 ; GIOVANNI
- db 1,0 ; ROCKET
- db 1,3,0 ; COOLTRAINER_M
- db 1,3,0 ; COOLTRAINER_F
- db 1,0 ; BRUNO
- db 1,0 ; BROCK
- db 1,3,0 ; MISTY
- db 1,0 ; LT_SURGE
- db 1,3,0 ; ERIKA
- db 1,3,0 ; KOGA
- db 1,0 ; BLAINE
- db 1,0 ; SABRINA
- db 1,2,0 ; GENTLEMAN
- db 1,3,0 ; SONY2
- db 1,3,0 ; SONY3
- db 1,2,3,0; LORELEI
- db 1,0 ; CHANNELER
- db 1,0 ; AGATHA
- db 1,3,0 ; LANCE
+INCLUDE "data/trainers/move_choices.asm"
-INCLUDE "engine/battle/trainer_pic_money_pointers.asm"
+INCLUDE "data/trainers/pic_pointers_money.asm"
-INCLUDE "text/trainer_names.asm"
+INCLUDE "data/trainers/names.asm"
-INCLUDE "engine/battle/bank_e_misc.asm"
+INCLUDE "engine/battle/misc.asm"
INCLUDE "engine/battle/read_trainer_party.asm"
-INCLUDE "data/trainer_moves.asm"
+INCLUDE "data/trainers/special_moves.asm"
-INCLUDE "data/trainer_parties.asm"
+INCLUDE "data/trainers/parties.asm"
TrainerAI:
ld a, [wIsInBattle]
@@ -350,7 +301,7 @@ TrainerAI:
and 1 << USING_RAGE ; %1000000
jr nz, .done ; don't follow trainer ai if opponent is locked in rage
; note that this doesn't check for hyper beam recharge which can cause problems
- ld a,[wTrainerClass] ; what trainer class is this?
+ ld a, [wTrainerClass] ; what trainer class is this?
dec a
ld c, a
ld b, 0
@@ -377,57 +328,7 @@ TrainerAI:
and a
ret
-TrainerAIPointers:
-; one entry per trainer class
-; first byte, number of times (per Pokémon) it can occur
-; next two bytes, pointer to AI subroutine for trainer class
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,JugglerAI ; juggler_x
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 3,JugglerAI ; juggler
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 2,BlackbeltAI ; blackbelt
- dbw 3,GenericAI
- dbw 3,GenericAI
- dbw 1,GenericAI ; chief
- dbw 3,GenericAI
- dbw 1,GiovanniAI ; giovanni
- dbw 3,GenericAI
- dbw 2,CooltrainerMAI ; cooltrainerm
- dbw 1,CooltrainerFAI ; cooltrainerf
- dbw 2,BrunoAI ; bruno
- dbw 5,BrockAI ; brock
- dbw 1,MistyAI ; misty
- dbw 1,LtSurgeAI ; surge
- dbw 1,ErikaAI ; erika
- dbw 2,KogaAI ; koga
- dbw 2,BlaineAI ; blaine
- dbw 1,SabrinaAI ; sabrina
- dbw 3,GenericAI
- dbw 1,Sony2AI ; sony2
- dbw 1,Sony3AI ; sony3
- dbw 2,LoreleiAI ; lorelei
- dbw 3,GenericAI
- dbw 2,AgathaAI ; agatha
- dbw 1,LanceAI ; lance
+INCLUDE "data/trainers/ai_pointers.asm"
JugglerAI:
cp 25 percent + 1
@@ -650,14 +551,14 @@ AIRecoverHP:
AIPrintItemUseAndUpdateHPBar:
call AIPrintItemUse_
- coord hl, 2, 2
+ hlcoord 2, 2
xor a
ld [wHPBarType], a
predef UpdateHPBar2
jp DecrementAICount
AISwitchIfEnoughMons:
-; enemy trainer switches if there are 3 or more unfainted mons in party
+; enemy trainer switches if there are 2 or more unfainted mons in party
ld a, [wEnemyPartyCount]
ld c, a
ld hl, wEnemyMon1HP
@@ -681,7 +582,7 @@ AISwitchIfEnoughMons:
jr nz, .loop
ld a, d ; how many available monsters are there?
- cp 2 ; don't bother if only 1 or 2
+ cp 2 ; don't bother if only 1
jp nc, SwitchEnemyMon
and a
ret
@@ -707,7 +608,7 @@ SwitchEnemyMon:
; switching in a new mon in response to this switch.
ld a, 1
ld [wFirstMonsNotOutYet], a
- callab EnemySendOut
+ callfar EnemySendOut
xor a
ld [wFirstMonsNotOutYet], a
@@ -718,8 +619,8 @@ SwitchEnemyMon:
ret
AIBattleWithdrawText:
- TX_FAR _AIBattleWithdrawText
- db "@"
+ text_far _AIBattleWithdrawText
+ text_end
AIUseFullHeal:
call AIPlayRestoringSFX
@@ -763,17 +664,17 @@ AIUseDireHit: ; unused
AICheckIfHPBelowFraction:
; return carry if enemy trainer's current HP is below 1 / a of the maximum
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld hl, wEnemyMonMaxHP
ld a, [hli]
- ld [H_DIVIDEND], a
+ ldh [hDividend], a
ld a, [hl]
- ld [H_DIVIDEND + 1], a
+ ldh [hDividend + 1], a
ld b, 2
call Divide
- ld a, [H_QUOTIENT + 3]
+ ldh a, [hQuotient + 3]
ld c, a
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
ld b, a
ld hl, wEnemyMonHP + 1
ld a, [hld]
@@ -821,7 +722,7 @@ AIIncreaseStat:
ld a, ANIM_AF
ld [hli], a
ld [hl], b
- callab StatModifierUpEffect
+ callfar StatModifierUpEffect
pop hl
pop af
ld [hli], a
@@ -843,5 +744,5 @@ AIPrintItemUse_:
jp PrintText
AIBattleUseItemText:
- TX_FAR _AIBattleUseItemText
- db "@"
+ text_far _AIBattleUseItemText
+ text_end
diff --git a/engine/battle/trainer_pic_money_pointers.asm b/engine/battle/trainer_pic_money_pointers.asm
deleted file mode 100755
index 37678e74..00000000
--- a/engine/battle/trainer_pic_money_pointers.asm
+++ /dev/null
@@ -1,143 +0,0 @@
-TrainerPicAndMoneyPointers:
-; trainer pic pointers and base money.
-; money received after battle = base money × level of highest-level enemy mon
- dw YoungsterPic
- money 1500
-
- dw BugCatcherPic
- money 1000
-
- dw LassPic
- money 1500
-
- dw SailorPic
- money 3000
-
- dw JrTrainerMPic
- money 2000
-
- dw JrTrainerFPic
- money 2000
-
- dw PokemaniacPic
- money 5000
-
- dw SuperNerdPic
- money 2500
-
- dw HikerPic
- money 3500
-
- dw BikerPic
- money 2000
-
- dw BurglarPic
- money 9000
-
- dw EngineerPic
- money 5000
-
- dw JugglerPic
- money 3500
-
- dw FisherPic
- money 3500
-
- dw SwimmerPic
- money 500
-
- dw CueBallPic
- money 2500
-
- dw GamblerPic
- money 7000
-
- dw BeautyPic
- money 7000
-
- dw PsychicPic
- money 1000
-
- dw RockerPic
- money 2500
-
- dw JugglerPic
- money 3500
-
- dw TamerPic
- money 4000
-
- dw BirdKeeperPic
- money 2500
-
- dw BlackbeltPic
- money 2500
-
- dw Rival1Pic
- money 3500
-
- dw ProfOakPic
- money 9900
-
- dw ChiefPic
- money 3000
-
- dw ScientistPic
- money 5000
-
- dw GiovanniPic
- money 9900
-
- dw RocketPic
- money 3000
-
- dw CooltrainerMPic
- money 3500
-
- dw CooltrainerFPic
- money 3500
-
- dw BrunoPic
- money 9900
-
- dw BrockPic
- money 9900
-
- dw MistyPic
- money 9900
-
- dw LtSurgePic
- money 9900
-
- dw ErikaPic
- money 9900
-
- dw KogaPic
- money 9900
-
- dw BlainePic
- money 9900
-
- dw SabrinaPic
- money 9900
-
- dw GentlemanPic
- money 7000
-
- dw Rival2Pic
- money 6500
-
- dw Rival3Pic
- money 9900
-
- dw LoreleiPic
- money 9900
-
- dw ChannelerPic
- money 3000
-
- dw AgathaPic
- money 9900
-
- dw LancePic
- money 9900
diff --git a/engine/battle/unused_stats_functions.asm b/engine/battle/unused_stats_functions.asm
index 55f78fd3..5174adf5 100644
--- a/engine/battle/unused_stats_functions.asm
+++ b/engine/battle/unused_stats_functions.asm
@@ -1,6 +1,6 @@
; does nothing since no stats are ever selected (barring glitches)
DoubleSelectedStats:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, [wPlayerStatsToDouble]
ld hl, wBattleMonAttack + 1
@@ -30,7 +30,7 @@ DoubleSelectedStats:
; does nothing since no stats are ever selected (barring glitches)
HalveSelectedStats:
- ld a, [H_WHOSETURN]
+ ldh a, [hWhoseTurn]
and a
ld a, [wPlayerStatsToHalve]
ld hl, wBattleMonAttack
diff --git a/engine/battle/wild_encounters.asm b/engine/battle/wild_encounters.asm
index 0285346e..d16c6515 100644
--- a/engine/battle/wild_encounters.asm
+++ b/engine/battle/wild_encounters.asm
@@ -7,14 +7,14 @@ TryDoWildEncounter:
ld a, [wd736]
and a
ret nz
- callab IsPlayerStandingOnDoorTileOrWarpTile
+ callfar IsPlayerStandingOnDoorTileOrWarpTile
jr nc, .notStandingOnDoorOrWarpTile
.CantEncounter
ld a, $1
and a
ret
.notStandingOnDoorOrWarpTile
- callab IsPlayerJustOutsideMap
+ callfar IsPlayerJustOutsideMap
jr z, .CantEncounter
ld a, [wRepelRemainingSteps]
and a
@@ -26,7 +26,7 @@ TryDoWildEncounter:
; determine if wild pokemon can appear in the half-block we're standing in
; is the bottom left tile (8,9) of the half-block we're standing in a grass/water tile?
; note that by using the bottom left tile, this prevents the "left-shore" tiles from generating grass encounters
- coord hl, 8, 9
+ hlcoord 8, 9
ld c, [hl]
ld a, [wGrassTile]
cp c
@@ -40,7 +40,7 @@ TryDoWildEncounter:
; so long as the map is "indoor" and has wild pokemon defined.
; ...as long as it's not Viridian Forest or Safari Zone.
ld a, [wCurMap]
- cp REDS_HOUSE_1F ; is this an indoor map?
+ cp FIRST_INDOOR_MAP ; is this an indoor map?
jr c, .CantEncounter2
ld a, [wCurMapTileset]
cp FOREST ; Viridian Forest/Safari Zone
@@ -49,10 +49,10 @@ TryDoWildEncounter:
.CanEncounter
; compare encounter chance with a random number to determine if there will be an encounter
ld b, a
- ld a, [hRandomAdd]
+ ldh a, [hRandomAdd]
cp b
jr nc, .CantEncounter2
- ld a, [hRandomSub]
+ ldh a, [hRandomSub]
ld b, a
ld hl, WildMonEncounterSlotChances
.determineEncounterSlot
@@ -65,7 +65,7 @@ TryDoWildEncounter:
; determine which wild pokemon (grass or water) can appear in the half-block we're standing in
ld c, [hl]
ld hl, wGrassMons
- aCoord 8, 9
+ lda_coord 8, 9
cp $14 ; is the bottom left tile (8,9) of the half-block we're standing in a water tile?
jr nz, .gotWildEncounterType ; else, it's treated as a grass tile by default
ld hl, wWaterMons
@@ -89,7 +89,7 @@ TryDoWildEncounter:
.lastRepelStep
ld [wRepelRemainingSteps], a
ld a, TEXT_REPEL_WORE_OFF
- ld [hSpriteIndexOrTextID], a
+ ldh [hSpriteIndexOrTextID], a
call EnableAutoTextBoxDrawing
call DisplayTextID
.CantEncounter2
@@ -100,18 +100,4 @@ TryDoWildEncounter:
xor a
ret
-WildMonEncounterSlotChances:
-; There are 10 slots for wild pokemon, and this is the table that defines how common each of
-; those 10 slots is. A random number is generated and then the first byte of each pair in this
-; table is compared against that random number. If the random number is less than or equal
-; to the first byte, then that slot is chosen. The second byte is double the slot number.
- db $32, $00 ; 51/256 = 19.9% chance of slot 0
- db $65, $02 ; 51/256 = 19.9% chance of slot 1
- db $8C, $04 ; 39/256 = 15.2% chance of slot 2
- db $A5, $06 ; 25/256 = 9.8% chance of slot 3
- db $BE, $08 ; 25/256 = 9.8% chance of slot 4
- db $D7, $0A ; 25/256 = 9.8% chance of slot 5
- db $E4, $0C ; 13/256 = 5.1% chance of slot 6
- db $F1, $0E ; 13/256 = 5.1% chance of slot 7
- db $FC, $10 ; 11/256 = 4.3% chance of slot 8
- db $FF, $12 ; 3/256 = 1.2% chance of slot 9
+INCLUDE "data/wild/probabilities.asm"
diff --git a/engine/bcd.asm b/engine/bcd.asm
deleted file mode 100644
index d84e504b..00000000
--- a/engine/bcd.asm
+++ /dev/null
@@ -1,218 +0,0 @@
-; divide hMoney by hDivideBCDDivisor
-; return output in hDivideBCDQuotient (same as hDivideBCDDivisor)
-; used only to halve player money upon losing a fight
-DivideBCDPredef::
-DivideBCDPredef2::
-DivideBCDPredef3:: ; only used function
-DivideBCDPredef4::
- call GetPredefRegisters
-
-DivideBCD::
- xor a
- ld [hDivideBCDBuffer], a
- ld [hDivideBCDBuffer + 1], a
- ld [hDivideBCDBuffer + 2], a
- ld d, $1
-.mulBy10Loop
-; multiply the divisor by 10 until the leading digit is nonzero
-; to set up the standard long division algorithm
- ld a, [hDivideBCDDivisor]
- and $f0
- jr nz, .next
- inc d
- ld a, [hDivideBCDDivisor]
- swap a
- and $f0
- ld b, a
- ld a, [hDivideBCDDivisor + 1]
- swap a
- ld [hDivideBCDDivisor + 1], a
- and $f
- or b
- ld [hDivideBCDDivisor], a
- ld a, [hDivideBCDDivisor + 1]
- and $f0
- ld b, a
- ld a, [hDivideBCDDivisor + 2]
- swap a
- ld [hDivideBCDDivisor + 2], a
- and $f
- or b
- ld [hDivideBCDDivisor + 1], a
- ld a, [hDivideBCDDivisor + 2]
- and $f0
- ld [hDivideBCDDivisor + 2], a
- jr .mulBy10Loop
-
-.next
- push de
- push de
- call DivideBCD_getNextDigit
- pop de
- ld a, b
- swap a
- and $f0
- ld [hDivideBCDBuffer], a
- dec d
- jr z, .next2
- push de
- call DivideBCD_divDivisorBy10
- call DivideBCD_getNextDigit
- pop de
- ld a, [hDivideBCDBuffer]
- or b
- ld [hDivideBCDBuffer], a
- dec d
- jr z, .next2
- push de
- call DivideBCD_divDivisorBy10
- call DivideBCD_getNextDigit
- pop de
- ld a, b
- swap a
- and $f0
- ld [hDivideBCDBuffer + 1], a
- dec d
- jr z, .next2
- push de
- call DivideBCD_divDivisorBy10
- call DivideBCD_getNextDigit
- pop de
- ld a, [hDivideBCDBuffer + 1]
- or b
- ld [hDivideBCDBuffer + 1], a
- dec d
- jr z, .next2
- push de
- call DivideBCD_divDivisorBy10
- call DivideBCD_getNextDigit
- pop de
- ld a, b
- swap a
- and $f0
- ld [hDivideBCDBuffer + 2], a
- dec d
- jr z, .next2
- push de
- call DivideBCD_divDivisorBy10
- call DivideBCD_getNextDigit
- pop de
- ld a, [hDivideBCDBuffer + 2]
- or b
- ld [hDivideBCDBuffer + 2], a
-.next2
- ld a, [hDivideBCDBuffer]
- ld [hDivideBCDQuotient], a ; the same memory location as hDivideBCDDivisor
- ld a, [hDivideBCDBuffer + 1]
- ld [hDivideBCDQuotient + 1], a
- ld a, [hDivideBCDBuffer + 2]
- ld [hDivideBCDQuotient + 2], a
- pop de
- ld a, $6
- sub d
- and a
- ret z
-.divResultBy10loop
- push af
- call DivideBCD_divDivisorBy10
- pop af
- dec a
- jr nz, .divResultBy10loop
- ret
-
-DivideBCD_divDivisorBy10:
- ld a, [hDivideBCDDivisor + 2]
- swap a
- and $f
- ld b, a
- ld a, [hDivideBCDDivisor + 1]
- swap a
- ld [hDivideBCDDivisor + 1], a
- and $f0
- or b
- ld [hDivideBCDDivisor + 2], a
- ld a, [hDivideBCDDivisor + 1]
- and $f
- ld b, a
- ld a, [hDivideBCDDivisor]
- swap a
- ld [hDivideBCDDivisor], a
- and $f0
- or b
- ld [hDivideBCDDivisor + 1], a
- ld a, [hDivideBCDDivisor]
- and $f
- ld [hDivideBCDDivisor], a
- ret
-
-DivideBCD_getNextDigit:
- ld bc, $3
-.loop
- ld de, hMoney ; the dividend
- ld hl, hDivideBCDDivisor
- push bc
- call StringCmp
- pop bc
- ret c
- inc b
- ld de, hMoney + 2 ; since SubBCD works starting from the least significant digit
- ld hl, hDivideBCDDivisor + 2
- push bc
- call SubBCD
- pop bc
- jr .loop
-
-
-AddBCDPredef::
- call GetPredefRegisters
-
-AddBCD::
- and a
- ld b, c
-.add
- ld a, [de]
- adc [hl]
- daa
- ld [de], a
- dec de
- dec hl
- dec c
- jr nz, .add
- jr nc, .done
- ld a, $99
- inc de
-.fill
- ld [de], a
- inc de
- dec b
- jr nz, .fill
-.done
- ret
-
-
-SubBCDPredef::
- call GetPredefRegisters
-
-SubBCD::
- and a
- ld b, c
-.sub
- ld a, [de]
- sbc [hl]
- daa
- ld [de], a
- dec de
- dec hl
- dec c
- jr nz, .sub
- jr nc, .done
- ld a, $00
- inc de
-.fill
- ld [de], a
- inc de
- dec b
- jr nz, .fill
- scf
-.done
- ret
diff --git a/engine/bg_map_attributes.asm b/engine/bg_map_attributes.asm
index 90df9e27..4c50bcf8 100644
--- a/engine/bg_map_attributes.asm
+++ b/engine/bg_map_attributes.asm
@@ -19,37 +19,37 @@ LoadBGMapAttributes::
di
ld a, $1
- ld [rVBK], a
+ ldh [rVBK], a
push hl
ld a, [hl]
ld c, a ; save attribute count for later
ld de, $10
add hl, de
ld a, h
- ld [rHDMA1], a
+ ldh [rHDMA1], a
ld a, l
- ld [rHDMA2], a
+ ldh [rHDMA2], a
ld de, vBGMap0
ld a, d
- ld [rHDMA3], a
+ ldh [rHDMA3], a
ld a, e
- ld [rHDMA4], a
+ ldh [rHDMA4], a
- ld a, [rLCDC]
+ ldh a, [rLCDC]
and rLCDC_ENABLE_MASK ; is LCD off?
jr z, .lcdOff ; if off, transfer immediately
; wait for VBlank if LCD is on
.waitForVBlankLoop1
- ld a, [rLY]
+ ldh a, [rLY]
cp $90
jr nz, .waitForVBlankLoop1
.waitForAccessibleVRAMLoop1
- ld a, [rSTAT]
+ ldh a, [rSTAT]
and %10 ; are we in HBlank or VBlank?
jr nz, .waitForAccessibleVRAMLoop1 ; loop until we're in a safe period to transfer to VRAM
.lcdOff
ld a, c ; number of BG attributes to transfer, plus 1 times 16
- ld [rHDMA5], a ; initiate transfer
+ ldh [rHDMA5], a ; initiate transfer
call Func_3082 ; update audio so it doesn't "lag"
pop hl
ld a, [hli]
@@ -60,30 +60,30 @@ LoadBGMapAttributes::
ld d, a ; offset of the attributes
add hl, de ; hl = new pointer
ld a, h
- ld [rHDMA1], a
+ ldh [rHDMA1], a
ld a, l
- ld [rHDMA2], a
+ ldh [rHDMA2], a
ld de, vBGMap1 ; copy to vBGMap1
ld a, d
- ld [rHDMA3], a
+ ldh [rHDMA3], a
ld a, e
- ld [rHDMA4], a
+ ldh [rHDMA4], a
; LCD check again
- ld a, [rLCDC]
+ ldh a, [rLCDC]
and rLCDC_ENABLE_MASK ; is LCD off?
jr z, .lcdOff2 ; if off, transfer immediately
; wait for VBlank if LCD is on
.waitForVBlankLoop2
- ld a, [rLY]
+ ldh a, [rLY]
cp $90
jr nz, .waitForVBlankLoop2
.waitForAccessibleVRAMLoop2
- ld a, [rSTAT]
+ ldh a, [rSTAT]
and %10 ; are we in HBlank or VBlank?
jr nz, .waitForAccessibleVRAMLoop2 ; loop until we're in a safe period to transfer to VRAM
.lcdOff2
ld a, c
- ld [rHDMA5], a
+ ldh [rHDMA5], a
pop af
dec a
dec a
@@ -97,11 +97,11 @@ LoadBGMapAttributes::
call z, HandlePartyHPBarAttributes
.done
call Func_3082
- ld a, [rIF]
+ ldh a, [rIF]
res VBLANK, a
- ld [rIF], a
+ ldh [rIF], a
xor a
- ld [rVBK], a
+ ldh [rVBK], a
ei
ret
diff --git a/engine/black_out.asm b/engine/black_out.asm
deleted file mode 100644
index 0daa084b..00000000
--- a/engine/black_out.asm
+++ /dev/null
@@ -1,48 +0,0 @@
-ResetStatusAndHalveMoneyOnBlackout::
-; Reset player status on blackout.
- xor a
- ld [wd435], a
- xor a ; gamefreak copypasting functions (double xor a)
- ld [wBattleResult], a
- ld [wWalkBikeSurfState], a
- ld [wIsInBattle], a
- ld [wMapPalOffset], a
- ld [wNPCMovementScriptFunctionNum], a
- ld [hJoyHeld], a
- ld [wNPCMovementScriptPointerTableNum], a
- ld [wFlags_0xcd60], a
-
- ld [hMoney], a
- ld [hMoney + 1], a
- ld [hMoney + 2], a
- call HasEnoughMoney
- jr c, .lostmoney ; never happens
-
- ; Halve the player's money.
- ld a, [wPlayerMoney]
- ld [hMoney], a
- ld a, [wPlayerMoney + 1]
- ld [hMoney + 1], a
- ld a, [wPlayerMoney + 2]
- ld [hMoney + 2], a
- xor a
- ld [hDivideBCDDivisor], a
- ld [hDivideBCDDivisor + 1], a
- ld a, 2
- ld [hDivideBCDDivisor + 2], a
- predef DivideBCDPredef3
- ld a, [hDivideBCDQuotient]
- ld [wPlayerMoney], a
- ld a, [hDivideBCDQuotient + 1]
- ld [wPlayerMoney + 1], a
- ld a, [hDivideBCDQuotient + 2]
- ld [wPlayerMoney + 2], a
-
-.lostmoney
- ld hl, wd732
- set 2, [hl]
- res 3, [hl]
- set 6, [hl]
- ld a, %11111111
- ld [wJoyIgnore], a
- predef_jump HealParty
diff --git a/engine/debug/debug_menu.asm b/engine/debug/debug_menu.asm
new file mode 100644
index 00000000..a85c9c64
--- /dev/null
+++ b/engine/debug/debug_menu.asm
@@ -0,0 +1,46 @@
+DebugMenu:
+ ret
+
+TestBattle:
+.loop
+ call GBPalNormal
+
+ ; Don't mess around
+ ; with obedience.
+ ld a, 1 << BIT_EARTHBADGE
+ ld [wObtainedBadges], a
+
+ ld hl, wFlags_D733
+ set BIT_TEST_BATTLE, [hl]
+
+ ; Reset the party.
+ ld hl, wPartyCount
+ xor a
+ ld [hli], a
+ dec a
+ ld [hl], a
+
+ ; Give the player a
+ ; level 20 Rhydon.
+ ld a, RHYDON
+ ld [wcf91], a
+ ld a, 20
+ ld [wCurEnemyLVL], a
+ xor a
+ ld [wMonDataLocation], a
+ ld [wCurMap], a
+ call AddPartyMon
+
+ ; Fight against a
+ ; level 20 Rhydon.
+ ld a, RHYDON
+ ld [wCurOpponent], a
+
+ predef InitOpponent
+
+ ; When the battle ends,
+ ; do it all again.
+ ld a, 1
+ ld [wUpdateSpritesEnabled], a
+ ldh [hAutoBGTransferEnabled], a
+ jr .loop
diff --git a/engine/debug/debug_party.asm b/engine/debug/debug_party.asm
new file mode 100644
index 00000000..8545b848
--- /dev/null
+++ b/engine/debug/debug_party.asm
@@ -0,0 +1,24 @@
+; not IshiharaTeam
+SetDebugTeam:
+ ld de, DebugTeam
+.loop
+ ld a, [de]
+ cp -1
+ ret z
+ ld [wcf91], a
+ inc de
+ ld a, [de]
+ ld [wCurEnemyLVL], a
+ inc de
+ call AddPartyMon
+ jr .loop
+
+DebugTeam:
+ db SNORLAX, 80
+ db PERSIAN, 80
+ db JIGGLYPUFF, 15
+ db PIKACHU, 5
+ db -1 ; end
+
+DebugStart:
+ ret
diff --git a/engine/debug1.asm b/engine/debug1.asm
deleted file mode 100644
index a39e8cac..00000000
--- a/engine/debug1.asm
+++ /dev/null
@@ -1,24 +0,0 @@
-; not IshiharaTeam
-SetDebugTeam:
- ld de, DebugTeam
-.loop
- ld a, [de]
- cp $ff
- ret z
- ld [wcf91], a
- inc de
- ld a, [de]
- ld [wCurEnemyLVL], a
- inc de
- call AddPartyMon
- jr .loop
-
-DebugTeam:
- db SNORLAX,80
- db PERSIAN,80
- db JIGGLYPUFF,15
- db PIKACHU,5
- db $FF
-
-EmptyFunc:
- ret
diff --git a/engine/diploma_3a.asm b/engine/diploma_3a.asm
index f4504ad7..83a7345b 100755
--- a/engine/diploma_3a.asm
+++ b/engine/diploma_3a.asm
@@ -1,3 +1,5 @@
+CIRCLE_TILE_ID EQU $10
+
_DisplayDiploma:
call GBPalWhiteOutWithDelay3
call ClearScreen
@@ -6,51 +8,51 @@ _DisplayDiploma:
lb bc, BANK(SurfingPikachu3Graphics), (SurfingPikachu3GraphicsEnd - SurfingPikachu3Graphics) / $10
call CopyVideoData
- coord hl, 0, 0
+ hlcoord 0, 0
call Func_e9bdf
- coord hl, 0, 0
+ hlcoord 0, 0
call Func_e9beb
- coord hl, 19, 0
+ hlcoord 19, 0
call Func_e9beb
ld a, $00
- coord hl, 0, 0
+ hlcoord 0, 0
ld [hl], a
- coord hl, 19, 0
+ hlcoord 19, 0
ld [hl], a
ld de, String_e9a73
- coord hl, 5, 2
+ hlcoord 5, 2
call PlaceString
ld de, String_e9a7d
- coord hl, 3, 4
+ hlcoord 3, 4
call PlaceString
ld de, wPlayerName
- coord hl, 10, 4
+ hlcoord 10, 4
call PlaceString
ld de, String_e9a84
- coord hl, 2, 6
+ hlcoord 2, 6
call PlaceString
ld de, String_e9ac8
- coord hl, 9, 16
+ hlcoord 9, 16
call PlaceString
ld b, SET_PAL_GENERIC
call RunPaletteCommand
ld a, $01
- ld [$ffba], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call GBPalNormal
ret
String_e9a73:
- db $10, "Diploma", $10, "@"
+ db CIRCLE_TILE_ID, "Diploma", CIRCLE_TILE_ID, "@"
String_e9a7d:
db "Player@"
@@ -67,29 +69,29 @@ String_e9ac8:
Func_e9ad3:
call ClearScreen
- coord hl, 0, 17
+ hlcoord 0, 17
call Func_e9bdf
- coord hl, 0, 0
+ hlcoord 0, 0
call Func_e9beb
- coord hl, 19, 0
+ hlcoord 19, 0
call Func_e9beb
ld a, $00
- coord hl, 0, 17
+ hlcoord 0, 17
ld [hl], a
- coord hl, 19, 17
+ hlcoord 19, 17
ld [hl], a
ld de, Tilemap_e9b3e
- coord hl, 6, 2
+ hlcoord 6, 2
lb bc, 10, 12
call Diploma_Surfing_CopyBox
ld de, Tilemap_e9bb6
- coord hl, 5, 13
+ hlcoord 5, 13
lb bc, 1, 11
call Diploma_Surfing_CopyBox
ld de, String_e9bd5
- coord hl, 2, 15
+ hlcoord 2, 15
call PlaceString
- coord hl, 12, 15
+ hlcoord 12, 15
ld de, wPlayTimeHours
lb bc, $40 | 1, 3
call PrintNumber
@@ -102,7 +104,7 @@ Func_e9ad3:
cp 151
ret nz
ld de, TileMap_e9bc1
- coord hl, 2, 0
+ hlcoord 2, 0
lb bc, 4, 5
call Diploma_Surfing_CopyBox
ret
diff --git a/engine/display_text_id_init.asm b/engine/display_text_id_init.asm
deleted file mode 100644
index 0ef37370..00000000
--- a/engine/display_text_id_init.asm
+++ /dev/null
@@ -1,75 +0,0 @@
-; function that performs initialization for DisplayTextID
-DisplayTextIDInit:
- xor a
- ld [wListMenuID], a
- ld a, [wAutoTextBoxDrawingControl]
- bit 0, a
- jr nz, .skipDrawingTextBoxBorder
- ld a, [hSpriteIndexOrTextID] ; text ID (or sprite ID)
- and a
- jr nz, .notStartMenu
-; if text ID is 0 (i.e. the start menu)
-; Note that the start menu text border is also drawn in the function directly
-; below this, so this seems unnecessary.
- CheckEvent EVENT_GOT_POKEDEX
-; start menu with pokedex
- coord hl, 10, 0
- lb bc, 14, 8
- jr nz, .drawTextBoxBorder
-; start menu without pokedex
- coord hl, 10, 0
- lb bc, 12, 8
- jr .drawTextBoxBorder
-; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box
-.notStartMenu
- coord hl, 0, 12
- lb bc, 4, 18
-.drawTextBoxBorder
- call TextBoxBorder
-.skipDrawingTextBoxBorder
- ld hl, wFontLoaded
- set 0, [hl]
- ld hl, wFlags_0xcd60
- bit 4, [hl]
- res 4, [hl]
- jr nz, .skipMovingSprites
- call UpdateSprites
-.skipMovingSprites
-; loop to copy C1X9 (direction the sprite is facing) to C2X9 for each sprite
-; this is done because when you talk to an NPC, they turn to look your way
-; the original direction they were facing must be restored after the dialogue is over
- ld hl, wSpriteStateData1 + $19
- ld c, $0f
- ld de, $0010
-.spriteFacingDirectionCopyLoop
- ld a, [hl]
- inc h
- ld [hl], a
- dec h
- add hl, de
- dec c
- jr nz, .spriteFacingDirectionCopyLoop
-; loop to force all the sprites in the middle of animation to stand still
-; (so that they don't like they're frozen mid-step during the dialogue)
- ld hl, wSpriteStateData1 + 2
- ld de, $0010
- ld c, e
-.spriteStandStillLoop
- ld a, [hl]
- cp $ff ; is the sprite visible?
- jr z, .nextSprite
-; if it is visible
- and $fc
- ld [hl], a
-.nextSprite
- add hl, de
- dec c
- jr nz, .spriteStandStillLoop
- ld b, $9c ; window background address
- call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM
- xor a
- ld [hWY], a ; put the window on the screen
- call LoadFontTilePatterns
- ld a, $01
- ld [H_AUTOBGTRANSFERENABLED], a ; enable continuous WRAM to VRAM transfer each V-blank
- ret
diff --git a/engine/events/black_out.asm b/engine/events/black_out.asm
new file mode 100644
index 00000000..6d3d91b8
--- /dev/null
+++ b/engine/events/black_out.asm
@@ -0,0 +1,48 @@
+ResetStatusAndHalveMoneyOnBlackout::
+; Reset player status on blackout.
+ xor a
+ ld [wd435], a
+ xor a ; gamefreak copypasting functions (double xor a)
+ ld [wBattleResult], a
+ ld [wWalkBikeSurfState], a
+ ld [wIsInBattle], a
+ ld [wMapPalOffset], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ldh [hJoyHeld], a
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld [wFlags_0xcd60], a
+
+ ldh [hMoney], a
+ ldh [hMoney + 1], a
+ ldh [hMoney + 2], a
+ call HasEnoughMoney
+ jr c, .lostmoney ; never happens
+
+ ; Halve the player's money.
+ ld a, [wPlayerMoney]
+ ldh [hMoney], a
+ ld a, [wPlayerMoney + 1]
+ ldh [hMoney + 1], a
+ ld a, [wPlayerMoney + 2]
+ ldh [hMoney + 2], a
+ xor a
+ ldh [hDivideBCDDivisor], a
+ ldh [hDivideBCDDivisor + 1], a
+ ld a, 2
+ ldh [hDivideBCDDivisor + 2], a
+ predef DivideBCDPredef3
+ ldh a, [hDivideBCDQuotient]
+ ld [wPlayerMoney], a
+ ldh a, [hDivideBCDQuotient + 1]
+ ld [wPlayerMoney + 1], a
+ ldh a, [hDivideBCDQuotient + 2]
+ ld [wPlayerMoney + 2], a
+
+.lostmoney
+ ld hl, wd732
+ set 2, [hl]
+ res 3, [hl]
+ set 6, [hl]
+ ld a, %11111111
+ ld [wJoyIgnore], a
+ predef_jump HealParty
diff --git a/engine/events/card_key.asm b/engine/events/card_key.asm
new file mode 100755
index 00000000..de5f402e
--- /dev/null
+++ b/engine/events/card_key.asm
@@ -0,0 +1,102 @@
+PrintCardKeyText:
+ ld hl, SilphCoMapList
+ ld a, [wCurMap]
+ ld b, a
+.silphCoMapListLoop
+ ld a, [hli]
+ cp -1
+ ret z
+ cp b
+ jr nz, .silphCoMapListLoop
+; does not check for tile in front of player. This might be buggy
+ ;predef GetTileAndCoordsInFrontOfPlayer
+ ld a, [wTileInFrontOfPlayer]
+ cp $18
+ jr z, .cardKeyDoorInFrontOfPlayer
+ cp $24
+ jr z, .cardKeyDoorInFrontOfPlayer
+ ld b, a
+ ld a, [wCurMap]
+ cp SILPH_CO_11F
+ ret nz
+ ld a, b
+ cp $5e
+ ret nz
+.cardKeyDoorInFrontOfPlayer
+ ld b, CARD_KEY
+ call IsItemInBag
+ jr z, .noCardKey
+ xor a
+ ld [wPlayerMovingDirection], a
+ tx_pre_id CardKeySuccessText
+ ldh [hSpriteIndexOrTextID], a
+ call PrintPredefTextID
+ call GetCoordsInFrontOfPlayer
+ srl d
+ ld a, d
+ ld b, a
+ ld [wCardKeyDoorY], a
+ srl e
+ ld a, e
+ ld c, a
+ ld [wCardKeyDoorX], a
+ ld a, [wCurMap]
+ cp SILPH_CO_11F
+ jr nz, .notSilphCo11F
+ ld a, $3
+ jr .replaceCardKeyDoorTileBlock
+.notSilphCo11F
+ ld a, $e
+.replaceCardKeyDoorTileBlock
+ ld [wNewTileBlockID], a
+ predef ReplaceTileBlock
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+ ld a, SFX_GO_INSIDE
+ jp PlaySound
+.noCardKey
+ tx_pre_id CardKeyFailText
+ ldh [hSpriteIndexOrTextID], a
+ jp PrintPredefTextID
+
+INCLUDE "data/events/card_key_maps.asm"
+
+CardKeySuccessText::
+ text_far _CardKeySuccessText1
+ sound_get_item_1
+ text_far _CardKeySuccessText2
+ text_end
+
+CardKeyFailText::
+ text_far _CardKeyFailText
+ text_end
+
+; d = Y
+; e = X
+GetCoordsInFrontOfPlayer:
+ ld a, [wYCoord]
+ ld d, a
+ ld a, [wXCoord]
+ ld e, a
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ and a
+ jr nz, .notFacingDown
+; facing down
+ inc d
+ ret
+.notFacingDown
+ cp SPRITE_FACING_UP
+ jr nz, .notFacingUp
+; facing up
+ dec d
+ ret
+.notFacingUp
+ cp SPRITE_FACING_LEFT
+ jr nz, .notFacingLeft
+; facing left
+ dec e
+ ret
+.notFacingLeft
+; facing right
+ inc e
+ ret
diff --git a/engine/overworld/cinnabar_lab.asm b/engine/events/cinnabar_lab.asm
index 13313746..bccc95d1 100755
--- a/engine/overworld/cinnabar_lab.asm
+++ b/engine/events/cinnabar_lab.asm
@@ -1,4 +1,4 @@
-GiveFossilToCinnabarLab:
+GiveFossilToCinnabarLab::
ld hl, wd730
set 6, [hl]
xor a
@@ -20,7 +20,7 @@ GiveFossilToCinnabarLab:
dec l
ld b, l
ld c, $d
- coord hl, 0, 0
+ hlcoord 0, 0
call TextBoxBorder
call UpdateSprites
call PrintFossilsInBag
@@ -35,7 +35,7 @@ GiveFossilToCinnabarLab:
ld e, a
add hl, de
ld a, [hl]
- ld [$ffdb], a
+ ldh [hItemToRemoveID], a
cp DOME_FOSSIL
jr z, .choseDomeFossil
cp HELIX_FOSSIL
@@ -61,8 +61,8 @@ GiveFossilToCinnabarLab:
ld hl, LabFossil_610b3
call PrintText
ld a, [wFossilItem]
- ld [hItemToRemoveID], a
- callba RemoveItemByID
+ ldh [hItemToRemoveID], a
+ farcall RemoveItemByID
ld hl, LabFossil_610b8
call PrintText
SetEvents EVENT_GAVE_FOSSIL_TO_LAB, EVENT_LAB_STILL_REVIVING_FOSSIL
@@ -73,26 +73,26 @@ GiveFossilToCinnabarLab:
ret
LabFossil_610ae:
- TX_FAR _Lab4Text_610ae
- db "@"
+ text_far _Lab4Text_610ae
+ text_end
LabFossil_610b3:
- TX_FAR _Lab4Text_610b3
- db "@"
+ text_far _Lab4Text_610b3
+ text_end
LabFossil_610b8:
- TX_FAR _Lab4Text_610b8
- db "@"
+ text_far _Lab4Text_610b8
+ text_end
LabFossil_610bd:
- TX_FAR _Lab4Text_610bd
- db "@"
+ text_far _Lab4Text_610bd
+ text_end
PrintFossilsInBag:
; Prints each fossil in the player's bag on a separate line in the menu.
ld hl, wFilteredBagItems
xor a
- ld [hItemCounter], a
+ ldh [hItemCounter], a
.loop
ld a, [hli]
cp $ff
@@ -100,8 +100,8 @@ PrintFossilsInBag:
push hl
ld [wd11e], a
call GetItemName
- coord hl, 2, 2
- ld a, [hItemCounter]
+ hlcoord 2, 2
+ ldh a, [hItemCounter]
ld bc, SCREEN_WIDTH * 2
call AddNTimes
ld de, wcd6d
@@ -112,7 +112,7 @@ PrintFossilsInBag:
jr .loop
; loads the names of the fossil item and the resulting mon
-LoadFossilItemAndMonName:
+LoadFossilItemAndMonName::
ld a, [wFossilMon]
ld [wd11e], a
call GetMonName
diff --git a/engine/menu/diploma.asm b/engine/events/diploma.asm
index 3f309bd2..a5a007fa 100644
--- a/engine/menu/diploma.asm
+++ b/engine/events/diploma.asm
@@ -1,4 +1,4 @@
-DisplayDiploma:
+DisplayDiploma::
call SaveScreenTilesToBuffer2
call GBPalWhiteOutWithDelay3
call ClearScreen
@@ -6,7 +6,7 @@ DisplayDiploma:
ld [wUpdateSpritesEnabled], a
ld hl, wd730
set 6, [hl]
- callab _DisplayDiploma
+ callfar _DisplayDiploma
call WaitForTextScrollButtonPress
ld hl, wd730
res 6, [hl]
diff --git a/engine/display_pokedex.asm b/engine/events/display_pokedex.asm
index 96a2dd6c..d657ea85 100644
--- a/engine/display_pokedex.asm
+++ b/engine/events/display_pokedex.asm
@@ -1,4 +1,4 @@
-_DisplayPokedex:
+_DisplayPokedex::
ld hl, wd730
set 6, [hl]
predef ShowPokedexData
diff --git a/engine/events/elevator.asm b/engine/events/elevator.asm
new file mode 100755
index 00000000..004893a0
--- /dev/null
+++ b/engine/events/elevator.asm
@@ -0,0 +1,54 @@
+DisplayElevatorFloorMenu:
+ ld hl, wd730
+ ld a, [hl]
+ push af
+ set 6, [hl]
+ ld hl, WhichFloorText
+ call PrintText
+ pop af
+ ld [wd730], a
+ ld hl, wItemList
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ ld a, [wListScrollOffset]
+ push af
+ xor a
+ ld [wCurrentMenuItem], a
+ ld [wListScrollOffset], a
+ ld [wPrintItemPrices], a
+ ld a, SPECIALLISTMENU
+ ld [wListMenuID], a
+ call DisplayListMenuID
+ pop bc
+ ld a, b
+ ld [wListScrollOffset], a
+ ret c
+ ld hl, wCurrentMapScriptFlags
+ set 7, [hl]
+ ld hl, wElevatorWarpMaps
+ ld a, [wWhichPokemon]
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hli]
+ ld b, a
+ ld a, [hl]
+ ld c, a
+ ld hl, wWarpEntries
+ call .UpdateWarp
+
+.UpdateWarp
+ inc hl
+ inc hl
+ ld a, b
+ ld [hli], a ; destination warp ID
+ ld a, c
+ ld [hli], a ; destination map ID
+ ret
+
+WhichFloorText:
+ text_far _WhichFloorText
+ text_end
diff --git a/engine/give_pokemon.asm b/engine/events/give_pokemon.asm
index 6fdca2ef..efc184f8 100755
--- a/engine/give_pokemon.asm
+++ b/engine/events/give_pokemon.asm
@@ -1,4 +1,4 @@
-_GivePokemon:
+_GivePokemon::
; returns success in carry
; and whether the mon was added to the party in [wAddedToParty]
call EnableAutoTextBoxDrawing
@@ -15,9 +15,9 @@ _GivePokemon:
ld [wEnemyBattleStatus3], a
ld a, [wcf91]
ld [wEnemyMonSpecies2], a
- callab LoadEnemyMonData
+ callfar LoadEnemyMonData
call SetPokedexOwnedFlag
- callab SendNewMonToBox
+ callfar SendNewMonToBox
ld hl, wcf4b
ld a, [wCurrentBoxNum]
and $7f
@@ -33,7 +33,7 @@ _GivePokemon:
.next
ld [hli], a
ld [hl], "@"
- ld hl, SetToBoxText
+ ld hl, SentToBoxText
call PrintText
scf
ret
@@ -71,17 +71,17 @@ SetPokedexOwnedFlag:
jp PrintText
UnknownTerminator_f6794:
- db "@"
+ text_end
GotMonText:
- TX_FAR _GotMonText
- TX_SFX_ITEM_1
- db "@"
+ text_far _GotMonText
+ sound_get_item_1
+ text_end
-SetToBoxText:
- TX_FAR _SetToBoxText
- db "@"
+SentToBoxText:
+ text_far _SentToBoxText
+ text_end
BoxIsFullText:
- TX_FAR _BoxIsFullText
- db "@"
+ text_far _BoxIsFullText
+ text_end
diff --git a/engine/heal_party.asm b/engine/events/heal_party.asm
index 7aaa1bd1..7aaa1bd1 100644
--- a/engine/heal_party.asm
+++ b/engine/events/heal_party.asm
diff --git a/engine/overworld/hidden_items.asm b/engine/events/hidden_items.asm
index b64411c7..63b95bcf 100755
--- a/engine/overworld/hidden_items.asm
+++ b/engine/events/hidden_items.asm
@@ -20,14 +20,14 @@ HiddenItems:
.itemAlreadyFound
ld a, $ff
- ld [hItemAlreadyFound], a
+ ldh [hItemAlreadyFound], a
ret
-INCLUDE "data/hidden_item_coords.asm"
+INCLUDE "data/events/hidden_item_coords.asm"
-FoundHiddenItemText:
- TX_FAR _FoundHiddenItemText
- TX_ASM
+FoundHiddenItemText::
+ text_far _FoundHiddenItemText
+ text_asm
ld a, [wHiddenObjectFunctionArgument] ; item ID
ld b, a
ld c, 1
@@ -50,9 +50,9 @@ FoundHiddenItemText:
call PrintText
jp TextScriptEnd
-HiddenItemBagFullText:
- TX_FAR _HiddenItemBagFullText
- db "@"
+HiddenItemBagFullText::
+ text_far _HiddenItemBagFullText
+ text_end
HiddenCoins:
ld b, COIN_CASE
@@ -72,9 +72,9 @@ HiddenCoins:
and a
jr nz, .doNotPickUpCoins
xor a
- ld [hUnusedCoinsByte], a
- ld [hCoins], a
- ld [hCoins + 1], a
+ ldh [hUnusedCoinsByte], a
+ ldh [hCoins], a
+ ldh [hCoins + 1], a
ld a, [wHiddenObjectFunctionArgument]
sub COIN
cp 10
@@ -87,24 +87,24 @@ HiddenCoins:
.doNotPickUpCoins
ld a, $ff
- ld [hItemAlreadyFound], a
+ ldh [hItemAlreadyFound], a
ret
.bcd10
ld a, $10
- ld [hCoins + 1], a
+ ldh [hCoins + 1], a
jr .bcdDone
.bcd20
ld a, $20
- ld [hCoins + 1], a
+ ldh [hCoins + 1], a
jr .bcdDone
.bcd40 ; due to a typo, this is never used
ld a, $40
- ld [hCoins + 1], a
+ ldh [hCoins + 1], a
jr .bcdDone
.bcd100
ld a, $1
- ld [hCoins], a
+ ldh [hCoins], a
.bcdDone
ld de, wPlayerCoins + 1
ld hl, hCoins + 1
@@ -129,18 +129,18 @@ HiddenCoins:
.done
jp PrintPredefTextID
-INCLUDE "data/hidden_coins.asm"
+INCLUDE "data/events/hidden_coins.asm"
-FoundHiddenCoinsText:
- TX_FAR _FoundHiddenCoinsText
- TX_SFX_ITEM_2
- db "@"
+FoundHiddenCoinsText::
+ text_far _FoundHiddenCoinsText
+ sound_get_item_2
+ text_end
-DroppedHiddenCoinsText:
- TX_FAR _FoundHiddenCoins2Text
- TX_SFX_ITEM_2
- TX_FAR _DroppedHiddenCoinsText
- db "@"
+DroppedHiddenCoinsText::
+ text_far _FoundHiddenCoins2Text
+ sound_get_item_2
+ text_far _DroppedHiddenCoinsText
+ text_end
FindHiddenItemOrCoinsIndex:
ld a, [wHiddenObjectY]
@@ -153,7 +153,7 @@ FindHiddenItemOrCoinsIndex:
.loop
inc c
ld a, [hli]
- cp $ff ; end of the list?
+ cp -1 ; end of the list?
ret z ; if so, we're done here
cp b
jr nz, .next1
diff --git a/engine/events/hidden_objects/bench_guys.asm b/engine/events/hidden_objects/bench_guys.asm
new file mode 100644
index 00000000..b41434ad
--- /dev/null
+++ b/engine/events/hidden_objects/bench_guys.asm
@@ -0,0 +1,98 @@
+PrintBenchGuyText:
+ call EnableAutoTextBoxDrawing
+ ld hl, BenchGuyTextPointers
+ ld a, [wCurMap]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp -1
+ ret z
+ cp b
+ jr z, .match
+ inc hl
+ inc hl
+ jr .loop
+.match
+ ld a, [hli]
+ ld b, a
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp b
+ jr nz, .loop ; player isn't facing the bench guy
+ ld a, [hl]
+ jp PrintPredefTextID
+
+INCLUDE "data/events/bench_guys.asm"
+
+ViridianCityPokecenterBenchGuyText::
+ text_far _ViridianCityPokecenterGuyText
+ text_end
+
+PewterCityPokecenterBenchGuyText::
+ text_far _PewterCityPokecenterGuyText
+ text_end
+
+CeruleanCityPokecenterBenchGuyText::
+ text_far _CeruleanPokecenterGuyText
+ text_end
+
+LavenderCityPokecenterBenchGuyText::
+ text_far _LavenderPokecenterGuyText
+ text_end
+
+MtMoonPokecenterBenchGuyText::
+ text_far _MtMoonPokecenterBenchGuyText
+ text_end
+
+RockTunnelPokecenterBenchGuyText::
+ text_far _RockTunnelPokecenterGuyText
+ text_end
+
+UnusedBenchGuyText1::
+ text_far _UnusedBenchGuyText1
+ text_end
+
+UnusedBenchGuyText2::
+ text_far _UnusedBenchGuyText2
+ text_end
+
+UnusedBenchGuyText3::
+ text_far _UnusedBenchGuyText3
+ text_end
+
+VermilionCityPokecenterBenchGuyText::
+ text_far _VermilionPokecenterGuyText
+ text_end
+
+CeladonCityPokecenterBenchGuyText::
+ text_far _CeladonCityPokecenterGuyText
+ text_end
+
+FuchsiaCityPokecenterBenchGuyText::
+ text_far _FuchsiaCityPokecenterGuyText
+ text_end
+
+CinnabarIslandPokecenterBenchGuyText::
+ text_far _CinnabarPokecenterGuyText
+ text_end
+
+SaffronCityPokecenterBenchGuyText::
+ text_asm
+ CheckEvent EVENT_BEAT_SILPH_CO_GIOVANNI
+ ld hl, SaffronCityPokecenterBenchGuyText2
+ jr nz, .asm_624f2
+ ld hl, SaffronCityPokecenterBenchGuyText1
+.asm_624f2
+ call PrintText
+ jp TextScriptEnd
+
+SaffronCityPokecenterBenchGuyText1:
+ text_far _SaffronCityPokecenterGuyText1
+ text_end
+
+SaffronCityPokecenterBenchGuyText2:
+ text_far _SaffronCityPokecenterGuyText2
+ text_end
+
+CeladonCityHotelText::
+ text_far _CeladonCityHotelText
+ text_end
diff --git a/engine/events/hidden_objects/bills_house_pc.asm b/engine/events/hidden_objects/bills_house_pc.asm
new file mode 100644
index 00000000..bdbaff7e
--- /dev/null
+++ b/engine/events/hidden_objects/bills_house_pc.asm
@@ -0,0 +1,131 @@
+BillsHousePC:
+ call EnableAutoTextBoxDrawing
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ 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::
+ text_far _BillsHouseMonitorText
+ text_end
+
+BillsHouseInitiatedText::
+ text_far _BillsHouseInitiatedText
+ text_promptbutton
+ text_asm
+ call StopAllMusic
+ ld c, 16
+ call DelayFrames
+ ld a, SFX_SWITCH
+ call PlaySound
+ call WaitForSoundToFinish
+ ld c, 60
+ call DelayFrames
+ jp TextScriptEnd
+
+BillsHousePokemonList::
+ text_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]
+ hlcoord 0, 0
+ lb bc, 10, 9
+ call TextBoxBorder
+ hlcoord 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:
+ text_far _BillsHousePokemonListText1
+ text_end
+
+BillsMonListText:
+ db "EEVEE"
+ next "FLAREON"
+ next "JOLTEON"
+ next "VAPOREON"
+ next "CANCEL@"
+
+BillsHousePokemonListText2:
+ text_far _BillsHousePokemonListText2
+ text_end
diff --git a/engine/events/hidden_objects/blues_room.asm b/engine/events/hidden_objects/blues_room.asm
new file mode 100644
index 00000000..bcbad556
--- /dev/null
+++ b/engine/events/hidden_objects/blues_room.asm
@@ -0,0 +1,13 @@
+
+ ret ; unused
+
+UnusedPredefText::
+ db "@"
+
+PrintBookcaseText:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump BookcaseText
+
+BookcaseText::
+ text_far _BookcaseText
+ text_end
diff --git a/engine/events/hidden_objects/book_or_sculpture.asm b/engine/events/hidden_objects/book_or_sculpture.asm
new file mode 100644
index 00000000..e04f4047
--- /dev/null
+++ b/engine/events/hidden_objects/book_or_sculpture.asm
@@ -0,0 +1,21 @@
+BookOrSculptureText::
+ text_asm
+ ld hl, PokemonBooksText
+ ld a, [wCurMapTileset]
+ cp MANSION ; Celadon Mansion tileset
+ jr nz, .ok
+ lda_coord 8, 6
+ cp $38
+ jr nz, .ok
+ ld hl, DiglettSculptureText
+.ok
+ call PrintText
+ jp TextScriptEnd
+
+PokemonBooksText:
+ text_far _PokemonBooksText
+ text_end
+
+DiglettSculptureText:
+ text_far _DiglettSculptureText
+ text_end
diff --git a/engine/events/hidden_objects/bookshelves.asm b/engine/events/hidden_objects/bookshelves.asm
new file mode 100644
index 00000000..b58444af
--- /dev/null
+++ b/engine/events/hidden_objects/bookshelves.asm
@@ -0,0 +1,39 @@
+; prints text for bookshelves in buildings without sign events
+PrintBookshelfText::
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ jr nz, .noMatch
+; facing up
+ ld a, [wCurMapTileset]
+ ld b, a
+ lda_coord 8, 7
+ ld c, a
+ ld hl, BookshelfTileIDs
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .noMatch
+ cp b
+ jr nz, .nextBookshelfEntry1
+ ld a, [hli]
+ cp c
+ jr nz, .nextBookshelfEntry2
+ ld a, [hl]
+ push af
+ call EnableAutoTextBoxDrawing
+ pop af
+ call PrintPredefTextID
+ xor a
+ ldh [hFFDB], a
+ ret
+.nextBookshelfEntry1
+ inc hl
+.nextBookshelfEntry2
+ inc hl
+ jr .loop
+.noMatch
+ ld a, $ff
+ ldh [hFFDB], a
+ farjp PrintCardKeyText
+
+INCLUDE "data/tilesets/bookshelf_tile_ids.asm"
diff --git a/engine/events/hidden_objects/cinnabar_gym_quiz.asm b/engine/events/hidden_objects/cinnabar_gym_quiz.asm
new file mode 100644
index 00000000..da550c76
--- /dev/null
+++ b/engine/events/hidden_objects/cinnabar_gym_quiz.asm
@@ -0,0 +1,246 @@
+PrintCinnabarQuiz:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump CinnabarGymQuiz
+
+CinnabarGymQuiz::
+ text_asm
+ xor a
+ ld [wOpponentAfterWrongAnswer], a
+ ld hl, wd475
+ res 7, [hl]
+ ld a, [wHiddenObjectFunctionArgument]
+ push af
+ and $f
+ ldh [hGymGateIndex], a
+ pop af
+ and $f0
+ swap a
+ ldh [hGymGateAnswer], a
+ ldh a, [hGymGateIndex]
+ ld hl, CinnabarGymQuizIntroText
+ cp 1
+ jr z, .onFirstQuestion
+ ld hl, CinnabarGymQuizShortIntroText
+.onFirstQuestion
+ call PrintText
+ ldh 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
+
+CinnabarGymQuizDummyIntroText:
+ text_far _CinnabarGymQuizDummyIntroText
+ text_end
+
+CinnabarGymQuizIntroText:
+ text_far _CinnabarGymQuizIntroText
+ text_end
+
+CinnabarGymQuizShortIntroText:
+ text_far _CinnabarGymQuizShortIntroText
+ text_end
+
+CinnabarQuizQuestions:
+ dw CinnabarQuizQuestionsText1
+ dw CinnabarQuizQuestionsText2
+ dw CinnabarQuizQuestionsText3
+ dw CinnabarQuizQuestionsText4
+ dw CinnabarQuizQuestionsText5
+ dw CinnabarQuizQuestionsText6
+
+CinnabarQuizQuestionsText1:
+ text_far _CinnabarQuizQuestionsText1
+ text_end
+
+CinnabarQuizQuestionsText2:
+ text_far _CinnabarQuizQuestionsText2
+ text_end
+
+CinnabarQuizQuestionsText3:
+ text_far _CinnabarQuizQuestionsText3
+ text_end
+
+CinnabarQuizQuestionsText4:
+ text_far _CinnabarQuizQuestionsText4
+ text_end
+
+CinnabarQuizQuestionsText5:
+ text_far _CinnabarQuizQuestionsText5
+ text_end
+
+CinnabarQuizQuestionsText6:
+ text_far _CinnabarQuizQuestionsText6
+ text_end
+
+CinnabarGymQuiz_1ea92:
+ call YesNoChoice
+ ldh a, [hGymGateAnswer]
+ ld c, a
+ ld a, [wCurrentMenuItem]
+ cp c
+ jr nz, .wrongAnswer
+ ld hl, wCurrentMapScriptFlags
+ set 5, [hl]
+ ldh a, [hGymGateIndex]
+ ldh [hBackupGymGateIndex], a
+ ld hl, CinnabarGymQuizCorrectText
+ call PrintText
+ ldh a, [hBackupGymGateIndex]
+ 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
+ ldh 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
+ ldh a, [hGymGateIndex]
+ add $2
+ ld [wOpponentAfterWrongAnswer], a
+ ld hl, wd475
+ set 7, [hl]
+ ret
+
+CinnabarGymQuizCorrectText:
+ sound_get_item_1
+ text_far _CinnabarGymQuizCorrectText
+ text_promptbutton
+ text_asm
+
+ ldh a, [hBackupGymGateIndex]
+ 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:
+ text_far _CinnabarGymQuizIncorrectText
+ text_end
+
+CinnabarGymGateFlagAction:
+ EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED
+ predef_jump FlagActionPredef
+
+UpdateCinnabarGymGateTileBlocks_::
+; Update the overworld map with open floor blocks or locked gate blocks
+; depending on event flags.
+ ld a, 6
+ ldh [hGymGateIndex], a
+.loop
+ ldh 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
+ ldh a, [hGymGateIndex]
+ ldh [hBackupGymGateIndex], 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
+ call CinnabarGym_ReplaceTileBlock
+ ld hl, hGymGateIndex
+ dec [hl]
+ jr nz, .loop
+ callfar RedrawMapView
+ ret
+
+gym_gate_coord: MACRO
+ db \1, \2, \3, 0
+ENDM
+
+HORIZONTAL_GATE_BLOCK EQU $54
+VERTICAL_GATE_BLOCK EQU $5f
+
+CinnabarGymGateCoords:
+ ; x coord, y coord, block id
+ gym_gate_coord 9, 3, HORIZONTAL_GATE_BLOCK
+ gym_gate_coord 6, 3, HORIZONTAL_GATE_BLOCK
+ gym_gate_coord 6, 6, HORIZONTAL_GATE_BLOCK
+ gym_gate_coord 3, 8, VERTICAL_GATE_BLOCK
+ gym_gate_coord 2, 6, HORIZONTAL_GATE_BLOCK
+ gym_gate_coord 2, 3, HORIZONTAL_GATE_BLOCK
+
+
+CinnabarGym_ReplaceTileBlock:
+; basically a copy of the first half of ReplaceTileBlock
+; before checking if it is necessary to redraw the map view
+ ld hl, wOverworldMap
+ ld a, [wCurMapWidth]
+ add $6
+ ld e, a
+ ld d, $0
+ add hl, de
+ add hl, de
+ add hl, de
+ ld e, $3
+ add hl, de
+ ld e, a
+ ld a, b
+ and a
+ jr z, .addX
+.addWidthYTimesLoop
+ add hl, de
+ dec b
+ jr nz, .addWidthYTimesLoop
+.addX
+ add hl, bc
+ ld a, [wNewTileBlockID]
+ ld [hl], a
+ ret
diff --git a/engine/events/hidden_objects/elevator.asm b/engine/events/hidden_objects/elevator.asm
new file mode 100644
index 00000000..ab0f731f
--- /dev/null
+++ b/engine/events/hidden_objects/elevator.asm
@@ -0,0 +1,3 @@
+ElevatorText::
+ text_far _ElevatorText
+ text_end
diff --git a/engine/events/hidden_objects/fanclub_pictures.asm b/engine/events/hidden_objects/fanclub_pictures.asm
new file mode 100644
index 00000000..30bc72c7
--- /dev/null
+++ b/engine/events/hidden_objects/fanclub_pictures.asm
@@ -0,0 +1,23 @@
+FanClubPicture1:
+ ld a, RAPIDASH
+ ld [wcf91], a
+ call DisplayMonFrontSpriteInBox
+ call EnableAutoTextBoxDrawing
+ tx_pre FanClubPicture1Text
+ ret
+
+FanClubPicture1Text::
+ text_far _FanClubPicture1Text
+ text_end
+
+FanClubPicture2:
+ ld a, FEAROW
+ ld [wcf91], a
+ call DisplayMonFrontSpriteInBox
+ call EnableAutoTextBoxDrawing
+ tx_pre FanClubPicture2Text
+ ret
+
+FanClubPicture2Text::
+ text_far _FanClubPicture2Text
+ text_end
diff --git a/engine/events/hidden_objects/fighting_dojo.asm b/engine/events/hidden_objects/fighting_dojo.asm
new file mode 100644
index 00000000..b4f89985
--- /dev/null
+++ b/engine/events/hidden_objects/fighting_dojo.asm
@@ -0,0 +1,23 @@
+PrintFightingDojoText2:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump EnemiesOnEverySideText
+
+EnemiesOnEverySideText::
+ text_far _EnemiesOnEverySideText
+ text_end
+
+PrintFightingDojoText3:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump WhatGoesAroundComesAroundText
+
+WhatGoesAroundComesAroundText::
+ text_far _WhatGoesAroundComesAroundText
+ text_end
+
+PrintFightingDojoText:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump FightingDojoText
+
+FightingDojoText::
+ text_far _FightingDojoText
+ text_end
diff --git a/engine/events/hidden_objects/gym_statues.asm b/engine/events/hidden_objects/gym_statues.asm
new file mode 100644
index 00000000..1c7eb970
--- /dev/null
+++ b/engine/events/hidden_objects/gym_statues.asm
@@ -0,0 +1,39 @@
+GymStatues:
+; if in a gym and have the corresponding badge, a = GymStatueText2_id and jp PrintPredefTextID
+; if in a gym and don't have the corresponding badge, a = GymStatueText1_id and jp PrintPredefTextID
+; else ret
+ call EnableAutoTextBoxDrawing
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ ld hl, MapBadgeFlags
+ ld a, [wCurMap]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp $ff
+ ret z
+ cp b
+ jr z, .match
+ inc hl
+ jr .loop
+.match
+ ld b, [hl]
+ ld a, [wBeatGymFlags]
+ and b
+ cp b
+ tx_pre_id GymStatueText2
+ jr z, .haveBadge
+ tx_pre_id GymStatueText1
+.haveBadge
+ jp PrintPredefTextID
+
+INCLUDE "data/maps/badge_maps.asm"
+
+GymStatueText1::
+ text_far _GymStatueText1
+ text_end
+
+GymStatueText2::
+ text_far _GymStatueText2
+ text_end
diff --git a/engine/events/hidden_objects/indigo_plateau_hq.asm b/engine/events/hidden_objects/indigo_plateau_hq.asm
new file mode 100644
index 00000000..e8fd0220
--- /dev/null
+++ b/engine/events/hidden_objects/indigo_plateau_hq.asm
@@ -0,0 +1,10 @@
+PrintIndigoPlateauHQText:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump IndigoPlateauHQText
+
+IndigoPlateauHQText::
+ text_far _IndigoPlateauHQText
+ text_end
diff --git a/engine/events/hidden_objects/indigo_plateau_statues.asm b/engine/events/hidden_objects/indigo_plateau_statues.asm
new file mode 100644
index 00000000..23e94fcf
--- /dev/null
+++ b/engine/events/hidden_objects/indigo_plateau_statues.asm
@@ -0,0 +1,24 @@
+IndigoPlateauStatues::
+ text_asm
+ ld hl, IndigoPlateauStatuesText1
+ call PrintText
+ ld a, [wXCoord]
+ bit 0, a
+ ld hl, IndigoPlateauStatuesText2
+ jr nz, .ok
+ ld hl, IndigoPlateauStatuesText3
+.ok
+ call PrintText
+ jp TextScriptEnd
+
+IndigoPlateauStatuesText1:
+ text_far _IndigoPlateauStatuesText1
+ text_end
+
+IndigoPlateauStatuesText2:
+ text_far _IndigoPlateauStatuesText2
+ text_end
+
+IndigoPlateauStatuesText3:
+ text_far _IndigoPlateauStatuesText3
+ text_end
diff --git a/engine/events/hidden_objects/magazines.asm b/engine/events/hidden_objects/magazines.asm
new file mode 100644
index 00000000..b58636ff
--- /dev/null
+++ b/engine/events/hidden_objects/magazines.asm
@@ -0,0 +1,8 @@
+PrintMagazinesText:
+ call EnableAutoTextBoxDrawing
+ tx_pre MagazinesText
+ ret
+
+MagazinesText::
+ text_far _MagazinesText
+ text_end
diff --git a/engine/events/hidden_objects/museum_fossils.asm b/engine/events/hidden_objects/museum_fossils.asm
new file mode 100644
index 00000000..539f2c3f
--- /dev/null
+++ b/engine/events/hidden_objects/museum_fossils.asm
@@ -0,0 +1,23 @@
+AerodactylFossil:
+ ld a, FOSSIL_AERODACTYL
+ ld [wcf91], a
+ call DisplayMonFrontSpriteInBox
+ call EnableAutoTextBoxDrawing
+ tx_pre AerodactylFossilText
+ ret
+
+AerodactylFossilText::
+ text_far _AerodactylFossilText
+ text_end
+
+KabutopsFossil:
+ ld a, FOSSIL_KABUTOPS
+ ld [wcf91], a
+ call DisplayMonFrontSpriteInBox
+ call EnableAutoTextBoxDrawing
+ tx_pre KabutopsFossilText
+ ret
+
+KabutopsFossilText::
+ text_far _KabutopsFossilText
+ text_end
diff --git a/engine/events/hidden_objects/museum_fossils2.asm b/engine/events/hidden_objects/museum_fossils2.asm
new file mode 100644
index 00000000..fce0f03a
--- /dev/null
+++ b/engine/events/hidden_objects/museum_fossils2.asm
@@ -0,0 +1,28 @@
+DisplayMonFrontSpriteInBox:
+; Displays a pokemon's front sprite in a pop-up window.
+; [wcf91] = pokemon internal id number
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ call Delay3
+ xor a
+ ldh [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
+ ldh [hStartTileID], a
+ hlcoord 10, 11
+ predef AnimateSendingOutMon
+ call WaitForTextScrollButtonPress
+ call LoadScreenTilesFromBuffer1
+ call Delay3
+ ld a, $90
+ ldh [hWY], a
+ ret
diff --git a/engine/events/hidden_objects/new_bike.asm b/engine/events/hidden_objects/new_bike.asm
new file mode 100644
index 00000000..5bce5937
--- /dev/null
+++ b/engine/events/hidden_objects/new_bike.asm
@@ -0,0 +1,7 @@
+PrintNewBikeText:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump NewBicycleText
+
+NewBicycleText::
+ text_far _NewBicycleText
+ text_end
diff --git a/engine/events/hidden_objects/oaks_lab_email.asm b/engine/events/hidden_objects/oaks_lab_email.asm
new file mode 100644
index 00000000..bd4c66d7
--- /dev/null
+++ b/engine/events/hidden_objects/oaks_lab_email.asm
@@ -0,0 +1,11 @@
+DisplayOakLabEmailText:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ tx_pre OakLabEmailText
+ ret
+
+OakLabEmailText::
+ text_far _OakLabEmailText
+ text_end
diff --git a/engine/events/hidden_objects/oaks_lab_posters.asm b/engine/events/hidden_objects/oaks_lab_posters.asm
new file mode 100644
index 00000000..502cf951
--- /dev/null
+++ b/engine/events/hidden_objects/oaks_lab_posters.asm
@@ -0,0 +1,29 @@
+DisplayOakLabLeftPoster:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump PushStartText
+
+PushStartText::
+ text_far _PushStartText
+ text_end
+
+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::
+ text_far _SaveOptionText
+ text_end
+
+StrengthsAndWeaknessesText::
+ text_far _StrengthsAndWeaknessesText
+ text_end
diff --git a/engine/events/hidden_objects/pokecenter_pc.asm b/engine/events/hidden_objects/pokecenter_pc.asm
new file mode 100644
index 00000000..f20f40ed
--- /dev/null
+++ b/engine/events/hidden_objects/pokecenter_pc.asm
@@ -0,0 +1,11 @@
+OpenPokemonCenterPC:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ ld a, TRUE
+ ld [wAutoTextBoxDrawingControl], a
+ tx_pre_jump PokemonCenterPCText
+
+PokemonCenterPCText::
+ script_pokecenter_pc
diff --git a/engine/events/hidden_objects/pokemon_stuff.asm b/engine/events/hidden_objects/pokemon_stuff.asm
new file mode 100644
index 00000000..267a191a
--- /dev/null
+++ b/engine/events/hidden_objects/pokemon_stuff.asm
@@ -0,0 +1,3 @@
+PokemonStuffText::
+ text_far _PokemonStuffText
+ text_end
diff --git a/engine/events/hidden_objects/reds_room.asm b/engine/events/hidden_objects/reds_room.asm
new file mode 100644
index 00000000..7b8d51a0
--- /dev/null
+++ b/engine/events/hidden_objects/reds_room.asm
@@ -0,0 +1,14 @@
+PrintRedSNESText:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump RedBedroomSNESText
+
+RedBedroomSNESText::
+ text_far _RedBedroomSNESText
+ text_end
+
+OpenRedsPC:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump RedBedroomPCText
+
+RedBedroomPCText::
+ script_players_pc
diff --git a/engine/events/hidden_objects/route_15_binoculars.asm b/engine/events/hidden_objects/route_15_binoculars.asm
new file mode 100644
index 00000000..9734e833
--- /dev/null
+++ b/engine/events/hidden_objects/route_15_binoculars.asm
@@ -0,0 +1,17 @@
+Route15GateLeftBinoculars:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ cp SPRITE_FACING_UP
+ ret nz
+ call EnableAutoTextBoxDrawing
+ tx_pre Route15UpstairsBinocularsText
+ ld a, ARTICUNO
+ ld [wcf91], a
+ call PlayCry
+ call DisplayMonFrontSpriteInBox
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Route15UpstairsBinocularsText::
+ text_far _Route15UpstairsBinocularsText
+ text_end
diff --git a/engine/events/hidden_objects/safari_game.asm b/engine/events/hidden_objects/safari_game.asm
new file mode 100644
index 00000000..5001a5d4
--- /dev/null
+++ b/engine/events/hidden_objects/safari_game.asm
@@ -0,0 +1,78 @@
+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
+ call StopAllMusic
+ ld c, BANK(SFX_Safari_Zone_PA)
+ ld a, SFX_SAFARI_ZONE_PA
+ call PlayMusic
+.waitForMusicToPlay
+ ld a, [wChannelSoundIDs + Ch5]
+ cp SFX_SAFARI_ZONE_PA
+ jr nz, .waitForMusicToPlay
+ ld a, TEXT_SAFARI_GAME_OVER
+ ldh [hSpriteIndexOrTextID], a
+ call DisplayTextID
+ xor a
+ ld [wPlayerMovingDirection], a
+ ld a, SAFARI_ZONE_GATE
+ ldh [hWarpDestinationMap], a
+ ld a, $3
+ ld [wDestinationWarpID], a
+ ld a, $5
+ ld [wSafariZoneGateCurScript], a
+ SetEvent EVENT_SAFARI_GAME_OVER
+ ld a, 1
+ ld [wSafariZoneGameOver], a
+ ret
+
+PrintSafariGameOverText::
+ xor a
+ ld [wJoyIgnore], a
+ ld hl, SafariGameOverText
+ jp PrintText
+
+SafariGameOverText:
+ text_asm
+ ld a, [wNumSafariBalls]
+ and a
+ jr z, .noMoreSafariBalls
+ ld hl, TimesUpText
+ call PrintText
+.noMoreSafariBalls
+ ld hl, GameOverText
+ call PrintText
+ jp TextScriptEnd
+
+TimesUpText:
+ text_far _TimesUpText
+ text_end
+
+GameOverText:
+ text_far _GameOverText
+ text_end
diff --git a/engine/events/hidden_objects/school_blackboard.asm b/engine/events/hidden_objects/school_blackboard.asm
new file mode 100644
index 00000000..eb927292
--- /dev/null
+++ b/engine/events/hidden_objects/school_blackboard.asm
@@ -0,0 +1,223 @@
+PrintBlackboardLinkCableText:
+ call EnableAutoTextBoxDrawing
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld a, [wHiddenObjectFunctionArgument]
+ call PrintPredefTextID
+ ret
+
+LinkCableHelp::
+ text_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]
+ hlcoord 0, 0
+ lb bc, 8, 13
+ call TextBoxBorder
+ hlcoord 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:
+ text_far _LinkCableHelpText1
+ text_end
+
+LinkCableHelpText2:
+ text_far _LinkCableHelpText2
+ text_end
+
+HowToLinkText:
+ db "HOW TO LINK"
+ next "COLOSSEUM"
+ next "TRADE CENTER"
+ next "STOP READING@"
+
+LinkCableInfoTexts:
+ dw LinkCableInfoText1
+ dw LinkCableInfoText2
+ dw LinkCableInfoText3
+
+LinkCableInfoText1:
+ text_far _LinkCableInfoText1
+ text_end
+
+LinkCableInfoText2:
+ text_far _LinkCableInfoText2
+ text_end
+
+LinkCableInfoText3:
+ text_far _LinkCableInfoText3
+ text_end
+
+ViridianSchoolBlackboard::
+ text_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]
+ hlcoord 0, 0
+ lb bc, 6, 10
+ call TextBoxBorder
+ hlcoord 1, 2
+ ld de, StatusAilmentText1
+ call PlaceString
+ hlcoord 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:
+ text_far _ViridianSchoolBlackboardText1
+ text_end
+
+ViridianSchoolBlackboardText2:
+ text_far _ViridianSchoolBlackboardText2
+ text_end
+
+StatusAilmentText1:
+ db " SLP"
+ next " PSN"
+ next " PAR@"
+
+StatusAilmentText2:
+ db " BRN"
+ next " FRZ"
+ next " QUIT@"
+
+ db "@" ; unused
+
+ViridianBlackboardStatusPointers:
+ dw ViridianBlackboardSleepText
+ dw ViridianBlackboardPoisonText
+ dw ViridianBlackboardPrlzText
+ dw ViridianBlackboardBurnText
+ dw ViridianBlackboardFrozenText
+
+ViridianBlackboardSleepText:
+ text_far _ViridianBlackboardSleepText
+ text_end
+
+ViridianBlackboardPoisonText:
+ text_far _ViridianBlackboardPoisonText
+ text_end
+
+ViridianBlackboardPrlzText:
+ text_far _ViridianBlackboardPrlzText
+ text_end
+
+ViridianBlackboardBurnText:
+ text_far _ViridianBlackboardBurnText
+ text_end
+
+ViridianBlackboardFrozenText:
+ text_far _ViridianBlackboardFrozenText
+ text_end
diff --git a/engine/events/hidden_objects/school_notebooks.asm b/engine/events/hidden_objects/school_notebooks.asm
new file mode 100644
index 00000000..96a44ab5
--- /dev/null
+++ b/engine/events/hidden_objects/school_notebooks.asm
@@ -0,0 +1,65 @@
+PrintNotebookText:
+ call EnableAutoTextBoxDrawing
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld a, [wHiddenObjectFunctionArgument]
+ jp PrintPredefTextID
+
+TMNotebook::
+ text_far TMNotebookText
+ text_waitbutton
+ text_end
+
+ViridianSchoolNotebook::
+ text_asm
+ ld hl, ViridianSchoolNotebookText1
+ call PrintText
+ call TurnPageSchoolNotebook
+ jr nz, .doneReading
+ ld hl, ViridianSchoolNotebookText2
+ call PrintText
+ call TurnPageSchoolNotebook
+ jr nz, .doneReading
+ ld hl, ViridianSchoolNotebookText3
+ call PrintText
+ call TurnPageSchoolNotebook
+ jr nz, .doneReading
+ ld hl, ViridianSchoolNotebookText4
+ call PrintText
+ ld hl, ViridianSchoolNotebookText5
+ call PrintText
+.doneReading
+ jp TextScriptEnd
+
+TurnPageSchoolNotebook:
+ ld hl, TurnPageText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ ret
+
+TurnPageText:
+ text_far _TurnPageText
+ text_end
+
+ViridianSchoolNotebookText5:
+ text_far _ViridianSchoolNotebookText5
+ text_waitbutton
+ text_end
+
+ViridianSchoolNotebookText1:
+ text_far _ViridianSchoolNotebookText1
+ text_end
+
+ViridianSchoolNotebookText2:
+ text_far _ViridianSchoolNotebookText2
+ text_end
+
+ViridianSchoolNotebookText3:
+ text_far _ViridianSchoolNotebookText3
+ text_end
+
+ViridianSchoolNotebookText4:
+ text_far _ViridianSchoolNotebookText4
+ text_end
diff --git a/engine/events/hidden_objects/town_map.asm b/engine/events/hidden_objects/town_map.asm
new file mode 100644
index 00000000..4284214f
--- /dev/null
+++ b/engine/events/hidden_objects/town_map.asm
@@ -0,0 +1,22 @@
+TownMapText::
+ text_far _TownMapText
+ text_promptbutton
+ text_asm
+ ld a, $1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld hl, wd730
+ set 6, [hl]
+ call GBPalWhiteOutWithDelay3
+ xor a
+ ldh [hWY], a
+ inc a
+ ldh [hAutoBGTransferEnabled], a
+ call LoadFontTilePatterns
+ farcall DisplayTownMap
+ ld hl, wd730
+ res 6, [hl]
+ ld de, TextScriptEnd
+ push de
+ ldh a, [hLoadedROMBank]
+ push af
+ jp CloseTextDisplay
diff --git a/engine/events/hidden_objects/vermilion_gym_trash.asm b/engine/events/hidden_objects/vermilion_gym_trash.asm
new file mode 100644
index 00000000..21dd3ee0
--- /dev/null
+++ b/engine/events/hidden_objects/vermilion_gym_trash.asm
@@ -0,0 +1,134 @@
+PrintTrashText:
+ call EnableAutoTextBoxDrawing
+ tx_pre_jump VermilionGymTrashText
+
+VermilionGymTrashText::
+ text_far _VermilionGymTrashText
+ text_end
+
+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
+ callfar Yellow_SampleSecondTrashCan
+ tx_pre_id VermilionGymTrashSuccessText1
+ jr .done
+
+.trySecondLock
+ ld a, [wGymTrashCanIndex]
+ ld b, a
+ ld a, [wSecondLockTrashCanIndex]
+ cp b
+ jr z, .openSecondLock
+ ld a, [wSecondLockTrashCanIndex + 1]
+ 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
+; Note that the mask is simply the number of valid trash can indices that
+; follow. The remaining bytes are filled with -1 to pad the length of each entry
+; to 5 bytes.
+; This is functionally replaced with GymTrashCans3a but was never removed from source.
+
+ db 2, 1, 3, -1, -1 ; 0
+ db 3, 0, 2, 4, -1 ; 1
+ db 2, 1, 5, -1, -1 ; 2
+ db 3, 0, 4, 6, -1 ; 3
+ db 4, 1, 3, 5, 7 ; 4
+ db 3, 2, 4, 8, -1 ; 5
+ db 3, 3, 7, 9, -1 ; 6
+ db 4, 4, 6, 8, 10 ; 7
+ db 3, 5, 7, 11, -1 ; 8
+ db 3, 6, 10, 12, -1 ; 9
+ db 4, 7, 9, 11, 13 ; 10
+ db 3, 8, 10, 14, -1 ; 11
+ db 2, 9, 13, -1, -1 ; 12
+ db 3, 10, 12, 14, -1 ; 13
+ db 2, 11, 13, -1, -1 ; 14
+
+VermilionGymTrashSuccessText1::
+ text_far _VermilionGymTrashSuccessText1
+ text_asm
+ call WaitForSoundToFinish
+ ld a, SFX_SWITCH
+ call PlaySound
+ call WaitForSoundToFinish
+ jp TextScriptEnd
+
+; unused
+VermilionGymTrashSuccessText2::
+ text_far _VermilionGymTrashSuccessText2
+ text_end
+
+; unused
+VermilionGymTrashSuccesPlaySfx:
+ text_asm
+ call WaitForSoundToFinish
+ ld a, SFX_SWITCH
+ call PlaySound
+ call WaitForSoundToFinish
+ jp TextScriptEnd
+
+VermilionGymTrashSuccessText3::
+ text_far _VermilionGymTrashSuccessText3
+ text_asm
+ call WaitForSoundToFinish
+ ld a, SFX_GO_INSIDE
+ call PlaySound
+ call WaitForSoundToFinish
+ jp TextScriptEnd
+
+VermilionGymTrashFailText::
+ text_far _VermilionGymTrashFailText
+ text_asm
+ call WaitForSoundToFinish
+ ld a, SFX_DENIED
+ call PlaySound
+ call WaitForSoundToFinish
+ jp TextScriptEnd
diff --git a/engine/in_game_trades.asm b/engine/events/in_game_trades.asm
index 720920df..a0a23dfa 100755
--- a/engine/in_game_trades.asm
+++ b/engine/events/in_game_trades.asm
@@ -76,7 +76,7 @@ InGameTrade_GetMonName:
ld bc, NAME_LENGTH
jp CopyData
-INCLUDE "data/trades.asm"
+INCLUDE "data/events/trades.asm"
InGameTrade_DoTrade:
xor a ; NORMAL_PARTY_MENU
@@ -129,7 +129,7 @@ InGameTrade_DoTrade:
call InGameTrade_CheckForTradeEvo
call ClearScreen
call InGameTrade_RestoreScreen
- callba RedrawMapView
+ farcall RedrawMapView
and a
ld a, $3
jr .tradeSucceeded
@@ -148,7 +148,7 @@ InGameTrade_RestoreScreen:
call LoadGBPal
ld c, 10
call DelayFrames
- jpba LoadWildData
+ farjp LoadWildData
InGameTrade_PrepareTradeData:
ld hl, wTradedPlayerMonSpecies
@@ -219,41 +219,41 @@ InGameTrade_GetReceivedMonPointer:
ret
InGameTrade_FlagActionPredef:
- ld hl,wCompletedInGameTradeFlags
- ld a,[wWhichTrade]
- ld c,a
+ ld hl, wCompletedInGameTradeFlags
+ ld a, [wWhichTrade]
+ ld c, a
predef_jump FlagActionPredef
InGameTrade_CheckForTradeEvo:
- ld a,[wInGameTradeReceiveMonSpecies]
+ ld a, [wInGameTradeReceiveMonSpecies]
cp KADABRA
- jr z,.tradeEvo
+ jr z, .tradeEvo
cp GRAVELER
- jr z,.tradeEvo
+ jr z, .tradeEvo
cp MACHOKE
- jr z,.tradeEvo
+ jr z, .tradeEvo
cp HAUNTER
- jr z,.tradeEvo
+ jr z, .tradeEvo
ret
.tradeEvo
- ld a,[wPartyCount]
+ ld a, [wPartyCount]
dec a
- ld [wWhichPokemon],a
- ld a,$1
- ld [wForceEvolution],a
- ld a,LINK_STATE_TRADING
- ld [wLinkState],a
- callab EvolveTradeMon
+ ld [wWhichPokemon], a
+ ld a, $1
+ ld [wForceEvolution], a
+ ld a, LINK_STATE_TRADING
+ ld [wLinkState], a
+ callfar EvolveTradeMon
xor a ; LINK_STATE_NONE
- ld [wLinkState],a
+ ld [wLinkState], a
jp PlayDefaultMusic
InGameTrade_TrainerString:
- ; "TRAINER@@@@@@@@@@"
- db $5d, "@@@@@@@@@@"
+ db "<TRAINER>@@@@@@@@@@"
InGameTradeTextPointers:
+; entries correspond to TRADE_DIALOGSET_* constants
dw TradeTextPointers1
dw TradeTextPointers2
dw TradeTextPointers3
@@ -280,71 +280,71 @@ TradeTextPointers3:
dw AfterTrade3Text
ConnectCableText:
- TX_FAR _ConnectCableText
- db "@"
+ text_far _ConnectCableText
+ text_end
TradedForText:
- TX_FAR _TradedForText
- TX_SFX_KEY_ITEM
- TX_DELAY
- db "@"
+ text_far _TradedForText
+ sound_get_key_item
+ text_pause
+ text_end
WannaTrade1Text:
- TX_FAR _WannaTrade1Text
- db "@"
+ text_far _WannaTrade1Text
+ text_end
NoTrade1Text:
- TX_FAR _NoTrade1Text
- db "@"
+ text_far _NoTrade1Text
+ text_end
WrongMon1Text:
- TX_FAR _WrongMon1Text
- db "@"
+ text_far _WrongMon1Text
+ text_end
Thanks1Text:
- TX_FAR _Thanks1Text
- db "@"
+ text_far _Thanks1Text
+ text_end
AfterTrade1Text:
- TX_FAR _AfterTrade1Text
- db "@"
+ text_far _AfterTrade1Text
+ text_end
WannaTrade2Text:
- TX_FAR _WannaTrade2Text
- db "@"
+ text_far _WannaTrade2Text
+ text_end
NoTrade2Text:
- TX_FAR _NoTrade2Text
- db "@"
+ text_far _NoTrade2Text
+ text_end
WrongMon2Text:
- TX_FAR _WrongMon2Text
- db "@"
+ text_far _WrongMon2Text
+ text_end
Thanks2Text:
- TX_FAR _Thanks2Text
- db "@"
+ text_far _Thanks2Text
+ text_end
AfterTrade2Text:
- TX_FAR _AfterTrade2Text
- db "@"
+ text_far _AfterTrade2Text
+ text_end
WannaTrade3Text:
- TX_FAR _WannaTrade3Text
- db "@"
+ text_far _WannaTrade3Text
+ text_end
NoTrade3Text:
- TX_FAR _NoTrade3Text
- db "@"
+ text_far _NoTrade3Text
+ text_end
WrongMon3Text:
- TX_FAR _WrongMon3Text
- db "@"
+ text_far _WrongMon3Text
+ text_end
Thanks3Text:
- TX_FAR _Thanks3Text
- db "@"
+ text_far _Thanks3Text
+ text_end
AfterTrade3Text:
- TX_FAR _AfterTrade3Text
- db "@"
+ text_far _AfterTrade3Text
+ text_end
diff --git a/engine/events/oaks_aide.asm b/engine/events/oaks_aide.asm
new file mode 100755
index 00000000..f1801f5c
--- /dev/null
+++ b/engine/events/oaks_aide.asm
@@ -0,0 +1,71 @@
+OaksAideScript:
+ ld hl, OaksAideHiText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .choseNo
+ ld hl, wPokedexOwned
+ ld b, wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ ld a, [wNumSetBits]
+ ldh [hOaksAideNumMonsOwned], a
+ ld b, a
+ ldh a, [hOaksAideRequirement]
+ cp b
+ jr z, .giveItem
+ jr nc, .notEnoughOwnedMons
+.giveItem
+ ld hl, OaksAideHereYouGoText
+ call PrintText
+ ldh a, [hOaksAideRewardItem]
+ ld b, a
+ ld c, 1
+ call GiveItem
+ jr nc, .bagFull
+ ld hl, OaksAideGotItemText
+ call PrintText
+ ld a, OAKS_AIDE_GOT_ITEM
+ jr .done
+.bagFull
+ ld hl, OaksAideNoRoomText
+ call PrintText
+ xor a ; OAKS_AIDE_BAG_FULL
+ jr .done
+.notEnoughOwnedMons
+ ld hl, OaksAideUhOhText
+ call PrintText
+ ld a, OAKS_AIDE_NOT_ENOUGH_MONS
+ jr .done
+.choseNo
+ ld hl, OaksAideComeBackText
+ call PrintText
+ ld a, OAKS_AIDE_REFUSED
+.done
+ ldh [hOaksAideResult], a
+ ret
+
+OaksAideHiText:
+ text_far _OaksAideHiText
+ text_end
+
+OaksAideUhOhText:
+ text_far _OaksAideUhOhText
+ text_end
+
+OaksAideComeBackText:
+ text_far _OaksAideComeBackText
+ text_end
+
+OaksAideHereYouGoText:
+ text_far _OaksAideHereYouGoText
+ text_end
+
+OaksAideGotItemText:
+ text_far _OaksAideGotItemText
+ sound_get_item_1
+ text_end
+
+OaksAideNoRoomText:
+ text_far _OaksAideNoRoomText
+ text_end
diff --git a/engine/overworld/pewter_guys.asm b/engine/events/pewter_guys.asm
index 532fa4bf..532fa4bf 100755
--- a/engine/overworld/pewter_guys.asm
+++ b/engine/events/pewter_guys.asm
diff --git a/engine/events/pick_up_item.asm b/engine/events/pick_up_item.asm
new file mode 100644
index 00000000..548db5be
--- /dev/null
+++ b/engine/events/pick_up_item.asm
@@ -0,0 +1,54 @@
+PickUpItem:
+ call EnableAutoTextBoxDrawing
+
+ ldh a, [hSpriteIndexOrTextID]
+ ld b, a
+ ld hl, wMissableObjectList
+.missableObjectsListLoop
+ ld a, [hli]
+ cp $ff
+ ret z
+ cp b
+ jr z, .isMissable
+ inc hl
+ jr .missableObjectsListLoop
+
+.isMissable
+ ld a, [hl]
+ ldh [hMissableObjectIndex], a
+
+ ld hl, wMapSpriteExtraData
+ ldh a, [hSpriteIndexOrTextID]
+ dec a
+ add a
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hl]
+ ld b, a ; item
+ ld c, 1 ; quantity
+ call GiveItem
+ jr nc, .BagFull
+
+ ldh a, [hMissableObjectIndex]
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld a, 1
+ ld [wDoNotWaitForButtonPressAfterDisplayingText], a
+ ld hl, FoundItemText
+ jr .print
+
+.BagFull
+ ld hl, NoMoreRoomForItemText
+.print
+ call PrintText
+ ret
+
+FoundItemText:
+ text_far _FoundItemText
+ sound_get_item_1
+ text_end
+
+NoMoreRoomForItemText:
+ text_far _NoMoreRoomForItemText
+ text_end
diff --git a/engine/overworld/poison.asm b/engine/events/poison.asm
index 03fb8a65..9f3ad391 100644
--- a/engine/overworld/poison.asm
+++ b/engine/events/poison.asm
@@ -59,12 +59,12 @@ ApplyOutOfBattlePoisonDamage:
ld [wJoyIgnore], a
call EnableAutoTextBoxDrawing
ld a, TEXT_MON_FAINTED
- ld [hSpriteIndexOrTextID], a
+ ldh [hSpriteIndexOrTextID], a
call DisplayTextID
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .curMonNotPlayerPikachu
ld e, $3
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
calladb_ModifyPikachuHappiness PIKAHAPPY_PSNFNT
.curMonNotPlayerPikachu
pop de
@@ -112,7 +112,7 @@ ApplyOutOfBattlePoisonDamage:
jr nz, .noBlackOut
call EnableAutoTextBoxDrawing
ld a, TEXT_BLACKED_OUT
- ld [hSpriteIndexOrTextID], a
+ ldh [hSpriteIndexOrTextID], a
call DisplayTextID
ld hl, wd72e
set 5, [hl]
diff --git a/engine/events/pokecenter.asm b/engine/events/pokecenter.asm
new file mode 100755
index 00000000..e007030a
--- /dev/null
+++ b/engine/events/pokecenter.asm
@@ -0,0 +1,149 @@
+DisplayPokemonCenterDialogue_::
+ ld a, [wCurMap]
+ cp PEWTER_POKECENTER
+ jr nz, .regularCenter
+ call CheckPikachuFollowingPlayer
+ jr z, .regularCenter
+ ld hl, LooksContentText ; if pikachu is sleeping, don't heal
+ call PrintText
+ ret
+.regularCenter
+ call SaveScreenTilesToBuffer1 ; save screen
+ ld hl, PokemonCenterWelcomeText
+ call PrintText
+ ld hl, wd72e
+ bit 2, [hl]
+ set 1, [hl]
+ set 2, [hl]
+ jr nz, .skipShallWeHealYourPokemon
+ ld hl, ShallWeHealYourPokemonText
+ call PrintText
+.skipShallWeHealYourPokemon
+ call YesNoChoicePokeCenter ; yes/no menu
+ call UpdateSprites
+ ld a, [wCurrentMenuItem]
+ and a
+ jp nz, .declinedHealing ; if the player chose No
+ call SetLastBlackoutMap
+ callfar IsStarterPikachuInOurParty
+ jr nc, .notHealingPlayerPikachu
+ call CheckPikachuFollowingPlayer
+ jr nz, .notHealingPlayerPikachu
+ call LoadCurrentMapView
+ call Delay3
+ call UpdateSprites
+ callfar PikachuWalksToNurseJoy ; todo
+.notHealingPlayerPikachu
+ ld hl, NeedYourPokemonText
+ call PrintText
+ ld c, 64
+ call DelayFrames
+ call CheckPikachuFollowingPlayer
+ jr nz, .playerPikachuNotOnScreen
+ call DisablePikachuOverworldSpriteDrawing
+ callfar IsStarterPikachuInOurParty
+ call c, Func_6eaa
+.playerPikachuNotOnScreen
+ lb bc, 1, 8
+ call Func_6ebb
+ ld c, 30
+ call DelayFrames
+ farcall AnimateHealingMachine ; do the healing machine animation
+ predef HealParty
+ xor a
+ ld [wAudioFadeOutControl], a
+ ld a, [wAudioSavedROMBank]
+ ld [wAudioROMBank], a
+ ld a, [wMapMusicSoundID]
+ ld [wLastMusicSoundID], a
+ ld [wNewSoundID], a
+ call PlaySound
+ call CheckPikachuFollowingPlayer
+ jr nz, .doNotReturnPikachu
+ callfar IsStarterPikachuInOurParty
+ call c, Func_6eaa
+ ld a, $5
+ ld [wPikachuSpawnState], a
+ call EnablePikachuOverworldSpriteDrawing
+.doNotReturnPikachu
+ lb bc, 1, 0
+ call Func_6ebb
+ ld hl, PokemonFightingFitText
+ call PrintText
+ callfar IsStarterPikachuInOurParty
+ jr nc, .notInParty
+ lb bc, 15, 0
+ call Func_6ebb
+.notInParty
+ call LoadCurrentMapView
+ call Delay3
+ call UpdateSprites
+ callfar ReloadWalkingTilePatterns
+ ld a, $1
+ ldh [hSpriteIndex], a
+ ld a, $1
+ ldh [hSpriteImageIndex], a
+ call SpriteFunc_34a1
+ ld c, 40
+ call DelayFrames
+ call UpdateSprites
+ call LoadFontTilePatterns
+ jr .done
+.declinedHealing
+ call LoadScreenTilesFromBuffer1 ; restore screen
+.done
+ ld hl, PokemonCenterFarewellText
+ call PrintText
+ call UpdateSprites
+ ret
+
+Func_6eaa:
+ ld a, $1
+ ldh [hSpriteIndex], a
+ ld a, $4
+ ldh [hSpriteImageIndex], a
+ call SpriteFunc_34a1
+ ld c, 64
+ call DelayFrames
+ ret
+
+Func_6ebb:
+ ld a, b
+ ldh [hSpriteIndex], a
+ ld a, c
+ ldh [hSpriteImageIndex], a
+ push bc
+ call SetSpriteFacingDirectionAndDelay
+ pop bc
+ ld a, b
+ ldh [hSpriteIndex], a
+ ld a, c
+ ldh [hSpriteImageIndex], a
+ call SpriteFunc_34a1
+ ret
+
+PokemonCenterWelcomeText:
+ text_far _PokemonCenterWelcomeText
+ text_end
+
+ShallWeHealYourPokemonText:
+ text_pause
+ text_far _ShallWeHealYourPokemonText
+ text_end
+
+NeedYourPokemonText:
+ text_far _NeedYourPokemonText
+ text_end
+
+PokemonFightingFitText:
+ text_far _PokemonFightingFitText
+ text_end
+
+PokemonCenterFarewellText:
+ text_pause
+ text_far _PokemonCenterFarewellText
+ text_end
+
+LooksContentText:
+ text_far _LooksContentText
+ text_end
diff --git a/engine/events/pokedex_rating.asm b/engine/events/pokedex_rating.asm
new file mode 100755
index 00000000..1086257a
--- /dev/null
+++ b/engine/events/pokedex_rating.asm
@@ -0,0 +1,138 @@
+DisplayDexRating:
+ ld hl, wPokedexSeen
+ ld b, wPokedexSeenEnd - wPokedexSeen
+ call CountSetBits
+ ld a, [wNumSetBits]
+ ldh [hDexRatingNumMonsSeen], a
+ ld hl, wPokedexOwned
+ ld b, wPokedexOwnedEnd - wPokedexOwned
+ call CountSetBits
+ ld a, [wNumSetBits]
+ ldh [hDexRatingNumMonsOwned], a
+ ld hl, DexRatingsTable
+.findRating
+ ld a, [hli]
+ ld b, a
+ ldh a, [hDexRatingNumMonsOwned]
+ cp b
+ jr c, .foundRating
+ inc hl
+ inc hl
+ jr .findRating
+.foundRating
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; load text pointer into hl
+ CheckAndResetEventA EVENT_HALL_OF_FAME_DEX_RATING
+ jr nz, .hallOfFame
+ push hl
+ ld hl, DexCompletionText
+ call PrintText
+ pop hl
+ call PrintText
+ farcall PlayPokedexRatingSfx
+ jp WaitForTextScrollButtonPress
+.hallOfFame
+ ld de, wDexRatingNumMonsSeen
+ ldh a, [hDexRatingNumMonsSeen]
+ ld [de], a
+ inc de
+ ldh a, [hDexRatingNumMonsOwned]
+ ld [de], a
+ inc de
+.copyRatingTextLoop
+ ld a, [hli]
+ cp "@"
+ jr z, .doneCopying
+ ld [de], a
+ inc de
+ jr .copyRatingTextLoop
+.doneCopying
+ ld [de], a
+ ret
+
+DexCompletionText:
+ text_far _DexCompletionText
+ text_end
+
+DexRatingsTable:
+ dbw 10, DexRatingText_Own0To9
+ dbw 20, DexRatingText_Own10To19
+ dbw 30, DexRatingText_Own20To29
+ dbw 40, DexRatingText_Own30To39
+ dbw 50, DexRatingText_Own40To49
+ dbw 60, DexRatingText_Own50To59
+ dbw 70, DexRatingText_Own60To69
+ dbw 80, DexRatingText_Own70To79
+ dbw 90, DexRatingText_Own80To89
+ dbw 100, DexRatingText_Own90To99
+ dbw 110, DexRatingText_Own100To109
+ dbw 120, DexRatingText_Own110To119
+ dbw 130, DexRatingText_Own120To129
+ dbw 140, DexRatingText_Own130To139
+ dbw 150, DexRatingText_Own140To149
+ dbw NUM_POKEMON + 1, DexRatingText_Own150To151
+
+DexRatingText_Own0To9:
+ text_far _DexRatingText_Own0To9
+ text_end
+
+DexRatingText_Own10To19:
+ text_far _DexRatingText_Own10To19
+ text_end
+
+DexRatingText_Own20To29:
+ text_far _DexRatingText_Own20To29
+ text_end
+
+DexRatingText_Own30To39:
+ text_far _DexRatingText_Own30To39
+ text_end
+
+DexRatingText_Own40To49:
+ text_far _DexRatingText_Own40To49
+ text_end
+
+DexRatingText_Own50To59:
+ text_far _DexRatingText_Own50To59
+ text_end
+
+DexRatingText_Own60To69:
+ text_far _DexRatingText_Own60To69
+ text_end
+
+DexRatingText_Own70To79:
+ text_far _DexRatingText_Own70To79
+ text_end
+
+DexRatingText_Own80To89:
+ text_far _DexRatingText_Own80To89
+ text_end
+
+DexRatingText_Own90To99:
+ text_far _DexRatingText_Own90To99
+ text_end
+
+DexRatingText_Own100To109:
+ text_far _DexRatingText_Own100To109
+ text_end
+
+DexRatingText_Own110To119:
+ text_far _DexRatingText_Own110To119
+ text_end
+
+DexRatingText_Own120To129:
+ text_far _DexRatingText_Own120To129
+ text_end
+
+DexRatingText_Own130To139:
+ text_far _DexRatingText_Own130To139
+ text_end
+
+DexRatingText_Own140To149:
+ text_far _DexRatingText_Own140To149
+ text_end
+
+DexRatingText_Own150To151:
+ text_far _DexRatingText_Own150To151
+ text_end
diff --git a/engine/overworld/pokemart.asm b/engine/events/pokemart.asm
index dc5b29b5..c7cb8115 100755
--- a/engine/overworld/pokemart.asm
+++ b/engine/events/pokemart.asm
@@ -1,4 +1,4 @@
-DisplayPokemartDialogue_:
+DisplayPokemartDialogue_::
ld a, [wListScrollOffset]
ld [wSavedListScrollOffset], a
call UpdateSprites
@@ -42,7 +42,7 @@ DisplayPokemartDialogue_:
ld [wPrintItemPrices], a
ld a, INIT_BAG_ITEM_LIST
ld [wInitListType], a
- callab InitList
+ callfar InitList
ld a, [wNumBagItems]
and a
@@ -77,14 +77,14 @@ DisplayPokemartDialogue_:
jr c, .unsellableItem
ld a, PRICEDITEMLISTMENU
ld [wListMenuID], a
- ld [hHalveItemPrices], a ; halve prices when selling
+ ldh [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
+ hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -126,7 +126,7 @@ DisplayPokemartDialogue_:
ld [wPrintItemPrices], a
ld a, INIT_OTHER_ITEM_LIST
ld [wInitListType], a
- callab InitList
+ callfar InitList
ld hl, PokemartBuyingGreetingText
call PrintText
@@ -152,7 +152,7 @@ DisplayPokemartDialogue_:
ld a, 99
ld [wMaxItemQuantity], a
xor a
- ld [hHalveItemPrices], a ; don't halve item prices when buying
+ ldh [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
@@ -162,7 +162,7 @@ DisplayPokemartDialogue_:
call CopyStringToCF4B ; copy name to wcf4b
ld hl, PokemartTellBuyPriceText
call PrintText
- coord hl, 14, 7
+ hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -228,45 +228,45 @@ DisplayPokemartDialogue_:
ret
PokemartBuyingGreetingText:
- TX_FAR _PokemartBuyingGreetingText
- db "@"
+ text_far _PokemartBuyingGreetingText
+ text_end
PokemartTellBuyPriceText:
- TX_FAR _PokemartTellBuyPriceText
- db "@"
+ text_far _PokemartTellBuyPriceText
+ text_end
PokemartBoughtItemText:
- TX_FAR _PokemartBoughtItemText
- db "@"
+ text_far _PokemartBoughtItemText
+ text_end
PokemartNotEnoughMoneyText:
- TX_FAR _PokemartNotEnoughMoneyText
- db "@"
+ text_far _PokemartNotEnoughMoneyText
+ text_end
PokemartItemBagFullText:
- TX_FAR _PokemartItemBagFullText
- db "@"
+ text_far _PokemartItemBagFullText
+ text_end
PokemonSellingGreetingText:
- TX_FAR _PokemonSellingGreetingText
- db "@"
+ text_far _PokemonSellingGreetingText
+ text_end
PokemartTellSellPriceText:
- TX_FAR _PokemartTellSellPriceText
- db "@"
+ text_far _PokemartTellSellPriceText
+ text_end
PokemartItemBagEmptyText:
- TX_FAR _PokemartItemBagEmptyText
- db "@"
+ text_far _PokemartItemBagEmptyText
+ text_end
PokemartUnsellableItemText:
- TX_FAR _PokemartUnsellableItemText
- db "@"
+ text_far _PokemartUnsellableItemText
+ text_end
PokemartThankYouText:
- TX_FAR _PokemartThankYouText
- db "@"
+ text_far _PokemartThankYouText
+ text_end
PokemartAnythingElseText:
- TX_FAR _PokemartAnythingElseText
- db "@"
+ text_far _PokemartAnythingElseText
+ text_end
diff --git a/engine/menu/prize_menu.asm b/engine/events/prize_menu.asm
index 405441c8..87244119 100755
--- a/engine/menu/prize_menu.asm
+++ b/engine/events/prize_menu.asm
@@ -1,4 +1,4 @@
-CeladonPrizeMenu:
+CeladonPrizeMenu::
ld b, COIN_CASE
call IsItemInBag
jr nz, .havingCoinCase
@@ -22,7 +22,7 @@ CeladonPrizeMenu:
ld a, $01
ld [wTopMenuItemX], a
call PrintPrizePrice
- coord hl, 0, 2
+ hlcoord 0, 2
lb bc, 8, 16
call TextBoxBorder
call GetPrizeMenuId
@@ -42,17 +42,17 @@ CeladonPrizeMenu:
ret
RequireCoinCaseTextPtr:
- TX_FAR _RequireCoinCaseText
- TX_WAIT
- db "@"
+ text_far _RequireCoinCaseText
+ text_waitbutton
+ text_end
ExchangeCoinsForPrizesTextPtr:
- TX_FAR _ExchangeCoinsForPrizesText
- db "@"
+ text_far _ExchangeCoinsForPrizesText
+ text_end
WhichPrizeTextPtr:
- TX_FAR _WhichPrizeText
- db "@"
+ text_far _WhichPrizeText
+ text_end
GetPrizeMenuId:
; determine which one among the three
@@ -63,7 +63,7 @@ GetPrizeMenuId:
; display the three prizes' names
; (distinguishing between Pokemon names
; and Items (specifically TMs) names)
- ld a, [hSpriteIndexOrTextID]
+ ldh 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
@@ -92,75 +92,73 @@ GetPrizeMenuId:
ld a, [wPrize1]
ld [wd11e], a
call GetItemName
- coord hl, 2, 4
+ hlcoord 2, 4
call PlaceString
ld a, [wPrize2]
ld [wd11e], a
call GetItemName
- coord hl, 2, 6
+ hlcoord 2, 6
call PlaceString
ld a, [wPrize3]
ld [wd11e], a
call GetItemName
- coord hl, 2, 8
+ hlcoord 2, 8
call PlaceString
jr .putNoThanksText
.putMonName
ld a, [wPrize1]
ld [wd11e], a
call GetMonName
- coord hl, 2, 4
+ hlcoord 2, 4
call PlaceString
ld a, [wPrize2]
ld [wd11e], a
call GetMonName
- coord hl, 2, 6
+ hlcoord 2, 6
call PlaceString
ld a, [wPrize3]
ld [wd11e], a
call GetMonName
- coord hl, 2, 8
+ hlcoord 2, 8
call PlaceString
.putNoThanksText
- coord hl, 2, 10
+ hlcoord 2, 10
ld de, NoThanksText
call PlaceString
; put prices on the right side of the textbox
ld de, wPrize1Price
- coord hl, 13, 5
+ hlcoord 13, 5
; reg. c:
; [low nybble] number of bytes
-; [bit 765 = %100] space-padding (not zero-padding)
+; [bits 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
+ hlcoord 13, 7
ld c, (1 << 7 | 2)
call PrintBCDNumber
ld de, wPrize3Price
- coord hl, 13, 9
+ hlcoord 13, 9
ld c, (1 << 7 | 2)
jp PrintBCDNumber
NoThanksText:
db "NO THANKS@"
-INCLUDE "data/prizes.asm"
+INCLUDE "data/events/prizes.asm"
PrintPrizePrice:
- coord hl, 11, 0
+ hlcoord 11, 0
lb bc, 1, 7
call TextBoxBorder
call UpdateSprites
- coord hl, 12, 0
+ hlcoord 12, 0
ld de, .CoinString
call PlaceString
- coord hl, 13, 1
+ hlcoord 13, 1
ld de, .SixSpacesString
call PlaceString
- coord hl, 13, 1
+ hlcoord 13, 1
ld de, wPlayerCoins
ld c, %10000010
call PrintBCDNumber
@@ -180,11 +178,11 @@ LoadCoinsToSubtract:
ld hl, wPrize1Price
add hl, de ; get selected prize's price
xor a
- ld [hUnusedCoinsByte], a
+ ldh [hUnusedCoinsByte], a
ld a, [hli]
- ld [hCoins], a
+ ldh [hCoins], a
ld a, [hl]
- ld [hCoins + 1], a
+ ldh [hCoins + 1], a
ret
HandlePrizeChoice:
@@ -266,28 +264,28 @@ UnknownPrizeData:
db $00,$01,$00,$01,$00,$01,$00,$00,$01
HereYouGoTextPtr:
- TX_FAR _HereYouGoText
- TX_WAIT
- db "@"
+ text_far _HereYouGoText
+ text_waitbutton
+ text_end
SoYouWantPrizeTextPtr:
- TX_FAR _SoYouWantPrizeText
- db "@"
+ text_far _SoYouWantPrizeText
+ text_end
SorryNeedMoreCoinsText:
- TX_FAR _SorryNeedMoreCoinsText
- TX_WAIT
- db "@"
+ text_far _SorryNeedMoreCoinsText
+ text_waitbutton
+ text_end
PrizeRoomBagIsFullTextPtr:
- TX_FAR _OopsYouDontHaveEnoughRoomText
- TX_WAIT
- db "@"
+ text_far _OopsYouDontHaveEnoughRoomText
+ text_waitbutton
+ text_end
OhFineThenTextPtr:
- TX_FAR _OhFineThenText
- TX_WAIT
- db "@"
+ text_far _OhFineThenText
+ text_waitbutton
+ text_end
GetPrizeMonLevel:
ld a, [wcf91]
@@ -304,4 +302,4 @@ GetPrizeMonLevel:
ld [wCurEnemyLVL], a
ret
-INCLUDE "data/prize_mon_levels.asm"
+INCLUDE "data/events/prize_mon_levels.asm"
diff --git a/engine/events/saffron_guards.asm b/engine/events/saffron_guards.asm
new file mode 100755
index 00000000..bf30b8c5
--- /dev/null
+++ b/engine/events/saffron_guards.asm
@@ -0,0 +1,15 @@
+RemoveGuardDrink::
+ ld hl, GuardDrinksList
+.drinkLoop
+ ld a, [hli]
+ ldh [hItemToRemoveID], a
+ and a
+ ret z
+ push hl
+ ld b, a
+ call IsItemInBag
+ pop hl
+ jr z, .drinkLoop
+ farjp RemoveItemByID
+
+INCLUDE "data/items/guard_drink_items.asm"
diff --git a/engine/events/set_blackout_map.asm b/engine/events/set_blackout_map.asm
new file mode 100644
index 00000000..e8460240
--- /dev/null
+++ b/engine/events/set_blackout_map.asm
@@ -0,0 +1,25 @@
+SetLastBlackoutMap:
+; Set the map to return to when
+; blacking out or using Teleport or Dig.
+; Safari rest houses don't count.
+
+ push hl
+ ld hl, SafariZoneRestHouses
+ ld a, [wCurMap]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .notresthouse
+ cp b
+ jr nz, .loop
+ jr .done
+
+.notresthouse
+ ld a, [wLastMap]
+ ld [wLastBlackoutMap], a
+.done
+ pop hl
+ ret
+
+INCLUDE "data/maps/rest_house_maps.asm"
diff --git a/engine/events/starter_dex.asm b/engine/events/starter_dex.asm
new file mode 100755
index 00000000..7cfe9af2
--- /dev/null
+++ b/engine/events/starter_dex.asm
@@ -0,0 +1,9 @@
+; this function temporarily makes the starters (and Ivysaur) seen
+; so that the full Pokedex information gets displayed in Oak's lab
+StarterDex:
+ ld a, 1 << (DEX_BULBASAUR - 1) | 1 << (DEX_IVYSAUR - 1) | 1 << (DEX_CHARMANDER - 1) | 1 << (DEX_SQUIRTLE - 1)
+ ld [wPokedexOwned], a
+ predef ShowPokedexData
+ xor a
+ ld [wPokedexOwned], a
+ ret
diff --git a/engine/menu/vending_machine.asm b/engine/events/vending_machine.asm
index 37d9b9e7..6ff6a5e4 100755
--- a/engine/menu/vending_machine.asm
+++ b/engine/events/vending_machine.asm
@@ -1,4 +1,4 @@
-VendingMachineMenu:
+VendingMachineMenu::
ld hl, VendingMachineText1
call PrintText
ld a, MONEY_BOX
@@ -17,14 +17,14 @@ VendingMachineMenu:
ld [wTopMenuItemX], a
ld hl, wd730
set 6, [hl]
- coord hl, 0, 3
+ hlcoord 0, 3
lb bc, 8, 12
call TextBoxBorder
call UpdateSprites
- coord hl, 2, 5
+ hlcoord 2, 5
ld de, DrinkText
call PlaceString
- coord hl, 9, 6
+ hlcoord 9, 6
ld de, DrinkPriceText
call PlaceString
ld hl, wd730
@@ -36,17 +36,17 @@ VendingMachineMenu:
cp 3 ; chose Cancel?
jr z, .notThirsty
xor a
- ld [hMoney], a
- ld [hMoney + 2], a
+ ldh [hMoney], a
+ ldh [hMoney + 2], a
ld a, $2
- ld [hMoney + 1], a
+ ldh [hMoney + 1], a
call HasEnoughMoney
jr nc, .enoughMoney
ld hl, VendingMachineText4
jp PrintText
.enoughMoney
call LoadVendingMachineItem
- ld a, [hVendingMachineItem]
+ ldh a, [hVendingMachineItem]
ld b, a
ld c, 1
call GiveItem
@@ -80,8 +80,8 @@ VendingMachineMenu:
jp PrintText
VendingMachineText1:
- TX_FAR _VendingMachineText1
- db "@"
+ text_far _VendingMachineText1
+ text_end
DrinkText:
db "FRESH WATER"
@@ -96,20 +96,20 @@ DrinkPriceText:
next "@"
VendingMachineText4:
- TX_FAR _VendingMachineText4
- db "@"
+ text_far _VendingMachineText4
+ text_end
VendingMachineText5:
- TX_FAR _VendingMachineText5
- db "@"
+ text_far _VendingMachineText5
+ text_end
VendingMachineText6:
- TX_FAR _VendingMachineText6
- db "@"
+ text_far _VendingMachineText6
+ text_end
VendingMachineText7:
- TX_FAR _VendingMachineText7
- db "@"
+ text_far _VendingMachineText7
+ text_end
LoadVendingMachineItem:
ld hl, VendingPrices
@@ -120,19 +120,13 @@ LoadVendingMachineItem:
ld e, a
add hl, de
ld a, [hli]
- ld [hVendingMachineItem], a
+ ldh [hVendingMachineItem], a
ld a, [hli]
- ld [hVendingMachinePrice], a
+ ldh [hVendingMachinePrice], a
ld a, [hli]
- ld [hVendingMachinePrice + 1], a
+ ldh [hVendingMachinePrice + 1], a
ld a, [hl]
- ld [hVendingMachinePrice + 2], a
+ ldh [hVendingMachinePrice + 2], a
ret
-VendingPrices:
- db FRESH_WATER
- money 200
- db SODA_POP
- money 300
- db LEMONADE
- money 350
+INCLUDE "data/items/vending_prices.asm"
diff --git a/engine/evos_moves.asm b/engine/evos_moves.asm
deleted file mode 100755
index 8ec2c4c7..00000000
--- a/engine/evos_moves.asm
+++ /dev/null
@@ -1,668 +0,0 @@
-; try to evolve the mon in [wWhichPokemon]
-TryEvolvingMon:
-EvolveTradeMon:
- ld hl, wCanEvolveFlags
- xor a
- ld [hl], a
- ld a, [wWhichPokemon]
- ld c, a
- ld b, FLAG_SET
- call Evolution_FlagAction
-
-; this is only called after battle
-; it is supposed to do level up evolutions, though there is a bug that allows item evolutions to occur
-EvolutionAfterBattle:
- ld a, [hTilesetType]
- push af
- xor a
- ld [wEvolutionOccurred], a
- dec a
- ld [wWhichPokemon], a
- push hl
- push bc
- push de
- ld hl, wPartyCount
- push hl
-
-Evolution_PartyMonLoop: ; loop over party mons
- ld hl, wWhichPokemon
- inc [hl]
- pop hl
- inc hl
- ld a, [hl]
- cp $ff ; have we reached the end of the party?
- jp z, .done
- ld [wEvoOldSpecies], a
- push hl
- ld a, [wWhichPokemon]
- ld c, a
- ld hl, wCanEvolveFlags
- ld b, FLAG_TEST
- call Evolution_FlagAction
- ld a, c
- and a ; is the mon's bit set?
- jp z, Evolution_PartyMonLoop ; if not, go to the next mon
- ld a, [wEvoOldSpecies]
- dec a
- ld b, 0
- ld hl, EvosMovesPointerTable
- add a
- rl b
- ld c, a
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
- push hl
- ld a, [wcf91]
- push af
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- call LoadMonData
- pop af
- ld [wcf91], a
- pop hl
-
-.evoEntryLoop ; loop over evolution entries
- ld a, [hli]
- and a ; have we reached the end of the evolution data?
- jr z, Evolution_PartyMonLoop
- ld b, a ; evolution type
- cp EV_TRADE
- jr z, .checkTradeEvo
-; not trade evolution
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- jr z, Evolution_PartyMonLoop ; if trading, go the next mon
- ld a, b
- cp EV_ITEM
- jr z, .checkItemEvo
- ld a, [wForceEvolution]
- and a
- jr nz, Evolution_PartyMonLoop
- ld a, b
- cp EV_LEVEL
- jr z, .checkLevel
-.checkTradeEvo
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- jp nz, .nextEvoEntry1 ; if not trading, go to the next evolution entry
- ld a, [hli] ; level requirement
- ld b, a
- ld a, [wLoadedMonLevel]
- cp b ; is the mon's level greater than the evolution requirement?
- jp c, Evolution_PartyMonLoop ; if so, go the next mon
- jr .doEvolution
-.checkItemEvo
- ld a, [wIsInBattle] ; are we in battle?
- and a
- ld a, [hli]
- jp nz, .nextEvoEntry1 ; don't evolve if we're in a battle as wcf91 could be holding the last mon sent out
-
- ld b, a ; evolution item
- ld a, [wcf91] ; last item used
- cp b ; was the evolution item in this entry used?
- jp nz, .nextEvoEntry1 ; if not, go to the next evolution entry
-.checkLevel
- ld a, [hli] ; level requirement
- ld b, a
- ld a, [wLoadedMonLevel]
- cp b ; is the mon's level greater than the evolution requirement?
- jp c, .nextEvoEntry2 ; if so, go the next evolution entry
-.doEvolution
- ld [wCurEnemyLVL], a
- ld a, 1
- ld [wEvolutionOccurred], a
- push hl
- ld a, [hl]
- ld [wEvoNewSpecies], a
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- call CopyStringToCF4B
- ld hl, IsEvolvingText
- call PrintText
- ld c, 50
- call DelayFrames
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 0
- lb bc, 12, 20
- call ClearScreenArea
- ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
- ld a, $ff
- ld [wUpdateSpritesEnabled], a
- call ClearSprites
- callab EvolveMon
- jp c, CancelledEvolution
- ld hl, EvolvedText
- call PrintText
- pop hl
- ld a, [hl]
- ld [wd0b5], a
- ld [wLoadedMonSpecies], a
- ld [wEvoNewSpecies], a
- ld a, MONSTER_NAME
- ld [wNameListType], a
- ld a, BANK(MonsterNames) ; bank is not used for monster names
- ld [wPredefBank], a
- call GetName
- push hl
- ld hl, IntoText
- call PrintText_NoCreatingTextBox
- ld a, SFX_GET_ITEM_2
- call PlaySoundWaitForCurrent
- call WaitForSoundToFinish
- ld c, 40
- call DelayFrames
- call ClearScreen
- call RenameEvolvedMon
- ld a, [wd11e]
- push af
- ld a, [wd0b5]
- ld [wd11e], a
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld hl, BaseStats
- ld bc, MonBaseStatsEnd - MonBaseStats
- call AddNTimes
- ld de, wMonHeader
- call CopyData
- ld a, [wd0b5]
- ld [wMonHIndex], a
- pop af
- ld [wd11e], a
- ld hl, wLoadedMonHPExp - 1
- ld de, wLoadedMonStats
- ld b, $1
- call CalcStats
- ld a, [wWhichPokemon]
- ld hl, wPartyMon1
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
- ld e, l
- ld d, h
- push hl
- push bc
- ld bc, wPartyMon1MaxHP - wPartyMon1
- add hl, bc
- ld a, [hli]
- ld b, a
- ld c, [hl]
- ld hl, wLoadedMonMaxHP + 1
- ld a, [hld]
- sub c
- ld c, a
- ld a, [hl]
- sbc b
- ld b, a
- ld hl, wLoadedMonHP + 1
- ld a, [hl]
- add c
- ld [hld], a
- ld a, [hl]
- adc b
- ld [hl], a
- dec hl
- pop bc
- call CopyData
- ld a, [wd0b5]
- ld [wd11e], a
- xor a
- ld [wMonDataLocation], a
- call LearnMoveFromLevelUp
- pop hl
- predef SetPartyMonTypes
- ld a, [wIsInBattle]
- and a
- call z, Evolution_ReloadTilesetTilePatterns
- predef IndexToPokedex
- ld a, [wd11e]
- dec a
- ld c, a
- ld b, FLAG_SET
- ld hl, wPokedexOwned
- push bc
- call Evolution_FlagAction
- pop bc
- ld hl, wPokedexSeen
- call Evolution_FlagAction
- pop de
- pop hl
- ld a, [wLoadedMonSpecies]
- ld [hl], a
- push hl
- ld l, e
- ld h, d
- jr .nextEvoEntry2
-
-.nextEvoEntry1
- inc hl
-
-.nextEvoEntry2
- inc hl
- jp .evoEntryLoop
-
-.done
- pop de
- pop bc
- pop hl
- pop af
- ld [hTilesetType], a
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- ret z
- ld a, [wIsInBattle]
- and a
- ret nz
- ld a, [wEvolutionOccurred]
- and a
- call nz, PlayDefaultMusic
- ret
-
-RenameEvolvedMon:
-; Renames the mon to its new, evolved form's standard name unless it had a
-; nickname, in which case the nickname is kept.
- ld a, [wd0b5]
- push af
- ld a, [wMonHIndex]
- ld [wd0b5], a
- call GetName
- pop af
- ld [wd0b5], a
- ld hl, wcd6d
- ld de, wcf4b
-.compareNamesLoop
- ld a, [de]
- inc de
- cp [hl]
- inc hl
- ret nz
- cp "@"
- jr nz, .compareNamesLoop
- ld a, [wWhichPokemon]
- ld bc, NAME_LENGTH
- ld hl, wPartyMonNicks
- call AddNTimes
- push hl
- call GetName
- ld hl, wcd6d
- pop de
- jp CopyData
-
-CancelledEvolution:
- ld hl, StoppedEvolvingText
- call PrintText
- call ClearScreen
- pop hl
- call Evolution_ReloadTilesetTilePatterns
- jp Evolution_PartyMonLoop
-
-EvolvedText:
- TX_FAR _EvolvedText
- db "@"
-
-IntoText:
- TX_FAR _IntoText
- db "@"
-
-StoppedEvolvingText:
- TX_FAR _StoppedEvolvingText
- db "@"
-
-IsEvolvingText:
- TX_FAR _IsEvolvingText
- db "@"
-
-Evolution_ReloadTilesetTilePatterns:
- ld a, [wLinkState]
- cp LINK_STATE_TRADING
- ret z
- jp ReloadTilesetTilePatterns
-
-LearnMoveFromLevelUp:
- ld a, [wd11e] ; species
- ld [wcf91], a
- call GetMonLearnset
-.learnSetLoop ; loop over the learn set until we reach a move that is learnt at the current level or the end of the list
- ld a, [hli]
- and a ; have we reached the end of the learn set?
- jr z, .done ; if we've reached the end of the learn set, jump
- ld b, a ; level the move is learnt at
- ld a, [wCurEnemyLVL]
- cp b ; is the move learnt at the mon's current level?
- ld a, [hli] ; move ID
- jr nz, .learnSetLoop
- ld d, a ; ID of move to learn
- ld a, [wMonDataLocation]
- and a
- jr nz, .next
-; If [wMonDataLocation] is 0 (PLAYER_PARTY_DATA), get the address of the mon's
-; current moves in party data. Every call to this function sets
-; [wMonDataLocation] to 0 because other data locations are not supported.
-; If it is not 0, this function will not work properly.
- ld hl, wPartyMon1Moves
- ld a, [wWhichPokemon]
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
-.next
- ld b, NUM_MOVES
-.checkCurrentMovesLoop ; check if the move to learn is already known
- ld a, [hli]
- cp d
- jr z, .done ; if already known, jump
- dec b
- jr nz, .checkCurrentMovesLoop
- ld a, d
- ld [wMoveNum], a
- ld [wd11e], a
- call GetMoveName
- call CopyStringToCF4B
- predef LearnMove
- ld a, b
- and a
- jr z, .done
- callab IsThisPartymonStarterPikachu_Party
- jr nc, .done
- ld a, [wMoveNum]
- cp THUNDERBOLT
- jr z, .foundThunderOrThunderbolt
- cp THUNDER
- jr nz, .done
-.foundThunderOrThunderbolt
- ld a, $5
- ld [wd49c], a
- ld a, $85
- ld [wPikachuMood], a
-.done
- ld a, [wcf91]
- ld [wd11e], a
- ret
-
-Func_3b079:
- ld a, [wcf91]
- push af
- call Func_3b0a2
- jr c, .asm_3b09c
-
- call Func_3b10f
- jr nc, .asm_3b096
-
- call Func_3b0a2
- jr c, .asm_3b09c
-
- call Func_3b10f
- jr nc, .asm_3b096
-
- call Func_3b0a2
- jr c, .asm_3b09c
-.asm_3b096
- pop af
- ld [wcf91], a
- and a
- ret
-.asm_3b09c
- pop af
- ld [wcf91], a
- scf
- ret
-
-Func_3b0a2:
-; XXX what is wcf91 entering this function?
- ld a, [wd11e]
- ld [wMoveNum], a
- predef CanLearnTM
- ld a, c
- and a
- jr nz, .asm_3b0ec
- ld hl, Pointer_3b0ee
- ld a, [wcf91]
- ld de, $1
- call IsInArray
- jr c, .asm_3b0d2
- ld a, $ff
- ld [wMonHGrowthRate], a
- ld a, [wd11e]
- ld hl, wMonHMoves
- ld de, $1
- call IsInArray
- jr c, .asm_3b0ec
-.asm_3b0d2
- ld a, [wd11e]
- ld d, a
- call GetMonLearnset
-.loop
- ld a, [hli]
- and a
- jr z, .asm_3b0ea
- ld b, a
- ld a, [wCurEnemyLVL]
- cp b
- jr c, .asm_3b0ea
- ld a, [hli]
- cp d
- jr z, .asm_3b0ec
- jr .loop
-.asm_3b0ea
- and a
- ret
-.asm_3b0ec
- scf
- ret
-
-Pointer_3b0ee:
- db NIDOKING
- db IVYSAUR
- db EXEGGUTOR
- db GENGAR
- db NIDOQUEEN
- db ARCANINE
- db GYARADOS
- db BLASTOISE
- db GOLEM
- db DRAGONITE
- db NINETALES
- db DRAGONAIR
- db KABUTOPS
- db OMASTAR
- db JIGGLYPUFF
- db FLAREON
- db JOLTEON
- db VAPOREON
- db BEEDRILL
- db BUTTERFREE
- db MACHAMP
- db CLOYSTER
- db CLEFABLE
- db ALAKAZAM
- db STARMIE
- db VENUSAUR
- db TENTACRUEL
- db CHARMELEON
- db WARTORTLE
- db CHARIZARD
- db VILEPLUME
- db VICTREEBEL
- db $ff
-
-Func_3b10f:
- ld c, $0
-.asm_3b111
- ld hl, EvosMovesPointerTable
- ld b, $0
- add hl, bc
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.asm_3b11b
- ld a, [hli]
- and a
- jr z, .asm_3b130
- cp $2
- jr nz, .asm_3b124
- inc hl
-.asm_3b124
- inc hl
- ld a, [wcf91]
- cp [hl]
- jr z, .asm_3b138
- inc hl
- ld a, [hl]
- and a
- jr nz, .asm_3b11b
-.asm_3b130
- inc c
- ld a, c
- cp VICTREEBEL
- jr c, .asm_3b111
- and a
- ret
-.asm_3b138
- inc c
- ld a, c
- ld [wcf91], a
- scf
- ret
-
-; writes the moves a mon has at level [wCurEnemyLVL] to [de]
-; move slots are being filled up sequentially and shifted if all slots are full
-WriteMonMoves:
- call GetPredefRegisters
- push hl
- push de
- push bc
- call GetMonLearnset
- jr .firstMove
-.nextMove
- pop de
-.nextMove2
- inc hl
-.firstMove
- ld a, [hli] ; read level of next move in learnset
- and a
- jp z, .done ; end of list
- ld b, a
- ld a, [wCurEnemyLVL]
- cp b
- jp c, .done ; mon level < move level (assumption: learnset is sorted by level)
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .skipMinLevelCheck
- ld a, [wDayCareStartLevel]
- cp b
- jr nc, .nextMove2 ; min level >= move level
-
-.skipMinLevelCheck
-
-; check if the move is already known
- push de
- ld c, NUM_MOVES
-.alreadyKnowsCheckLoop
- ld a, [de]
- inc de
- cp [hl]
- jr z, .nextMove
- dec c
- jr nz, .alreadyKnowsCheckLoop
-
-; try to find an empty move slot
- pop de
- push de
- ld c, NUM_MOVES
-.findEmptySlotLoop
- ld a, [de]
- and a
- jr z, .writeMoveToSlot2
- inc de
- dec c
- jr nz, .findEmptySlotLoop
-
-; no empty move slots found
- pop de
- push de
- push hl
- ld h, d
- ld l, e
- call WriteMonMoves_ShiftMoveData ; shift all moves one up (deleting move 1)
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .writeMoveToSlot
-
-; shift PP as well if learning moves from day care
- push de
- ld bc, wPartyMon1PP - (wPartyMon1Moves + 3)
- add hl, bc
- ld d, h
- ld e, l
- call WriteMonMoves_ShiftMoveData ; shift all move PP data one up
- pop de
-
-.writeMoveToSlot
- pop hl
-.writeMoveToSlot2
- ld a, [hl]
- ld [de], a
- ld a, [wLearningMovesFromDayCare]
- and a
- jr z, .nextMove
-
-; write move PP value if learning moves from day care
- push hl
- ld a, [hl]
- ld hl, wPartyMon1PP - wPartyMon1Moves
- add hl, de
- push hl
- dec a
- ld hl, Moves
- ld bc, MoveEnd - Moves
- call AddNTimes
- ld de, wBuffer
- ld a, BANK(Moves)
- call FarCopyData
- ld a, [wBuffer + 5]
- pop hl
- ld [hl], a
- pop hl
- jr .nextMove
-
-.done
- pop bc
- pop de
- pop hl
- ret
-
-; shifts all move data one up (freeing 4th move slot)
-WriteMonMoves_ShiftMoveData:
- ld c, NUM_MOVES - 1
-.loop
- inc de
- ld a, [de]
- ld [hli], a
- dec c
- jr nz, .loop
- ret
-
-Evolution_FlagAction:
- predef_jump FlagActionPredef
-
-GetMonLearnset:
- ld hl, EvosMovesPointerTable
- ld b, 0
- ld a, [wcf91]
- dec a
- ld c, a
- add hl, bc
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.skipEvolutionDataLoop ; loop to skip past the evolution data, which comes before the move data
- ld a, [hli]
- and a ; have we reached the end of the evolution data?
- jr nz, .skipEvolutionDataLoop ; if not, jump back up
- ret
-
-INCLUDE "data/evos_moves.asm"
diff --git a/engine/experience.asm b/engine/experience.asm
deleted file mode 100755
index 2efc13de..00000000
--- a/engine/experience.asm
+++ /dev/null
@@ -1,160 +0,0 @@
-; calculates the level a mon should be based on its current exp
-CalcLevelFromExperience:
- ld a, [wLoadedMonSpecies]
- ld [wd0b5], a
- call GetMonHeader
- ld d, $1 ; init level to 1
-.loop
- inc d ; increment level
- call CalcExperience
- push hl
- ld hl, wLoadedMonExp + 2 ; current exp
-; compare exp needed for level d with current exp
- ld a, [hExperience + 2]
- ld c, a
- ld a, [hld]
- sub c
- ld a, [hExperience + 1]
- ld c, a
- ld a, [hld]
- sbc c
- ld a, [hExperience]
- ld c, a
- ld a, [hl]
- sbc c
- pop hl
- jr nc, .loop ; if exp needed for level d is not greater than exp, try the next level
- dec d ; since the exp was too high on the last loop iteration, go back to the previous value and return
- ret
-
-; calculates the amount of experience needed for level d
-CalcExperience:
- ld a, [wMonHGrowthRate]
- add a
- add a
- ld c, a
- ld b, 0
- ld hl, GrowthRateTable
- add hl, bc
- call CalcDSquared
- ld a, d
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hl]
- and $f0
- swap a
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hli]
- and $f
- ld [H_DIVISOR], a
- ld b, $4
- call Divide
- ld a, [H_QUOTIENT + 1]
- push af
- ld a, [H_QUOTIENT + 2]
- push af
- ld a, [H_QUOTIENT + 3]
- push af
- call CalcDSquared
- ld a, [hl]
- and $7f
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [H_PRODUCT + 1]
- push af
- ld a, [H_PRODUCT + 2]
- push af
- ld a, [H_PRODUCT + 3]
- push af
- ld a, [hli]
- push af
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- ld a, d
- ld [H_MULTIPLICAND + 2], a
- ld a, [hli]
- ld [H_MULTIPLIER], a
- call Multiply
- ld b, [hl]
- ld a, [H_PRODUCT + 3]
- sub b
- ld [H_PRODUCT + 3], a
- ld b, $0
- ld a, [H_PRODUCT + 2]
- sbc b
- ld [H_PRODUCT + 2], a
- ld a, [H_PRODUCT + 1]
- sbc b
- ld [H_PRODUCT + 1], a
-; The difference of the linear term and the constant term consists of 3 bytes
-; starting at H_PRODUCT + 1. Below, hExperience (an alias of that address) will
-; be used instead for the further work of adding or subtracting the squared
-; term and adding the cubed term.
- pop af
- and $80
- jr nz, .subtractSquaredTerm ; check sign
- pop bc
- ld a, [hExperience + 2]
- add b
- ld [hExperience + 2], a
- pop bc
- ld a, [hExperience + 1]
- adc b
- ld [hExperience + 1], a
- pop bc
- ld a, [hExperience]
- adc b
- ld [hExperience], a
- jr .addCubedTerm
-.subtractSquaredTerm
- pop bc
- ld a, [hExperience + 2]
- sub b
- ld [hExperience + 2], a
- pop bc
- ld a, [hExperience + 1]
- sbc b
- ld [hExperience + 1], a
- pop bc
- ld a, [hExperience]
- sbc b
- ld [hExperience], a
-.addCubedTerm
- pop bc
- ld a, [hExperience + 2]
- add b
- ld [hExperience + 2], a
- pop bc
- ld a, [hExperience + 1]
- adc b
- ld [hExperience + 1], a
- pop bc
- ld a, [hExperience]
- adc b
- ld [hExperience], a
- ret
-
-; calculates d*d
-CalcDSquared:
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- ld a, d
- ld [H_MULTIPLICAND + 2], a
- ld [H_MULTIPLIER], a
- jp Multiply
-
-; each entry has the following scheme:
-; %AAAABBBB %SCCCCCCC %DDDDDDDD %EEEEEEEE
-; resulting in
-; (a*n^3)/b + sign*c*n^2 + d*n - e
-; where sign = -1 <=> S=1
-GrowthRateTable:
- db $11,$00,$00,$00 ; medium fast n^3
- db $34,$0A,$00,$1E ; (unused?) 3/4 n^3 + 10 n^2 - 30
- db $34,$14,$00,$46 ; (unused?) 3/4 n^3 + 20 n^2 - 70
- db $65,$8F,$64,$8C ; medium slow: 6/5 n^3 - 15 n^2 + 100 n - 140
- db $45,$00,$00,$00 ; fast: 4/5 n^3
- db $54,$00,$00,$00 ; slow: 5/4 n^3
diff --git a/engine/game_corner_slots.asm b/engine/game_corner_slots.asm
deleted file mode 100755
index 3c5b3a10..00000000
--- a/engine/game_corner_slots.asm
+++ /dev/null
@@ -1,54 +0,0 @@
-StartSlotMachine:
- ld a, [wHiddenObjectFunctionArgument]
- cp $fd
- jr z, .printOutOfOrder
- cp $fe
- jr z, .printOutToLunch
- cp $ff
- jr z, .printSomeonesKeys
- callba AbleToPlaySlotsCheck
- ld a, [wCanPlaySlots]
- and a
- ret z
- ld a, [wLuckySlotHiddenObjectIndex]
- ld b, a
- ld a, [wHiddenObjectIndex]
- inc a
- cp b
- jr z, .match
- ld a, 253
- jr .next
-.match
- ld a, 250
-.next
- ld [wSlotMachineSevenAndBarModeChance], a
- ld a, [H_LOADEDROMBANK]
- ld [wSlotMachineSavedROMBank], a
- call PromptUserToPlaySlots
- ret
-.printOutOfOrder
- tx_pre_id GameCornerOutOfOrderText
- jr .printText
-.printOutToLunch
- tx_pre_id GameCornerOutToLunchText
- jr .printText
-.printSomeonesKeys
- tx_pre_id GameCornerSomeonesKeysText
-.printText
- push af
- call EnableAutoTextBoxDrawing
- pop af
- call PrintPredefTextID
- ret
-
-GameCornerOutOfOrderText:
- TX_FAR _GameCornerOutOfOrderText
- db "@"
-
-GameCornerOutToLunchText:
- TX_FAR _GameCornerOutToLunchText
- db "@"
-
-GameCornerSomeonesKeysText:
- TX_FAR _GameCornerSomeonesKeysText
- db "@"
diff --git a/engine/game_corner_slots2.asm b/engine/game_corner_slots2.asm
deleted file mode 100755
index 6bbaf72d..00000000
--- a/engine/game_corner_slots2.asm
+++ /dev/null
@@ -1,31 +0,0 @@
-AbleToPlaySlotsCheck:
- ld a, [wSpriteStateData1 + 2]
- and $8
- jr z, .done ; not able
- ld b, COIN_CASE
- predef GetQuantityOfItemInBag
- ld a, b
- and a
- ld b, (GameCornerCoinCaseText_id - TextPredefs) / 2 + 1
- jr z, .printCoinCaseRequired
- ld hl, wPlayerCoins
- ld a, [hli]
- or [hl]
- jr nz, .done ; able to play
- ld b, (GameCornerNoCoinsText_id - TextPredefs) / 2 + 1
-.printCoinCaseRequired
- call EnableAutoTextBoxDrawing
- ld a, b
- call PrintPredefTextID
- xor a
-.done
- ld [wCanPlaySlots], a
- ret
-
-GameCornerCoinCaseText:
- TX_FAR _GameCornerCoinCaseText
- db "@"
-
-GameCornerNoCoinsText:
- TX_FAR _GameCornerNoCoinsText
- db "@"
diff --git a/engine/gamefreak.asm b/engine/gamefreak.asm
deleted file mode 100755
index 5472a56e..00000000
--- a/engine/gamefreak.asm
+++ /dev/null
@@ -1,263 +0,0 @@
-LoadShootingStarGraphics:
- ld a, $f9
- ld [rOBP0], a
- ld a, $a4
- ld [rOBP1], a
- call UpdateGBCPal_OBP0
- call UpdateGBCPal_OBP1
- ld de, AnimationTileset2 + $30 ; star tile (top left quadrant)
- ld hl, vChars1 + $200
- lb bc, BANK(AnimationTileset2), $01
- call CopyVideoData
- ld de, AnimationTileset2 + $130 ; star tile (bottom left quadrant)
- ld hl, vChars1 + $210
- lb bc, BANK(AnimationTileset2), $01
- call CopyVideoData
- ld de, FallingStar
- ld hl, vChars1 + $220
- lb bc, BANK(FallingStar), (FallingStarEnd - FallingStar) / $10
- call CopyVideoData
- ld hl, GameFreakLogoOAMData
- ld de, wOAMBuffer + $60
- ld bc, GameFreakLogoOAMDataEnd - GameFreakLogoOAMData
- call CopyData
- ld hl, GameFreakShootingStarOAMData
- ld de, wOAMBuffer
- ld bc, GameFreakShootingStarOAMDataEnd - GameFreakShootingStarOAMData
- jp CopyData
-
-AnimateShootingStar:
- call LoadShootingStarGraphics
- ld a, SFX_SHOOTING_STAR
- call PlaySound
-
-; Move the big star down and left across the screen.
- ld hl, wOAMBuffer
- lb bc, $a0, $4
-.bigStarLoop
- push hl
- push bc
-.bigStarInnerLoop
- ld a, [hl] ; Y
- add 4
- ld [hli], a
- ld a, [hl] ; X
- add -4
- ld [hli], a
- inc hl
- inc hl
- dec c
- jr nz, .bigStarInnerLoop
- ld c, 1
- call CheckForUserInterruption
- pop bc
- pop hl
- ret c
- ld a, [hl]
- cp 80
- jr nz, .next
- jr .bigStarLoop
-.next
- cp b
- jr nz, .bigStarLoop
-
-; Clear big star OAM.
- ld hl, wOAMBuffer
- ld c, 4
- ld de, 4
-.clearOAMLoop
- ld [hl], 160
- add hl, de
- dec c
- jr nz, .clearOAMLoop
-
-; Make Gamefreak logo flash.
- ld b, 3
-.flashLogoLoop
- ld hl, rOBP0
- rrc [hl]
- rrc [hl]
- call UpdateGBCPal_OBP0
- ld c, 10
- call CheckForUserInterruption
- ret c
- dec b
- jr nz, .flashLogoLoop
-
-; Copy 24 instances of the small stars OAM data.
-; Note that their coordinates put them off-screen.
- ld de, wOAMBuffer
- ld a, 24
-.initSmallStarsOAMLoop
- push af
- ld hl, SmallStarsOAM
- ld bc, SmallStarsOAMEnd - SmallStarsOAM
- call CopyData
- pop af
- dec a
- jr nz, .initSmallStarsOAMLoop
-
-; Animate the small stars falling from the Gamefreak logo.
- xor a
- ld [wMoveDownSmallStarsOAMCount], a
- ld hl, SmallStarsWaveCoordsPointerTable
- ld c, 6
-.smallStarsLoop
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- push bc
- push hl
- ld hl, wOAMBuffer + $50
- ld c, 4
-.smallStarsInnerLoop ; introduce new wave of 4 small stars OAM entries
- ld a, [de]
- cp $ff
- jr z, .next2
- ld [hli], a ; Y
- inc de
- ld a, [de]
- ld [hli], a ; X
- inc de
- inc hl
- push bc
- ld a, [de]
- ld b,a
- ld a, [hl]
- and $f0
- or b
- ld [hl], a
- inc de
- pop bc
- inc hl
- dec c
- jr nz, .smallStarsInnerLoop
- ld a, [wMoveDownSmallStarsOAMCount]
- cp 24
- jr z, .next2
- add 6 ; should be 4, but the extra 2 aren't visible on screen
- ld [wMoveDownSmallStarsOAMCount], a
-.next2
- call MoveDownSmallStars
- push af
-
-; shift the existing OAM entries down to make room for the next wave
- ld hl, wOAMBuffer + $10
- ld de, wOAMBuffer
- ld bc, $50
- call CopyData
-
- pop af
- pop hl
- pop bc
- ret c
- dec c
- jr nz, .smallStarsLoop
- and a
- ret
-
-SmallStarsOAM:
- db $00,$00,$A2,$90
-SmallStarsOAMEnd:
-
-SmallStarsWaveCoordsPointerTable:
- dw SmallStarsWave1Coords
- dw SmallStarsWave2Coords
- dw SmallStarsWave3Coords
- dw SmallStarsWave4Coords
- dw SmallStarsEmptyWave
- dw SmallStarsEmptyWave
-
-; The stars that fall from the Gamefreak logo come in 4 waves of 4 OAM entries.
-; These arrays contain the Y and X coordinates of each OAM entry.
-
-SmallStarsWave1Coords:
- db $68,$30
- db $05,$68
- db $40,$05
- db $68,$58
- db $04,$68
- db $78,$07
-
-SmallStarsWave2Coords:
- db $68,$38
- db $05,$68
- db $48,$06
- db $68,$60
- db $04,$68
- db $70,$07
-
-SmallStarsWave3Coords:
- db $68,$34
- db $05,$68
- db $4c,$06
- db $68,$54
- db $06,$68
- db $64,$07
-
-SmallStarsWave4Coords:
- db $68,$3c
- db $05,$68
- db $5c,$04
- db $68,$6c
- db $07,$68
- db $74,$07
-
-SmallStarsEmptyWave:
- db $FF
-
-MoveDownSmallStars:
- ld b, 8
-.loop
- ld hl, wOAMBuffer + $5c
- ld a, [wMoveDownSmallStarsOAMCount]
- ld de, -4
- ld c, a
-.innerLoop
- inc [hl] ; Y
- add hl, de
- dec c
- jr nz, .innerLoop
-; Toggle the palette so that the lower star in the small stars tile blinks in
-; and out.
- ld a, [rOBP1]
- xor %10100000
- ld [rOBP1], a
- call UpdateGBCPal_OBP1
- ld c, 3
- call CheckForUserInterruption
- ret c
- dec b
- jr nz, .loop
- ret
-
-GameFreakLogoOAMData:
- db $48,$50,$8D,$00
- db $48,$58,$8E,$00
- db $50,$50,$8F,$00
- db $50,$58,$90,$00
- db $58,$50,$91,$00
- db $58,$58,$92,$00
- db $60,$30,$80,$00
- db $60,$38,$81,$00
- db $60,$40,$82,$00
- db $60,$48,$83,$00
- db $60,$50,$93,$00
- db $60,$58,$84,$00
- db $60,$60,$85,$00
- db $60,$68,$83,$00
- db $60,$70,$81,$00
- db $60,$78,$86,$00
-GameFreakLogoOAMDataEnd:
-
-GameFreakShootingStarOAMData:
- db $00,$A0,$A0,$14
- db $00,$A8,$A0,$34
- db $08,$A0,$A1,$14
- db $08,$A8,$A1,$34
-GameFreakShootingStarOAMDataEnd:
-
-FallingStar:
- INCBIN "gfx/falling_star.2bpp"
-FallingStarEnd:
diff --git a/engine/hp_bar.asm b/engine/gfx/hp_bar.asm
index 566a7b61..b47b1fbd 100755
--- a/engine/hp_bar.asm
+++ b/engine/gfx/hp_bar.asm
@@ -6,7 +6,7 @@ HPBarLength:
GetHPBarLength:
push hl
xor a
- ld hl, H_MULTIPLICAND
+ ld hl, hMultiplicand
ld [hli], a
ld a, b
ld [hli], a
@@ -21,22 +21,22 @@ GetHPBarLength:
rr e
srl d
rr e
- ld a, [H_MULTIPLICAND+1]
+ ldh a, [hMultiplicand+1]
ld b, a
- ld a, [H_MULTIPLICAND+2]
+ ldh a, [hMultiplicand+2]
srl b ; divide multiplication result as well
rr a
srl b
rr a
- ld [H_MULTIPLICAND+2], a
+ ldh [hMultiplicand+2], a
ld a, b
- ld [H_MULTIPLICAND+1], a
+ ldh [hMultiplicand+1], a
.maxHPSmaller256
ld a, e
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $4
call Divide
- ld a, [H_MULTIPLICAND+2]
+ ldh a, [hMultiplicand+2]
ld e, a ; e = bc * 48 / de (num of pixels of HP bar)
pop hl
and a
@@ -214,7 +214,7 @@ UpdateHPBar_PrintHPNumber:
ld [wHPBarTempHP], a
push hl
ld de, $15
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
bit 0, a
jr z, .next
ld de, $9
diff --git a/engine/load_pokedex_tiles.asm b/engine/gfx/load_pokedex_tiles.asm
index 70bcf04d..a3f69171 100755
--- a/engine/load_pokedex_tiles.asm
+++ b/engine/gfx/load_pokedex_tiles.asm
@@ -2,10 +2,10 @@
LoadPokedexTilePatterns:
call LoadHpBarAndStatusTilePatterns
ld de, PokedexTileGraphics
- ld hl, vChars2 + $600
+ ld hl, vChars2 tile $60
lb bc, BANK(PokedexTileGraphics), (PokedexTileGraphicsEnd - PokedexTileGraphics) / $10
call CopyVideoData
ld de, PokeballTileGraphics
- ld hl, vChars2 + $720
- lb bc, BANK(PokeballTileGraphics), $01
+ ld hl, vChars2 tile $72
+ lb bc, BANK(PokeballTileGraphics), 1
jp CopyVideoData ; load pokeball tile for marking caught mons
diff --git a/engine/gfx/mon_icons.asm b/engine/gfx/mon_icons.asm
new file mode 100755
index 00000000..6e2cf0ba
--- /dev/null
+++ b/engine/gfx/mon_icons.asm
@@ -0,0 +1,307 @@
+AnimatePartyMon_ForceSpeed1:
+ xor a
+ ld [wCurrentMenuItem], a
+ ld b, a
+ inc a
+ jr GetAnimationSpeed
+
+; wPartyMenuHPBarColors contains the party mon's health bar colors
+; 0: green
+; 1: yellow
+; 2: red
+AnimatePartyMon::
+ ld hl, wPartyMenuHPBarColors
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+
+GetAnimationSpeed:
+ ld c, a
+ ld hl, PartyMonSpeeds
+ add hl, bc
+ ld a, [wOnSGB]
+ xor $1
+ add [hl]
+ ld c, a
+ add a
+ ld b, a
+ ld a, [wAnimCounter]
+ and a
+ jr z, .resetSprites
+ cp c
+ jr z, .animateSprite
+.incTimer
+ inc a
+ cp b
+ jr nz, .skipResetTimer
+ xor a ; reset timer
+.skipResetTimer
+ ld [wAnimCounter], a
+ jp DelayFrame
+.resetSprites
+ push bc
+ ld hl, wMonPartySpritesSavedOAM
+ ld de, wOAMBuffer
+ ld bc, $60
+ call CopyData
+ pop bc
+ xor a
+ jr .incTimer
+.animateSprite
+ push bc
+ ld hl, wOAMBuffer + $02 ; OAM tile id
+ ld bc, $10
+ ld a, [wCurrentMenuItem]
+ call AddNTimes
+ ld c, ICONOFFSET
+ ld a, [hl]
+ cp ICON_BALL << 2
+ jr z, .editCoords
+ cp ICON_HELIX << 2
+ jr nz, .editTileIDS
+; ICON_BALL and ICON_HELIX only shake up and down
+.editCoords
+ dec hl
+ dec hl ; dec hl to the OAM y coord
+ ld c, $1 ; amount to increase the y coord by
+; otherwise, load a second sprite frame
+.editTileIDS
+ ld b, $4
+ ld de, $4
+.loop
+ ld a, [hl]
+ add c
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ pop bc
+ ld a, c
+ jr .incTimer
+
+; Party mon animations cycle between 2 frames.
+; The members of the PartyMonSpeeds array specify the number of V-blanks
+; that each frame lasts for green HP, yellow HP, and red HP in order.
+; On the naming screen, the yellow HP speed is always used.
+PartyMonSpeeds:
+ db 5, 16, 32
+
+LoadMonPartySpriteGfx:
+; Load mon party sprite tile patterns into VRAM during V-blank.
+ ld hl, MonPartySpritePointers
+ ld a, $1e
+
+LoadAnimSpriteGfx:
+; Load animated sprite tile patterns into VRAM during V-blank. hl is the address
+; of an array of structures that contain arguments for CopyVideoData and a is
+; the number of structures in the array.
+ ld bc, $0
+.loop
+ push af
+ push bc
+ push hl
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CopyVideoData
+ pop hl
+ pop bc
+ ld a, $6
+ add c
+ ld c, a
+ pop af
+ dec a
+ jr nz, .loop
+ ret
+
+LoadMonPartySpriteGfxWithLCDDisabled:
+; Load mon party sprite tile patterns into VRAM immediately by disabling the
+; LCD.
+ call DisableLCD
+ ld hl, MonPartySpritePointers
+ ld a, $1e
+ ld bc, $0
+.loop
+ push af
+ push bc
+ push hl
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ push de
+ ld a, [hli]
+ ld c, a
+ swap c
+ ld b, $0
+ ld a, [hli]
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ call FarCopyData
+ pop hl
+ pop bc
+ ld a, $6
+ add c
+ ld c, a
+ pop af
+ dec a
+ jr nz, .loop
+ jp EnableLCD
+
+INCLUDE "data/icon_pointers.asm"
+
+WriteMonPartySpriteOAMByPartyIndex:
+; Write OAM blocks for the party mon in [hPartyMonIndex].
+ push hl
+ push de
+ push bc
+ ldh a, [hPartyMonIndex]
+ cp $ff
+ jr z, .asm_7191f
+ ld hl, wPartySpecies
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+ call GetPartyMonSpriteID
+ ld [wOAMBaseTile], a
+ call WriteMonPartySpriteOAM
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.asm_7191f
+ ld hl, wOAMBuffer
+ ld de, wMonPartySpritesSavedOAM
+ ld bc, $60
+ call CopyData
+ pop bc
+ pop de
+ pop hl
+ ret
+
+WriteMonPartySpriteOAMBySpecies:
+; Write OAM blocks for the party sprite of the species in
+; [wMonPartySpriteSpecies].
+ xor a
+ ldh [hPartyMonIndex], a
+ ld a, [wMonPartySpriteSpecies]
+ call GetPartyMonSpriteID
+ ld [wOAMBaseTile], a
+ jr WriteMonPartySpriteOAM
+
+UnusedPartyMonSpriteFunction:
+; This function is unused and doesn't appear to do anything useful. It looks
+; like it may have been intended to load the tile patterns and OAM data for
+; the mon party sprite associated with the species in [wcf91].
+; However, its calculations are off and it loads garbage data.
+ ld a, [wcf91]
+ call GetPartyMonSpriteID
+ push af
+ ld hl, vSprites tile $00
+ call .LoadTilePatterns
+ pop af
+ add $5A
+ ld hl, vSprites tile $04
+ call .LoadTilePatterns
+ xor a
+ ld [wMonPartySpriteSpecies], a
+ jr WriteMonPartySpriteOAMBySpecies
+
+.LoadTilePatterns
+ push hl
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, MonPartySpritePointers
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ pop hl
+ jp CopyVideoData
+
+WriteMonPartySpriteOAM:
+; Write the OAM blocks for the first animation frame into the OAM buffer and
+; make a copy at wMonPartySpritesSavedOAM.
+ push af
+ ld c, $10
+ ld h, HIGH(wOAMBuffer)
+ ldh a, [hPartyMonIndex]
+ swap a
+ ld l, a
+ add $10
+ ld b, a
+ pop af
+ cp ICON_HELIX << 2
+ jr z, .helix
+ call WriteSymmetricMonPartySpriteOAM
+ jr .makeCopy
+.helix
+ call WriteAsymmetricMonPartySpriteOAM
+; Make a copy of the OAM buffer with the first animation frame written so that
+; we can flip back to it from the second frame by copying it back.
+.makeCopy
+ ld hl, wOAMBuffer
+ ld de, wMonPartySpritesSavedOAM
+ ld bc, $60
+ jp CopyData
+
+GetPartyMonSpriteID:
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld a, [wd11e]
+ ld c, a
+ dec a
+ srl a
+ ld hl, MonPartyData
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+ bit 0, c
+ jr nz, .skipSwap
+ swap a ; use lower nybble if pokedex num is even
+.skipSwap
+ and $f0
+ srl a ; value == ICON constant << 2
+ srl a
+ ret
+
+INCLUDE "data/pokemon/menu_icons.asm"
+
+INC_FRAME_1 EQUS "0, $20"
+INC_FRAME_2 EQUS "$20, $20"
+
+BugIconFrame1: INCBIN "gfx/icons/bug.2bpp", INC_FRAME_1
+PlantIconFrame1: INCBIN "gfx/icons/plant.2bpp", INC_FRAME_1
+BugIconFrame2: INCBIN "gfx/icons/bug.2bpp", INC_FRAME_2
+PlantIconFrame2: INCBIN "gfx/icons/plant.2bpp", INC_FRAME_2
+SnakeIconFrame1: INCBIN "gfx/icons/snake.2bpp", INC_FRAME_1
+QuadrupedIconFrame1: INCBIN "gfx/icons/quadruped.2bpp", INC_FRAME_1
+SnakeIconFrame2: INCBIN "gfx/icons/snake.2bpp", INC_FRAME_2
+QuadrupedIconFrame2: INCBIN "gfx/icons/quadruped.2bpp", INC_FRAME_2
+
+TradeBubbleIconGFX: INCBIN "gfx/trade/bubble.2bpp"
diff --git a/engine/gfx/oam_dma.asm b/engine/gfx/oam_dma.asm
new file mode 100644
index 00000000..fe93e90d
--- /dev/null
+++ b/engine/gfx/oam_dma.asm
@@ -0,0 +1,28 @@
+WriteDMACodeToHRAM::
+; Since no other memory is available during OAM DMA,
+; DMARoutine is copied to HRAM and executed there.
+ ld c, LOW(hDMARoutine)
+ ld b, DMARoutineEnd - DMARoutine
+ ld hl, DMARoutine
+.copy
+ ld a, [hli]
+ ldh [c], a
+ inc c
+ dec b
+ jr nz, .copy
+ ret
+
+DMARoutine:
+LOAD "OAM DMA", HRAM
+hDMARoutine::
+ ; initiate DMA
+ ld a, HIGH(wOAMBuffer)
+ ldh [rDMA], a
+ ; wait for DMA to finish
+ ld a, $28
+.wait
+ dec a
+ jr nz, .wait
+ ret
+ENDL
+DMARoutineEnd:
diff --git a/engine/gfx/palettes.asm b/engine/gfx/palettes.asm
new file mode 100755
index 00000000..dd723afa
--- /dev/null
+++ b/engine/gfx/palettes.asm
@@ -0,0 +1,1117 @@
+_RunPaletteCommand:
+ call GetPredefRegisters
+ ld a, b
+ cp SET_PAL_DEFAULT
+ jr nz, .not_default
+ ld a, [wDefaultPaletteCommand]
+.not_default
+ cp SET_PAL_PARTY_MENU_HP_BARS
+ jp z, UpdatePartyMenuBlkPacket
+ ld l, a
+ ld h, 0
+ add hl, hl
+ ld de, SetPalFunctions
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, SendSGBPackets
+ push de
+ jp hl
+
+SetPal_Black:
+ ld hl, PalPacket_Black
+ ld de, BlkPacket_Battle
+ ret
+
+; uses PalPacket_Empty to build a packet based on mon IDs and health color
+SetPal_Battle:
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ;ld a, [wPlayerBattleStatus3]
+ ld hl, wBattleMonSpecies
+ ld a, [hl]
+ and a
+ jr z, .asm_71ef9
+ ld hl, wPartyMon1
+ ld a, [wPlayerMonNumber]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+.asm_71ef9
+ call DeterminePaletteID
+ ld b, a
+ ;ld a, [wEnemyBattleStatus3]
+ ld hl, wEnemyMonSpecies2
+ call DeterminePaletteID
+ ld c, a
+ ld hl, wPalPacket + 1
+ ld a, [wPlayerHPBarColor]
+ add PAL_GREENBAR
+ ld [hli], a
+ inc hl
+ ld a, [wEnemyHPBarColor]
+ add PAL_GREENBAR
+ ld [hli], a
+ inc hl
+ ld a, b
+ ld [hli], a
+ inc hl
+ ld a, c
+ ld [hl], a
+ ld hl, wPalPacket
+ ld de, BlkPacket_Battle
+ ld a, SET_PAL_BATTLE
+ ld [wDefaultPaletteCommand], a
+ ret
+
+SetPal_TownMap:
+ ld hl, PalPacket_TownMap
+ ld de, BlkPacket_WholeScreen
+ ret
+
+; uses PalPacket_Empty to build a packet based the mon ID
+SetPal_StatusScreen:
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ld a, [wcf91]
+ cp NUM_POKEMON_INDEXES + 1
+ jr c, .pokemon
+ ld a, $1 ; not pokemon
+.pokemon
+ call DeterminePaletteIDOutOfBattle
+ push af
+ ld hl, wPalPacket + 1
+ ld a, [wStatusScreenHPBarColor]
+ add PAL_GREENBAR
+ ld [hli], a
+ inc hl
+ pop af
+ ld [hl], a
+ ld hl, wPalPacket
+ ld de, BlkPacket_StatusScreen
+ ret
+
+SetPal_PartyMenu:
+ ld hl, PalPacket_PartyMenu
+ ld de, wPartyMenuBlkPacket
+ ret
+
+SetPal_Pokedex:
+ ld hl, PalPacket_Pokedex
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ld a, [wcf91]
+ call DeterminePaletteIDOutOfBattle
+ ld hl, wPalPacket + 3
+ ld [hl], a
+ ld hl, wPalPacket
+ ld de, BlkPacket_Pokedex
+ ret
+
+SetPal_Slots:
+ ld hl, PalPacket_Slots
+ ld de, BlkPacket_Slots
+ ret
+
+SetPal_Titlescreen:
+ ld hl, PalPacket_Titlescreen
+ ld de, BlkPacket_Titlescreen
+ ret
+
+; used mostly for menus and the Oak intro
+SetPal_Generic:
+ ld hl, PalPacket_Generic
+ ld de, BlkPacket_WholeScreen
+ ret
+
+SetPal_NidorinoIntro:
+ ld hl, PalPacket_NidorinoIntro
+ ld de, BlkPacket_NidorinoIntro
+ ret
+
+SetPal_GameFreakIntro:
+ ld hl, PalPacket_GameFreakIntro
+ ld de, BlkPacket_GameFreakIntro
+ ld a, SET_PAL_GENERIC
+ ld [wDefaultPaletteCommand], a
+ ret
+
+; uses PalPacket_Empty to build a packet based on the current map
+SetPal_Overworld:
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ld a, [wCurMapTileset]
+ cp CEMETERY
+ jr z, .PokemonTowerOrAgatha
+ cp CAVERN
+ jr z, .caveOrBruno
+ ld a, [wCurMap]
+ cp FIRST_INDOOR_MAP
+ jr c, .townOrRoute
+ cp CERULEAN_CAVE_2F
+ jr c, .normalDungeonOrBuilding
+ cp CERULEAN_CAVE_1F + 1
+ jr c, .caveOrBruno
+ cp LORELEIS_ROOM
+ jr z, .Lorelei
+ cp BRUNOS_ROOM
+ jr z, .caveOrBruno
+ cp TRADE_CENTER
+ jr z, .trade_center_colosseum
+ cp COLOSSEUM
+ jr z, .trade_center_colosseum
+.normalDungeonOrBuilding
+ ld a, [wLastMap] ; town or route that current dungeon or building is located
+.townOrRoute
+ cp NUM_CITY_MAPS
+ jr c, .town
+ ld a, PAL_ROUTE - 1
+.town
+ inc a ; a town's palette ID is its map ID + 1
+ ld hl, wPalPacket + 1
+ ld [hld], a
+ ld de, BlkPacket_WholeScreen
+ ld a, SET_PAL_OVERWORLD
+ ld [wDefaultPaletteCommand], a
+ ret
+.PokemonTowerOrAgatha
+ ld a, PAL_GREYMON - 1
+ jr .town
+.caveOrBruno
+ ld a, PAL_CAVE - 1
+ jr .town
+.Lorelei
+ xor a
+ jr .town
+.trade_center_colosseum
+ ld a, PAL_GREYMON - 1
+ jr .town
+
+; used when a Pokemon is the only thing on the screen
+; such as evolution, trading and the Hall of Fame
+SetPal_PokemonWholeScreen:
+ push bc
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ pop bc
+ ld a, c
+ and a
+ ld a, PAL_BLACK
+ jr nz, .next
+ ld a, [wWholeScreenPaletteMonSpecies]
+ call DeterminePaletteIDOutOfBattle
+.next
+ ld [wPalPacket + 1], a
+ ld hl, wPalPacket
+ ld de, BlkPacket_WholeScreen
+ ret
+
+SetPal_TrainerCard:
+ ld hl, BlkPacket_TrainerCard
+ ld de, wTrainerCardBlkPacket
+ ld bc, $40
+ call CopyData
+ ld de, BadgeBlkDataLengths
+ ld hl, wTrainerCardBlkPacket + 2
+ ld a, [wObtainedBadges]
+ ld c, NUM_BADGES
+.badgeLoop
+ srl a
+ push af
+ jr c, .haveBadge
+; The player doens't have the badge, so zero the badge's blk data.
+ push bc
+ ld a, [de]
+ ld c, a
+ xor a
+.zeroBadgeDataLoop
+ ld [hli], a
+ dec c
+ jr nz, .zeroBadgeDataLoop
+ pop bc
+ jr .nextBadge
+.haveBadge
+; The player does have the badge, so skip past the badge's blk data.
+ ld a, [de]
+.skipBadgeDataLoop
+ inc hl
+ dec a
+ jr nz, .skipBadgeDataLoop
+.nextBadge
+ pop af
+ inc de
+ dec c
+ jr nz, .badgeLoop
+ ld hl, PalPacket_TrainerCard
+ ld de, wTrainerCardBlkPacket
+ ret
+
+SendUnknownPalPacket_7205d::
+ ld hl, UnknownPalPacket_72811
+ ld de, BlkPacket_WholeScreen
+ ret
+
+SendUnknownPalPacket_72064::
+ ld hl, UnknownPalPacket_72821
+ ld de, UnknownPacket_72751
+ ret
+
+SetPalFunctions:
+; entries correspond to SET_PAL_* constants
+ dw SetPal_Black
+ dw SetPal_Battle
+ dw SetPal_TownMap
+ dw SetPal_StatusScreen
+ dw SetPal_Pokedex
+ dw SetPal_Slots
+ dw SetPal_Titlescreen
+ dw SetPal_NidorinoIntro
+ dw SetPal_Generic
+ dw SetPal_Overworld
+ dw SetPal_PartyMenu
+ dw SetPal_PokemonWholeScreen
+ dw SetPal_GameFreakIntro
+ dw SetPal_TrainerCard
+ dw SendUnknownPalPacket_7205d
+ dw SendUnknownPalPacket_72064
+
+; The length of the blk data of each badge on the Trainer Card.
+; The Rainbow Badge has 3 entries because of its many colors.
+BadgeBlkDataLengths:
+ db 6 ; Boulder Badge
+ db 6 ; Cascade Badge
+ db 6 ; Thunder Badge
+ db 6 * 3 ; Rainbow Badge
+ db 6 ; Soul Badge
+ db 6 ; Marsh Badge
+ db 6 ; Volcano Badge
+ db 6 ; Earth Badge
+
+DeterminePaletteID:
+ ld a, [hl]
+DeterminePaletteIDOutOfBattle:
+ ld [wd11e], a
+ and a ; is the mon index 0?
+ jr z, .skipDexNumConversion
+ push bc
+ predef IndexToPokedex
+ pop bc
+ ld a, [wd11e]
+.skipDexNumConversion
+ ld e, a
+ ld d, 0
+ ld hl, MonsterPalettes ; not just for Pokemon, Trainers use it too
+ add hl, de
+ ld a, [hl]
+ ret
+
+YellowIntroPaletteAction::
+ ld a, e
+ and a
+ jr nz, .asm_720bd
+ ld hl, PalPacket_Generic
+ ldh a, [hGBC]
+ and a
+ jp z, SendSGBPacket
+ jp InitGBCPalettes
+
+.asm_720bd
+ ld hl, UnknownPalPacket_72811
+ ldh a, [hGBC]
+ and a
+ jp z, SendSGBPacket
+ call InitGBCPalettes
+ ld hl, PalPacket_Generic
+ inc hl
+ ld a, [hli]
+ call GetGBCBasePalAddress
+ ld a, e
+ ld [wGBCBasePalPointers + 2], a
+ ld a, d
+ ld [wGBCBasePalPointers + 2 + 1], a
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, 1
+ call TransferCurBGPData
+ ret
+
+LoadOverworldPikachuFrontpicPalettes::
+ ld hl, PalPacket_Empty
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ call GetPal_Pikachu
+ ld hl, wPartyMenuBlkPacket
+ ld [hl], a
+ ld hl, wPartyMenuBlkPacket + 2
+ ld a, $26
+ ld [hl], a
+ ld hl, wPalPacket
+ ldh a, [hGBC]
+ and a
+ jr nz, .cgb_1
+ call SendSGBPacket
+ jr .okay_1
+
+.cgb_1
+ call InitGBCPalettes
+.okay_1
+ ld hl, BlkPacket_WholeScreen
+ ld de, wPalPacket
+ ld bc, $10
+ call CopyData
+ ld hl, wPartyMenuBlkPacket + 2
+ ld a, $5
+ ld [hli], a
+ ld a, $7
+ ld [hli], a
+ ld a, $6
+ ld [hli], a
+ ld a, $b
+ ld [hli], a
+ ld a, $a
+ ld [hl], a
+ ld hl, wPalPacket
+ ldh a, [hGBC]
+ and a
+ jr nz, .cgb_2
+ call SendSGBPacket
+ jr .okay_2
+
+.cgb_2
+ call InitGBCPalettes
+.okay_2
+ ret
+
+GetPal_Pikachu::
+; similar to SetPal_Overworld
+ ld a, [wCurMapTileset]
+ cp CEMETERY
+ jr z, .PokemonTowerOrAgatha
+ cp CAVERN
+ jr z, .caveOrBruno
+ ld a, [wCurMap]
+ cp REDS_HOUSE_1F
+ jr c, .townOrRoute
+ cp CERULEAN_CAVE_2F
+ jr c, .normalDungeonOrBuilding
+ cp NAME_RATERS_HOUSE
+ jr c, .caveOrBruno
+ cp LORELEIS_ROOM
+ jr z, .Lorelei
+ cp BRUNOS_ROOM
+ jr z, .caveOrBruno
+ cp TRADE_CENTER
+ jr z, .battleOrTradeCenter
+ cp COLOSSEUM
+ jr z, .battleOrTradeCenter
+.normalDungeonOrBuilding
+ ld a, [wLastMap] ; town or route that current dungeon or building is located
+.townOrRoute
+ cp SAFFRON_CITY + 1
+ jr c, .town
+ ld a, PAL_ROUTE - 1
+.town
+ inc a ; a town's pallete ID is its map ID + 1
+ ret
+
+.PokemonTowerOrAgatha
+ ld a, PAL_GREYMON - 1
+ jr .town
+
+.caveOrBruno
+ ld a, PAL_CAVE - 1
+ jr .town
+
+.Lorelei
+ xor a ; PAL_PALLET - 1
+ jr .town
+
+.battleOrTradeCenter
+ ld a, PAL_GREYMON - 1
+ jr .town
+
+InitPartyMenuBlkPacket:
+ ld hl, BlkPacket_PartyMenu
+ ld de, wPartyMenuBlkPacket
+ ld bc, $30
+ jp CopyData
+
+UpdatePartyMenuBlkPacket:
+; Update the blk packet with the palette of the HP bar that is
+; specified in [wWhichPartyMenuHPBar].
+ ld hl, wPartyMenuHPBarColors
+ ld a, [wWhichPartyMenuHPBar]
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld e, l
+ ld d, h
+ ld a, [de]
+ and a
+ ld e, (1 << 2) | 1 ; green
+ jr z, .next
+ dec a
+ ld e, (2 << 2) | 2 ; yellow
+ jr z, .next
+ ld e, (3 << 2) | 3 ; red
+.next
+ push de
+ ld hl, wPartyMenuBlkPacket + 8 + 1
+ ld bc, 6
+ ld a, [wWhichPartyMenuHPBar]
+ call AddNTimes
+ pop de
+ ld [hl], e
+ ret
+
+SendSGBPacket:
+ ld a, 1
+ ldh [hDisableJoypadPolling], a ; don't poll joypad while sending packet
+ call _SendSGBPacket
+ xor a
+ ldh [hDisableJoypadPolling], a
+ ret
+
+_SendSGBPacket:
+;check number of packets
+ ld a, [hl]
+ and $07
+ ret z
+; store number of packets in B
+ ld b, a
+.loop2
+; save B for later use
+ push bc
+; send RESET signal (P14=LOW, P15=LOW)
+ xor a
+ ldh [rJOYP], a
+; set P14=HIGH, P15=HIGH
+ ld a, $30
+ ldh [rJOYP], a
+;load length of packets (16 bytes)
+ ld b, $10
+.nextByte
+;set bit counter (8 bits per byte)
+ ld e, $08
+; get next byte in the packet
+ ld a, [hli]
+ ld d, a
+.nextBit0
+ bit 0, d
+; if 0th bit is not zero set P14=HIGH, P15=LOW (send bit 1)
+ ld a, $10
+ jr nz, .next0
+; else (if 0th bit is zero) set P14=LOW, P15=HIGH (send bit 0)
+ ld a, $20
+.next0
+ ldh [rJOYP], a
+; must set P14=HIGH,P15=HIGH between each "pulse"
+ ld a, $30
+ ldh [rJOYP], a
+; rotation will put next bit in 0th position (so we can always use command
+; "bit 0, d" to fetch the bit that has to be sent)
+ rr d
+; decrease bit counter so we know when we have sent all 8 bits of current byte
+ dec e
+ jr nz, .nextBit0
+ dec b
+ jr nz, .nextByte
+; send bit 1 as a "stop bit" (end of parameter data)
+ ld a, $20
+ ldh [rJOYP], a
+; set P14=HIGH,P15=HIGH
+ ld a, $30
+ ldh [rJOYP], a
+; wait for about 70000 cycles
+ call Wait7000
+; restore (previously pushed) number of packets
+ pop bc
+ dec b
+; return if there are no more packets
+ ret z
+; else send 16 more bytes
+ jr .loop2
+
+LoadSGB:
+ xor a
+ ld [wOnSGB], a
+ call CheckSGB
+ jr c, .onSGB
+ ldh a, [hGBC]
+ and a
+ jr z, .onDMG
+ ld a, $1
+ ld [wOnSGB], a
+.onDMG
+ ret
+.onSGB
+ ld a, $1
+ ld [wOnSGB], a
+ di
+ call PrepareSuperNintendoVRAMTransfer
+ ei
+ ld a, 1
+ ld [wCopyingSGBTileData], a
+ ld de, ChrTrnPacket
+ ld hl, SGBBorderGraphics
+ call CopyGfxToSuperNintendoVRAM
+ xor a
+ ld [wCopyingSGBTileData], a
+ ld de, PctTrnPacket
+ ld hl, BorderPalettes
+ call CopyGfxToSuperNintendoVRAM
+ xor a
+ ld [wCopyingSGBTileData], a
+ ld de, PalTrnPacket
+ ld hl, SuperPalettes
+ call CopyGfxToSuperNintendoVRAM
+ call ClearVram
+ ld hl, MaskEnCancelPacket
+ jp SendSGBPacket
+
+PrepareSuperNintendoVRAMTransfer:
+ ld hl, .packetPointers
+ ld c, 9
+.loop
+ push bc
+ ld a, [hli]
+ push hl
+ ld h, [hl]
+ ld l, a
+ call SendSGBPacket
+ pop hl
+ inc hl
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+.packetPointers
+; Only the first packet is needed.
+ dw MaskEnFreezePacket
+ dw DataSnd_728a1
+ dw DataSnd_728b1
+ dw DataSnd_728c1
+ dw DataSnd_728d1
+ dw DataSnd_728e1
+ dw DataSnd_728f1
+ dw DataSnd_72901
+ dw DataSnd_72911
+
+CheckSGB:
+; Returns whether the game is running on an SGB in carry.
+ ld hl, MltReq2Packet
+ call SendSGBPacket
+ call Wait7000
+ ldh a, [rJOYP]
+ and $3
+ cp $3
+ jr nz, .isSGB
+ ld a, $20
+ ldh [rJOYP], a
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ call Wait7000
+ call Wait7000
+ ld a, $30
+ ldh [rJOYP], a
+ call Wait7000
+ call Wait7000
+ ld a, $10
+ ldh [rJOYP], a
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ call Wait7000
+ call Wait7000
+ ld a, $30
+ ldh [rJOYP], a
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
+ call Wait7000
+ call Wait7000
+ ldh a, [rJOYP]
+ and $3
+ cp $3
+ jr nz, .isSGB
+ call SendMltReq1Packet
+ and a
+ ret
+.isSGB
+ call SendMltReq1Packet
+ scf
+ ret
+
+SendMltReq1Packet:
+ ld hl, MltReq1Packet
+ call SendSGBPacket
+ jp Wait7000
+
+CopyGfxToSuperNintendoVRAM:
+ di
+ push de
+ call DisableLCD
+ ld a, $e4
+ ldh [rBGP], a
+ call _UpdateGBCPal_BGP_CheckDMG
+ ld de, vChars1
+ ld a, [wCopyingSGBTileData]
+ and a
+ jr z, .notCopyingTileData
+ call CopySGBBorderTiles
+ jr .next
+.notCopyingTileData
+ ld bc, $1000
+ call CopyData
+.next
+ ld hl, vBGMap0
+ ld de, $c
+ ld a, $80
+ ld c, $d
+.loop
+ ld b, $14
+.innerLoop
+ ld [hli], a
+ inc a
+ dec b
+ jr nz, .innerLoop
+ add hl, de
+ dec c
+ jr nz, .loop
+ ld a, $e3
+ ldh [rLCDC], a
+ pop hl
+ call SendSGBPacket
+ xor a
+ ldh [rBGP], a
+ call _UpdateGBCPal_BGP_CheckDMG
+ ei
+ ret
+
+Wait7000:
+; Each loop takes 9 cycles so this routine actually waits 63000 cycles.
+ ld de, 7000
+.loop
+ nop
+ nop
+ nop
+ dec de
+ ld a, d
+ or e
+ jr nz, .loop
+ ret
+
+SendSGBPackets:
+ ldh a, [hGBC]
+ and a
+ jr z, .notGBC
+ push de
+ call InitGBCPalettes
+ pop hl
+ call InitGBCPalettes
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ ret z
+ call Delay3
+ ret
+.notGBC
+ push de
+ call SendSGBPacket
+ pop hl
+ jp SendSGBPacket
+
+InitGBCPalettes:
+ ld a, [hl]
+ and $f8
+ cp $20
+ jp z, TranslatePalPacketToBGMapAttributes
+
+ inc hl
+
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ IF index > 0
+ pop hl
+ ENDC
+
+ ld a, [hli]
+ inc hl
+
+ IF index < (NUM_ACTIVE_PALS + -1)
+ push hl
+ ENDC
+
+ call GetGBCBasePalAddress
+ ld a, e
+ ld [wGBCBasePalPointers + index * 2], a
+ ld a, d
+ ld [wGBCBasePalPointers + index * 2 + 1], a
+
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, index
+ call TransferCurBGPData
+
+ ld a, CONVERT_OBP0
+ call DMGPalToGBCPal
+ ld a, index
+ call TransferCurOBPData
+
+ ld a, CONVERT_OBP1
+ call DMGPalToGBCPal
+ ld a, index + 4
+ call TransferCurOBPData
+
+index = index + 1
+ ENDR
+
+ ret
+
+GetGBCBasePalAddress::
+; Input: a = palette ID
+; Output: de = palette address
+ push hl
+ ld l, a
+ xor a
+ ld h, a
+ add hl, hl
+ add hl, hl
+ add hl, hl
+ ld de, GBCBasePalettes
+ add hl, de
+ ld a, l
+ ld e, a
+ ld a, h
+ ld d, a
+ pop hl
+ ret
+
+DMGPalToGBCPal::
+; Populate wGBCPal with colors from a base palette, selected using one of the
+; DMG palette registers.
+; Input:
+; a = which DMG palette register
+; de = address of GBC base palette
+ and a
+ jr nz, .notBGP
+ ldh a, [rBGP]
+ ld [wLastBGP], a
+ jr .convert
+.notBGP
+ dec a
+ jr nz, .notOBP0
+ ldh a, [rOBP0]
+ ld [wLastOBP0], a
+ jr .convert
+.notOBP0
+ ldh a, [rOBP1]
+ ld [wLastOBP1], a
+.convert
+color_index = 0
+ REPT NUM_COLORS
+ ld b, a
+ and %11
+ call .GetColorAddress
+ ld a, [hli]
+ ld [wGBCPal + color_index * 2], a
+ ld a, [hl]
+ ld [wGBCPal + color_index * 2 + 1], a
+
+ IF color_index < (NUM_COLORS + -1)
+ ld a, b
+ rrca
+ rrca
+ ENDC
+
+color_index = color_index + 1
+ ENDR
+ ret
+
+.GetColorAddress:
+ add a
+ ld l, a
+ xor a
+ ld h, a
+ add hl, de
+ ret
+
+TransferCurBGPData::
+ push de
+ add a
+ add a
+ add a
+ or $80 ; auto-increment
+ ldh [rBGPI], a
+ ld de, rBGPD
+ ld hl, wGBCPal
+ ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr nz, .lcdEnabled
+ rept NUM_COLORS
+ call TransferPalColorLCDDisabled
+ endr
+ jr .done
+.lcdEnabled
+ rept NUM_COLORS
+ call TransferPalColorLCDEnabled
+ endr
+.done
+ pop de
+ ret
+
+BufferBGPPal::
+; Copy wGBCPal to palette a in wBGPPalsBuffer.
+ push de
+ add a
+ add a
+ add a
+ ld l, a
+ xor a
+ ld h, a
+ ld de, wBGPPalsBuffer
+ add hl, de
+ ld de, wGBCPal
+ ld c, PAL_SIZE
+.loop
+ ld a, [de]
+ ld [hli], a
+ inc de
+ dec c
+ jr nz, .loop
+ pop de
+ ret
+
+TransferBGPPals::
+; Transfer the buffered BG palettes.
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr z, .lcdDisabled
+ di
+.waitLoop
+ ldh a, [rLY]
+ cp 144
+ jr c, .waitLoop
+.lcdDisabled
+ call .DoTransfer
+ ei
+ ret
+
+.DoTransfer:
+ xor a
+ or $80 ; auto-increment
+ ldh [rBGPI], a
+ ld de, rBGPD
+ ld hl, wBGPPalsBuffer
+ ld c, 4 * PAL_SIZE
+.loop
+ ld a, [hli]
+ ld [de], a
+ dec c
+ jr nz, .loop
+ ret
+
+TransferCurOBPData:
+ push de
+ add a
+ add a
+ add a
+ or $80 ; auto-increment
+ ldh [rOBPI], a
+ ld de, rOBPD
+ ld hl, wGBCPal
+ ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
+ ldh a, [rLCDC]
+ and rLCDC_ENABLE_MASK
+ jr nz, .lcdEnabled
+ rept NUM_COLORS
+ call TransferPalColorLCDDisabled
+ endr
+ jr .done
+.lcdEnabled
+ rept NUM_COLORS
+ call TransferPalColorLCDEnabled
+ endr
+.done
+ pop de
+ ret
+
+TransferPalColorLCDEnabled:
+; Transfer a palette color while the LCD is enabled.
+
+; In case we're already in H-blank or V-blank, wait for it to end. This is a
+; precaution so that the transfer doesn't extend past the blanking period.
+ ldh a, [rSTAT]
+ and b
+ jr z, TransferPalColorLCDEnabled
+
+; Wait for H-blank or V-blank to begin.
+.notInBlankingPeriod
+ ldh a, [rSTAT]
+ and b
+ jr nz, .notInBlankingPeriod
+; fall through
+
+TransferPalColorLCDDisabled:
+; Transfer a palette color while the LCD is disabled.
+ ld a, [hli]
+ ld [de], a
+ ld a, [hli]
+ ld [de], a
+ ret
+
+_UpdateGBCPal_BGP_CheckDMG::
+ ldh a, [hGBC]
+ and a
+ ret z
+; fall through
+
+_UpdateGBCPal_BGP::
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ ld a, [wGBCBasePalPointers + index * 2]
+ ld e, a
+ ld a, [wGBCBasePalPointers + index * 2 + 1]
+ ld d, a
+ xor a ; CONVERT_BGP
+ call DMGPalToGBCPal
+ ld a, index
+ call BufferBGPPal
+
+index = index + 1
+ ENDR
+
+ call TransferBGPPals
+ ret
+
+_UpdateGBCPal_OBP::
+index = 0
+
+ REPT NUM_ACTIVE_PALS
+ ld a, [wGBCBasePalPointers + index * 2]
+ ld e, a
+ ld a, [wGBCBasePalPointers + index * 2 + 1]
+ ld d, a
+ ld a, c
+ call DMGPalToGBCPal
+ ld a, c
+ dec a
+ rlca
+ rlca
+
+ IF index > 0
+ IF index == 1
+ inc a
+ ELSE
+ add index
+ ENDC
+ ENDC
+
+ call TransferCurOBPData
+
+index = index + 1
+ ENDR
+
+ ret
+
+TranslatePalPacketToBGMapAttributes::
+; translate the SGB pal packets into something usable for the GBC
+ push hl
+ pop de
+ ld hl, PalPacketPointers
+ ld a, [hli]
+ ld c, a
+.loop
+ ld a, e
+.innerLoop
+ cp [hl]
+ jr z, .checkHighByte
+ inc hl
+ inc hl
+ dec c
+ jr nz, .innerLoop
+ ret
+.checkHighByte
+; the low byte of pointer matched, so check the high byte
+ inc hl
+ ld a, d
+ cp [hl]
+ jr z, .foundMatchingPointer
+ inc hl
+ dec c
+ jr nz, .loop
+ ret
+.foundMatchingPointer
+ farcall LoadBGMapAttributes
+ ret
+
+PalPacketPointers::
+ db (palPacketPointersEnd - palPacketPointers) / 2
+palPacketPointers:
+ dw BlkPacket_WholeScreen
+ dw BlkPacket_Battle
+ dw BlkPacket_StatusScreen
+ dw BlkPacket_Pokedex
+ dw BlkPacket_Slots
+ dw BlkPacket_Titlescreen
+ dw BlkPacket_NidorinoIntro
+ dw wPartyMenuBlkPacket
+ dw wTrainerCardBlkPacket
+ dw BlkPacket_GameFreakIntro
+ dw wPalPacket
+ dw UnknownPacket_72751
+palPacketPointersEnd:
+
+CopySGBBorderTiles:
+; SGB tile data is stored in a 4BPP planar format.
+; Each tile is 32 bytes. The first 16 bytes contain bit planes 1 and 2, while
+; the second 16 bytes contain bit planes 3 and 4.
+; This function converts 2BPP planar data into this format by mapping
+; 2BPP colors 0-3 to 4BPP colors 0-3. 4BPP colors 4-15 are not used.
+ ld b, 128
+.tileLoop
+; Copy bit planes 1 and 2 of the tile data.
+ ld c, 16
+.copyLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyLoop
+
+; Zero bit planes 3 and 4.
+ ld c, 16
+ xor a
+.zeroLoop
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .zeroLoop
+
+ dec b
+ jr nz, .tileLoop
+ ret
+
+INCLUDE "data/sgb/sgb_packets.asm"
+
+INCLUDE "data/pokemon/palettes.asm"
+
+INCLUDE "data/sgb/sgb_palettes.asm"
+
+INCLUDE "data/sgb/sgb_border.asm"
diff --git a/engine/gfx/screen_effects.asm b/engine/gfx/screen_effects.asm
new file mode 100644
index 00000000..973a951a
--- /dev/null
+++ b/engine/gfx/screen_effects.asm
@@ -0,0 +1,73 @@
+; inverts the BGP for 4 (6 on CGB due to lag) frames
+ChangeBGPalColor0_4Frames:
+ call GetPredefRegisters ; leftover of red/blue, has no use here
+ ldh a, [rBGP]
+ xor $ff
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 4
+ call DelayFrames
+ ldh a, [rBGP]
+ xor $ff
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ret
+
+PredefShakeScreenVertically:
+; Moves the window down and then back in a sequence of progressively smaller
+; numbers of pixels, starting at b.
+ call GetPredefRegisters
+ ld a, 1
+ ld [wDisableVBlankWYUpdate], a
+ xor a
+.loop
+ ldh [hMutateWY], a
+ call .MutateWY
+ call .MutateWY
+ dec b
+ ld a, b
+ jr nz, .loop
+ xor a
+ ld [wDisableVBlankWYUpdate], a
+ ret
+
+.MutateWY
+ ldh a, [hMutateWY]
+ xor b
+ ldh [hMutateWY], a
+ ldh [rWY], a
+ ld c, 3
+ jp DelayFrames
+
+PredefShakeScreenHorizontally:
+; Moves the window right and then back in a sequence of progressively smaller
+; numbers of pixels, starting at b.
+ call GetPredefRegisters
+ xor a
+.loop
+ ldh [hMutateWX], a
+ call .MutateWX
+ ld c, 1
+ call DelayFrames
+ call .MutateWX
+ dec b
+ ld a, b
+ jr nz, .loop
+
+; restore normal WX
+ ld a, 7
+ ldh [rWX], a
+ ret
+
+.MutateWX
+ ldh a, [hMutateWX]
+ xor b
+ ldh [hMutateWX], a
+ bit 7, a
+ jr z, .skipZeroing
+ xor a ; zero a if it's negative
+.skipZeroing
+ add 7
+ ldh [rWX], a
+ ld c, 4
+ jp DelayFrames
diff --git a/engine/gfx/sprite_oam.asm b/engine/gfx/sprite_oam.asm
new file mode 100644
index 00000000..01b2c412
--- /dev/null
+++ b/engine/gfx/sprite_oam.asm
@@ -0,0 +1,232 @@
+PrepareOAMData::
+; Determine OAM data for currently visible
+; sprites and write it to wOAMBuffer.
+; Yellow code has been changed to use registers more efficiently
+; as well as tweaking the code to show gbc palettes
+
+ ld a, [wUpdateSpritesEnabled]
+ dec a
+ jr z, .updateEnabled
+
+ cp -1
+ ret nz
+ ld [wUpdateSpritesEnabled], a
+ jp HideSprites
+
+.updateEnabled
+ xor a
+ ldh [hOAMBufferOffset], a
+
+.spriteLoop
+ ldh [hSpriteOffset2], a
+
+ ld e, a
+ ld d, HIGH(wSpriteStateData1)
+
+ ld a, [de] ; [x#SPRITESTATEDATA1_PICTUREID]
+ and a
+ jp z, .nextSprite
+
+ inc e
+ inc e
+ ld a, [de] ; [x#SPRITESTATEDATA1_IMAGEINDEX]
+ ld [wd5cd], a
+ cp $ff ; off-screen (don't draw)
+ jr nz, .visible
+
+ call GetSpriteScreenXY
+ jr .nextSprite
+
+.visible
+ cp $a0 ; is the sprite unchanging like an item ball or boulder?
+ jr c, .usefacing
+
+; unchanging
+ ld a, $0
+ jr .next
+
+.usefacing
+ and $f
+
+.next
+; read the entry from the table
+ ld c, a
+ ld b, 0
+ ld hl, SpriteFacingAndAnimationTable
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+; get sprite priority
+ push de
+ inc d
+ ld a, e
+ add $5
+ ld e, a
+ ld a, [de] ; [x#SPRITESTATEDATA2_GRASSPRIORITY]
+ and $80
+ ldh [hSpritePriority], a ; temp store sprite priority
+ pop de
+
+
+ call GetSpriteScreenXY
+
+ ldh a, [hOAMBufferOffset]
+ add [hl]
+ cp $a0
+ jr z, .hidden
+ jr nc, .asm_4a41
+.hidden
+ call Func_4a7b
+ ld [wd5cd], a
+ ldh a, [hOAMBufferOffset]
+
+ ld e, a
+ ld d, HIGH(wOAMBuffer)
+
+.tileLoop
+ ld a, [hli]
+ ld c, a
+.loop
+ ldh a, [hSpriteScreenY] ; temp for sprite Y position
+ add $10 ; Y=16 is top of screen (Y=0 is invisible)
+ add [hl] ; add Y offset from table
+ ld [de], a ; write new sprite OAM Y position
+ inc hl
+ inc e
+ ldh a, [hSpriteScreenX] ; temp for sprite X position
+ add $8 ; X=8 is left of screen (X=0 is invisible)
+ add [hl] ; add X offset from table
+ ld [de], a
+ inc hl
+ inc e
+ ld a, [wd5cd]
+ add [hl]
+ cp $80
+ jr c, .asm_4a1c
+ ld b, a
+ ldh a, [hFFFC]
+ add b
+.asm_4a1c
+ ld [de], a ; tile id
+ inc hl
+ inc e
+ ld a, [hl]
+ bit 1, a ; is the tile allowed to set the sprite priority bit?
+ jr z, .skipPriority
+ ldh a, [hSpritePriority]
+ or [hl]
+.skipPriority
+ and $f0
+ bit 4, a ; OBP0 or OBP1
+ jr z, .spriteusesOBP0
+ or %100 ; palettes 4-7 are OBP1
+.spriteusesOBP0
+ ld [de], a
+ inc hl
+ inc e
+ dec c
+ jr nz, .loop
+
+ ld a, e
+ ldh [hOAMBufferOffset], a
+.nextSprite
+ ldh a, [hSpriteOffset2]
+ add $10
+ cp LOW($100)
+ jp nz, .spriteLoop
+
+ ; Clear unused OAM.
+.asm_4a41
+ ld a, [wd736]
+ bit 6, a ; jumping down ledge or fishing animation?
+ ld c, $a0
+ jr z, .clear
+
+; Don't clear the last 4 entries because they are used for the shadow in the
+; jumping down ledge animation and the rod in the fishing animation.
+ ld c, $90
+
+.clear
+ ldh a, [hOAMBufferOffset]
+ cp c
+ ret nc
+ ld l, a
+ ld h, wOAMBuffer / $100
+ ld a, c
+ ld de, $4 ; entry size
+ ld b, $a0
+.clearLoop
+ ld [hl], b
+ add hl, de
+ cp l
+ jr nz, .clearLoop
+ ret
+
+GetSpriteScreenXY:
+ inc e
+ inc e
+ ld a, [de] ; [x#SPRITESTATEDATA1_YPIXELS]
+ ldh [hSpriteScreenY], a
+ inc e
+ inc e
+ ld a, [de] ; [x#SPRITESTATEDATA1_XPIXELS]
+ ldh [hSpriteScreenX], a
+ ld a, 4
+ add e
+ ld e, a
+ ldh a, [hSpriteScreenY]
+ add 4
+ and $f0
+ ld [de], a ; [x#SPRITESTATEDATA1_YADJUSTED]
+ inc e
+ ldh a, [hSpriteScreenX]
+ and $f0
+ ld [de], a ; [x#SPRITESTATEDATA1_XADJUSTED]
+ ret
+
+Func_4a7b:
+ push bc
+ ld a, [wd5cd] ; temp copy of [x#SPRITESTATEDATA1_IMAGEINDEX]
+ swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
+ and $f
+
+ ; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
+ ; As a result, sprite $b's tile offset is less than normal.
+ cp $b
+ jr nz, .notFourTileSprite
+ ld a, $a * 12 + 4 ; $7c
+ jr .done
+
+.notFourTileSprite
+ ; a *= 12
+ add a
+ add a
+ ld c, a
+ add a
+ add c
+.done
+ pop bc
+ ret
+
+INCLUDE "engine/gfx/oam_dma.asm"
+
+_IsTilePassable::
+ ld hl, wTilesetCollisionPtr ; pointer to list of passable tiles
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a ; hl now points to passable tiles
+.loop
+ ld a, [hli]
+ cp a, $ff
+ jr z, .tileNotPassable
+ cp c
+ jr nz, .loop
+ xor a
+ ret
+.tileNotPassable
+ scf
+ ret
+
+INCLUDE "data/tilesets/collision_tile_ids.asm"
diff --git a/engine/hidden_object_functions14.asm b/engine/hidden_object_functions14.asm
deleted file mode 100755
index 04f9cb35..00000000
--- a/engine/hidden_object_functions14.asm
+++ /dev/null
@@ -1,100 +0,0 @@
-PrintNotebookText:
- call EnableAutoTextBoxDrawing
- ld a, $1
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a
- ld a, [wHiddenObjectFunctionArgument]
- jp PrintPredefTextID
-
-TMNotebook:
- TX_FAR TMNotebookText
- TX_WAIT
- db "@"
-
-ViridianSchoolNotebook:
- TX_ASM
- ld hl, ViridianSchoolNotebookText1
- call PrintText
- call TurnPageSchoolNotebook
- jr nz, .doneReading
- ld hl, ViridianSchoolNotebookText2
- call PrintText
- call TurnPageSchoolNotebook
- jr nz, .doneReading
- ld hl, ViridianSchoolNotebookText3
- call PrintText
- call TurnPageSchoolNotebook
- jr nz, .doneReading
- ld hl, ViridianSchoolNotebookText4
- call PrintText
- ld hl, ViridianSchoolNotebookText5
- call PrintText
-.doneReading
- jp TextScriptEnd
-
-TurnPageSchoolNotebook:
- ld hl, TurnPageText
- call PrintText
- call YesNoChoice
- ld a, [wCurrentMenuItem]
- and a
- ret
-
-TurnPageText:
- TX_FAR _TurnPageText
- db "@"
-
-ViridianSchoolNotebookText5:
- TX_FAR _ViridianSchoolNotebookText5
- TX_WAIT
- db "@"
-
-ViridianSchoolNotebookText1:
- TX_FAR _ViridianSchoolNotebookText1
- db "@"
-
-ViridianSchoolNotebookText2:
- TX_FAR _ViridianSchoolNotebookText2
- db "@"
-
-ViridianSchoolNotebookText3:
- TX_FAR _ViridianSchoolNotebookText3
- db "@"
-
-ViridianSchoolNotebookText4:
- TX_FAR _ViridianSchoolNotebookText4
- db "@"
-
-PrintFightingDojoText2:
- call EnableAutoTextBoxDrawing
- tx_pre_jump EnemiesOnEverySideText
-
-EnemiesOnEverySideText:
- TX_FAR _EnemiesOnEverySideText
- db "@"
-
-PrintFightingDojoText3:
- call EnableAutoTextBoxDrawing
- tx_pre_jump WhatGoesAroundComesAroundText
-
-WhatGoesAroundComesAroundText:
- TX_FAR _WhatGoesAroundComesAroundText
- db "@"
-
-PrintFightingDojoText:
- call EnableAutoTextBoxDrawing
- tx_pre_jump FightingDojoText
-
-FightingDojoText:
- TX_FAR _FightingDojoText
- db "@"
-
-PrintIndigoPlateauHQText:
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP
- ret nz
- call EnableAutoTextBoxDrawing
- tx_pre_jump IndigoPlateauHQText
-
-IndigoPlateauHQText:
- TX_FAR _IndigoPlateauHQText
- db "@"
diff --git a/engine/hidden_object_functions17.asm b/engine/hidden_object_functions17.asm
deleted file mode 100755
index 8775fd39..00000000
--- a/engine/hidden_object_functions17.asm
+++ /dev/null
@@ -1,466 +0,0 @@
-PrintRedSNESText:
- call EnableAutoTextBoxDrawing
- tx_pre_jump RedBedroomSNESText
-
-RedBedroomSNESText:
- TX_FAR _RedBedroomSNESText
- db "@"
-
-OpenRedsPC:
- call EnableAutoTextBoxDrawing
- tx_pre_jump RedBedroomPCText
-
-RedBedroomPCText:
- TX_PLAYERS_PC
-
-Route15GateLeftBinoculars:
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP
- ret nz
- call EnableAutoTextBoxDrawing
- tx_pre Route15UpstairsBinocularsText
- ld a, ARTICUNO
- ld [wcf91], a
- call PlayCry
- call DisplayMonFrontSpriteInBox
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-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 "@"
-
-FanClubPicture1:
- ld a, RAPIDASH
- ld [wcf91], a
- call DisplayMonFrontSpriteInBox
- call EnableAutoTextBoxDrawing
- tx_pre FanClubPicture1Text
- ret
-
-FanClubPicture1Text:
- TX_FAR _FanClubPicture1Text
- db "@"
-
-FanClubPicture2:
- ld a, FEAROW
- ld [wcf91], a
- call DisplayMonFrontSpriteInBox
- call EnableAutoTextBoxDrawing
- tx_pre FanClubPicture2Text
- ret
-
-FanClubPicture2Text:
- TX_FAR _FanClubPicture2Text
- 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
- lb bc, 8, 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
- callab Yellow_SampleSecondTrashCan
- tx_pre_id VermilionGymTrashSuccessText1
- jr .done
-
-.trySecondLock
- ld a, [wGymTrashCanIndex]
- ld b, a
- ld a, [wSecondLockTrashCanIndex]
- cp b
- jr z, .openSecondLock
- ld a, [wSecondLockTrashCanIndex + 1]
- 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
-; Note that the mask is simply the number of valid trash can indices that
-; follow. The remaining bytes are filled with -1 to pad the length of each entry
-; to 5 bytes.
-; This is functionally replaced with GymTrashCans3a but was never removed from source.
-
- db 2, 1, 3, -1, -1 ; 0
- db 3, 0, 2, 4, -1 ; 1
- db 2, 1, 5, -1, -1 ; 2
- db 3, 0, 4, 6, -1 ; 3
- db 4, 1, 3, 5, 7 ; 4
- db 3, 2, 4, 8, -1 ; 5
- db 3, 3, 7, 9, -1 ; 6
- db 4, 4, 6, 8, 10 ; 7
- db 3, 5, 7, 11, -1 ; 8
- db 3, 6, 10, 12, -1 ; 9
- db 4, 7, 9, 11, 13 ; 10
- db 3, 8, 10, 14, -1 ; 11
- db 2, 9, 13, -1, -1 ; 12
- db 3, 10, 12, 14, -1 ; 13
- db 2, 11, 13, -1, -1 ; 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/engine/hidden_object_functions18.asm b/engine/hidden_object_functions18.asm
deleted file mode 100755
index 3fd5dd47..00000000
--- a/engine/hidden_object_functions18.asm
+++ /dev/null
@@ -1,204 +0,0 @@
-GymStatues:
-; if in a gym and have the corresponding badge, a = GymStatueText2_id and jp PrintPredefTextID
-; if in a gym and don’t have the corresponding badge, a = GymStatueText1_id and jp PrintPredefTextID
-; else ret
- call EnableAutoTextBoxDrawing
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP
- ret nz
- ld hl, .BadgeFlags
- ld a, [wCurMap]
- ld b, a
-.loop
- ld a, [hli]
- cp $ff
- ret z
- cp b
- jr z, .match
- inc hl
- jr .loop
-.match
- ld b, [hl]
- ld a, [wBeatGymFlags]
- and b
- cp b
- tx_pre_id GymStatueText2
- jr z, .haveBadge
- tx_pre_id GymStatueText1
-.haveBadge
- jp PrintPredefTextID
-
-.BadgeFlags:
- db PEWTER_GYM, %00000001
- db CERULEAN_GYM, %00000010
- db VERMILION_GYM, %00000100
- db CELADON_GYM, %00001000
- db FUCHSIA_GYM, %00010000
- db SAFFRON_GYM, %00100000
- db CINNABAR_GYM, %01000000
- db VIRIDIAN_GYM, %10000000
- db $ff
-
-GymStatueText1:
- TX_FAR _GymStatueText1
- db "@"
-
-GymStatueText2:
- TX_FAR _GymStatueText2
- db "@"
-
-PrintBenchGuyText:
- call EnableAutoTextBoxDrawing
- ld hl, BenchGuyTextPointers
- ld a, [wCurMap]
- ld b, a
-.loop
- ld a, [hli]
- cp $ff
- ret z
- cp b
- jr z, .match
- inc hl
- inc hl
- jr .loop
-.match
- ld a, [hli]
- ld b, a
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp b
- jr nz, .loop ; player isn't facing left at the bench guy
- ld a, [hl]
- jp PrintPredefTextID
-
-; format: db map id, player sprite facing direction, text id of PredefTextIDPointerTable
-BenchGuyTextPointers:
- db VIRIDIAN_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre ViridianCityPokecenterBenchGuyText
- db PEWTER_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre PewterCityPokecenterBenchGuyText
- db CERULEAN_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre CeruleanCityPokecenterBenchGuyText
- db LAVENDER_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre LavenderCityPokecenterBenchGuyText
- db VERMILION_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre VermilionCityPokecenterBenchGuyText
- db CELADON_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre CeladonCityPokecenterBenchGuyText
- db CELADON_HOTEL, SPRITE_FACING_LEFT
- db_tx_pre CeladonCityHotelText
- db FUCHSIA_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre FuchsiaCityPokecenterBenchGuyText
- db CINNABAR_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre CinnabarIslandPokecenterBenchGuyText
- db SAFFRON_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre SaffronCityPokecenterBenchGuyText
- db MT_MOON_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre MtMoonPokecenterBenchGuyText
- db ROCK_TUNNEL_POKECENTER, SPRITE_FACING_LEFT
- db_tx_pre RockTunnelPokecenterBenchGuyText
- db SAFARI_ZONE_WEST_REST_HOUSE,SPRITE_FACING_LEFT
- db_tx_pre UnusedBenchGuyText1
- db SAFARI_ZONE_EAST_REST_HOUSE,SPRITE_FACING_LEFT
- db_tx_pre UnusedBenchGuyText2
- db SAFARI_ZONE_NORTH_REST_HOUSE,SPRITE_FACING_LEFT
- db_tx_pre UnusedBenchGuyText3
- db $FF
-
-ViridianCityPokecenterBenchGuyText:
- TX_FAR _ViridianCityPokecenterGuyText
- db "@"
-
-PewterCityPokecenterBenchGuyText:
- TX_FAR _PewterCityPokecenterGuyText
- db "@"
-
-CeruleanCityPokecenterBenchGuyText:
- TX_FAR _CeruleanPokecenterGuyText
- db "@"
-
-LavenderCityPokecenterBenchGuyText:
- TX_FAR _LavenderPokecenterGuyText
- db "@"
-
-MtMoonPokecenterBenchGuyText:
- TX_FAR _MtMoonPokecenterBenchGuyText
- db "@"
-
-RockTunnelPokecenterBenchGuyText:
- TX_FAR _RockTunnelPokecenterGuyText
- db "@"
-
-UnusedBenchGuyText1:
- TX_FAR _UnusedBenchGuyText1
- db "@"
-
-UnusedBenchGuyText2:
- TX_FAR _UnusedBenchGuyText2
- db "@"
-
-UnusedBenchGuyText3:
- TX_FAR _UnusedBenchGuyText3
- db "@"
-
-VermilionCityPokecenterBenchGuyText:
- TX_FAR _VermilionPokecenterGuyText
- db "@"
-
-CeladonCityPokecenterBenchGuyText:
- TX_FAR _CeladonCityPokecenterGuyText
- db "@"
-
-FuchsiaCityPokecenterBenchGuyText:
- TX_FAR _FuchsiaCityPokecenterGuyText
- db "@"
-
-CinnabarIslandPokecenterBenchGuyText:
- TX_FAR _CinnabarPokecenterGuyText
- db "@"
-
-SaffronCityPokecenterBenchGuyText:
- TX_ASM
- CheckEvent EVENT_BEAT_SILPH_CO_GIOVANNI
- ld hl, SaffronCityPokecenterBenchGuyText2
- jr nz, .asm_624f2
- ld hl, SaffronCityPokecenterBenchGuyText1
-.asm_624f2
- call PrintText
- jp TextScriptEnd
-
-SaffronCityPokecenterBenchGuyText1:
- TX_FAR _SaffronCityPokecenterGuyText1
- db "@"
-
-SaffronCityPokecenterBenchGuyText2:
- TX_FAR _SaffronCityPokecenterGuyText2
- db "@"
-
-CeladonCityHotelText:
- TX_FAR _CeladonCityHotelText
- db "@"
-
- ret
-
-UnusedPredefText:
- db "@"
-
-PrintBookcaseText:
- call EnableAutoTextBoxDrawing
- tx_pre_jump BookcaseText
-
-BookcaseText:
- TX_FAR _BookcaseText
- db "@"
-
-OpenPokemonCenterPC:
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP ; check to see if player is facing up
- ret nz
- call EnableAutoTextBoxDrawing
- ld a, $1
- ld [wAutoTextBoxDrawingControl], a
- tx_pre_jump PokemonCenterPCText
-
-PokemonCenterPCText:
- TX_POKECENTER_PC
diff --git a/engine/hidden_object_functions3.asm b/engine/hidden_object_functions3.asm
deleted file mode 100755
index 11aecd5b..00000000
--- a/engine/hidden_object_functions3.asm
+++ /dev/null
@@ -1,153 +0,0 @@
-; prints text for bookshelves in buildings without sign events
-PrintBookshelfText:
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
- cp SPRITE_FACING_UP
- jr nz, .noMatch
-; facing up
- ld a, [wCurMapTileset]
- ld b, a
- aCoord 8, 7
- ld c, a
- ld hl, BookshelfTileIDs
-.loop
- ld a, [hli]
- cp $ff
- jr z, .noMatch
- cp b
- jr nz, .nextBookshelfEntry1
- ld a, [hli]
- cp c
- jr nz, .nextBookshelfEntry2
- ld a, [hl]
- push af
- call EnableAutoTextBoxDrawing
- pop af
- call PrintPredefTextID
- xor a
- ld [$ffdb], a
- ret
-.nextBookshelfEntry1
- inc hl
-.nextBookshelfEntry2
- inc hl
- jr .loop
-.noMatch
- ld a, $ff
- ld [$ffdb], a
- jpba PrintCardKeyText
-
-; format: db tileset id, bookshelf tile id, text id
-BookshelfTileIDs:
- db PLATEAU, $30
- db_tx_pre IndigoPlateauStatues
- db HOUSE, $3D
- db_tx_pre TownMapText
- db HOUSE, $1E
- db_tx_pre BookOrSculptureText
- db MANSION, $32
- db_tx_pre BookOrSculptureText
- db REDS_HOUSE_1, $32
- db_tx_pre BookOrSculptureText
- db LAB, $28
- db_tx_pre BookOrSculptureText
- db LOBBY, $16
- db_tx_pre ElevatorText
- db GYM, $1D
- db_tx_pre BookOrSculptureText
- db DOJO, $1D
- db_tx_pre BookOrSculptureText
- db GATE, $22
- db_tx_pre BookOrSculptureText
- db MART, $54
- db_tx_pre PokemonStuffText
- db MART, $55
- db_tx_pre PokemonStuffText
- db POKECENTER, $54
- db_tx_pre PokemonStuffText
- db POKECENTER, $55
- db_tx_pre PokemonStuffText
- db LOBBY, $50
- db_tx_pre PokemonStuffText
- db LOBBY, $52
- db_tx_pre PokemonStuffText
- db SHIP, $36
- db_tx_pre BookOrSculptureText
- db $FF
-
-IndigoPlateauStatues:
- TX_ASM
- ld hl, IndigoPlateauStatuesText1
- call PrintText
- ld a, [wXCoord]
- bit 0, a
- ld hl, IndigoPlateauStatuesText2
- jr nz, .ok
- ld hl, IndigoPlateauStatuesText3
-.ok
- call PrintText
- jp TextScriptEnd
-
-IndigoPlateauStatuesText1:
- TX_FAR _IndigoPlateauStatuesText1
- db "@"
-
-IndigoPlateauStatuesText2:
- TX_FAR _IndigoPlateauStatuesText2
- db "@"
-
-IndigoPlateauStatuesText3:
- TX_FAR _IndigoPlateauStatuesText3
- db "@"
-
-BookOrSculptureText:
- TX_ASM
- ld hl, PokemonBooksText
- ld a, [wCurMapTileset]
- cp MANSION ; Celadon Mansion tileset
- jr nz, .ok
- aCoord 8, 6
- cp $38
- jr nz, .ok
- ld hl, DiglettSculptureText
-.ok
- call PrintText
- jp TextScriptEnd
-
-PokemonBooksText:
- TX_FAR _PokemonBooksText
- db "@"
-
-DiglettSculptureText:
- TX_FAR _DiglettSculptureText
- db "@"
-
-ElevatorText:
- TX_FAR _ElevatorText
- db "@"
-
-TownMapText:
- TX_FAR _TownMapText
- TX_BLINK
- TX_ASM
- ld a, $1
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a
- ld hl, wd730
- set 6, [hl]
- call GBPalWhiteOutWithDelay3
- xor a
- ld [hWY], a
- inc a
- ld [H_AUTOBGTRANSFERENABLED], a
- call LoadFontTilePatterns
- callba DisplayTownMap
- ld hl, wd730
- res 6, [hl]
- ld de, TextScriptEnd
- push de
- ld a, [H_LOADEDROMBANK]
- push af
- jp CloseTextDisplay
-
-PokemonStuffText:
- TX_FAR _PokemonStuffText
- db "@"
diff --git a/engine/hidden_object_functions7.asm b/engine/hidden_object_functions7.asm
deleted file mode 100755
index 2498c167..00000000
--- a/engine/hidden_object_functions7.asm
+++ /dev/null
@@ -1,510 +0,0 @@
-PrintNewBikeText:
- call EnableAutoTextBoxDrawing
- tx_pre_jump NewBicycleText
-
-NewBicycleText:
- TX_FAR _NewBicycleText
- db "@"
-
-DisplayOakLabLeftPoster:
- call EnableAutoTextBoxDrawing
- tx_pre_jump PushStartText
-
-PushStartText:
- TX_FAR _PushStartText
- db "@"
-
-DisplayOakLabRightPoster:
- call EnableAutoTextBoxDrawing
- ld hl, wPokedexOwned
- ld b, wPokedexOwnedEnd - wPokedexOwned
- call CountSetBits
- ld a, [wNumSetBits]
- cp 2
- tx_pre_id SaveOptionText
- jr c, .ownLessThanTwo
- ; own two or more mon
- tx_pre_id StrengthsAndWeaknessesText
-.ownLessThanTwo
- jp PrintPredefTextID
-
-SaveOptionText:
- TX_FAR _SaveOptionText
- db "@"
-
-StrengthsAndWeaknessesText:
- TX_FAR _StrengthsAndWeaknessesText
- db "@"
-
-SafariZoneCheck:
- CheckEventHL EVENT_IN_SAFARI_ZONE ; if we are not in the Safari Zone,
- jr z, SafariZoneGameStillGoing ; don't bother printing game over text
- ld a, [wNumSafariBalls]
- and a
- jr z, SafariZoneGameOver
- jr SafariZoneGameStillGoing
-
-SafariZoneCheckSteps:
- ld a, [wSafariSteps]
- ld b, a
- ld a, [wSafariSteps + 1]
- ld c, a
- or b
- jr z, SafariZoneGameOver
- dec bc
- ld a, b
- ld [wSafariSteps], a
- ld a, c
- ld [wSafariSteps + 1], a
-SafariZoneGameStillGoing:
- xor a
- ld [wSafariZoneGameOver], a
- ret
-
-SafariZoneGameOver:
- call EnableAutoTextBoxDrawing
- xor a
- ld [wAudioFadeOutControl], a
- call StopAllMusic
- ld c, BANK(SFX_Safari_Zone_PA)
- ld a, SFX_SAFARI_ZONE_PA
- call PlayMusic
-.waitForMusicToPlay
- ld a, [wChannelSoundIDs + Ch5]
- cp SFX_SAFARI_ZONE_PA
- jr nz, .waitForMusicToPlay
- ld a, TEXT_SAFARI_GAME_OVER
- ld [hSpriteIndexOrTextID], a
- call DisplayTextID
- xor a
- ld [wPlayerMovingDirection], a
- ld a, SAFARI_ZONE_GATE
- ld [hWarpDestinationMap], a
- ld a, $3
- ld [wDestinationWarpID], a
- ld a, $5
- ld [wSafariZoneGateCurScript], a
- SetEvent EVENT_SAFARI_GAME_OVER
- ld a, 1
- ld [wSafariZoneGameOver], a
- ret
-
-PrintSafariGameOverText:
- xor a
- ld [wJoyIgnore], a
- ld hl, SafariGameOverText
- jp PrintText
-
-SafariGameOverText:
- TX_ASM
- ld a, [wNumSafariBalls]
- and a
- jr z, .noMoreSafariBalls
- ld hl, TimesUpText
- call PrintText
-.noMoreSafariBalls
- ld hl, GameOverText
- call PrintText
- jp TextScriptEnd
-
-TimesUpText:
- TX_FAR _TimesUpText
- db "@"
-
-GameOverText:
- TX_FAR _GameOverText
- db "@"
-
-PrintCinnabarQuiz:
- ld a, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP
- ret nz
- call EnableAutoTextBoxDrawing
- tx_pre_jump CinnabarGymQuiz
-
-CinnabarGymQuiz:
- TX_ASM
- xor a
- ld [wOpponentAfterWrongAnswer], a
- ld hl, wd475
- res 7, [hl]
- ld a, [wHiddenObjectFunctionArgument]
- push af
- and $f
- ld [hGymGateIndex], a
- pop af
- and $f0
- swap a
- ld [$ffdc], a
- ld a, [hGymGateIndex]
- ld hl, CinnabarGymQuizIntroText
- cp 1
- jr z, .onFirstQuestion
- ld hl, CinnabarGymQuizShortIntroText
-.onFirstQuestion
- 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
-
-CinnabarGymQuizDummyIntroText:
- TX_FAR _CinnabarGymQuizDummyIntroText
- db "@"
-
-CinnabarGymQuizIntroText:
- TX_FAR _CinnabarGymQuizIntroText
- db "@"
-
-CinnabarGymQuizShortIntroText:
- TX_FAR _CinnabarGymQuizShortIntroText
- 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 "@"
-
-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
- ld hl, wd475
- set 7, [hl]
- 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 "@"
-
-CinnabarGymGateFlagAction:
- EventFlagAddress hl, EVENT_CINNABAR_GYM_GATE0_UNLOCKED
- predef_jump FlagActionPredef
-
-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
- call CinnabarGym_ReplaceTileBlock
- ld hl, hGymGateIndex
- dec [hl]
- jr nz, .loop
- callab RedrawMapView
- 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
-
-
-CinnabarGym_ReplaceTileBlock:
-; basically a copy of the first half of ReplaceTileBlock
-; before checking if it is necessary to redraw the map view
- ld hl, wOverworldMap
- ld a, [wCurMapWidth]
- add $6
- ld e, a
- ld d, $0
- add hl, de
- add hl, de
- add hl, de
- ld e, $3
- add hl, de
- ld e, a
- ld a, b
- and a
- jr z, .addX
-.addWidthYTimesLoop
- add hl, de
- dec b
- jr nz, .addWidthYTimesLoop
-.addX
- add hl, bc
- ld a, [wNewTileBlockID]
- ld [hl], a
- ret
-
-PrintMagazinesText:
- call EnableAutoTextBoxDrawing
- tx_pre MagazinesText
- ret
-
-MagazinesText:
- TX_FAR _MagazinesText
- db "@"
-
-BillsHousePC:
- call EnableAutoTextBoxDrawing
- ld a, [wSpritePlayerStateData1FacingDirection]
- 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
- call StopAllMusic
- 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
- lb bc, 10, 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, [wSpritePlayerStateData1FacingDirection]
- cp SPRITE_FACING_UP
- ret nz
- call EnableAutoTextBoxDrawing
- tx_pre OakLabEmailText
- ret
-
-OakLabEmailText:
- TX_FAR _OakLabEmailText
- db "@"
diff --git a/engine/get_bag_item_quantity.asm b/engine/items/get_bag_item_quantity.asm
index f10df1a0..f10df1a0 100644
--- a/engine/get_bag_item_quantity.asm
+++ b/engine/items/get_bag_item_quantity.asm
diff --git a/engine/items/inventory.asm b/engine/items/inventory.asm
index 58bcf7e9..c2e0b2b4 100644
--- a/engine/items/inventory.asm
+++ b/engine/items/inventory.asm
@@ -4,7 +4,7 @@
; [wcf91] = item ID
; [wItemQuantity] = item quantity
; sets carry flag if successful, unsets carry flag if unsuccessful
-AddItemToInventory_:
+AddItemToInventory_::
ld a, [wItemQuantity] ; a = item quantity
push af
push bc
@@ -12,10 +12,10 @@ AddItemToInventory_:
push hl
push hl
ld d, PC_ITEM_CAPACITY ; how many items the PC can hold
- ld a, wNumBagItems & $FF
+ ld a, LOW(wNumBagItems)
cp l
jr nz, .checkIfInventoryFull
- ld a, wNumBagItems >> 8
+ ld a, HIGH(wNumBagItems)
cp h
jr nz, .checkIfInventoryFull
; if the destination is the bag
@@ -98,7 +98,7 @@ AddItemToInventory_:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [wWhichPokemon] = index (within the inventory) of the item to remove
; [wItemQuantity] = quantity to remove
-RemoveItemFromInventory_:
+RemoveItemFromInventory_::
push hl
inc hl
ld a, [wWhichPokemon] ; index (within the inventory) of the item being removed
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
new file mode 100755
index 00000000..b1b458ab
--- /dev/null
+++ b/engine/items/item_effects.asm
@@ -0,0 +1,3186 @@
+UseItem_::
+ ld a, 1
+ ld [wActionResultOrTookBattleTurn], a ; initialise to success value
+ ld a, [wcf91] ;contains item_ID
+ cp HM01
+ 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:
+; entries correspond to item ids
+ 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]
+ cp BATTLE_TYPE_OLD_MAN
+ jr z, .canUseBall
+ cp BATTLE_TYPE_PIKACHU
+ 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.
+ callfar IsGhostBattle
+ ld b, $10 ; can't be caught value
+ jp z, .setAnimData
+
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_OLD_MAN
+ jr z, .oldManBattle
+ cp BATTLE_TYPE_PIKACHU
+ jr z, .oldManBattle ; pikachu battle technically old man battle
+ jr .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)
+ ld a, [wBattleType]
+ cp BATTLE_TYPE_OLD_MAN
+ jp nz, .captured
+ ld a, $1
+ ld [wCapturedMonSpecies], a
+ CheckEvent EVENT_02F
+ ld b, $63
+ jp nz, .setAnimData
+ 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 POKEMON_TOWER_6F
+ jr nz, .loop
+ ld a, [wEnemyMonSpecies2]
+ cp RESTLESS_SOUL
+ 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
+ ldh [hMultiplicand], a
+ ld hl, wEnemyMonMaxHP
+ ld a, [hli]
+ ldh [hMultiplicand + 1], a
+ ld a, [hl]
+ ldh [hMultiplicand + 2], a
+ ld a, 255
+ ldh [hMultiplier], 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.
+ ldh [hDivisor], 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.
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+
+; If W > 255, store 255 in [hQuotient + 3].
+; Let X = min(W, 255) = [hQuotient + 3].
+ ldh a, [hQuotient + 2]
+ and a
+ jr z, .skip3
+ ld a, 255
+ ldh [hQuotient + 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.
+ ldh a, [hQuotient + 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
+ ldh a, [hQuotient + 3]
+ cp b
+ jr c, .failedToCapture
+
+.captured
+ jr .skipShakeCalculations
+
+.failedToCapture
+ ldh a, [hQuotient + 3]
+ ld [wPokeBallCaptureCalcTemp], a ; Save X.
+
+; Calculate CatchRate * 100.
+ xor a
+ ldh [hMultiplicand], a
+ ldh [hMultiplicand + 1], a
+ ld a, [wEnemyMonActualCatchRate]
+ ldh [hMultiplicand + 2], a
+ ld a, 100
+ ldh [hMultiplier], 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
+ ldh [hDivisor], 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.
+ ldh a, [hQuotient + 2]
+ and a
+ ld b, $63 ; 3 shakes
+ jr nz, .setAnimData
+
+; Calculate X * Y.
+ ld a, [wPokeBallCaptureCalcTemp]
+ ldh [hMultiplier], a
+ call Multiply
+
+; Calculate (X * Y) / 255.
+ ld a, 255
+ ldh [hDivisor], 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.
+ ldh a, [hQuotient + 3]
+ add b
+ ldh [hQuotient + 3], a
+
+.skip5
+; Finally determine the number of shakes.
+; Let Z = ((X * Y) / 255) + Status2 = [hQuotient + 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
+ ldh a, [hQuotient + 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
+ ldh [hWhoseTurn], 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
+ callfar 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]
+ cp BATTLE_TYPE_OLD_MAN ; is this the old man battle?
+ jp z, .oldManCaughtMon ; if so, don't give the player the caught Pokémon
+ cp BATTLE_TYPE_PIKACHU
+ jr z, .oldManCaughtMon ; same with Pikachu battle
+ 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, $1
+ ld [wd49c], a
+ ld a, $85
+ ld [wPikachuMood], a
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH ; is party full?
+ jr z, .sendToBox
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ call ClearSprites
+ ld hl, .emptyString
+ call PrintText
+ 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
+
+.emptyString
+ db "@"
+
+ItemUseBallText00:
+;"It dodged the thrown ball!"
+;"This pokemon can't be caught"
+ text_far _ItemUseBallText00
+ text_end
+ItemUseBallText01:
+;"You missed the pokemon!"
+ text_far _ItemUseBallText01
+ text_end
+ItemUseBallText02:
+;"Darn! The pokemon broke free!"
+ text_far _ItemUseBallText02
+ text_end
+ItemUseBallText03:
+;"Aww! It appeared to be caught!"
+ text_far _ItemUseBallText03
+ text_end
+ItemUseBallText04:
+;"Shoot! It was so close too!"
+ text_far _ItemUseBallText04
+ text_end
+ItemUseBallText05:
+;"All right! {MonName} was caught!"
+;play sound
+ text_far _ItemUseBallText05
+ sound_caught_mon
+ text_promptbutton
+ text_end
+ItemUseBallText07:
+;"X was transferred to Bill's PC"
+ text_far _ItemUseBallText07
+ text_end
+ItemUseBallText08:
+;"X was transferred to someone's PC"
+ text_far _ItemUseBallText08
+ text_end
+
+ItemUseBallText06:
+;"New DEX data will be added..."
+;play sound
+ text_far _ItemUseBallText06
+ sound_dex_page_added
+ text_promptbutton
+ text_end
+
+ItemUseTownMap:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ farjp 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
+ ld a, $00
+ ld [wPikachuSpawnState], a
+ call PlayDefaultMusic ; play walking music
+ ld hl, GotOffBicycleText
+ jp PrintText
+
+.tryToGetOnBike
+ call IsBikeRidingAllowed
+ jp nc, NoCyclingAllowedHere
+ call ItemUseReloadOverworldData
+ xor a ; no keys pressed
+ ldh [hJoyHeld], a ; current joypad state
+ ld a, $1
+ ld [wWalkBikeSurfState], a ; change player state to bicycling
+ call PlayDefaultMusic ; play bike riding music
+ xor a
+ ld [wWalkBikeSurfState], a
+ ld hl, GotOnBicycleText
+ call PrintText
+ ld a, $1
+ ld [wWalkBikeSurfState], a
+ ret
+
+; 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 nc, 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
+ ldh [hSpriteIndexOrTextID], a
+ ld d, 16 ; talking range in pixels (normal range)
+ call IsSpriteInFrontOfPlayer2
+ res 7, [hl]
+ ldh a, [hSpriteIndexOrTextID]
+ and a ; is there a sprite in the way?
+ jr nz, .cannotStopSurfing
+ ld hl, TilePairCollisionsWater
+ call CheckForTilePairCollisions
+ jr c, .cannotStopSurfing
+ ld a, [wTileInFrontOfPlayer]
+ ld c, a
+ call IsTilePassable
+ jr nc, .stopSurfing
+.cannotStopSurfing
+ ld hl, SurfingNoPlaceToGetOffText
+ jp PrintText
+
+.stopSurfing
+ call .makePlayerMoveForward
+ ld a, $3
+ ld [wPikachuSpawnState], a
+ ld hl, wPikachuOverworldStateFlags
+ set 5, [hl]
+ 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
+ call GBPalWhiteOutWithDelay3
+ 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:
+ text_far _SurfingGotOnText
+ text_end
+
+SurfingNoPlaceToGetOffText:
+ text_far _SurfingNoPlaceToGetOffText
+ text_end
+
+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
+ ld a, [wcf91]
+ ld [wLoadedMon], a
+ pop bc
+ jr c, .canceledItemUse
+ ld a, b
+ ld [wcf91], a
+ call Func_d85d
+ jr nc, .noEffect
+ callfar IsThisPartymonStarterPikachu_Party
+ jr nc, .notPlayerPikachu
+ ld e, $1b
+ callfar PlayPikachuSoundClip
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ ld hl, RefusingText
+ call PrintText
+ ld a, $4
+ ld [wd49c], a
+ ld a, $82
+ ld [wPikachuMood], a
+ jr .canceledItemUse
+
+.notPlayerPikachu
+ ld a, SFX_HEAL_AILMENT
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ ld a, $01
+ ld [wForceEvolution], a
+ callfar TryEvolvingMon ; try to evolve pokemon
+ 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
+
+Func_d85d:
+ ld hl, EvosMovesPointerTable
+ ld a, [wLoadedMon]
+ dec a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld de, wcd6d
+ ld a, BANK(TryEvolvingMon)
+ ld bc, $2
+ call FarCopyData
+ ld hl, wcd6d
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wcd6d
+ ld a, BANK(TryEvolvingMon)
+ ld bc, 13
+ call FarCopyData
+ ld hl, wcd6d
+.loop
+ ld a, [hli]
+ and a
+ jr z, .cannotEvolveWithUsedStone
+ inc hl
+ inc hl
+ cp EV_ITEM
+ jr nz, .loop
+ dec hl
+ dec hl
+ ld b, [hl]
+ ld a, [wcf91]
+ inc hl
+ inc hl
+ inc hl
+ cp b
+ jr nz, .loop
+ scf
+ ret
+
+.cannotEvolveWithUsedStone
+ and a
+ ret
+
+RefusingText:
+ text_far _RefusingText
+ text_end
+
+ItemUseVitamin:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+
+ItemUseMedicine:
+ ld a, [wPartyCount]
+ and a
+ jp z, Func_e4bf
+ 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
+.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
+ push af
+ cp $28
+ jr nc, .asm_d906
+ push hl
+ push de
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDITEM
+ pop de
+ pop hl
+.asm_d906
+ 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, [wWhichPokemon]
+ push af
+ ld a, [wUsedItemOnWhichPokemon]
+ ld [wWhichPokemon], a
+ push hl
+ push de
+ push bc
+ callfar Func_2fd6a
+ pop bc
+ pop de
+ pop hl
+ pop af
+ ld [wWhichPokemon], a
+
+ 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 + Ch5], 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
+ ldh [hDividend], a
+ ld a, [hl]
+ ld [wHPBarMaxHP], a
+ ldh [hDividend + 1], a
+ ld a, 5
+ ldh [hDivisor], 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
+ ldh a, [hQuotient + 3]
+ push af
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarOldHP], a
+ sub b
+ ld [hld], a
+ ld [wHPBarNewHP], a
+ ldh a, [hQuotient + 2]
+ ld b, a
+ ld a, [hl]
+ ld [wHPBarOldHP+1], a
+ sbc b
+ ld [hl], a
+ ld [wHPBarNewHP+1], a
+ hlcoord 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
+ ldh a, [hFlagsFFFA]
+ set 0, a
+ ldh [hFlagsFFFA], a
+ ld a, $02
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
+ ldh a, [hFlagsFFFA]
+ res 0, a
+ ldh [hFlagsFFFA], 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
+ ldh a, [hFlagsFFFA]
+ set 0, a
+ ldh [hFlagsFFFA], a
+ ld a, $02
+ ld [wHPBarType], a
+ predef UpdateHPBar2 ; animate the HP bar lengthening
+ ldh a, [hFlagsFFFA]
+ res 0, a
+ ldh [hFlagsFFFA], 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
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ dec a
+ ld [wUpdateSpritesEnabled], a
+ call RedrawPartyMenu ; redraws the party menu and displays the message
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], 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
+ callfar CalcExperience ; calculate experience for next level and store it at hExperience
+ 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
+ ldh a, [hExperience]
+ ld [hli], a
+ ldh a, [hExperience + 1]
+ ld [hli], a
+ ldh 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
+ callfar 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
+ callabd_ModifyPikachuHappiness PIKAHAPPY_LEVELUP
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wUsedItemOnWhichPokemon]
+ ld [wWhichPokemon], a
+ callfar Func_2fd6a ; evolve pokemon, if appropriate
+ pop af
+ ld [wWhichPokemon], a
+
+ callfar TryEvolvingMon
+ ld a, $01
+ ld [wUpdateSpritesEnabled], a
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+ jp RemoveUsedItem
+
+VitaminStatRoseText:
+ text_far _VitaminStatRoseText
+ text_end
+
+VitaminNoEffectText:
+ text_far _VitaminNoEffectText
+ text_end
+
+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
+ ldh [hWhoseTurn], 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:
+ text_far _ThrewBaitText
+ text_end
+
+ThrewRockText:
+ text_far _ThrewRockText
+ text_end
+
+; 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
+ cp BILLS_HOUSE
+ jr z, .notUsable
+ cp POKEMON_FAN_CLUB
+ 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]
+ call Func_1510
+ ld hl, wd72e
+ res 4, [hl]
+ ResetEvent EVENT_IN_SAFARI_ZONE
+ xor a
+ ld [wNumSafariBalls], a
+ ld [wSafariZoneGateCurScript], 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
+
+INCLUDE "data/tilesets/escape_rope_tilesets.asm"
+
+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
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
+ 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 -1
+ 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
+
+INCLUDE "data/events/card_key_coords.asm"
+
+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 a, [wWhichPokemon]
+ push af
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
+ pop af
+ ld [wWhichPokemon], a
+
+ 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 a, [wWhichPokemon]
+ push af
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
+ pop af
+ ld [wWhichPokemon], a
+
+ 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
+ ldh [hWhoseTurn], a ; set turn to player's turn
+ farcall StatModifierUpEffect ; do stat increase move
+
+ ld a, [wWhichPokemon]
+ push af
+ ld a, [wPlayerMonNumber]
+ ld [wWhichPokemon], a
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
+ pop af
+ ld [wWhichPokemon], a
+
+ 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, .noSnorlaxOrPikachuToWakeUp
+; if the player hasn't beaten Route 12 Snorlax
+ ld hl, Route12SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc, .noSnorlaxOrPikachuToWakeUp
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ SetEvent EVENT_FIGHT_ROUTE12_SNORLAX
+ ret
+
+.notRoute12
+ cp ROUTE_16
+ jr nz, .notRoute16
+ CheckEvent EVENT_BEAT_ROUTE16_SNORLAX
+ jr nz, .noSnorlaxOrPikachuToWakeUp
+; if the player hasn't beaten Route 16 Snorlax
+ ld hl, Route16SnorlaxFluteCoords
+ call ArePlayerCoordsInArray
+ jr nc, .noSnorlaxOrPikachuToWakeUp
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ SetEvent EVENT_FIGHT_ROUTE16_SNORLAX
+ ret
+
+.notRoute16
+ cp PEWTER_POKECENTER
+ jr nz, .noSnorlaxOrPikachuToWakeUp
+ call CheckPikachuFollowingPlayer
+ jr z, .noSnorlaxOrPikachuToWakeUp
+ callfar IsPikachuRightNextToPlayer
+ jr nc, .noSnorlaxOrPikachuToWakeUp
+ ld hl, PlayedFluteHadEffectText
+ call PrintText
+ call ItemUseReloadOverworldData
+ ldpikaemotion e, PikachuEmotion26
+ callfar PlaySpecificPikachuEmotion
+ ret
+
+.noSnorlaxOrPikachuToWakeUp
+ 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]
+ ld c, a
+ and b ; remove Sleep status
+ ld [hl], a
+ ld a, c
+ and SLP
+ jr z, .asm_e063
+ ld a, $1
+ ld [wWereAnyMonsAsleep], a
+.asm_e063
+ 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
+ farcall Music_PokeFluteInBattle ; play in-battle pokeflute music
+.musicWaitLoop ; wait for music to finish playing
+ ld a, [wChannelSoundIDs + Ch7]
+ 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
+
+Route12SnorlaxFluteCoords:
+ dbmapcoord 9, 62 ; one space West of Snorlax
+ dbmapcoord 10, 61 ; one space North of Snorlax
+ dbmapcoord 10, 63 ; one space South of Snorlax
+ dbmapcoord 11, 62 ; one space East of Snorlax
+ db -1 ; end
+
+Route16SnorlaxFluteCoords:
+ dbmapcoord 27, 10 ; one space East of Snorlax
+ dbmapcoord 25, 10 ; one space West of Snorlax
+ db -1 ; end
+
+PlayedFluteNoEffectText:
+ text_far _PlayedFluteNoEffectText
+ text_end
+
+FluteWokeUpText:
+ text_far _FluteWokeUpText
+ text_end
+
+PlayedFluteHadEffectText:
+ text_far _PlayedFluteHadEffectText
+ text_promptbutton
+ text_asm
+ ld a, [wIsInBattle]
+ and a
+ jr nz, .done
+; play out-of-battle pokeflute music
+ call StopAllMusic
+ ld a, SFX_POKEFLUTE
+ ld c, BANK(SFX_Pokeflute)
+ call PlayMusic
+.musicWaitLoop ; wait for music to finish playing
+ ld a, [wChannelSoundIDs + Ch3]
+ 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:
+ text_far _CoinCaseNumCoinsText
+ text_end
+
+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/wild/good_rod.asm"
+
+ItemUseSuperRod:
+ call FishingInit
+ jp c, ItemUseNotTime
+ callfar ReadSuperRodData
+ ld c, e
+ ld b, d
+ ld a, $2
+ ld [wRodResponse], a
+ ld a, c
+ and a ; are there fish in the map?
+ jr z, DoNotGenerateFishingEncounter ; if not, do not generate an encounter
+ ld a, $1
+ ld [wRodResponse], a
+ call Random
+ and $1
+ jr nz, RodResponse
+ xor a
+ ld [wRodResponse], a
+ jr DoNotGenerateFishingEncounter
+
+RodResponse:
+ ld [wRodResponse], a
+
+ dec a ; is there a bite?
+ jr nz, DoNotGenerateFishingEncounter
+ ; 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
+
+DoNotGenerateFishingEncounter:
+ ld hl, wWalkBikeSurfState
+ ld a, [hl] ; store the value in a
+ push af
+ push hl
+ ld [hl], 0
+ farcall 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
+ jr nc, .cannotFish
+ ld a, [wWalkBikeSurfState]
+ cp 2 ; Surfing?
+ jr z, .cannotFish
+ call ItemUseReloadOverworldData
+ ld hl, ItemUseText00
+ call PrintText
+ ld a, SFX_HEAL_AILMENT
+ call PlaySound
+ ld a, $2
+ ld [wd49c], a
+ ld a, $81
+ ld [wPikachuMood], a
+ ld c, 80
+ call DelayFrames
+ and a
+ ret
+
+.cannotFish
+ scf ; can't fish when surfing
+ ret
+
+ItemUseOaksParcel:
+ jp ItemUseNotYoursToUse
+
+ItemUseItemfinder:
+ ld a, [wIsInBattle]
+ and a
+ jp nz, ItemUseNotTime
+ call ItemUseReloadOverworldData
+ farcall 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:
+ text_far _ItemfinderFoundItemText
+ text_end
+
+ItemfinderFoundNothingText:
+ text_far _ItemfinderFoundNothingText
+ text_end
+
+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, [wIsInBattle]
+ and a
+ jr z, .usePPItem
+ ld a, [wWhichPokemon]
+ ld b, a
+ ld a, [wPlayerMonNumber]
+ cp b
+ jr nz, .usePPItem
+ ld a, [wPlayerBattleStatus3]
+ bit TRANSFORMED, a
+ jr z, .usePPItem
+ call ItemUseNotTime
+ jp .itemNotUsed
+
+.usePPItem
+ 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
+ callfar 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 a, SFX_HEAL_AILMENT
+ call PlaySound
+ 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:
+ text_far _RaisePPWhichTechniqueText
+ text_end
+
+RestorePPWhichTechniqueText:
+ text_far _RestorePPWhichTechniqueText
+ text_end
+
+PPMaxedOutText:
+ text_far _PPMaxedOutText
+ text_end
+
+PPIncreasedText:
+ text_far _PPIncreasedText
+ text_end
+
+PPRestoredText:
+ text_far _PPRestoredText
+ text_end
+
+; 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 TM01 ; underflows below 0 for HM items (before TM items)
+ push af
+ jr nc, .skipAdding
+ add NUM_TMS + NUM_HMS ; adjust HM IDs to come after TM IDs
+.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
+ hlcoord 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
+ callfar CheckIfMoveIsKnown ; check if the pokemon already knows the move
+ jr c, .chooseMon
+ predef LearnMove ; teach move
+ ld a, [wWhichPokemon]
+ ld d, a
+ pop af
+ ld [wcf91], a
+ pop af
+ ld [wWhichPokemon], a
+ ld a, b
+ and a
+ ret z
+
+ ld a, [wWhichPokemon]
+ push af
+ ld a, d
+ ld [wWhichPokemon], a
+ callabd_ModifyPikachuHappiness PIKAHAPPY_USEDTMHM
+ callfar IsThisPartymonStarterPikachu_Party
+ jr nc, .notTeachingThunderboltOrThunderToPikachu
+ ld a, [wcf91]
+ cp TM_THUNDERBOLT ; are we teaching thunderbolt to the player pikachu?
+ jr z, .teachingThunderboltOrThunderToPlayerPikachu
+ cp TM_THUNDER ; are we teaching thunder then?
+ jr nz, .notTeachingThunderboltOrThunderToPikachu
+.teachingThunderboltOrThunderToPlayerPikachu
+ ld a, $5
+ ld [wd49c], a
+ ld a, $85
+ ld [wPikachuMood], a
+.notTeachingThunderboltOrThunderToPikachu
+ pop af
+ ld [wWhichPokemon], a
+
+ ld a, [wcf91]
+ call IsItemHM
+ ret c
+ jp RemoveUsedItem
+
+BootedUpTMText:
+ text_far _BootedUpTMText
+ text_end
+
+BootedUpHMText:
+ text_far _BootedUpHMText
+ text_end
+
+TeachMachineMoveText:
+ text_far _TeachMachineMoveText
+ text_end
+
+MonCannotLearnMachineMoveText:
+ text_far _MonCannotLearnMachineMoveText
+ text_end
+
+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
+
+Func_e4bf:
+ ld a, $2
+ ld [wActionResultOrTookBattleTurn], a
+ ld hl, DontHavePokemonText
+ jp PrintText
+
+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:
+ text_far _ItemUseNotTimeText
+ text_end
+
+ItemUseNotYoursToUseText:
+ text_far _ItemUseNotYoursToUseText
+ text_end
+
+ItemUseNoEffectText:
+ text_far _ItemUseNoEffectText
+ text_end
+
+ThrowBallAtTrainerMonText1:
+ text_far _ThrowBallAtTrainerMonText1
+ text_end
+
+ThrowBallAtTrainerMonText2:
+ text_far _ThrowBallAtTrainerMonText2
+ text_end
+
+NoCyclingAllowedHereText:
+ text_far _NoCyclingAllowedHereText
+ text_end
+
+NoSurfingHereText:
+ text_far _NoSurfingHereText
+ text_end
+
+BoxFullCannotThrowBallText:
+ text_far _BoxFullCannotThrowBallText
+ text_end
+
+DontHavePokemonText:
+ text_far _DontHavePokemonText
+ text_end
+
+ItemUseText00:
+ text_far _ItemUseText001
+ text_low
+ text_far _ItemUseText002
+ text_end
+
+GotOnBicycleText:
+ text_far _GotOnBicycleText1
+ text_low
+ text_far _GotOnBicycleText2
+ text_end
+
+GotOffBicycleText:
+ text_far _GotOffBicycleText1
+ text_low
+ text_far _GotOffBicycleText2
+ text_end
+
+; 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
+ ldh [hDividend + 3], a
+ xor a
+ ldh [hDividend], a
+ ldh [hDividend + 1], a
+ ldh [hDividend + 2], a
+ ld a, 5
+ ldh [hDivisor], 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
+ ldh a, [hQuotient + 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
+ hlcoord 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:
+ text_far _ThrewAwayItemText
+ text_end
+
+IsItOKToTossItemText:
+ text_far _IsItOKToTossItemText
+ text_end
+
+TooImportantToTossText:
+ text_far _TooImportantToTossText
+ text_end
+
+; 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 HM01 ; 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/items/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_e6f5
+ inc de
+ ld a, [de]
+ ld b, a
+ ld a, c
+ ld c, b
+ ld [de], a
+ cp $ff
+ jr nz, .asm_e6f5
+ call GetMonHeader
+ ld hl, wBoxMonOT
+ ld bc, NAME_LENGTH
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e732
+ 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_e71f
+ 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_e71f
+.asm_e732
+ ld hl, wPlayerName
+ ld de, wBoxMonOT
+ ld bc, NAME_LENGTH
+ call CopyData
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e76e
+ 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_e75b
+ 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_e75b
+.asm_e76e
+ ld hl, wBoxMonNicks
+ ld a, NAME_MON_SCREEN
+ ld [wNamingScreenType], a
+ predef AskName
+ ld a, [wNumInBox]
+ dec a
+ jr z, .asm_e7ab
+ 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_e798
+ 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_e798
+.asm_e7ab
+ 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
+ callfar CalcExperience
+ pop de
+ ldh a, [hExperience]
+ ld [de], a
+ inc de
+ ldh a, [hExperience + 1]
+ ld [de], a
+ inc de
+ ldh a, [hExperience + 2]
+ ld [de], a
+ inc de
+ xor a
+ ld b, NUM_STATS * 2
+.asm_e7e3
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .asm_e7e3
+ 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_e7f5
+ ld a, [hli]
+ inc de
+ ld [de], a
+ dec b
+ jr nz, .asm_e7f5
+ ld a, [wcf91]
+ cp KADABRA
+ jr nz, .notKadabra
+ ld a, $60 ; twistedspoon in gsc
+ ld [wBoxMon1CatchRate], a
+.notKadabra
+ 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 ; does the current map allow surfing?
+ ret nc ; if not, return
+ ld hl, WaterTile
+ ld a, [wCurMapTileset]
+ cp SHIP_PORT ; Vermilion Dock tileset
+ jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
+ cp GYM ; eastern shore tile in Safari Zone
+ jr z, .skipShoreTiles
+ cp DOJO ; usual eastern shore tile
+ jr z, .skipShoreTiles
+ ld hl, ShoreTiles
+.skipShoreTiles
+ ld a, [wTileInFrontOfPlayer]
+ ld de, $1
+ call IsInArray
+ ret
+
+INCLUDE "data/tilesets/water_tilesets.asm"
+
+; shore tiles
+ShoreTiles:
+ db $48, $32
+WaterTile:
+ db $14
+ db $ff ; terminator
+
+; 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/engine/items/items.asm b/engine/items/items.asm
deleted file mode 100755
index e935f292..00000000
--- a/engine/items/items.asm
+++ /dev/null
@@ -1,3235 +0,0 @@
-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]
- cp BATTLE_TYPE_OLD_MAN
- jr z, .canUseBall
- cp BATTLE_TYPE_PIKACHU
- 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]
- cp BATTLE_TYPE_OLD_MAN
- jr z, .oldManBattle
- cp BATTLE_TYPE_PIKACHU
- jr z, .oldManBattle ; pikachu battle technically old man battle
- jr .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)
- ld a, [wBattleType]
- cp BATTLE_TYPE_OLD_MAN
- jp nz,.captured
- ld a,$1
- ld [wCapturedMonSpecies], a
- CheckEvent EVENT_02F
- ld b, $63
- jp nz,.setAnimData
- 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 POKEMON_TOWER_6F
- jr nz, .loop
- ld a, [wEnemyMonSpecies2]
- cp RESTLESS_SOUL
- 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]
- cp BATTLE_TYPE_OLD_MAN ; is this the old man battle?
- jp z, .oldManCaughtMon ; if so, don't give the player the caught Pokémon
- cp BATTLE_TYPE_PIKACHU
- jr z, .oldManCaughtMon ; same with Pikachu battle
- 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, $1
- ld [wd49c], a
- ld a, $85
- ld [wPikachuMood], a
- ld a, [wPartyCount]
- cp PARTY_LENGTH ; is party full?
- jr z, .sendToBox
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- call ClearSprites
- ld hl, .emptyString
- call PrintText
- 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
-
-.emptyString
- db "@"
-
-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
- ld a, $00
- ld [wPikachuSpawnState], a
- call PlayDefaultMusic ; play walking music
- ld hl, GotOffBicycleText
- jp PrintText
-
-.tryToGetOnBike
- call IsBikeRidingAllowed
- jp nc, NoCyclingAllowedHere
- call ItemUseReloadOverworldData
- xor a ; no keys pressed
- ld [hJoyHeld], a ; current joypad state
- ld a, $1
- ld [wWalkBikeSurfState], a ; change player state to bicycling
- call PlayDefaultMusic ; play bike riding music
- xor a
- ld [wWalkBikeSurfState], a
- ld hl, GotOnBicycleText
- call PrintText
- ld a, $1
- ld [wWalkBikeSurfState], a
- ret
-
-; 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 nc, 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 a, [wTileInFrontOfPlayer]
- ld c, a
- call IsTilePassable
- jr nc, .stopSurfing
-.cannotStopSurfing
- ld hl, SurfingNoPlaceToGetOffText
- jp PrintText
-
-.stopSurfing
- call .makePlayerMoveForward
- ld a, $3
- ld [wPikachuSpawnState], a
- ld hl, wPikachuOverworldStateFlags
- set 5, [hl]
- 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
- call GBPalWhiteOutWithDelay3
- 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
- ld a, [wcf91]
- ld [wLoadedMon], a
- pop bc
- jr c, .canceledItemUse
- ld a, b
- ld [wcf91], a
- call Func_d85d
- jr nc, .noEffect
- callab IsThisPartymonStarterPikachu_Party
- jr nc, .notPlayerPikachu
- ld e, $1b
- callab PlayPikachuSoundClip
- ld a, [wWhichPokemon]
- ld hl, wPartyMonNicks
- call GetPartyMonName
- ld hl, RefusingText
- call PrintText
- ld a, $4
- ld [wd49c], a
- ld a, $82
- ld [wPikachuMood], a
- jr .canceledItemUse
-
-.notPlayerPikachu
- ld a, SFX_HEAL_AILMENT
- call PlaySoundWaitForCurrent
- call WaitForSoundToFinish
- ld a, $01
- ld [wForceEvolution], a
- callab TryEvolvingMon ; try to evolve pokemon
- 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
-
-Func_d85d:
- ld hl, EvosMovesPointerTable
- ld a, [wLoadedMon]
- dec a
- ld c, a
- ld b, $0
- add hl, bc
- add hl, bc
- ld de, wcd6d
- ld a, BANK(TryEvolvingMon)
- ld bc, $2
- call FarCopyData
- ld hl, wcd6d
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, wcd6d
- ld a, BANK(TryEvolvingMon)
- ld bc, 13
- call FarCopyData
- ld hl, wcd6d
-.loop
- ld a, [hli]
- and a
- jr z, .cannotEvolveWithUsedStone
- inc hl
- inc hl
- cp EV_ITEM
- jr nz, .loop
- dec hl
- dec hl
- ld b, [hl]
- ld a, [wcf91]
- inc hl
- inc hl
- inc hl
- cp b
- jr nz, .loop
- scf
- ret
-
-.cannotEvolveWithUsedStone
- and a
- ret
-
-RefusingText:
- TX_FAR _RefusingText
- db "@"
-
-ItemUseVitamin:
- ld a, [wIsInBattle]
- and a
- jp nz, ItemUseNotTime
-
-ItemUseMedicine:
- ld a, [wPartyCount]
- and a
- jp z, Func_e4bf
- 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
-.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
- push af
- cp $28
- jr nc, .asm_d906
- push hl
- push de
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDITEM
- pop de
- pop hl
-.asm_d906
- 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, [wWhichPokemon]
- push af
- ld a, [wUsedItemOnWhichPokemon]
- ld [wWhichPokemon], a
- push hl
- push de
- push bc
- callab Func_2fd6a
- pop bc
- pop de
- pop hl
- pop af
- ld [wWhichPokemon], a
-
- 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 + Ch5], 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_0xFFFA]
- set 0, a
- ld [hFlags_0xFFFA], a
- ld a, $02
- ld [wHPBarType], a
- predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
- ld a, [hFlags_0xFFFA]
- res 0, a
- ld [hFlags_0xFFFA], 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_0xFFFA]
- set 0, a
- ld [hFlags_0xFFFA], a
- ld a, $02
- ld [wHPBarType], a
- predef UpdateHPBar2 ; animate the HP bar lengthening
- ld a, [hFlags_0xFFFA]
- res 0, a
- ld [hFlags_0xFFFA], 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
- callabd_ModifyPikachuHappiness PIKAHAPPY_LEVELUP
- ld a, [wWhichPokemon]
- push af
- ld a, [wUsedItemOnWhichPokemon]
- ld [wWhichPokemon], a
- callab Func_2fd6a ; evolve pokemon, if appropriate
- pop af
- ld [wWhichPokemon], a
-
- callab TryEvolvingMon
- 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
- cp BILLS_HOUSE
- jr z, .notUsable
- cp POKEMON_FAN_CLUB
- 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]
- call Func_1510
- ld hl, wd72e
- res 4, [hl]
- ResetEvent EVENT_IN_SAFARI_ZONE
- xor a
- ld [wNumSafariBalls], a
- ld [wSafariZoneGateCurScript], 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
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
- 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 a, [wWhichPokemon]
- push af
- ld a, [wPlayerMonNumber]
- ld [wWhichPokemon], a
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
- pop af
- ld [wWhichPokemon], a
-
- 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 a, [wWhichPokemon]
- push af
- ld a, [wPlayerMonNumber]
- ld [wWhichPokemon], a
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
- pop af
- ld [wWhichPokemon], a
-
- 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
-
- ld a, [wWhichPokemon]
- push af
- ld a, [wPlayerMonNumber]
- ld [wWhichPokemon], a
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDXITEM
- pop af
- ld [wWhichPokemon], a
-
- 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, .noSnorlaxOrPikachuToWakeUp
-; if the player hasn't beaten Route 12 Snorlax
- ld hl, Route12SnorlaxFluteCoords
- call ArePlayerCoordsInArray
- jr nc, .noSnorlaxOrPikachuToWakeUp
- ld hl, PlayedFluteHadEffectText
- call PrintText
- SetEvent EVENT_FIGHT_ROUTE12_SNORLAX
- ret
-
-.notRoute12
- cp ROUTE_16
- jr nz, .notRoute16
- CheckEvent EVENT_BEAT_ROUTE16_SNORLAX
- jr nz, .noSnorlaxOrPikachuToWakeUp
-; if the player hasn't beaten Route 16 Snorlax
- ld hl, Route16SnorlaxFluteCoords
- call ArePlayerCoordsInArray
- jr nc, .noSnorlaxOrPikachuToWakeUp
- ld hl, PlayedFluteHadEffectText
- call PrintText
- SetEvent EVENT_FIGHT_ROUTE16_SNORLAX
- ret
-
-.notRoute16
- cp PEWTER_POKECENTER
- jr nz, .noSnorlaxOrPikachuToWakeUp
- call CheckPikachuFollowingPlayer
- jr z, .noSnorlaxOrPikachuToWakeUp
- callab IsPikachuRightNextToPlayer
- jr nc, .noSnorlaxOrPikachuToWakeUp
- ld hl, PlayedFluteHadEffectText
- call PrintText
- call ItemUseReloadOverworldData
- ldpikaemotion e, PikachuEmotion26
- callab PlaySpecificPikachuEmotion
- ret
-
-.noSnorlaxOrPikachuToWakeUp
- 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]
- ld c, a
- and b ; remove Sleep status
- ld [hl], a
- ld a, c
- and SLP
- jr z, .asm_e063
- ld a, $1
- ld [wWereAnyMonsAsleep], a
-.asm_e063
- 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 + Ch7]
- 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
- call StopAllMusic ; turn off music
- ld a, SFX_POKEFLUTE
- ld c, BANK(SFX_Pokeflute)
- call PlayMusic
-.musicWaitLoop ; wait for music to finish playing
- ld a, [wChannelSoundIDs + Ch3]
- 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
- callab ReadSuperRodData
- ld c, e
- ld b, d
- ld a, $2
- ld [wRodResponse], a
- ld a, c
- and a ; are there fish in the map?
- jr z, DoNotGenerateFishingEncounter ; if not, do not generate an encounter
- ld a, $1
- ld [wRodResponse], a
- call Random
- and $1
- jr nz, RodResponse
- xor a
- ld [wRodResponse], a
- jr DoNotGenerateFishingEncounter
-
-RodResponse:
- ld [wRodResponse], a
-
- dec a ; is there a bite?
- jr nz, DoNotGenerateFishingEncounter
- ; 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
-
-DoNotGenerateFishingEncounter:
- 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
- jr nc, .cannotFish
- ld a, [wWalkBikeSurfState]
- cp 2 ; Surfing?
- jr z, .cannotFish
- call ItemUseReloadOverworldData
- ld hl, ItemUseText00
- call PrintText
- ld a, SFX_HEAL_AILMENT
- call PlaySound
- ld a, $2
- ld [wd49c], a
- ld a, $81
- ld [wPikachuMood], a
- ld c, 80
- call DelayFrames
- and a
- ret
-
-.cannotFish
- 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, [wIsInBattle]
- and a
- jr z, .usePPItem
- ld a, [wWhichPokemon]
- ld b, a
- ld a, [wPlayerMonNumber]
- cp b
- jr nz, .usePPItem
- ld a, [wPlayerBattleStatus3]
- bit TRANSFORMED, a
- jr z, .usePPItem
- call ItemUseNotTime
- jp .itemNotUsed
-
-.usePPItem
- 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 a, SFX_HEAL_AILMENT
- call PlaySound
- 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
- ld a, [wWhichPokemon]
- ld d, a
- pop af
- ld [wcf91], a
- pop af
- ld [wWhichPokemon], a
- ld a, b
- and a
- ret z
-
- ld a, [wWhichPokemon]
- push af
- ld a, d
- ld [wWhichPokemon], a
- callabd_ModifyPikachuHappiness PIKAHAPPY_USEDTMHM
- callab IsThisPartymonStarterPikachu_Party
- jr nc, .notTeachingThunderboltOrThunderToPikachu
- ld a, [wcf91]
- cp TM_24 ; are we teaching thunderbolt to the player pikachu?
- jr z, .teachingThunderboltOrThunderToPlayerPikachu
- cp TM_25 ; are we teaching thunder then?
- jr nz, .notTeachingThunderboltOrThunderToPikachu
-.teachingThunderboltOrThunderToPlayerPikachu
- ld a, $5
- ld [wd49c], a
- ld a, $85
- ld [wPikachuMood], a
-.notTeachingThunderboltOrThunderToPikachu
- pop af
- ld [wWhichPokemon], a
-
- 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
-
-Func_e4bf:
- ld a, $2
- ld [wActionResultOrTookBattleTurn], a
- ld hl, DontHavePokemonText
- jp PrintText
-
-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 "@"
-
-DontHavePokemonText:
- TX_FAR _DontHavePokemonText
- 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_e6f5
- inc de
- ld a, [de]
- ld b, a
- ld a, c
- ld c, b
- ld [de], a
- cp $ff
- jr nz, .asm_e6f5
- call GetMonHeader
- ld hl, wBoxMonOT
- ld bc, NAME_LENGTH
- ld a, [wNumInBox]
- dec a
- jr z, .asm_e732
- 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_e71f
- 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_e71f
-.asm_e732
- ld hl, wPlayerName
- ld de, wBoxMonOT
- ld bc, NAME_LENGTH
- call CopyData
- ld a, [wNumInBox]
- dec a
- jr z, .asm_e76e
- 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_e75b
- 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_e75b
-.asm_e76e
- ld hl, wBoxMonNicks
- ld a, NAME_MON_SCREEN
- ld [wNamingScreenType], a
- predef AskName
- ld a, [wNumInBox]
- dec a
- jr z, .asm_e7ab
- 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_e798
- 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_e798
-.asm_e7ab
- 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_e7e3
- ld [de], a
- inc de
- dec b
- jr nz, .asm_e7e3
- 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_e7f5
- ld a, [hli]
- inc de
- ld [de], a
- dec b
- jr nz, .asm_e7f5
- ld a, [wcf91]
- cp KADABRA
- jr nz, .notKadabra
- ld a, $60 ; twistedspoon in gsc
- ld [wBoxMon1CatchRate], a
-.notKadabra
- 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 ; does the current map allow surfing?
- ret nc ; if not, return
- ld hl, WaterTile
- ld a, [wCurMapTileset]
- cp SHIP_PORT ; Vermilion Dock tileset
- jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
- cp GYM ; eastern shore tile in Safari Zone
- jr z, .skipShoreTiles
- cp DOJO ; usual eastern shore tile
- jr z, .skipShoreTiles
- ld hl, ShoreTiles
-.skipShoreTiles
- ld a, [wTileInFrontOfPlayer]
- ld de, $1
- call IsInArray
- ret
-
-; tilesets with water
-WaterTilesets:
- db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
- db $ff ; terminator
-
-; shore tiles
-ShoreTiles:
- db $48, $32
-WaterTile:
- db $14
- db $ff ; terminator
-
-; 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/engine/subtract_paid_money.asm b/engine/items/subtract_paid_money.asm
index a6a6ec2e..fdefe3d6 100644
--- a/engine/subtract_paid_money.asm
+++ b/engine/items/subtract_paid_money.asm
@@ -1,6 +1,6 @@
; subtracts the amount the player paid from their money
-; sets carry flag if there is enough money and unsets carry flag if not
-SubtractAmountPaidFromMoney_:
+; OUTPUT: carry = 0(success) or 1(fail because there is not enough money)
+SubtractAmountPaidFromMoney_::
ld de, wPlayerMoney
ld hl, hMoney ; total price of items
ld c, 3 ; length of money in bytes
diff --git a/engine/items/tm_prices.asm b/engine/items/tm_prices.asm
index 80e6bf3c..df9761bd 100755
--- a/engine/items/tm_prices.asm
+++ b/engine/items/tm_prices.asm
@@ -1,9 +1,9 @@
-GetMachinePrice:
+GetMachinePrice::
; Input: [wcf91] = Item Id of a TM
; Output: Stores the TM price at hItemPrice
ld a, [wcf91] ; a contains TM item id
- sub TM_01
- ret c
+ sub TM01 ; underflows below 0 for HM items (before TM items)
+ ret c ; HMs are priceless
ld d, a
ld hl, TechnicalMachinePrices
srl a
@@ -16,10 +16,10 @@ GetMachinePrice:
swap a
.highNybbleIsPrice
and $f0
- ld [hItemPrice + 1], a
+ ldh [hItemPrice + 1], a
xor a
- ld [hItemPrice], a
- ld [hItemPrice + 2], a
+ ldh [hItemPrice], a
+ ldh [hItemPrice + 2], a
ret
-INCLUDE "data/tm_prices.asm"
+INCLUDE "data/items/tm_prices.asm"
diff --git a/engine/items/tmhm.asm b/engine/items/tmhm.asm
index 7ccaa232..a11cd736 100755
--- a/engine/items/tmhm.asm
+++ b/engine/items/tmhm.asm
@@ -22,5 +22,5 @@ CheckIfMoveIsKnown:
ret
AlreadyKnowsText:
- TX_FAR _AlreadyKnowsText
- db "@"
+ text_far _AlreadyKnowsText
+ text_end
diff --git a/engine/items/tms.asm b/engine/items/tms.asm
index 84770747..dcf2665d 100755
--- a/engine/items/tms.asm
+++ b/engine/items/tms.asm
@@ -39,4 +39,4 @@ TMToMove:
ld [wd11e], a
ret
-INCLUDE "data/tms.asm"
+INCLUDE "data/moves/tmhm_moves.asm"
diff --git a/engine/items/town_map.asm b/engine/items/town_map.asm
new file mode 100755
index 00000000..c401d1c1
--- /dev/null
+++ b/engine/items/town_map.asm
@@ -0,0 +1,629 @@
+NOT_VISITED EQU $fe
+
+DisplayTownMap:
+ call LoadTownMap
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ ld a, $1
+ ldh [hJoy7], a
+ ld a, [wCurMap]
+ push af
+ ld b, $0
+ call DrawPlayerOrBirdSprite ; player sprite
+ hlcoord 1, 0
+ ld de, wcd6d
+ call PlaceString
+ ld hl, wOAMBuffer
+ ld de, wTileMapBackup
+ ld bc, $10
+ call CopyData
+ ld hl, vSprites tile $04
+ ld de, TownMapCursor
+ lb bc, BANK(TownMapCursor), (TownMapCursorEnd - TownMapCursor) / $8
+ call CopyVideoDataDouble
+ xor a
+ ld [wWhichTownMapLocation], a
+ pop af
+ jr .enterLoop
+
+.townMapLoop
+ hlcoord 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
+ hlcoord 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
+ ldh 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
+ ldh [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
+
+.asm_70f87
+ ldh a, [hJoy5]
+ and D_DOWN | D_UP
+ ret z
+ callfar PlayPikachuSoundClip
+ ret
+
+INCLUDE "data/maps/town_map_order.asm"
+
+TownMapCursor:
+ INCBIN "gfx/town_map/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
+ hlcoord 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
+ ld a, $1
+ ldh [hJoy7], a
+ call LoadPlayerSpriteGraphics
+ call LoadFontTilePatterns
+ ld de, BirdSprite
+ ld b, BANK(BirdSprite)
+ ld c, $c
+ ld hl, vSprites tile $04
+ call CopyVideoData
+ ld de, TownMapUpArrow
+ ld hl, vChars1 tile $6d
+ lb bc, BANK(TownMapUpArrow), (TownMapUpArrowEnd - TownMapUpArrow) / $8
+ call CopyVideoDataDouble
+ call BuildFlyLocationsList
+ ld hl, wUpdateSpritesEnabled
+ ld a, [hl]
+ push af
+ ld [hl], $ff
+ push hl
+ hlcoord 0, 0
+ ld de, ToText
+ call PlaceString
+ ld a, [wCurMap]
+ ld b, $0
+ call DrawPlayerOrBirdSprite
+ ld hl, wFlyLocationsList
+ decoord 18, 0
+.townMapFlyLoop
+ ld a, " "
+ ld [de], a
+ push hl
+ push hl
+ hlcoord 3, 0
+ lb bc, 1, 15
+ call ClearScreenArea
+ pop hl
+ ld a, [hl]
+ ld b, $4
+ call DrawPlayerOrBirdSprite ; draw bird sprite
+ hlcoord 3, 0
+ ld de, wcd6d
+ call PlaceString
+ ld c, 15
+ call DelayFrames
+ hlcoord 18, 0
+ ld [hl], "▶"
+ hlcoord 19, 0
+ ld [hl], "▼"
+ pop hl
+.inputLoop
+ push hl
+ call DelayFrame
+ call JoypadLowSensitivity
+ ldh 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
+ ldh [hJoy7], a
+ call GBPalWhiteOutWithDelay3
+ pop hl
+ pop af
+ ld [hl], a
+ ret
+.pressedUp
+ decoord 18, 0
+ inc hl
+ ld a, [hl]
+ cp $ff
+ jr z, .wrapToStartOfList
+ cp NOT_VISITED
+ jr z, .pressedUp ; skip past unvisited towns
+ jp .townMapFlyLoop
+.wrapToStartOfList
+ ld hl, wFlyLocationsList
+ jp .townMapFlyLoop
+.pressedDown
+ decoord 19, 0
+ dec hl
+ ld a, [hl]
+ cp $ff
+ jr z, .wrapToEndOfList
+ cp NOT_VISITED
+ jr z, .pressedDown ; skip past unvisited towns
+ jp .townMapFlyLoop
+.wrapToEndOfList
+ ld hl, wFlyLocationsList + NUM_CITY_MAPS
+ 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
+ lb bc, 0, NUM_CITY_MAPS
+.loop
+ srl d
+ rr e
+ ld a, NOT_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/town_map/up_arrow.1bpp"
+TownMapUpArrowEnd:
+
+LoadTownMap:
+ call GBPalWhiteOutWithDelay3
+ call ClearScreen
+ call UpdateSprites
+ hlcoord 0, 0
+ lb bc, $12, $12
+ call TextBoxBorder
+ call DisableLCD
+ ld hl, WorldMapTileGraphics
+ ld de, vChars2 tile $60
+ ld bc, WorldMapTileGraphicsEnd - WorldMapTileGraphics
+ ld a, BANK(WorldMapTileGraphics)
+ call FarCopyData
+ ld hl, MonNestIcon
+ ld de, vSprites tile $04
+ ld bc, MonNestIconEnd - MonNestIcon
+ ld a, BANK(MonNestIcon)
+ call FarCopyDataDouble
+ hlcoord 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:
+ INCBIN "gfx/town_map/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:
+ farcall 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
+ hlcoord 1, 7
+ lb bc, 2, 15
+ call TextBoxBorder
+ hlcoord 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 FIRST_INDOOR_MAP
+ 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/maps/town_map_entries.asm"
+
+INCLUDE "data/maps/names.asm"
+
+MonNestIcon:
+ INCBIN "gfx/town_map/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/engine/joypad.asm b/engine/joypad.asm
index 4126568c..06a15e4e 100644
--- a/engine/joypad.asm
+++ b/engine/joypad.asm
@@ -2,34 +2,34 @@ ReadJoypad_::
; Poll joypad input.
; Unlike the hardware register, button
; presses are indicated by a set bit.
- ld a, [hDisableJoypadPolling]
+ ldh a, [hDisableJoypadPolling]
and a
ret nz
ld a, 1 << 5 ; select direction keys
;ld c, 0
- ld [rJOYP], a
- ld a, [rJOYP]
- ld a, [rJOYP]
+ ldh [rJOYP], a
+ ldh a, [rJOYP]
+ ldh a, [rJOYP]
cpl
and %1111
swap a
ld b, a
ld a, 1 << 4 ; select button keys
- ld [rJOYP], a
- rept 6
- ld a, [rJOYP]
- endr
+ ldh [rJOYP], a
+ REPT 6
+ ldh a, [rJOYP]
+ ENDR
cpl
and %1111
or b
- ld [hJoyInput], a
+ ldh [hJoyInput], a
ld a, 1 << 4 + 1 << 5 ; deselect keys
- ld [rJOYP], a
+ ldh [rJOYP], a
ret
@@ -37,30 +37,30 @@ _Joypad::
; hJoyReleased: (hJoyLast ^ hJoyInput) & hJoyLast
; hJoyPressed: (hJoyLast ^ hJoyInput) & hJoyInput
- ld a, [hJoyInput]
- ld b,a
+ ldh a, [hJoyInput]
+ ld b, a
and $4F
cp A_BUTTON + B_BUTTON + SELECT + START ; soft reset
jp z, TrySoftReset
- ld a, [hJoyLast]
+ ldh a, [hJoyLast]
ld e, a
xor b
ld d, a
and e
- ld [hJoyReleased], a
+ ldh [hJoyReleased], a
ld a, d
and b
- ld [hJoyPressed], a
+ ldh [hJoyPressed], a
ld a, b
- ld [hJoyLast], a
+ ldh [hJoyLast], a
ld a, [wd730]
bit 5, a
jr nz, DiscardButtonPresses
- ld a, [hJoyLast]
- ld [hJoyHeld], a
+ ldh a, [hJoyLast]
+ ldh [hJoyHeld], a
ld a, [wJoyIgnore]
and a
@@ -68,19 +68,19 @@ _Joypad::
cpl
ld b, a
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
and b
- ld [hJoyHeld], a
- ld a, [hJoyPressed]
+ ldh [hJoyHeld], a
+ ldh a, [hJoyPressed]
and b
- ld [hJoyPressed], a
+ ldh [hJoyPressed], a
ret
DiscardButtonPresses:
xor a
- ld [hJoyHeld], a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
+ ldh [hJoyHeld], a
+ ldh [hJoyPressed], a
+ ldh [hJoyReleased], a
ret
TrySoftReset:
@@ -88,7 +88,7 @@ TrySoftReset:
; deselect (redundant)
ld a, $30
- ld [rJOYP], a
+ ldh [rJOYP], a
ld hl, hSoftReset
dec [hl]
diff --git a/engine/cable_club.asm b/engine/link/cable_club.asm
index a8dc5d8d..c75ab200 100755
--- a/engine/cable_club.asm
+++ b/engine/link/cable_club.asm
@@ -9,10 +9,10 @@ CableClub_DoBattleOrTrade:
call LoadFontTilePatterns
call LoadHpBarAndStatusTilePatterns
call LoadTrainerInfoTextBoxTiles
- coord hl, 3, 8
+ hlcoord 3, 8
lb bc, 2, 12
call CableClub_TextBoxBorder
- coord hl, 4, 10
+ hlcoord 4, 10
ld de, PleaseWaitString
call PlaceString
ld hl, wPlayerNumHits
@@ -101,26 +101,26 @@ CableClub_DoBattleOrTradeAgain:
ld a, SERIAL_PATCH_LIST_PART_TERMINATOR
ld [de], a ; end of part 2
call Serial_SyncAndExchangeNybble
- ld a, [hSerialConnectionStatus]
+ ldh 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
+ ldh [hSerialSendData], a
ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
+ ldh [rSC], a
call DelayFrame
xor a
- ld [hSerialSendData], a
+ ldh [hSerialSendData], a
ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
+ ldh [rSC], a
.skipSendingTwoZeroBytes
call Delay3
call StopAllMusic
ld a, (1 << SERIAL)
- ld [rIE], a
+ ldh [rIE], a
ld hl, wSerialRandomNumberListBlock
ld de, wSerialOtherGameboyRandomNumberListBlock
ld bc, $11
@@ -138,8 +138,8 @@ CableClub_DoBattleOrTradeAgain:
ld bc, $c8
call Serial_ExchangeBytes
ld a, (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK)
- ld [rIE], a
- ld a, [hSerialConnectionStatus]
+ ldh [rIE], a
+ ldh 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
@@ -253,14 +253,14 @@ CableClub_DoBattleOrTradeAgain:
ld hl, wEnemyMons + (SERIAL_PREAMBLE_BYTE - 1)
dec c
jr nz, .unpatchEnemyMonsLoop
- ld a, wEnemyMonOT % $100
+ ld a, LOW(wEnemyMonOT)
ld [wUnusedCF8D], a
- ld a, wEnemyMonOT / $100
+ ld a, HIGH(wEnemyMonOT)
ld [wUnusedCF8D + 1], a
xor a
ld [wTradeCenterPointerTableIndex], a
call StopAllMusic
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
ld c, 66
call z, DelayFrames ; delay if using internal clock
@@ -271,7 +271,7 @@ CableClub_DoBattleOrTradeAgain:
jr nz, .trading
ld a, LINK_STATE_BATTLING
ld [wLinkState], a
- ld a, OPP_SONY1
+ ld a, OPP_RIVAL1
ld [wCurOpponent], a
call ClearScreen
call Delay3
@@ -346,10 +346,10 @@ TradeCenter_SelectMon:
ld a, 1
ld [wTopMenuItemX], a
.enemyMonMenu_HandleInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 1, [hl]
and a
jp z, .getNewInput
@@ -367,7 +367,7 @@ TradeCenter_SelectMon:
.displayEnemyMonStats
ld a, INIT_ENEMYOT_LIST
ld [wInitListType], a
- callab InitList ; the list isn't used
+ callfar InitList ; the list isn't used
ld hl, wEnemyMons
call TradeCenter_DisplayStats
jp .getNewInput
@@ -407,14 +407,14 @@ TradeCenter_SelectMon:
ld [wTopMenuItemY], a
ld a, 1
ld [wTopMenuItemX], a
- coord hl, 1, 1
+ hlcoord 1, 1
lb bc, 6, 1
call ClearScreenArea
.playerMonMenu_HandleInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 1, [hl]
and a ; was anything pressed?
jr nz, .playerMonMenu_SomethingPressed
@@ -426,7 +426,7 @@ TradeCenter_SelectMon:
; unreachable code
ld a, INIT_PLAYEROT_LIST
ld [wInitListType], a
- callab InitList ; the list isn't used
+ callfar InitList ; the list isn't used
call TradeCenter_DisplayStats
jp .getNewInput
.playerMonMenu_ANotPressed
@@ -472,10 +472,10 @@ TradeCenter_SelectMon:
dec a
.displayStatsTradeMenu
push af
- coord hl, 0, 14
+ hlcoord 0, 14
lb bc, 2, 18
call CableClub_TextBoxBorder
- coord hl, 2, 16
+ hlcoord 2, 16
ld de, .statsTrade
call PlaceString
xor a
@@ -487,7 +487,7 @@ TradeCenter_SelectMon:
ld [wTopMenuItemY], a
.selectStatsMenuItem
ld a, " "
- Coorda 11, 16
+ ldcoord_a 11, 16
ld a, D_RIGHT | B_BUTTON | A_BUTTON
ld [wMenuWatchedKeys], a
ld a, 1
@@ -504,7 +504,7 @@ TradeCenter_SelectMon:
jp .playerMonMenu
.selectTradeMenuItem
ld a, " "
- Coorda 1, 16
+ ldcoord_a 1, 16
ld a, D_LEFT | B_BUTTON | A_BUTTON
ld [wMenuWatchedKeys], a
ld a, 11
@@ -520,7 +520,7 @@ TradeCenter_SelectMon:
ld [wCurrentMenuItem], a
ld a, INIT_PLAYEROT_LIST
ld [wInitListType], a
- callab InitList ; the list isn't used
+ callfar InitList ; the list isn't used
call TradeCenter_DisplayStats
call LoadScreenTilesFromBuffer1
jp .playerMonMenu
@@ -555,10 +555,10 @@ TradeCenter_SelectMon:
ld [hl], a
.cancelMenuItem_Loop
ld a, "▶" ; filled arrow cursor
- Coorda 1, 16
+ ldcoord_a 1, 16
.cancelMenuItem_JoypadLoop
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and a ; pressed anything?
jr z, .cancelMenuItem_JoypadLoop
bit 0, a ; A button pressed?
@@ -567,14 +567,14 @@ TradeCenter_SelectMon:
jr z, .cancelMenuItem_JoypadLoop
; if Up pressed
ld a, " "
- Coorda 1, 16
+ ldcoord_a 1, 16
ld a, [wPartyCount]
dec a
ld [wCurrentMenuItem], a
jp .playerMonMenu
.cancelMenuItem_APressed
ld a, "▷" ; unfilled arrow cursor
- Coorda 1, 16
+ ldcoord_a 1, 16
ld a, $f
ld [wSerialExchangeNybbleSendData], a
call Serial_PrintWaitingTextAndSyncAndExchangeNybble
@@ -595,7 +595,7 @@ ReturnToCableClubRoom:
dec a
ld [wDestinationWarpID], a
call LoadMapData
- callba ClearVariablesOnEnterMap
+ farcall ClearVariablesOnEnterMap
pop hl
pop af
ld [hl], a
@@ -603,14 +603,14 @@ ReturnToCableClubRoom:
ret
TradeCenter_DrawCancelBox:
- coord hl, 11, 15
+ hlcoord 11, 15
ld a, $7e
ld bc, 2 * SCREEN_WIDTH + 9
call FillMemory
- coord hl, 0, 15
+ hlcoord 0, 15
lb bc, 1, 9
call CableClub_TextBoxBorder
- coord hl, 2, 16
+ hlcoord 2, 16
ld de, CancelTextString
jp PlaceString
@@ -619,7 +619,7 @@ CancelTextString:
TradeCenter_PlaceSelectedEnemyMonMenuCursor:
ld a, [wSerialSyncAndExchangeNybbleReceiveData]
- coord hl, 1, 9
+ hlcoord 1, 9
ld bc, SCREEN_WIDTH
call AddNTimes
ld [hl], "▷" ; cursor
@@ -639,22 +639,22 @@ TradeCenter_DisplayStats:
jp TradeCenter_DrawCancelBox
TradeCenter_DrawPartyLists:
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 6, 18
call CableClub_TextBoxBorder
- coord hl, 0, 8
+ hlcoord 0, 8
lb bc, 6, 18
call CableClub_TextBoxBorder
- coord hl, 5, 0
+ hlcoord 5, 0
ld de, wPlayerName
call PlaceString
- coord hl, 5, 8
+ hlcoord 5, 8
ld de, wLinkEnemyTrainerName
call PlaceString
- coord hl, 2, 1
+ hlcoord 2, 1
ld de, wPartySpecies
call TradeCenter_PrintPartyListNames
- coord hl, 2, 9
+ hlcoord 2, 9
ld de, wEnemyPartyMons
; fall through
@@ -670,7 +670,7 @@ TradeCenter_PrintPartyListNames:
push de
push hl
ld a, c
- ld [$ff95], a
+ ldh [hPastLeadingZeros], a
call GetMonName
pop hl
call PlaceString
@@ -691,7 +691,7 @@ TradeCenter_Trade:
ld [wSerialExchangeNybbleReceiveData], a
ld [wMenuWatchMovingOutOfBounds], a
ld [wMenuJoypadPollCount], a
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call CableClub_TextBoxBorder
ld a, [wTradingWhichPlayerMon]
@@ -715,10 +715,10 @@ TradeCenter_Trade:
ld [wd11e], a
call GetMonName
ld hl, WillBeTradedText
- coord bc, 1, 14
+ bccoord 1, 14
call TextCommandProcessor
call SaveScreenTilesToBuffer1
- coord hl, 10, 7
+ hlcoord 10, 7
lb bc, 8, 11
ld a, TRADE_CANCEL_MENU
ld [wTwoOptionMenuID], a
@@ -732,10 +732,10 @@ TradeCenter_Trade:
; if trade cancelled
ld a, $1
ld [wSerialExchangeNybbleSendData], a
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call CableClub_TextBoxBorder
- coord hl, 1, 14
+ hlcoord 1, 14
ld de, TradeCanceled
call PlaceString
call Serial_PrintWaitingTextAndSyncAndExchangeNybble
@@ -748,10 +748,10 @@ TradeCenter_Trade:
dec a ; did the other person cancel?
jr nz, .doTrade
; if the other person cancelled
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call CableClub_TextBoxBorder
- coord hl, 1, 14
+ hlcoord 1, 14
ld de, TradeCanceled
call PlaceString
jp .tradeCancelled
@@ -842,7 +842,7 @@ TradeCenter_Trade:
call LoadHpBarAndStatusTilePatterns
xor a
ld [wUnusedCC5B], a
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
jr z, .usingExternalClock
predef InternalClockTradeAnim
@@ -850,7 +850,7 @@ TradeCenter_Trade:
.usingExternalClock
predef ExternalClockTradeAnim
.tradeCompleted
- callab TryEvolvingMon
+ callfar TryEvolvingMon
call ClearScreen
call LoadTrainerInfoTextBoxTiles
call Serial_PrintWaitingTextAndSyncAndExchangeNybble
@@ -859,10 +859,10 @@ TradeCenter_Trade:
call Delay3
ld b, $9
call RunPaletteCommand
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call CableClub_TextBoxBorder
- coord hl, 1, 14
+ hlcoord 1, 14
ld de, TradeCompleted
call PlaceString
predef SaveSAVtoSRAM2
@@ -879,8 +879,8 @@ TradeCenter_Trade:
jp CallCurrentTradeCenterFunction
WillBeTradedText:
- TX_FAR _WillBeTradedText
- db "@"
+ text_far _WillBeTradedText
+ text_end
TradeCompleted:
db "Trade completed!@"
@@ -901,7 +901,7 @@ CableClub_Run:
jr z, .doBattleOrTrade
cp LINK_STATE_RESET ; this is never used
ret nz
- predef EmptyFunc3
+ predef EmptyFunc
jp Init
.doBattleOrTrade
call CableClub_DoBattleOrTrade
@@ -910,7 +910,7 @@ CableClub_Run:
ld [wTilesetGfxPtr + 1], a
ld a, l
ld [wTilesetGfxPtr], a
- ld a, Bank(Club_GFX)
+ ld a, BANK(Club_GFX)
ld [wTilesetBank], a
ld hl, Club_Coll
ld a, h
@@ -921,7 +921,7 @@ CableClub_Run:
ld [wGrassRate], a
inc a ; LINK_STATE_IN_CABLE_CLUB
ld [wLinkState], a
- ld [hJoy5], a
+ ldh [hJoy5], a
ld a, 10
ld [wAudioFadeOutControl], a
ld a, BANK(Music_Celadon)
@@ -930,7 +930,7 @@ CableClub_Run:
ld [wNewSoundID], a
jp PlaySound
-EmptyFunc3:
+EmptyFunc:
ret
Diploma_TextBoxBorder:
@@ -979,6 +979,6 @@ CableClub_DrawHorizontalLine:
LoadTrainerInfoTextBoxTiles:
ld de, TrainerInfoTextBoxTileGraphics
- ld hl, vChars2 + $760
+ ld hl, vChars2 tile $76
lb bc, BANK(TrainerInfoTextBoxTileGraphics), (TrainerInfoTextBoxTileGraphicsEnd - TrainerInfoTextBoxTileGraphics) / $10
jp CopyVideoData
diff --git a/engine/overworld/cable_club_npc.asm b/engine/link/cable_club_npc.asm
index 12ce64a4..4d0a0a8a 100755
--- a/engine/overworld/cable_club_npc.asm
+++ b/engine/link/cable_club_npc.asm
@@ -1,4 +1,4 @@
-CableClubNPC:
+CableClubNPC::
ld hl, CableClubNPCWelcomeText
call PrintText
call CheckPikachuFollowingPlayer
@@ -18,27 +18,27 @@ CableClubNPC:
ld a, 90
ld [wLinkTimeoutCounter], a
.establishConnectionLoop
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
jr z, .establishedConnection
cp USING_EXTERNAL_CLOCK
jr z, .establishedConnection
ld a, CONNECTION_NOT_ESTABLISHED
- ld [hSerialConnectionStatus], a
+ ldh [hSerialConnectionStatus], a
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
- ld [rSB], a
+ ldh [rSB], a
xor a
- ld [hSerialReceiveData], a
+ ldh [hSerialReceiveData], a
ld a, START_TRANSFER_EXTERNAL_CLOCK
- ld [rSC], a
+ ldh [rSC], a
ld a, [wLinkTimeoutCounter]
dec a
ld [wLinkTimeoutCounter], a
jr z, .failedToEstablishConnection
ld a, ESTABLISH_CONNECTION_WITH_INTERNAL_CLOCK
- ld [rSB], a
+ ldh [rSB], a
ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
+ ldh [rSC], a
call DelayFrame
jr .establishConnectionLoop
.establishedConnection
@@ -57,7 +57,7 @@ CableClubNPC:
ld a, [wCurrentMenuItem]
and a
jr nz, .choseNo
- callab SaveSAVtoSRAM
+ callfar SaveSAVtoSRAM
call WaitForSoundToFinish
ld a, SFX_SAVE
call PlaySoundWaitForCurrent
@@ -68,7 +68,7 @@ CableClubNPC:
ld [hli], a
xor a
ld [hl], a
- ld [hSerialReceivedNewData], a
+ ldh [hSerialReceivedNewData], a
ld [wSerialExchangeNybbleSendData], a
call Serial_SyncAndExchangeNybble
ld hl, wUnknownSerialCounter
@@ -112,7 +112,7 @@ CableClubNPC:
ld [hl], a
ld a, [wLetterPrintingDelayFlags]
push af
- callab LinkMenu
+ callfar LinkMenu
pop af
ld [wLetterPrintingDelayFlags], a
ret
@@ -167,42 +167,42 @@ Serial_SyncAndExchangeNybbleDouble:
ret
CableClubNPCAreaReservedFor2FriendsLinkedByCableText:
- TX_FAR _CableClubNPCAreaReservedFor2FriendsLinkedByCableText
- db "@"
+ text_far _CableClubNPCAreaReservedFor2FriendsLinkedByCableText
+ text_end
CableClubNPCWelcomeText:
- TX_FAR _CableClubNPCWelcomeText
- db "@"
+ text_far _CableClubNPCWelcomeText
+ text_end
CableClubNPCPleaseApplyHereHaveToSaveText:
- TX_FAR _CableClubNPCPleaseApplyHereHaveToSaveText
- db "@"
+ text_far _CableClubNPCPleaseApplyHereHaveToSaveText
+ text_end
CableClubNPCPleaseWaitText:
- TX_FAR _CableClubNPCPleaseWaitText
- TX_DELAY
- db "@"
+ text_far _CableClubNPCPleaseWaitText
+ text_pause
+ text_end
CableClubNPCLinkClosedBecauseOfInactivityText:
- TX_FAR _CableClubNPCLinkClosedBecauseOfInactivityText
- db "@"
+ text_far _CableClubNPCLinkClosedBecauseOfInactivityText
+ text_end
CableClubNPCPleaseComeAgainText:
- TX_FAR _CableClubNPCPleaseComeAgainText
- db "@"
+ text_far _CableClubNPCPleaseComeAgainText
+ text_end
CableClubNPCMakingPreparationsText:
- TX_FAR _CableClubNPCMakingPreparationsText
- db "@"
+ text_far _CableClubNPCMakingPreparationsText
+ text_end
CloseLinkConnection:
call Delay3
ld a, CONNECTION_NOT_ESTABLISHED
- ld [hSerialConnectionStatus], a
+ ldh [hSerialConnectionStatus], a
ld a, ESTABLISH_CONNECTION_WITH_EXTERNAL_CLOCK
- ld [rSB], a
+ ldh [rSB], a
xor a
- ld [hSerialReceiveData], a
+ ldh [hSerialReceiveData], a
ld a, START_TRANSFER_EXTERNAL_CLOCK
- ld [rSC], a
+ ldh [rSC], a
ret
diff --git a/engine/print_waiting_text.asm b/engine/link/print_waiting_text.asm
index bd2180a1..98a44970 100644
--- a/engine/print_waiting_text.asm
+++ b/engine/link/print_waiting_text.asm
@@ -1,5 +1,5 @@
-PrintWaitingText:
- coord hl, 3, 10
+PrintWaitingText::
+ hlcoord 3, 10
lb bc, 1, 11
ld a, [wIsInBattle]
and a
@@ -9,7 +9,7 @@ PrintWaitingText:
.asm_4b9a
call CableClub_TextBoxBorder
.asm_4b9d
- coord hl, 4, 11
+ hlcoord 4, 11
ld de, WaitingText
call PlaceString
ld c, 50
diff --git a/engine/math/bcd.asm b/engine/math/bcd.asm
new file mode 100644
index 00000000..92bf6f17
--- /dev/null
+++ b/engine/math/bcd.asm
@@ -0,0 +1,218 @@
+; divide hMoney by hDivideBCDDivisor
+; return output in hDivideBCDQuotient (same as hDivideBCDDivisor)
+; used only to halve player money upon losing a fight
+DivideBCDPredef::
+DivideBCDPredef2::
+DivideBCDPredef3:: ; only used function
+DivideBCDPredef4::
+ call GetPredefRegisters
+
+DivideBCD::
+ xor a
+ ldh [hDivideBCDBuffer], a
+ ldh [hDivideBCDBuffer+1], a
+ ldh [hDivideBCDBuffer+2], a
+ ld d, $1
+.mulBy10Loop
+; multiply the divisor by 10 until the leading digit is nonzero
+; to set up the standard long division algorithm
+ ldh a, [hDivideBCDDivisor]
+ and $f0
+ jr nz, .next
+ inc d
+ ldh a, [hDivideBCDDivisor]
+ swap a
+ and $f0
+ ld b, a
+ ldh a, [hDivideBCDDivisor+1]
+ swap a
+ ldh [hDivideBCDDivisor+1], a
+ and $f
+ or b
+ ldh [hDivideBCDDivisor], a
+ ldh a, [hDivideBCDDivisor+1]
+ and $f0
+ ld b, a
+ ldh a, [hDivideBCDDivisor+2]
+ swap a
+ ldh [hDivideBCDDivisor+2], a
+ and $f
+ or b
+ ldh [hDivideBCDDivisor+1], a
+ ldh a, [hDivideBCDDivisor+2]
+ and $f0
+ ldh [hDivideBCDDivisor+2], a
+ jr .mulBy10Loop
+
+.next
+ push de
+ push de
+ call DivideBCD_getNextDigit
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ldh [hDivideBCDBuffer], a
+ dec d
+ jr z, .next2
+ push de
+ call DivideBCD_divDivisorBy10
+ call DivideBCD_getNextDigit
+ pop de
+ ldh a, [hDivideBCDBuffer]
+ or b
+ ldh [hDivideBCDBuffer], a
+ dec d
+ jr z, .next2
+ push de
+ call DivideBCD_divDivisorBy10
+ call DivideBCD_getNextDigit
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ldh [hDivideBCDBuffer+1], a
+ dec d
+ jr z, .next2
+ push de
+ call DivideBCD_divDivisorBy10
+ call DivideBCD_getNextDigit
+ pop de
+ ldh a, [hDivideBCDBuffer+1]
+ or b
+ ldh [hDivideBCDBuffer+1], a
+ dec d
+ jr z, .next2
+ push de
+ call DivideBCD_divDivisorBy10
+ call DivideBCD_getNextDigit
+ pop de
+ ld a, b
+ swap a
+ and $f0
+ ldh [hDivideBCDBuffer+2], a
+ dec d
+ jr z, .next2
+ push de
+ call DivideBCD_divDivisorBy10
+ call DivideBCD_getNextDigit
+ pop de
+ ldh a, [hDivideBCDBuffer+2]
+ or b
+ ldh [hDivideBCDBuffer+2], a
+.next2
+ ldh a, [hDivideBCDBuffer]
+ ldh [hDivideBCDQuotient], a ; the same memory location as hDivideBCDDivisor
+ ldh a, [hDivideBCDBuffer+1]
+ ldh [hDivideBCDQuotient+1], a
+ ldh a, [hDivideBCDBuffer+2]
+ ldh [hDivideBCDQuotient+2], a
+ pop de
+ ld a, $6
+ sub d
+ and a
+ ret z
+.divResultBy10loop
+ push af
+ call DivideBCD_divDivisorBy10
+ pop af
+ dec a
+ jr nz, .divResultBy10loop
+ ret
+
+DivideBCD_divDivisorBy10:
+ ldh a, [hDivideBCDDivisor+2]
+ swap a
+ and $f
+ ld b, a
+ ldh a, [hDivideBCDDivisor+1]
+ swap a
+ ldh [hDivideBCDDivisor+1], a
+ and $f0
+ or b
+ ldh [hDivideBCDDivisor+2], a
+ ldh a, [hDivideBCDDivisor+1]
+ and $f
+ ld b, a
+ ldh a, [hDivideBCDDivisor]
+ swap a
+ ldh [hDivideBCDDivisor], a
+ and $f0
+ or b
+ ldh [hDivideBCDDivisor+1], a
+ ldh a, [hDivideBCDDivisor]
+ and $f
+ ldh [hDivideBCDDivisor], a
+ ret
+
+DivideBCD_getNextDigit:
+ ld bc, $3
+.loop
+ ld de, hMoney ; the dividend
+ ld hl, hDivideBCDDivisor
+ push bc
+ call StringCmp
+ pop bc
+ ret c
+ inc b
+ ld de, hMoney + 2 ; since SubBCD works starting from the least significant digit
+ ld hl, hDivideBCDDivisor + 2
+ push bc
+ call SubBCD
+ pop bc
+ jr .loop
+
+
+AddBCDPredef::
+ call GetPredefRegisters
+
+AddBCD::
+ and a
+ ld b, c
+.add
+ ld a, [de]
+ adc [hl]
+ daa
+ ld [de], a
+ dec de
+ dec hl
+ dec c
+ jr nz, .add
+ jr nc, .done
+ ld a, $99
+ inc de
+.fill
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .fill
+.done
+ ret
+
+
+SubBCDPredef::
+ call GetPredefRegisters
+
+SubBCD::
+ and a
+ ld b, c
+.sub
+ ld a, [de]
+ sbc [hl]
+ daa
+ ld [de], a
+ dec de
+ dec hl
+ dec c
+ jr nz, .sub
+ jr nc, .done
+ ld a, $00
+ inc de
+.fill
+ ld [de], a
+ inc de
+ dec b
+ jr nz, .fill
+ scf
+.done
+ ret
diff --git a/engine/math/multiply_divide.asm b/engine/math/multiply_divide.asm
new file mode 100755
index 00000000..2fcda158
--- /dev/null
+++ b/engine/math/multiply_divide.asm
@@ -0,0 +1,143 @@
+_Multiply::
+ ld a, $8
+ ld b, a
+ xor a
+ ldh [hProduct], a
+ ldh [hMultiplyBuffer], a
+ ldh [hMultiplyBuffer+1], a
+ ldh [hMultiplyBuffer+2], a
+ ldh [hMultiplyBuffer+3], a
+.loop
+ ldh a, [hMultiplier]
+ srl a
+ ldh [hMultiplier], a ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ jr nc, .smallMultiplier
+ ldh a, [hMultiplyBuffer+3]
+ ld c, a
+ ldh a, [hMultiplicand+2]
+ add c
+ ldh [hMultiplyBuffer+3], a
+ ldh a, [hMultiplyBuffer+2]
+ ld c, a
+ ldh a, [hMultiplicand+1]
+ adc c
+ ldh [hMultiplyBuffer+2], a
+ ldh a, [hMultiplyBuffer+1]
+ ld c, a
+ ldh a, [hMultiplicand] ; (aliases: hMultiplicand)
+ adc c
+ ldh [hMultiplyBuffer+1], a
+ ldh a, [hMultiplyBuffer]
+ ld c, a
+ ldh a, [hProduct] ; (aliases: hProduct, hPastLeadingZeros, hQuotient)
+ adc c
+ ldh [hMultiplyBuffer], a
+.smallMultiplier
+ dec b
+ jr z, .done
+ ldh a, [hMultiplicand+2]
+ sla a
+ ldh [hMultiplicand+2], a
+ ldh a, [hMultiplicand+1]
+ rl a
+ ldh [hMultiplicand+1], a
+ ldh a, [hMultiplicand]
+ rl a
+ ldh [hMultiplicand], a
+ ldh a, [hProduct]
+ rl a
+ ldh [hProduct], a
+ jr .loop
+.done
+ ldh a, [hMultiplyBuffer+3]
+ ldh [hProduct+3], a
+ ldh a, [hMultiplyBuffer+2]
+ ldh [hProduct+2], a
+ ldh a, [hMultiplyBuffer+1]
+ ldh [hProduct+1], a
+ ldh a, [hMultiplyBuffer]
+ ldh [hProduct], a
+ ret
+
+_Divide::
+ xor a
+ ldh [hDivideBuffer], a
+ ldh [hDivideBuffer+1], a
+ ldh [hDivideBuffer+2], a
+ ldh [hDivideBuffer+3], a
+ ldh [hDivideBuffer+4], a
+ ld a, $9
+ ld e, a
+.asm_37db3
+ ldh a, [hDivideBuffer]
+ ld c, a
+ ldh a, [hDividend+1] ; (aliases: hMultiplicand)
+ sub c
+ ld d, a
+ ldh a, [hDivisor] ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ ld c, a
+ ldh a, [hDividend] ; (aliases: hProduct, hPastLeadingZeros, hQuotient)
+ sbc c
+ jr c, .asm_37dce
+ ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient)
+ ld a, d
+ ldh [hDividend+1], a ; (aliases: hMultiplicand)
+ ldh a, [hDivideBuffer+4]
+ inc a
+ ldh [hDivideBuffer+4], a
+ jr .asm_37db3
+.asm_37dce
+ ld a, b
+ cp $1
+ jr z, .asm_37e18
+ ldh a, [hDivideBuffer+4]
+ sla a
+ ldh [hDivideBuffer+4], a
+ ldh a, [hDivideBuffer+3]
+ rl a
+ ldh [hDivideBuffer+3], a
+ ldh a, [hDivideBuffer+2]
+ rl a
+ ldh [hDivideBuffer+2], a
+ ldh a, [hDivideBuffer+1]
+ rl a
+ ldh [hDivideBuffer+1], a
+ dec e
+ jr nz, .asm_37e04
+ ld a, $8
+ ld e, a
+ ldh a, [hDivideBuffer]
+ ldh [hDivisor], a ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ xor a
+ ldh [hDivideBuffer], a
+ ldh a, [hDividend+1] ; (aliases: hMultiplicand)
+ ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient)
+ ldh a, [hDividend+2]
+ ldh [hDividend+1], a ; (aliases: hMultiplicand)
+ ldh a, [hDividend+3]
+ ldh [hDividend+2], a
+.asm_37e04
+ ld a, e
+ cp $1
+ jr nz, .asm_37e0a
+ dec b
+.asm_37e0a
+ ldh a, [hDivisor] ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ srl a
+ ldh [hDivisor], a ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ ldh a, [hDivideBuffer]
+ rr a
+ ldh [hDivideBuffer], a
+ jr .asm_37db3
+.asm_37e18
+ ldh a, [hDividend+1] ; (aliases: hMultiplicand)
+ ldh [hRemainder], a ; (aliases: hDivisor, hMultiplier, hPowerOf10)
+ ldh a, [hDivideBuffer+4]
+ ldh [hQuotient+3], a
+ ldh a, [hDivideBuffer+3]
+ ldh [hQuotient+2], a
+ ldh a, [hDivideBuffer+2]
+ ldh [hQuotient+1], a ; (aliases: hMultiplicand)
+ ldh a, [hDivideBuffer+1]
+ ldh [hDividend], a ; (aliases: hProduct, hPastLeadingZeros, hQuotient)
+ ret
diff --git a/engine/math/random.asm b/engine/math/random.asm
new file mode 100755
index 00000000..c8760157
--- /dev/null
+++ b/engine/math/random.asm
@@ -0,0 +1,13 @@
+Random_::
+; Generate a random 16-bit value.
+ ldh a, [rDIV]
+ ld b, a
+ ldh a, [hRandomAdd]
+ adc b
+ ldh [hRandomAdd], a
+ ldh a, [rDIV]
+ ld b, a
+ ldh a, [hRandomSub]
+ sbc b
+ ldh [hRandomSub], a
+ ret
diff --git a/engine/menu/link_menu.asm b/engine/menu/link_menu.asm
deleted file mode 100644
index 9bc28b31..00000000
--- a/engine/menu/link_menu.asm
+++ /dev/null
@@ -1,910 +0,0 @@
-Func_f531b::
- ld c,$14
- call DelayFrames
- ld a,$1
- ld [wBuffer],a
- xor a
- ld [wUnknownSerialFlag_d499],a
- coord hl, 0,0
- lb bc, 4, 5
- call TextBoxBorder
- ld de,Text_f5791
- coord hl, 1,2
- call PlaceString
- coord hl, 8,0
- lb bc, 8, 10
- call TextBoxBorder
- coord hl, 10,2
- ld de,Text_f579c
- call PlaceString
- coord hl, 0,10
- lb bc, 6, 18
- call TextBoxBorder
- call UpdateSprites
- xor a
- ld [wUnusedCD37],a
- ld [wd72d],a
- ld [wd11e],a
- ld hl,wTopMenuItemY
- ld a,$2
- ld [hli],a
- ld a,$9
- ld [hli],a
- xor a
- ld [hli],a
- inc hl
- ld a,$3
- ld [hli],a
- ld a,$3
- ld [hli],a
- xor a
- ld [hl],a
-.asm_f5377
- call Func_f56bd
- call HandleMenuInput
- and $3
- add a
- add a
- ld b,a
- ld a,[wCurrentMenuItem]
- cp $3
- jr nz,.asm_f5390
- bit 2,b
- jr z,.asm_f5390
- dec a
- ld b,$8
-.asm_f5390
- add b
- add $c0
- ld [wLinkMenuSelectionSendBuffer],a
- ld [wLinkMenuSelectionSendBuffer+1],a
-.asm_f5399
- ld hl,wLinkMenuSelectionSendBuffer
- ld a,[hl]
- ld [hSerialSendData],a
- call Serial_ExchangeByte
- push af
- ld hl,wLinkMenuSelectionSendBuffer
- ld a,[hl]
- ld [hSerialSendData],a
- call Serial_ExchangeByte
- pop bc
- cp b
- jr nz,.asm_f5399
- and $f0
- cp $c0
- jr nz,.asm_f5399
- ld a,b
- and $c
- jr nz,.asm_f53c4
- ld a,[wLinkMenuSelectionSendBuffer]
- and $c
- jr z,.asm_f5377
- jr .asm_f53df
-.asm_f53c4
- ld a,[wLinkMenuSelectionSendBuffer]
- and $c
- jr z,.asm_f53d1
- ld a,[hSerialConnectionStatus]
- cp $2
- jr z,.asm_f53df
-.asm_f53d1
- ld a,$1
- ld [wd11e],a
- ld a,b
- ld [wLinkMenuSelectionSendBuffer],a
- and $3
- ld [wCurrentMenuItem],a
-.asm_f53df
- call DelayFrame
- call DelayFrame
- ld hl,wLinkMenuSelectionSendBuffer
- ld a,[hl]
- ld [hSerialSendData],a
- call Serial_ExchangeByte
- call Serial_ExchangeByte
- ld b,$14
-.loop
- call DelayFrame
- call Serial_SendZeroByte
- dec b
- jr nz,.loop
- ld b,$7f
- ld c,$7f
- ld d,$7f
- ld e,$ec
- ld a,[wLinkMenuSelectionSendBuffer]
- bit 3,a
- jr nz,.asm_f541a
- ld b,e
- ld e,c
- ld a,[wCurrentMenuItem]
- and a
- jr z,.asm_f541a
- ld c,b
- ld b,d
- dec a
- jr z,.asm_f541a
- ld d,c
- ld c,b
-.asm_f541a
- ld a,b
- Coorda 9,2
- ld a,c
- Coorda 9,4
- ld a,d
- Coorda 9,6
- ld a,e
- Coorda 9,8
- ld c,40
- call DelayFrames
- ld a,[wLinkMenuSelectionSendBuffer]
- bit 3,a
- jr nz,asm_f547f
- ld a,[wCurrentMenuItem]
- cp $3
- jr z,asm_f547f
- inc a
- ld [wUnknownSerialFlag_d499],a
- ld a,[wCurrentMenuItem]
- ld hl,PointerTable_f5488
- ld c,a
- ld b,$0
- add hl,bc
- add hl,bc
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld de,.returnaddress
- push de
- jp hl
-.returnaddress
- ld [wLinkMenuSelectionSendBuffer],a
- xor a
- ld [wUnknownSerialCounter],a
- ld [wUnknownSerialCounter+1],a
- call Serial_SyncAndExchangeNybble
- ld a,[wLinkMenuSelectionSendBuffer]
- and a
- jr nz,asm_f547c
- ld a, [wLinkMenuSelectionReceiveBuffer]
- and a
- jr nz, Func_f5476
- xor a
- ld [wUnknownSerialCounter],a
- ld [wUnknownSerialCounter+1],a
- and a
- ret
-
-Func_f5476::
- ld hl,ColosseumIneligibleText
- call PrintText
-asm_f547c::
- jp Func_f531b
-
-asm_f547f::
- xor a
- ld [wUnknownSerialCounter],a
- ld [wUnknownSerialCounter+1],a
- scf
- ret
-
-PointerTable_f5488::
- dw PokeCup
- dw PikaCup
- dw PetitCup
-
-PokeCup::
- ld hl,wPartyCount
- ld a,[hli]
- cp $3
- jp nz,NotThreeMonsInParty
- ld b,$3
-.loop
- ld a,[hli]
- cp MEW
- jp z,MewInParty
- dec b
- jr nz,.loop
- dec hl
- dec hl
- cp [hl] ; is third mon second mon?
- jp z,DuplicateSpecies
- dec hl ; wPartySpecies
- cp [hl] ; is third mon first mon?
- jp z,DuplicateSpecies
- ld a,[hli]
- cp [hl] ; is first mon second mon?
- jp z,DuplicateSpecies
- ld a,[wPartyMon1Level]
- cp 56
- jp nc,LevelAbove55
- cp 50
- jp c,LevelUnder50
- ld b,a
- ld a,[wPartyMon2Level]
- cp 56
- jp nc,LevelAbove55
- cp 50
- jp c,LevelUnder50
- ld c,a
- ld a,[wPartyMon3Level]
- cp 56
- jp nc,LevelAbove55
- cp 50
- jp c,LevelUnder50
- add b
- add c
- cp 156
- jp nc,CombinedLevelsGreaterThan155
- xor a
- ret
-
-PikaCup::
- ld hl,wPartyCount
- ld a,[hli]
- cp $3
- jp nz,NotThreeMonsInParty
- ld b,$3
-.loop
- ld a,[hli] ; wPartySpecies
- cp MEW
- jp z,MewInParty
- dec b
- jr nz,.loop
- dec hl
- dec hl
- cp [hl] ; is third mon second mon?
- jp z,DuplicateSpecies
- dec hl ; wPartySpecies
- cp [hl] ; is third mon first mon?
- jp z,DuplicateSpecies
- ld a,[hli]
- cp [hl] ; is first mon second mon?
- jp z,DuplicateSpecies
- ld a,[wPartyMon1Level]
- cp 21
- jp nc,LevelAbove20
- cp 15
- jp c,LevelUnder15
- ld b,a
- ld a,[wPartyMon2Level]
- cp 21
- jp nc,LevelAbove20
- cp 15
- jp c,LevelUnder15
- ld c,a
- ld a,[wPartyMon3Level]
- cp 21
- jp nc,LevelAbove20
- cp 15
- jp c,LevelUnder15
- add b
- add c
- cp 51
- jp nc,CombinedLevelsAbove50
- xor a
- ret
-
-PetitCup::
- ld hl,wPartyCount
- ld a,[hli]
- cp $3
- jp nz,NotThreeMonsInParty
- ld b,$3
-.loop
- ld a,[hli]
- cp MEW
- jp z,MewInParty
- dec b
- jr nz,.loop
- dec hl
- dec hl
- cp [hl] ; is third mon second mon?
- jp z,DuplicateSpecies
- dec hl ; wPartySpecies
- cp [hl] ; is third mon first mon?
- jp z,DuplicateSpecies
- ld a,[hli]
- cp [hl] ; is first mon second mon?
- jp z,DuplicateSpecies
- dec hl
- ld a,[hl]
- ld [wcf91],a
- push hl
- callab Func_3b10f
- pop hl
- jp c,asm_f56ad
- inc hl
- ld a,[hl]
- ld [wcf91],a
- push hl
- callab Func_3b10f
- pop hl
- jp c,asm_f56ad
- inc hl
- ld a,[hl]
- ld [wcf91],a
- push hl
- callab Func_3b10f
- pop hl
- jp c,asm_f56ad
- dec hl
- dec hl
- ld b,$3
-.bigloop
- ld a,[hli]
- push hl
- push bc
- push af
- dec a
- ld c,a
- ld b,$0
- ld hl,PokedexEntryPointers
- add hl,bc
- add hl,bc
- ld de,wcd6d
- ld bc,$2
- ld a,BANK(PokedexEntryPointers)
- call FarCopyData
- ld hl,wcd6d
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld de,wcd6d
- ld bc,$14
- ld a,BANK(PokedexEntryPointers)
- call FarCopyData
- ld hl,wcd6d
-.loop2
- ld a,[hli]
- cp "@"
- jr nz,.loop2
- ld a,[hli]
- cp $7
- jp nc,asm_f5689
- add a
- add a
- ld b,a
- add a
- add b
- ld b,a
- ld a,[hli]
- add b
- cp $51
- jp nc,asm_f5689
- ld a,[hli]
- sub $b9
- ld a,[hl]
- sbc $1
- jp nc,asm_f569b
- pop af
- pop bc
- pop hl
- dec b
- jr nz,.bigloop
- ld a,[wPartyMon1Level]
- cp 31
- jp nc,LevelAbove30
- cp 25
- jp c,LevelUnder25
- ld b,a
- ld a,[wPartyMon2Level]
- cp 31
- jp nc,LevelAbove30
- cp 25
- jp c,LevelUnder25
- ld c,a
- ld a,[wPartyMon3Level]
- cp 31
- jp nc,LevelAbove30
- cp 25
- jp c,LevelUnder25
- add b
- add c
- cp 81
- jp nc,CombinedLevelsAbove80
- xor a
- ret
-
-NotThreeMonsInParty::
- ld hl,Colosseum3MonsText
- call PrintText
- ld a,$1
- ret
-
-MewInParty::
- ld hl,ColosseumMewText
- call PrintText
- ld a,$2
- ret
-
-DuplicateSpecies::
- ld hl,ColosseumDifferentMonsText
- call PrintText
- ld a,$3
- ret
-
-LevelAbove55::
- ld hl,ColosseumMaxL55Text
- call PrintText
- ld a,$4
- ret
-
-LevelUnder50::
- ld hl,ColosseumMinL50Text
- call PrintText
- ld a,$5
- ret
-
-CombinedLevelsGreaterThan155::
- ld hl,ColosseumTotalL155Text
- call PrintText
- ld a,$6
- ret
-
-LevelAbove30::
- ld hl,ColosseumMaxL30Text
- call PrintText
- ld a,$7
- ret
-
-LevelUnder25::
- ld hl,ColosseumMinL25Text
- call PrintText
- ld a,$8
- ret
-
-CombinedLevelsAbove80::
- ld hl,ColosseumTotalL80Text
- call PrintText
- ld a,$9
- ret
-
-LevelAbove20::
- ld hl,ColosseumMaxL20Text
- call PrintText
- ld a,$a
- ret
-
-LevelUnder15::
- ld hl,ColosseumMinL15Text
- call PrintText
- ld a,$b
- ret
-
-CombinedLevelsAbove50::
- ld hl,ColosseumTotalL50Text
- call PrintText
- ld a,$c
- ret
-
-asm_f5689::
- pop af
- pop bc
- pop hl
- ld [wd11e],a
- call GetMonName
- ld hl,ColosseumHeightText
- call PrintText
- ld a,$d
- ret
-
-asm_f569b::
- pop af
- pop bc
- pop hl
- ld [wd11e],a
- call GetMonName
- ld hl,ColosseumWeightText
- call PrintText
- ld a,$e
- ret
-
-asm_f56ad::
- ld a,[hl]
- ld [wd11e],a
- call GetMonName
- ld hl,ColosseumEvolvedText
- call PrintText
- ld a,$f
- ret
-
-Func_f56bd::
- xor a
- ld [H_AUTOBGTRANSFERENABLED],a
- coord hl, 1,11
- lb bc, 6, 18
- call ClearScreenArea
- ld a,[wCurrentMenuItem]
- cp $3
- jr nc,.asm_f56e6
- ld hl,PointerTable_f56ee
- ld a,[wCurrentMenuItem]
- ld c,a
- ld b,$0
- add hl,bc
- add hl,bc
- ld a,[hli]
- ld h,[hl]
- ld l,a
- ld d,h
- ld e,l
- coord hl, 1,12
- call PlaceString
-.asm_f56e6
- call Delay3
- ld a,$1
- ld [H_AUTOBGTRANSFERENABLED],a
- ret
-
-PointerTable_f56ee::
- dw Text_f56f4
- dw Text_f5728
- dw Text_f575b
-
-Text_f56f4::
- db "LVs of 3<pkmn>:50-55"
- next "Sum of LVs:155 MAX"
- next "MEW can't attend.@"
-
-Text_f5728::
- db "LVs of 3<pkmn>:15-20"
- next "Sum of LVs:50 MAX"
- next "MEW can't attend.@"
-
-Text_f575b::
- db "3 Basic <pkmn>.LV25-30"
- next "Sum of LVs:80 MAX"
- next "6′8″ and 44lb MAX@"
-
-Text_f5791::
- db "View"
- next "Rules@"
-
-Text_f579c::
- db "# Cup"
- next "Pika Cup"
- next "Petit Cup"
- next "CANCEL@"
-
-Colosseum3MonsText::
- TX_FAR _Colosseum3MonsText
- db "@"
-
-ColosseumMewText::
- TX_FAR _ColosseumMewText
- db "@"
-
-ColosseumDifferentMonsText::
- TX_FAR _ColosseumDifferentMonsText
- db "@"
-
-ColosseumMaxL55Text::
- TX_FAR _ColosseumMaxL55Text
- db "@"
-
-ColosseumMinL50Text::
- TX_FAR _ColosseumMinL50Text
- db "@"
-
-ColosseumTotalL155Text::
- TX_FAR _ColosseumTotalL155Text
- db "@"
-
-ColosseumMaxL30Text::
- TX_FAR _ColosseumMaxL30Text
- db "@"
-
-ColosseumMinL25Text::
- TX_FAR _ColosseumMinL25Text
- db "@"
-
-ColosseumTotalL80Text::
- TX_FAR _ColosseumTotalL80Text
- db "@"
-
-ColosseumMaxL20Text::
- TX_FAR _ColosseumMaxL20Text
- db "@"
-
-ColosseumMinL15Text::
- TX_FAR _ColosseumMinL15Text
- db "@"
-
-ColosseumTotalL50Text::
- TX_FAR _ColosseumTotalL50Text
- db "@"
-
-ColosseumHeightText::
- TX_FAR _ColosseumHeightText
- db "@"
-
-ColosseumWeightText::
- TX_FAR _ColosseumWeightText
- db "@"
-
-ColosseumEvolvedText::
- TX_FAR _ColosseumEvolvedText
- db "@"
-
-ColosseumIneligibleText::
- TX_FAR _ColosseumIneligibleText
- db "@"
-
-LinkMenu:
- xor a
- ld [wLetterPrintingDelayFlags], a
- ld hl, wd72e
- set 6, [hl]
- ld hl, TextTerminator_f5a16
- call PrintText
- call SaveScreenTilesToBuffer1
- ld hl, ColosseumWhereToText
- call PrintText
- coord hl, 5, 3
- lb bc, 8, 13
- call TextBoxBorder
- call UpdateSprites
- coord hl, 7, 5
- ld de, TradeCenterText
- call PlaceString
- xor a
- ld [wUnusedCD37], a
- ld [wd72d], a
- ld [wd11e], a
- ld hl, wTopMenuItemY
- ld a, $5
- ld [hli], a
- ld a, $6
- ld [hli], a
- xor a
- ld [hli], a
- inc hl
- ld a, $3
- ld [hli], a
- ld [hli], a
- xor a
- ld [hl], a
-.waitForInputLoop
- call HandleMenuInput
- and A_BUTTON | B_BUTTON
- add a
- add a
- ld b, a
- ld a, [wCurrentMenuItem]
- cp $3
- jr nz,.asm_f586b
- bit 2,b
- jr z,.asm_f586b
- dec a
- ld b,$8
-.asm_f586b
- 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_f5c7d
- ld a, [wLinkMenuSelectionReceiveBuffer + 1]
- ld b, a
- and $f0
- cp $d0
- jr nz, .exchangeMenuSelectionLoop
-.asm_f5c7d
- 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, $1
- ld [wd11e], a
- ld a, b
- ld [wLinkMenuSelectionSendBuffer], a
- and $3
- ld [wCurrentMenuItem], a ; wCurrentMenuItem
-.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, " "
- ld c, " "
- ld d, " "
- ld e, "▷"
- ld a, [wLinkMenuSelectionSendBuffer]
- and (B_BUTTON << 2) ; was B button pressed?
- jr nz, .updateCursorPosition
-; A button was pressed
- ld a, [wCurrentMenuItem]
- cp $2
- jp z, .asm_f5963
- ld b, e
- ld e, c
- ld a, [wCurrentMenuItem]
- and a
- jr z, .updateCursorPosition
- ld c, b
- ld b, d
- dec a
- jr z, .updateCursorPosition
- ld d, c
- ld c, b
-.updateCursorPosition
- call Func_f59ec
- 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, ColosseumPleaseWaitText
- call PrintText
- ld c, 50
- call DelayFrames
- ld hl, wd732
- res 1, [hl]
- ld a, [wDefaultMap]
- ld [wDestinationMap], a
- callab 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
- jpab SpecialEnterMap
-.choseCancel
- xor a
- ld [wMenuJoypadPollCount], a
- call Delay3
- callab CloseLinkConnection
- ld hl, ColosseumCanceledText
- call PrintText
- ld hl, wd72e
- res 6, [hl]
- ret
-
-.asm_f5963
- ld a,[wd11e]
- and a
- jr nz,.asm_f5974
- ld b," "
- ld c," "
- ld d,"▷"
- ld e," "
- call Func_f59ec
-.asm_f5974
- xor a
- ld [wBuffer], a
- ld a,$ff
- ld [wSerialExchangeNybbleReceiveData],a
- ld a, $b
- ld [wLinkMenuSelectionSendBuffer], a
- ld b,$78
-.loop
- ld a,[hSerialConnectionStatus]
- cp $2
- call z,DelayFrame
- dec b
- jr z,.asm_f59b2
- call Serial_ExchangeNybble
- call DelayFrame
- ld a,[wSerialExchangeNybbleReceiveData]
- inc a
- jr z,.loop
- ld b,$f
-.loop2
- call DelayFrame
- call Serial_ExchangeNybble
- dec b
- jr nz,.loop2
- ld b,$f
-.loop3
- call DelayFrame
- call Serial_SendZeroByte
- dec b
- jr nz,.loop3
- jr .asm_f59d6
-
-.asm_f59b2
- xor a
- ld [wUnknownSerialCounter],a
- ld [wUnknownSerialCounter+1],a
- ld a,[wd11e]
- and a
- jr z,.asm_f59cd
- ld b," "
- ld c," "
- ld d," "
- ld e,"▷"
- call Func_f59ec
- jp .choseCancel
-
-.asm_f59cd
- ld hl,ColosseumVersionText
- call PrintText
- jp .choseCancel
-
-.asm_f59d6
- ld b," "
- ld c," "
- ld d,"▷"
- ld e," "
- call Func_f59ec
- call Func_f531b
- jp c,.choseCancel
- ld a,$f0
- jp .next
-
-Func_f59ec::
- ld a, b
- Coorda 6, 5
- ld a, c
- Coorda 6, 7
- ld a, d
- Coorda 6, 9
- ld a, e
- Coorda 6, 11
- ld c, 40
- call DelayFrames
- ret
-
-ColosseumWhereToText:
- TX_FAR _ColosseumWhereToText
- db "@"
-
-ColosseumPleaseWaitText:
- TX_FAR _ColosseumPleaseWaitText
- db "@"
-
-ColosseumCanceledText:
- TX_FAR _ColosseumCanceledText
- db "@"
-
-ColosseumVersionText:
- TX_FAR _ColosseumVersionText
- db "@"
-
-TextTerminator_f5a16:
- db "@"
-
-TradeCenterText:
- db "TRADE CENTER"
- next "COLOSSEUM"
- next "COLOSSEUM2"
- next "CANCEL@"
diff --git a/engine/menu/oaks_pc.asm b/engine/menu/oaks_pc.asm
deleted file mode 100755
index 03c9b8f1..00000000
--- a/engine/menu/oaks_pc.asm
+++ /dev/null
@@ -1,28 +0,0 @@
-OpenOaksPC:
- call SaveScreenTilesToBuffer2
- ld hl, AccessedOaksPCText
- call PrintText
- ld hl, GetDexRatedText
- call PrintText
- call YesNoChoice
- ld a, [wCurrentMenuItem]
- and a
- jr nz, .closePC
- predef DisplayDexRating
-.closePC
- ld hl, ClosedOaksPCText
- call PrintText
- jp LoadScreenTilesFromBuffer2
-
-GetDexRatedText:
- TX_FAR _GetDexRatedText
- db "@"
-
-ClosedOaksPCText:
- TX_FAR _ClosedOaksPCText
- TX_WAIT
- db "@"
-
-AccessedOaksPCText:
- TX_FAR _AccessedOaksPCText
- db "@"
diff --git a/engine/menu/party_menu.asm b/engine/menu/party_menu.asm
deleted file mode 100755
index 00c757be..00000000
--- a/engine/menu/party_menu.asm
+++ /dev/null
@@ -1,333 +0,0 @@
-; [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
- ld a, [hPartyMonIndex]
- ld [wWhichPokemon], a
- callab IsThisPartymonStarterPikachu_Party
- jr nc, .regularMon
- call CheckPikachuFollowingPlayer
- jr z, .regularMon
- ld a, $ff
- ld [hPartyMonIndex], a
-.regularMon
- callba WriteMonPartySpriteOAMByPartyIndex ; place the appropriate pokemon icon
- ld a, [wWhichPokemon]
- 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_0xFFFA]
- set 0, a
- ld [hFlags_0xFFFA], a
- add hl, bc
- predef DrawHP2 ; draw HP bar and prints current / max HP
- ld a, [hFlags_0xFFFA]
- res 0, a
- ld [hFlags_0xFFFA], 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
- push hl
- ld bc, 20 + 9 ; down 1 row and right 9 columns
- 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
- pop hl
- push hl
- ld bc, 20 + 9 ; down 1 row and right 9 columns
- 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/engine/menu/text_box.asm b/engine/menu/text_box.asm
deleted file mode 100644
index a109bff2..00000000
--- a/engine/menu/text_box.asm
+++ /dev/null
@@ -1,739 +0,0 @@
-; 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
- lb bc, 1, 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
- xor a
- ld [wTwoOptionMenuID], a
- ld hl, wd730
- res 6, [hl] ; turn on the printing delay
- 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
- lb bc, 5, 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/engine/menus/display_text_id_init.asm b/engine/menus/display_text_id_init.asm
new file mode 100644
index 00000000..17f290b4
--- /dev/null
+++ b/engine/menus/display_text_id_init.asm
@@ -0,0 +1,76 @@
+; function that performs initialization for DisplayTextID
+DisplayTextIDInit::
+ xor a
+ ld [wListMenuID], a
+ ld a, [wAutoTextBoxDrawingControl]
+ bit 0, a
+ jr nz, .skipDrawingTextBoxBorder
+ ldh a, [hSpriteIndexOrTextID] ; text ID (or sprite ID)
+ and a
+ jr nz, .notStartMenu
+; if text ID is 0 (i.e. the start menu)
+; Note that the start menu text border is also drawn in the function directly
+; below this, so this seems unnecessary.
+ CheckEvent EVENT_GOT_POKEDEX
+; start menu with pokedex
+ hlcoord 10, 0
+ lb bc, 14, 8
+ jr nz, .drawTextBoxBorder
+; start menu without pokedex
+ hlcoord 10, 0
+ lb bc, 12, 8
+ jr .drawTextBoxBorder
+; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box
+.notStartMenu
+ hlcoord 0, 12
+ lb bc, 4, 18
+.drawTextBoxBorder
+ call TextBoxBorder
+.skipDrawingTextBoxBorder
+ ld hl, wFontLoaded
+ set 0, [hl]
+ ld hl, wFlags_0xcd60
+ bit 4, [hl]
+ res 4, [hl]
+ jr nz, .skipMovingSprites
+ call UpdateSprites
+.skipMovingSprites
+; loop to copy [x#SPRITESTATEDATA1_FACINGDIRECTION] to
+; [x#SPRITESTATEDATA2_ORIGFACINGDIRECTION] for each non-player sprite
+; this is done because when you talk to an NPC, they turn to look your way
+; the original direction they were facing must be restored after the dialogue is over
+ ld hl, wSprite01StateData1FacingDirection
+ ld c, $0f
+ ld de, $10
+.spriteFacingDirectionCopyLoop
+ ld a, [hl] ; x#SPRITESTATEDATA1_FACINGDIRECTION
+ inc h
+ ld [hl], a ; [x#SPRITESTATEDATA2_ORIGFACINGDIRECTION]
+ dec h
+ add hl, de
+ dec c
+ jr nz, .spriteFacingDirectionCopyLoop
+; loop to force all the sprites in the middle of animation to stand still
+; (so that they don't like they're frozen mid-step during the dialogue)
+ ld hl, wSpritePlayerStateData1ImageIndex
+ ld de, $10
+ ld c, e
+.spriteStandStillLoop
+ ld a, [hl]
+ cp $ff ; is the sprite visible?
+ jr z, .nextSprite
+; if it is visible
+ and $fc
+ ld [hl], a
+.nextSprite
+ add hl, de
+ dec c
+ jr nz, .spriteStandStillLoop
+ ld b, $9c ; window background address
+ call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM
+ xor a
+ ldh [hWY], a ; put the window on the screen
+ call LoadFontTilePatterns
+ ld a, $01
+ ldh [hAutoBGTransferEnabled], a ; enable continuous WRAM to VRAM transfer each V-blank
+ ret
diff --git a/engine/menu/draw_badges.asm b/engine/menus/draw_badges.asm
index 9e6262a0..0bb433cc 100644
--- a/engine/menu/draw_badges.asm
+++ b/engine/menus/draw_badges.asm
@@ -8,12 +8,12 @@ DrawBadges:
; Tile ids for face/badge graphics.
ld de, wBadgeOrFaceTiles
ld hl, .FaceBadgeTiles
- ld bc, 8
+ ld bc, NUM_BADGES
call CopyData
; Booleans for each badge.
ld hl, wTempObtainedBadgesBooleans
- ld bc, 8
+ ld bc, NUM_BADGES
xor a
call FillMemory
@@ -22,7 +22,7 @@ DrawBadges:
ld hl, wBadgeOrFaceTiles
ld a, [wObtainedBadges]
ld b, a
- ld c, 8
+ ld c, NUM_BADGES
.CheckBadge
srl b
jr nc, .NextBadge
@@ -43,11 +43,11 @@ DrawBadges:
ld [hli], a
ld [hl], $60 ; First name
- coord hl, 2, 11
+ hlcoord 2, 11
ld de, wTempObtainedBadgesBooleans
call .DrawBadgeRow
- coord hl, 2, 14
+ hlcoord 2, 14
ld de, wTempObtainedBadgesBooleans + 4
; call .DrawBadgeRow
; ret
@@ -92,7 +92,7 @@ DrawBadges:
push bc
ld hl, wBadgeOrFaceTiles + 1
ld de, wBadgeOrFaceTiles
- ld bc, 8
+ ld bc, NUM_BADGES
call CopyData
pop bc
@@ -117,4 +117,4 @@ DrawBadges:
db $20, $28, $30, $38, $40, $48, $50, $58
GymLeaderFaceAndBadgeTileGraphics:
- INCBIN "gfx/badges.2bpp"
+ INCBIN "gfx/trainer_card/badges.2bpp"
diff --git a/engine/menu/draw_start_menu.asm b/engine/menus/draw_start_menu.asm
index 632b8c3a..7ca75ecb 100644
--- a/engine/menu/draw_start_menu.asm
+++ b/engine/menus/draw_start_menu.asm
@@ -1,12 +1,12 @@
; function that displays the start menu
-DrawStartMenu:
+DrawStartMenu::
CheckEvent EVENT_GOT_POKEDEX
; menu with pokedex
- coord hl, 10, 0
+ hlcoord 10, 0
lb bc, 14, 8
- jr nz,.drawTextBoxBorder
+ jr nz, .drawTextBoxBorder
; shorter menu if the player doesn't have the pokedex
- coord hl, 10, 0
+ hlcoord 10, 0
lb bc, 12, 8
.drawTextBoxBorder
call TextBoxBorder
@@ -23,7 +23,7 @@ DrawStartMenu:
ld [wMenuWatchMovingOutOfBounds], a
ld hl, wd730
set 6, [hl] ; no pauses between printing each letter
- coord hl, 12, 2
+ hlcoord 12, 2
CheckEvent EVENT_GOT_POKEDEX
; case for not having pokedex
ld a, $06
diff --git a/engine/menu/league_pc.asm b/engine/menus/league_pc.asm
index 9946b90d..5551fd0b 100755
--- a/engine/menu/league_pc.asm
+++ b/engine/menus/league_pc.asm
@@ -6,10 +6,10 @@ PKMNLeaguePC:
push hl
ld a, [wUpdateSpritesEnabled]
push af
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld [wSpriteFlipped], a
ld [wUpdateSpritesEnabled], a
ld [wHoFTeamIndex2], a
@@ -29,7 +29,7 @@ PKMNLeaguePC:
push bc
ld a, [wHoFTeamIndex2]
ld [wHoFTeamIndex], a
- callba LoadHallOfFameTeams
+ farcall LoadHallOfFameTeams
call LeaguePCShowTeam
pop bc
jr c, .doneShowingTeams
@@ -40,7 +40,7 @@ PKMNLeaguePC:
jr nz, .loop
.doneShowingTeams
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
pop af
ld [wUpdateSpritesEnabled], a
pop hl
@@ -56,7 +56,7 @@ LeaguePCShowTeam:
push bc
call LeaguePCShowMon
call WaitForTextScrollButtonPress
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
bit 1, a
jr nz, .exit
ld hl, wHallOfFame + HOF_MON
@@ -95,25 +95,25 @@ LeaguePCShowMon:
ld b, SET_PAL_POKEMON_WHOLE_SCREEN
ld c, 0
call RunPaletteCommand
- coord hl, 12, 5
+ hlcoord 12, 5
call GetMonHeader
call LoadFrontSpriteByMonIndex
call GBPalNormal
- coord hl, 0, 13
+ hlcoord 0, 13
lb bc, 2, 18
call TextBoxBorder
- coord hl, 1, 15
+ hlcoord 1, 15
ld de, HallOfFameNoText
call PlaceString
- coord hl, 16, 15
+ hlcoord 16, 15
ld de, wHoFTeamNo
lb bc, 1, 3
call PrintNumber
- jpba Func_7033f
+ farjp Func_7033f
HallOfFameNoText:
db "HALL OF FAME No @"
AccessedHoFPCText:
- TX_FAR _AccessedHoFPCText
- db "@"
+ text_far _AccessedHoFPCText
+ text_end
diff --git a/engine/menus/link_menu.asm b/engine/menus/link_menu.asm
new file mode 100644
index 00000000..2f2db573
--- /dev/null
+++ b/engine/menus/link_menu.asm
@@ -0,0 +1,910 @@
+Func_f531b::
+ ld c, $14
+ call DelayFrames
+ ld a, $1
+ ld [wBuffer], a
+ xor a
+ ld [wUnknownSerialFlag_d499], a
+ coord hl, 0, 0
+ lb bc, 4, 5
+ call TextBoxBorder
+ ld de, Text_f5791
+ coord hl, 1, 2
+ call PlaceString
+ coord hl, 8, 0
+ lb bc, 8, 10
+ call TextBoxBorder
+ coord hl, 10, 2
+ ld de, Text_f579c
+ call PlaceString
+ coord hl, 0, 10
+ lb bc, 6, 18
+ call TextBoxBorder
+ call UpdateSprites
+ xor a
+ ld [wUnusedCD37], a
+ ld [wd72d], a
+ ld [wd11e], a
+ ld hl, wTopMenuItemY
+ ld a, $2
+ ld [hli], a
+ ld a, $9
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $3
+ ld [hli], a
+ ld a, $3
+ ld [hli], a
+ xor a
+ ld [hl], a
+.asm_f5377
+ call Func_f56bd
+ call HandleMenuInput
+ and $3
+ add a
+ add a
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp $3
+ jr nz, .asm_f5390
+ bit 2, b
+ jr z, .asm_f5390
+ dec a
+ ld b, $8
+.asm_f5390
+ add b
+ add $c0
+ ld [wLinkMenuSelectionSendBuffer], a
+ ld [wLinkMenuSelectionSendBuffer+1], a
+.asm_f5399
+ ld hl, wLinkMenuSelectionSendBuffer
+ ld a, [hl]
+ ldh [hSerialSendData], a
+ call Serial_ExchangeByte
+ push af
+ ld hl, wLinkMenuSelectionSendBuffer
+ ld a, [hl]
+ ldh [hSerialSendData], a
+ call Serial_ExchangeByte
+ pop bc
+ cp b
+ jr nz, .asm_f5399
+ and $f0
+ cp $c0
+ jr nz, .asm_f5399
+ ld a, b
+ and $c
+ jr nz, .asm_f53c4
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and $c
+ jr z, .asm_f5377
+ jr .asm_f53df
+.asm_f53c4
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and $c
+ jr z, .asm_f53d1
+ ldh a, [hSerialConnectionStatus]
+ cp $2
+ jr z, .asm_f53df
+.asm_f53d1
+ ld a, $1
+ ld [wd11e], a
+ ld a, b
+ ld [wLinkMenuSelectionSendBuffer], a
+ and $3
+ ld [wCurrentMenuItem], a
+.asm_f53df
+ call DelayFrame
+ call DelayFrame
+ ld hl, wLinkMenuSelectionSendBuffer
+ ld a, [hl]
+ ldh [hSerialSendData], a
+ call Serial_ExchangeByte
+ call Serial_ExchangeByte
+ ld b, $14
+.loop
+ call DelayFrame
+ call Serial_SendZeroByte
+ dec b
+ jr nz, .loop
+ ld b, " "
+ ld c, " "
+ ld d, " "
+ ld e, "▷"
+ ld a, [wLinkMenuSelectionSendBuffer]
+ bit 3, a
+ jr nz, .asm_f541a
+ ld b, e
+ ld e, c
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .asm_f541a
+ ld c, b
+ ld b, d
+ dec a
+ jr z, .asm_f541a
+ ld d, c
+ ld c, b
+.asm_f541a
+ ld a, b
+ ldcoord_a 9, 2
+ ld a, c
+ ldcoord_a 9, 4
+ ld a, d
+ ldcoord_a 9, 6
+ ld a, e
+ ldcoord_a 9, 8
+ ld c, 40
+ call DelayFrames
+ ld a, [wLinkMenuSelectionSendBuffer]
+ bit 3, a
+ jr nz, asm_f547f
+ ld a, [wCurrentMenuItem]
+ cp $3
+ jr z, asm_f547f
+ inc a
+ ld [wUnknownSerialFlag_d499], a
+ ld a, [wCurrentMenuItem]
+ ld hl, PointerTable_f5488
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .returnaddress
+ push de
+ jp hl
+.returnaddress
+ ld [wLinkMenuSelectionSendBuffer], a
+ xor a
+ ld [wUnknownSerialCounter], a
+ ld [wUnknownSerialCounter+1], a
+ call Serial_SyncAndExchangeNybble
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and a
+ jr nz, asm_f547c
+ ld a, [wLinkMenuSelectionReceiveBuffer]
+ and a
+ jr nz, Func_f5476
+ xor a
+ ld [wUnknownSerialCounter], a
+ ld [wUnknownSerialCounter+1], a
+ and a
+ ret
+
+Func_f5476::
+ ld hl, ColosseumIneligibleText
+ call PrintText
+asm_f547c::
+ jp Func_f531b
+
+asm_f547f::
+ xor a
+ ld [wUnknownSerialCounter], a
+ ld [wUnknownSerialCounter+1], a
+ scf
+ ret
+
+PointerTable_f5488::
+ dw PokeCup
+ dw PikaCup
+ dw PetitCup
+
+PokeCup::
+ ld hl, wPartyCount
+ ld a, [hli]
+ cp $3
+ jp nz, NotThreeMonsInParty
+ ld b, $3
+.loop
+ ld a, [hli]
+ cp MEW
+ jp z, MewInParty
+ dec b
+ jr nz, .loop
+ dec hl
+ dec hl
+ cp [hl] ; is third mon second mon?
+ jp z, DuplicateSpecies
+ dec hl ; wPartySpecies
+ cp [hl] ; is third mon first mon?
+ jp z, DuplicateSpecies
+ ld a, [hli]
+ cp [hl] ; is first mon second mon?
+ jp z, DuplicateSpecies
+ ld a, [wPartyMon1Level]
+ cp 56
+ jp nc, LevelAbove55
+ cp 50
+ jp c, LevelUnder50
+ ld b, a
+ ld a, [wPartyMon2Level]
+ cp 56
+ jp nc, LevelAbove55
+ cp 50
+ jp c, LevelUnder50
+ ld c, a
+ ld a, [wPartyMon3Level]
+ cp 56
+ jp nc, LevelAbove55
+ cp 50
+ jp c, LevelUnder50
+ add b
+ add c
+ cp 156
+ jp nc, CombinedLevelsGreaterThan155
+ xor a
+ ret
+
+PikaCup::
+ ld hl, wPartyCount
+ ld a, [hli]
+ cp $3
+ jp nz, NotThreeMonsInParty
+ ld b, $3
+.loop
+ ld a, [hli] ; wPartySpecies
+ cp MEW
+ jp z, MewInParty
+ dec b
+ jr nz, .loop
+ dec hl
+ dec hl
+ cp [hl] ; is third mon second mon?
+ jp z, DuplicateSpecies
+ dec hl ; wPartySpecies
+ cp [hl] ; is third mon first mon?
+ jp z, DuplicateSpecies
+ ld a, [hli]
+ cp [hl] ; is first mon second mon?
+ jp z, DuplicateSpecies
+ ld a, [wPartyMon1Level]
+ cp 21
+ jp nc, LevelAbove20
+ cp 15
+ jp c, LevelUnder15
+ ld b, a
+ ld a, [wPartyMon2Level]
+ cp 21
+ jp nc, LevelAbove20
+ cp 15
+ jp c, LevelUnder15
+ ld c, a
+ ld a, [wPartyMon3Level]
+ cp 21
+ jp nc, LevelAbove20
+ cp 15
+ jp c, LevelUnder15
+ add b
+ add c
+ cp 51
+ jp nc, CombinedLevelsAbove50
+ xor a
+ ret
+
+PetitCup::
+ ld hl, wPartyCount
+ ld a, [hli]
+ cp $3
+ jp nz, NotThreeMonsInParty
+ ld b, $3
+.loop
+ ld a, [hli]
+ cp MEW
+ jp z, MewInParty
+ dec b
+ jr nz, .loop
+ dec hl
+ dec hl
+ cp [hl] ; is third mon second mon?
+ jp z, DuplicateSpecies
+ dec hl ; wPartySpecies
+ cp [hl] ; is third mon first mon?
+ jp z, DuplicateSpecies
+ ld a, [hli]
+ cp [hl] ; is first mon second mon?
+ jp z, DuplicateSpecies
+ dec hl
+ ld a, [hl]
+ ld [wcf91], a
+ push hl
+ callfar Func_3b10f
+ pop hl
+ jp c, asm_f56ad
+ inc hl
+ ld a, [hl]
+ ld [wcf91], a
+ push hl
+ callfar Func_3b10f
+ pop hl
+ jp c, asm_f56ad
+ inc hl
+ ld a, [hl]
+ ld [wcf91], a
+ push hl
+ callfar Func_3b10f
+ pop hl
+ jp c, asm_f56ad
+ dec hl
+ dec hl
+ ld b, $3
+.bigloop
+ ld a, [hli]
+ push hl
+ push bc
+ push af
+ dec a
+ ld c, a
+ ld b, $0
+ ld hl, PokedexEntryPointers
+ add hl, bc
+ add hl, bc
+ ld de, wcd6d
+ ld bc, $2
+ ld a, BANK(PokedexEntryPointers)
+ call FarCopyData
+ ld hl, wcd6d
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wcd6d
+ ld bc, $14
+ ld a, BANK(PokedexEntryPointers)
+ call FarCopyData
+ ld hl, wcd6d
+.loop2
+ ld a, [hli]
+ cp "@"
+ jr nz, .loop2
+ ld a, [hli]
+ cp $7
+ jp nc, asm_f5689
+ add a
+ add a
+ ld b, a
+ add a
+ add b
+ ld b, a
+ ld a, [hli]
+ add b
+ cp $51
+ jp nc, asm_f5689
+ ld a, [hli]
+ sub $b9
+ ld a, [hl]
+ sbc $1
+ jp nc, asm_f569b
+ pop af
+ pop bc
+ pop hl
+ dec b
+ jr nz, .bigloop
+ ld a, [wPartyMon1Level]
+ cp 31
+ jp nc, LevelAbove30
+ cp 25
+ jp c, LevelUnder25
+ ld b, a
+ ld a, [wPartyMon2Level]
+ cp 31
+ jp nc, LevelAbove30
+ cp 25
+ jp c, LevelUnder25
+ ld c, a
+ ld a, [wPartyMon3Level]
+ cp 31
+ jp nc, LevelAbove30
+ cp 25
+ jp c, LevelUnder25
+ add b
+ add c
+ cp 81
+ jp nc, CombinedLevelsAbove80
+ xor a
+ ret
+
+NotThreeMonsInParty::
+ ld hl, Colosseum3MonsText
+ call PrintText
+ ld a, $1
+ ret
+
+MewInParty::
+ ld hl, ColosseumMewText
+ call PrintText
+ ld a, $2
+ ret
+
+DuplicateSpecies::
+ ld hl, ColosseumDifferentMonsText
+ call PrintText
+ ld a, $3
+ ret
+
+LevelAbove55::
+ ld hl, ColosseumMaxL55Text
+ call PrintText
+ ld a, $4
+ ret
+
+LevelUnder50::
+ ld hl, ColosseumMinL50Text
+ call PrintText
+ ld a, $5
+ ret
+
+CombinedLevelsGreaterThan155::
+ ld hl, ColosseumTotalL155Text
+ call PrintText
+ ld a, $6
+ ret
+
+LevelAbove30::
+ ld hl, ColosseumMaxL30Text
+ call PrintText
+ ld a, $7
+ ret
+
+LevelUnder25::
+ ld hl, ColosseumMinL25Text
+ call PrintText
+ ld a, $8
+ ret
+
+CombinedLevelsAbove80::
+ ld hl, ColosseumTotalL80Text
+ call PrintText
+ ld a, $9
+ ret
+
+LevelAbove20::
+ ld hl, ColosseumMaxL20Text
+ call PrintText
+ ld a, $a
+ ret
+
+LevelUnder15::
+ ld hl, ColosseumMinL15Text
+ call PrintText
+ ld a, $b
+ ret
+
+CombinedLevelsAbove50::
+ ld hl, ColosseumTotalL50Text
+ call PrintText
+ ld a, $c
+ ret
+
+asm_f5689::
+ pop af
+ pop bc
+ pop hl
+ ld [wd11e], a
+ call GetMonName
+ ld hl, ColosseumHeightText
+ call PrintText
+ ld a, $d
+ ret
+
+asm_f569b::
+ pop af
+ pop bc
+ pop hl
+ ld [wd11e], a
+ call GetMonName
+ ld hl, ColosseumWeightText
+ call PrintText
+ ld a, $e
+ ret
+
+asm_f56ad::
+ ld a, [hl]
+ ld [wd11e], a
+ call GetMonName
+ ld hl, ColosseumEvolvedText
+ call PrintText
+ ld a, $f
+ ret
+
+Func_f56bd::
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ coord hl, 1, 11
+ lb bc, 6, 18
+ call ClearScreenArea
+ ld a, [wCurrentMenuItem]
+ cp $3
+ jr nc, .asm_f56e6
+ ld hl, PointerTable_f56ee
+ ld a, [wCurrentMenuItem]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld d, h
+ ld e, l
+ coord hl, 1, 12
+ call PlaceString
+.asm_f56e6
+ call Delay3
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+PointerTable_f56ee::
+ dw Text_f56f4
+ dw Text_f5728
+ dw Text_f575b
+
+Text_f56f4::
+ db "LVs of 3<PKMN>:50-55"
+ next "Sum of LVs:155 MAX"
+ next "MEW can't attend.@"
+
+Text_f5728::
+ db "LVs of 3<PKMN>:15-20"
+ next "Sum of LVs:50 MAX"
+ next "MEW can't attend.@"
+
+Text_f575b::
+ db "3 Basic <PKMN>.LV25-30"
+ next "Sum of LVs:80 MAX"
+ next "6’8” and 44lb MAX@"
+
+Text_f5791::
+ db "View"
+ next "Rules@"
+
+Text_f579c::
+ db "# Cup"
+ next "Pika Cup"
+ next "Petit Cup"
+ next "CANCEL@"
+
+Colosseum3MonsText::
+ text_far _Colosseum3MonsText
+ text_end
+
+ColosseumMewText::
+ text_far _ColosseumMewText
+ text_end
+
+ColosseumDifferentMonsText::
+ text_far _ColosseumDifferentMonsText
+ text_end
+
+ColosseumMaxL55Text::
+ text_far _ColosseumMaxL55Text
+ text_end
+
+ColosseumMinL50Text::
+ text_far _ColosseumMinL50Text
+ text_end
+
+ColosseumTotalL155Text::
+ text_far _ColosseumTotalL155Text
+ text_end
+
+ColosseumMaxL30Text::
+ text_far _ColosseumMaxL30Text
+ text_end
+
+ColosseumMinL25Text::
+ text_far _ColosseumMinL25Text
+ text_end
+
+ColosseumTotalL80Text::
+ text_far _ColosseumTotalL80Text
+ text_end
+
+ColosseumMaxL20Text::
+ text_far _ColosseumMaxL20Text
+ text_end
+
+ColosseumMinL15Text::
+ text_far _ColosseumMinL15Text
+ text_end
+
+ColosseumTotalL50Text::
+ text_far _ColosseumTotalL50Text
+ text_end
+
+ColosseumHeightText::
+ text_far _ColosseumHeightText
+ text_end
+
+ColosseumWeightText::
+ text_far _ColosseumWeightText
+ text_end
+
+ColosseumEvolvedText::
+ text_far _ColosseumEvolvedText
+ text_end
+
+ColosseumIneligibleText::
+ text_far _ColosseumIneligibleText
+ text_end
+
+LinkMenu:
+ xor a
+ ld [wLetterPrintingDelayFlags], a
+ ld hl, wd72e
+ set 6, [hl]
+ ld hl, TextTerminator_f5a16
+ call PrintText
+ call SaveScreenTilesToBuffer1
+ ld hl, ColosseumWhereToText
+ call PrintText
+ hlcoord 5, 3
+ lb bc, 8, 13
+ call TextBoxBorder
+ call UpdateSprites
+ hlcoord 7, 5
+ ld de, TradeCenterText
+ call PlaceString
+ xor a
+ ld [wUnusedCD37], a
+ ld [wd72d], a
+ ld [wd11e], a
+ ld hl, wTopMenuItemY
+ ld a, $5
+ ld [hli], a
+ ld a, $6
+ ld [hli], a
+ xor a
+ ld [hli], a
+ inc hl
+ ld a, $3
+ ld [hli], a
+ ld [hli], a
+ xor a
+ ld [hl], a
+.waitForInputLoop
+ call HandleMenuInput
+ and A_BUTTON | B_BUTTON
+ add a
+ add a
+ ld b, a
+ ld a, [wCurrentMenuItem]
+ cp $3
+ jr nz, .asm_f586b
+ bit 2, b
+ jr z, .asm_f586b
+ dec a
+ ld b, $8
+.asm_f586b
+ 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_f5c7d
+ ld a, [wLinkMenuSelectionReceiveBuffer + 1]
+ ld b, a
+ and $f0
+ cp $d0
+ jr nz, .exchangeMenuSelectionLoop
+.asm_f5c7d
+ 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.
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .doneChoosingMenuSelection
+.useEnemyMenuSelection
+ ld a, $1
+ ld [wd11e], a
+ ld a, b
+ ld [wLinkMenuSelectionSendBuffer], a
+ and $3
+ ld [wCurrentMenuItem], a ; wCurrentMenuItem
+.doneChoosingMenuSelection
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr nz, .skipStartingTransfer
+ call DelayFrame
+ call DelayFrame
+ ld a, START_TRANSFER_INTERNAL_CLOCK
+ ldh [rSC], a
+.skipStartingTransfer
+ ld b, " "
+ ld c, " "
+ ld d, " "
+ ld e, "▷"
+ ld a, [wLinkMenuSelectionSendBuffer]
+ and (B_BUTTON << 2) ; was B button pressed?
+ jr nz, .updateCursorPosition
+; A button was pressed
+ ld a, [wCurrentMenuItem]
+ cp $2
+ jp z, .asm_f5963
+ ld b, e
+ ld e, c
+ ld a, [wCurrentMenuItem]
+ and a
+ jr z, .updateCursorPosition
+ ld c, b
+ ld b, d
+ dec a
+ jr z, .updateCursorPosition
+ ld d, c
+ ld c, b
+.updateCursorPosition
+ call Func_f59ec
+ 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, ColosseumPleaseWaitText
+ call PrintText
+ ld c, 50
+ call DelayFrames
+ ld hl, wd732
+ res 1, [hl]
+ ld a, [wDefaultMap]
+ ld [wDestinationMap], a
+ callfar 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
+ jpfar SpecialEnterMap
+.choseCancel
+ xor a
+ ld [wMenuJoypadPollCount], a
+ call Delay3
+ callfar CloseLinkConnection
+ ld hl, ColosseumCanceledText
+ call PrintText
+ ld hl, wd72e
+ res 6, [hl]
+ ret
+
+.asm_f5963
+ ld a, [wd11e]
+ and a
+ jr nz, .asm_f5974
+ ld b, " "
+ ld c, " "
+ ld d, "▷"
+ ld e, " "
+ call Func_f59ec
+.asm_f5974
+ xor a
+ ld [wBuffer], a
+ ld a, $ff
+ ld [wSerialExchangeNybbleReceiveData], a
+ ld a, $b
+ ld [wLinkMenuSelectionSendBuffer], a
+ ld b, $78
+.loop
+ ldh a, [hSerialConnectionStatus]
+ cp $2
+ call z, DelayFrame
+ dec b
+ jr z, .asm_f59b2
+ call Serial_ExchangeNybble
+ call DelayFrame
+ ld a, [wSerialExchangeNybbleReceiveData]
+ inc a
+ jr z, .loop
+ ld b, $f
+.loop2
+ call DelayFrame
+ call Serial_ExchangeNybble
+ dec b
+ jr nz, .loop2
+ ld b, $f
+.loop3
+ call DelayFrame
+ call Serial_SendZeroByte
+ dec b
+ jr nz, .loop3
+ jr .asm_f59d6
+
+.asm_f59b2
+ xor a
+ ld [wUnknownSerialCounter], a
+ ld [wUnknownSerialCounter+1], a
+ ld a, [wd11e]
+ and a
+ jr z, .asm_f59cd
+ ld b, " "
+ ld c, " "
+ ld d, " "
+ ld e, "▷"
+ call Func_f59ec
+ jp .choseCancel
+
+.asm_f59cd
+ ld hl, ColosseumVersionText
+ call PrintText
+ jp .choseCancel
+
+.asm_f59d6
+ ld b, " "
+ ld c, " "
+ ld d, "▷"
+ ld e, " "
+ call Func_f59ec
+ call Func_f531b
+ jp c, .choseCancel
+ ld a, $f0
+ jp .next
+
+Func_f59ec::
+ ld a, b
+ ldcoord_a 6, 5
+ ld a, c
+ ldcoord_a 6, 7
+ ld a, d
+ ldcoord_a 6, 9
+ ld a, e
+ ldcoord_a 6, 11
+ ld c, 40
+ call DelayFrames
+ ret
+
+ColosseumWhereToText:
+ text_far _ColosseumWhereToText
+ text_end
+
+ColosseumPleaseWaitText:
+ text_far _ColosseumPleaseWaitText
+ text_end
+
+ColosseumCanceledText:
+ text_far _ColosseumCanceledText
+ text_end
+
+ColosseumVersionText:
+ text_far _ColosseumVersionText
+ text_end
+
+TextTerminator_f5a16:
+ text_end
+
+TradeCenterText:
+ db "TRADE CENTER"
+ next "COLOSSEUM"
+ next "COLOSSEUM2"
+ next "CANCEL@"
diff --git a/engine/menu/main_menu.asm b/engine/menus/main_menu.asm
index ce27ebba..7d81d2f6 100755
--- a/engine/menu/main_menu.asm
+++ b/engine/menus/main_menu.asm
@@ -33,18 +33,18 @@ MainMenu:
cp 1
jr z, .noSaveFile
; there's a save file
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 6, 13
call TextBoxBorder
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, ContinueText
call PlaceString
jr .next2
.noSaveFile
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 4, 13
call TextBoxBorder
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, NewGameText
call PlaceString
.next2
@@ -92,11 +92,11 @@ MainMenu:
set 5, [hl]
.inputLoop
xor a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
- ld [hJoyHeld], a
+ ldh [hJoyPressed], a
+ ldh [hJoyReleased], a
+ ldh [hJoyHeld], a
call Joypad
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
bit 0, a
jr nz, .pressedA
bit 1, a
@@ -141,12 +141,13 @@ Func_5cc1:
ret
NotEnoughMemoryText:
- TX_FAR _NotEnoughMemoryText
- db "@"
+ text_far _NotEnoughMemoryText
+ text_end
StartNewGame:
ld hl, wd732
res 1, [hl]
+StartNewGameDebug:
call OakSpeech
ld a, $8
ld [wPlayerMovingDirection], a
@@ -154,11 +155,11 @@ StartNewGame:
call DelayFrames
; enter map after using a special warp or loading the game from the main menu
-SpecialEnterMap:
+SpecialEnterMap::
xor a
- ld [hJoyPressed], a
- ld [hJoyHeld], a
- ld [hJoy5], a
+ ldh [hJoyPressed], a
+ ldh [hJoyHeld], a
+ ldh [hJoy5], a
ld [wd72d], a
ld hl, wd732
set 0, [hl] ; count play time
@@ -172,7 +173,9 @@ SpecialEnterMap:
jp EnterMap
ContinueText:
- db "CONTINUE", $4e
+ db "CONTINUE"
+ next ""
+ ; fallthrough
NewGameText:
db "NEW GAME"
@@ -180,49 +183,49 @@ NewGameText:
DisplayContinueGameInfo:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 4, 7
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 4, 7
lb bc, 8, 14
call TextBoxBorder
- coord hl, 5, 9
+ hlcoord 5, 9
ld de, SaveScreenInfoText
call PlaceString
- coord hl, 12, 9
+ hlcoord 12, 9
ld de, wPlayerName
call PlaceString
- coord hl, 17, 11
+ hlcoord 17, 11
call PrintNumBadges
- coord hl, 16, 13
+ hlcoord 16, 13
call PrintNumOwnedMons
- coord hl, 13, 15
+ hlcoord 13, 15
call PrintPlayTime
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld c, 30
jp DelayFrames
PrintSaveScreenText:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 4, 0
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 4, 0
lb bc, 8, 14
call TextBoxBorder
call LoadTextBoxTilePatterns
call UpdateSprites
- coord hl, 5, 2
+ hlcoord 5, 2
ld de, SaveScreenInfoText
call PlaceString
- coord hl, 12, 2
+ hlcoord 12, 2
ld de, wPlayerName
call PlaceString
- coord hl, 17, 4
+ hlcoord 17, 4
call PrintNumBadges
- coord hl, 16, 6
+ hlcoord 16, 6
call PrintNumOwnedMons
- coord hl, 13, 8
+ hlcoord 13, 8
call PrintPlayTime
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld c, 30
jp DelayFrames
@@ -263,7 +266,7 @@ SaveScreenInfoText:
next "TIME@"
DisplayOptionMenu:
- callab DisplayOptionMenu_
+ callfar DisplayOptionMenu_
ret
CheckForPlayerNameInSRAM:
diff --git a/engine/menu/naming_screen.asm b/engine/menus/naming_screen.asm
index 2560677a..553c47d0 100755
--- a/engine/menu/naming_screen.asm
+++ b/engine/menus/naming_screen.asm
@@ -4,7 +4,7 @@ AskName:
push hl
ld a, [wIsInBattle]
dec a
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 4, 11
call z, ClearScreenArea ; only if in wild battle
ld a, [wcf91]
@@ -12,7 +12,7 @@ AskName:
call GetMonName
ld hl, DoYouWantToNicknameText
call PrintText
- coord hl, 14, 7
+ hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -49,10 +49,10 @@ AskName:
jp CopyData
DoYouWantToNicknameText:
- TX_FAR _DoYouWantToNicknameText
- db "@"
+ text_far _DoYouWantToNicknameText
+ text_end
-DisplayNameRaterScreen:
+DisplayNameRaterScreen::
ld hl, wBuffer
xor a
ld [wUpdateSpritesEnabled], a
@@ -91,8 +91,8 @@ DisplayNamingScreen:
call RunPaletteCommand
call LoadHpBarAndStatusTilePatterns
call LoadEDTile
- callba LoadMonPartySpriteGfx
- coord hl, 0, 4
+ farcall LoadMonPartySpriteGfx
+ hlcoord 0, 4
lb bc, 9, 18
call TextBoxBorder
call PrintNamingText
@@ -126,11 +126,11 @@ DisplayNamingScreen:
.inputLoop
ld a, [wCurrentMenuItem]
push af
- callba AnimatePartyMon_ForceSpeed1
+ farcall AnimatePartyMon_ForceSpeed1
pop af
ld [wCurrentMenuItem], a
call JoypadLowSensitivity
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and a
jr z, .inputLoop
ld hl, .namingScreenButtonFunctions
@@ -170,7 +170,7 @@ DisplayNamingScreen:
ld a, [wIsInBattle]
and a
jp z, LoadTextBoxTilePatterns
- jpab LoadHudTilePatterns
+ jpfar LoadHudTilePatterns
.namingScreenButtonFunctions
dw .dPadReturnPoint
@@ -229,10 +229,10 @@ DisplayNamingScreen:
ld [wNamingScreenLetter], a
call CalcStringLength
ld a, [wNamingScreenLetter]
- cp $e5
+ cp "゙"
ld de, Dakutens
jr z, .dakutensAndHandakutens
- cp $e4
+ cp "゚"
ld de, Handakutens
jr z, .dakutensAndHandakutens
ld a, [wNamingScreenType]
@@ -327,10 +327,10 @@ LoadEDTile:
; Because Yellow uses the MBC5, loading $0 into $2000 - $2fff range will load bank0 instead of bank1 and thus incorrectly load the tile
; Instead of defining the correct bank, GameFreak decided to simply copy the ED_Tile in the function during HBlank
ld de, ED_Tile
- ld hl, vFont + $700
+ ld hl, vFont tile $70
ld c, $4 ; number of copies needed
.waitForHBlankLoop
- ld a, [rSTAT]
+ ldh a, [rSTAT]
and %10 ; in HBlank?
jr nz, .waitForHBlankLoop
ld a, [de]
@@ -346,19 +346,19 @@ LoadEDTile:
ret
ED_Tile:
- INCBIN "gfx/ED_tile.1bpp"
+ INCBIN "gfx/font/ED.1bpp"
ED_TileEnd:
PrintAlphabet:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, [wAlphabetCase]
and a
ld de, LowerCaseAlphabet
jr nz, .lowercase
ld de, UpperCaseAlphabet
.lowercase
- coord hl, 2, 5
+ hlcoord 2, 5
lb bc, 5, 9 ; 5 rows, 9 columns
.outerLoop
push bc
@@ -376,26 +376,22 @@ PrintAlphabet:
jr nz, .outerLoop
call PlaceString
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
jp Delay3
-LowerCaseAlphabet:
- db "abcdefghijklmnopqrstuvwxyz ×():;[]",$e1,$e2,"-?!♂♀/⠄,¥UPPER CASE@"
-
-UpperCaseAlphabet:
- db "ABCDEFGHIJKLMNOPQRSTUVWXYZ ×():;[]",$e1,$e2,"-?!♂♀/⠄,¥lower case@"
+INCLUDE "data/text/alphabets.asm"
PrintNicknameAndUnderscores:
call CalcStringLength
ld a, c
ld [wNamingScreenNameLength], a
- coord hl, 10, 2
+ hlcoord 10, 2
lb bc, 1, 10
call ClearScreenArea
- coord hl, 10, 2
+ hlcoord 10, 2
ld de, wcf4b
call PlaceString
- coord hl, 10, 3
+ hlcoord 10, 3
ld a, [wNamingScreenType]
cp NAME_MON_SCREEN
jr nc, .pokemon1
@@ -434,7 +430,7 @@ PrintNicknameAndUnderscores:
.emptySpacesRemaining
ld c, a
ld b, $0
- coord hl, 10, 3
+ hlcoord 10, 3
add hl, bc
ld [hl], $77 ; raised underscore tile id
ret
@@ -453,21 +449,7 @@ DakutensAndHandakutens:
ld [wNamingScreenLetter], a
ret
-Dakutens:
- db "かが", "きぎ", "くぐ", "けげ", "こご"
- db "さざ", "しじ", "すず", "せぜ", "そぞ"
- db "ただ", "ちぢ", "つづ", "てで", "とど"
- db "はば", "ひび", "ふぶ", "へべ", "ほぼ"
- db "カガ", "キギ", "クグ", "ケゲ", "コゴ"
- db "サザ", "シジ", "スズ", "セゼ", "ソゾ"
- db "タダ", "チヂ", "ツヅ", "テデ", "トド"
- db "ハバ", "ヒビ", "フブ", "へべ", "ホボ"
- db $ff
-
-Handakutens:
- db "はぱ", "ひぴ", "ふぷ", "へぺ", "ほぽ"
- db "ハパ", "ヒピ", "フプ", "へぺ", "ホポ"
- db $ff
+INCLUDE "data/text/dakutens.asm"
; calculates the length of the string at wcf4b and stores it in c
CalcStringLength:
@@ -482,7 +464,7 @@ CalcStringLength:
jr .loop
PrintNamingText:
- coord hl, 0, 1
+ hlcoord 0, 1
ld a, [wNamingScreenType]
ld de, YourTextString
and a
@@ -493,16 +475,16 @@ PrintNamingText:
ld a, [wcf91]
ld [wMonPartySpriteSpecies], a
push af
- callba WriteMonPartySpriteOAMBySpecies
+ farcall WriteMonPartySpriteOAMBySpecies
pop af
ld [wd11e], a
call GetMonName
- coord hl, 4, 1
+ hlcoord 4, 1
call PlaceString
ld hl, $1
add hl, bc
- ld [hl], $c9
- coord hl, 1, 3
+ ld [hl], "の" ; leftover from Japanese version; blank tile $c9 in English
+ hlcoord 1, 3
ld de, NicknameTextString
jr .placeString
.notNickname
diff --git a/engine/menus/oaks_pc.asm b/engine/menus/oaks_pc.asm
new file mode 100755
index 00000000..7743e5df
--- /dev/null
+++ b/engine/menus/oaks_pc.asm
@@ -0,0 +1,28 @@
+OpenOaksPC:
+ call SaveScreenTilesToBuffer2
+ ld hl, AccessedOaksPCText
+ call PrintText
+ ld hl, GetDexRatedText
+ call PrintText
+ call YesNoChoice
+ ld a, [wCurrentMenuItem]
+ and a
+ jr nz, .closePC
+ predef DisplayDexRating
+.closePC
+ ld hl, ClosedOaksPCText
+ call PrintText
+ jp LoadScreenTilesFromBuffer2
+
+GetDexRatedText:
+ text_far _GetDexRatedText
+ text_end
+
+ClosedOaksPCText:
+ text_far _ClosedOaksPCText
+ text_waitbutton
+ text_end
+
+AccessedOaksPCText:
+ text_far _AccessedOaksPCText
+ text_end
diff --git a/engine/menu/options.asm b/engine/menus/options.asm
index da89ad82..110bef2a 100644
--- a/engine/menu/options.asm
+++ b/engine/menus/options.asm
@@ -2,7 +2,7 @@ DisplayOptionMenu_:
call InitOptionsMenu
.optionMenuLoop
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and START | B_BUTTON
jr nz, .exitOptionMenu
call OptionsControl
@@ -42,7 +42,7 @@ OptionMenuJumpTable:
OptionsMenu_TextSpeed:
call GetTextSpeed
- ld a, [hJoy5]
+ ldh a, [hJoy5]
bit 4, a ; right
jr nz, .pressedRight
bit 5, a
@@ -79,7 +79,7 @@ OptionsMenu_TextSpeed:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 14, 2
+ hlcoord 14, 2
call PlaceString
and a
ret
@@ -117,7 +117,7 @@ GetTextSpeed:
ret
OptionsMenu_BattleAnimations:
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and D_RIGHT | D_LEFT
jr nz, .asm_41d33
ld a, [wOptions]
@@ -137,7 +137,7 @@ OptionsMenu_BattleAnimations:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 14, 4
+ hlcoord 14, 4
call PlaceString
and a
ret
@@ -152,7 +152,7 @@ AnimationOffText:
db "OFF@"
OptionsMenu_BattleStyle:
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and D_LEFT | D_RIGHT
jr nz, .asm_41d6b
ld a, [wOptions]
@@ -173,7 +173,7 @@ OptionsMenu_BattleStyle:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 14, 6
+ hlcoord 14, 6
call PlaceString
and a
ret
@@ -192,7 +192,7 @@ OptionsMenu_SpeakerSettings:
and $30
swap a
ld c, a
- ld a, [hJoy5]
+ ldh a, [hJoy5]
bit 4, a
jr nz, .pressedRight
bit 5, a
@@ -212,7 +212,7 @@ OptionsMenu_SpeakerSettings:
swap a
ld b, a
xor a
- ld [rNR51], a
+ ldh [rNR51], a
ld a, [wOptions]
and $cf
or b
@@ -225,7 +225,7 @@ OptionsMenu_SpeakerSettings:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 8, 8
+ hlcoord 8, 8
call PlaceString
and a
ret
@@ -247,7 +247,7 @@ Earphone3SoundText:
OptionsMenu_GBPrinterBrightness:
call Func_41e7b
- ld a, [hJoy5]
+ ldh a, [hJoy5]
bit 4, a
jr nz, .pressedRight
bit 5, a
@@ -281,7 +281,7 @@ OptionsMenu_GBPrinterBrightness:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 8, 10
+ hlcoord 8, 10
call PlaceString
and a
ret
@@ -339,7 +339,7 @@ OptionsMenu_Dummy:
ret
OptionsMenu_Cancel:
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and A_BUTTON
jr nz, .pressedCancel
and a
@@ -350,7 +350,7 @@ OptionsMenu_Cancel:
OptionsControl:
ld hl, wOptionsCursorLocation
- ld a, [hJoy5]
+ ldh a, [hJoy5]
cp D_DOWN
jr z, .pressedDown
cp D_UP
@@ -389,7 +389,7 @@ OptionsControl:
ret
OptionsMenu_UpdateCursorPosition:
- coord hl, 1, 1
+ hlcoord 1, 1
ld de, SCREEN_WIDTH
ld c, 16
.loop
@@ -397,7 +397,7 @@ OptionsMenu_UpdateCursorPosition:
add hl, de
dec c
jr nz, .loop
- coord hl, 1, 2
+ hlcoord 1, 2
ld bc, SCREEN_WIDTH * 2
ld a, [wOptionsCursorLocation]
call AddNTimes
@@ -405,13 +405,13 @@ OptionsMenu_UpdateCursorPosition:
ret
InitOptionsMenu:
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, SCREEN_HEIGHT - 2, SCREEN_WIDTH - 2
call TextBoxBorder
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, AllOptionsText
call PlaceString
- coord hl, 2, 16
+ hlcoord 2, 16
ld de, OptionMenuCancelText
call PlaceString
xor a
@@ -428,7 +428,7 @@ InitOptionsMenu:
xor a
ld [wOptionsCursorLocation], a
inc a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
ret
diff --git a/engine/menus/party_menu.asm b/engine/menus/party_menu.asm
new file mode 100755
index 00000000..32f47f6a
--- /dev/null
+++ b/engine/menus/party_menu.asm
@@ -0,0 +1,314 @@
+DrawPartyMenu_::
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ call UpdateSprites
+ farcall LoadMonPartySpriteGfxWithLCDDisabled ; load pokemon icon graphics
+
+RedrawPartyMenu_::
+ ld a, [wPartyMenuTypeOrMessageID]
+ cp SWAP_MONS_PARTY_MENU
+ jp z, .printMessage
+ call ErasePartyMenuCursors
+ farcall InitPartyMenuBlkPacket
+ hlcoord 3, 0
+ ld de, wPartySpecies
+ xor a
+ ld c, a
+ ldh [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
+ ldh a, [hPartyMonIndex]
+ ld [wWhichPokemon], a
+ callfar IsThisPartymonStarterPikachu_Party
+ jr nc, .regularMon
+ call CheckPikachuFollowingPlayer
+ jr z, .regularMon
+ ld a, $ff
+ ldh [hPartyMonIndex], a
+.regularMon
+ farcall WriteMonPartySpriteOAMByPartyIndex ; place the appropriate pokemon icon
+ ld a, [wWhichPokemon]
+ inc a
+ ldh [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
+ ldh a, [hFlagsFFFA]
+ set 0, a
+ ldh [hFlagsFFFA], a
+ add hl, bc
+ predef DrawHP2 ; draw HP bar and prints current / max HP
+ ldh a, [hFlagsFFFA]
+ res 0, a
+ ldh [hFlagsFFFA], 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
+ push hl
+ ld bc, 20 + 9 ; down 1 row and right 9 columns
+ 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
+ pop hl
+ push hl
+ ld bc, 20 + 9 ; down 1 row and right 9 columns
+ 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 FIRST_PARTY_MENU_TEXT_ID
+ 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
+ ldh [hAutoBGTransferEnabled], 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:
+ text_far _PartyMenuNormalText
+ text_end
+
+PartyMenuItemUseText:
+ text_far _PartyMenuItemUseText
+ text_end
+
+PartyMenuBattleText:
+ text_far _PartyMenuBattleText
+ text_end
+
+PartyMenuUseTMText:
+ text_far _PartyMenuUseTMText
+ text_end
+
+PartyMenuSwapMonText:
+ text_far _PartyMenuSwapMonText
+ text_end
+
+PotionText:
+ text_far _PotionText
+ text_end
+
+AntidoteText:
+ text_far _AntidoteText
+ text_end
+
+ParlyzHealText:
+ text_far _ParlyzHealText
+ text_end
+
+BurnHealText:
+ text_far _BurnHealText
+ text_end
+
+IceHealText:
+ text_far _IceHealText
+ text_end
+
+AwakeningText:
+ text_far _AwakeningText
+ text_end
+
+FullHealText:
+ text_far _FullHealText
+ text_end
+
+ReviveText:
+ text_far _ReviveText
+ text_end
+
+RareCandyText:
+ text_far _RareCandyText
+ sound_get_item_1 ; probably supposed to play SFX_LEVEL_UP but the wrong music bank is loaded
+ text_promptbutton
+ text_end
+
+SetPartyMenuHPBarColor:
+ ld hl, wPartyMenuHPBarColors
+ ld a, [wWhichPartyMenuHPBar]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ call GetHealthBarColor
+ ld b, SET_PAL_PARTY_MENU_HP_BARS
+ call RunPaletteCommand
+ ld hl, wWhichPartyMenuHPBar
+ inc [hl]
+ ret
diff --git a/engine/menu/pc.asm b/engine/menus/pc.asm
index 5639bd99..4c340e7b 100755
--- a/engine/menu/pc.asm
+++ b/engine/menus/pc.asm
@@ -1,4 +1,4 @@
-ActivatePC:
+ActivatePC::
call SaveScreenTilesToBuffer2
ld a, SFX_TURN_ON_PC
call PlaySound
@@ -10,7 +10,7 @@ ActivatePC:
call LoadScreenTilesFromBuffer2
call Delay3
PCMainMenu:
- callba DisplayPCMainMenu
+ farcall DisplayPCMainMenu
ld hl, wFlags_0xcd60
set 5, [hl]
call HandleMenuInput
@@ -56,19 +56,19 @@ PCMainMenu:
call WaitForSoundToFinish
ld hl, AccessedMyPCText
call PrintText
- callba PlayerPC
+ farcall PlayerPC
jr ReloadMainMenu
OaksPC:
ld a, SFX_ENTER_PC
call PlaySound
call WaitForSoundToFinish
- callba OpenOaksPC
+ farcall OpenOaksPC
jr ReloadMainMenu
PKMNLeague:
ld a, SFX_ENTER_PC
call PlaySound
call WaitForSoundToFinish
- callba PKMNLeaguePC
+ farcall PKMNLeaguePC
jr ReloadMainMenu
BillsPC:
ld a, SFX_ENTER_PC
@@ -82,7 +82,7 @@ BillsPC:
ld hl, AccessedBillsPCText
.printText
call PrintText
- callba BillsPC_
+ farcall BillsPC_
ReloadMainMenu:
xor a
ld [wDoNotWaitForButtonPressAfterDisplayingText], a
@@ -99,28 +99,28 @@ LogOff:
ret
TurnedOnPC1Text:
- TX_FAR _TurnedOnPC1Text
- db "@"
+ text_far _TurnedOnPC1Text
+ text_end
AccessedBillsPCText:
- TX_FAR _AccessedBillsPCText
- db "@"
+ text_far _AccessedBillsPCText
+ text_end
AccessedSomeonesPCText:
- TX_FAR _AccessedSomeonesPCText
- db "@"
+ text_far _AccessedSomeonesPCText
+ text_end
AccessedMyPCText:
- TX_FAR _AccessedMyPCText
- db "@"
+ text_far _AccessedMyPCText
+ text_end
; removes one of the specified item ID [hItemToRemoveID] from bag (if existent)
-RemoveItemByID:
+RemoveItemByID::
ld hl, wBagItems
- ld a, [hItemToRemoveID]
+ ldh a, [hItemToRemoveID]
ld b, a
xor a
- ld [hItemToRemoveIndex], a
+ ldh [hItemToRemoveIndex], a
.loop
ld a, [hli]
cp -1 ; reached terminator?
@@ -128,14 +128,14 @@ RemoveItemByID:
cp b
jr z, .foundItem
inc hl
- ld a, [hItemToRemoveIndex]
+ ldh a, [hItemToRemoveIndex]
inc a
- ld [hItemToRemoveIndex], a
+ ldh [hItemToRemoveIndex], a
jr .loop
.foundItem
ld a, $1
ld [wItemQuantity], a
- ld a, [hItemToRemoveIndex]
+ ldh a, [hItemToRemoveIndex]
ld [wWhichPokemon], a
ld hl, wNumBagItems
jp RemoveItemFromInventory
diff --git a/engine/menu/players_pc.asm b/engine/menus/players_pc.asm
index 1cc02cbf..1fac030b 100755
--- a/engine/menu/players_pc.asm
+++ b/engine/menus/players_pc.asm
@@ -1,4 +1,4 @@
-PlayerPC:
+PlayerPC::
ld a, ITEM_NAME
ld [wNameListType], a
call SaveScreenTilesToBuffer1
@@ -22,11 +22,11 @@ PlayerPCMenu:
ld hl, wFlags_0xcd60
set 5, [hl]
call LoadScreenTilesFromBuffer2
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 8, 14
call TextBoxBorder
call UpdateSprites
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, PlayersPCMenuEntries
call PlaceString
ld hl, wTopMenuItemY
@@ -246,57 +246,57 @@ PlayersPCMenuEntries:
next "LOG OFF@"
TurnedOnPC2Text:
- TX_FAR _TurnedOnPC2Text
- db "@"
+ text_far _TurnedOnPC2Text
+ text_end
WhatDoYouWantText:
- TX_FAR _WhatDoYouWantText
- db "@"
+ text_far _WhatDoYouWantText
+ text_end
WhatToDepositText:
- TX_FAR _WhatToDepositText
- db "@"
+ text_far _WhatToDepositText
+ text_end
DepositHowManyText:
- TX_FAR _DepositHowManyText
- db "@"
+ text_far _DepositHowManyText
+ text_end
ItemWasStoredText:
- TX_FAR _ItemWasStoredText
- db "@"
+ text_far _ItemWasStoredText
+ text_end
NothingToDepositText:
- TX_FAR _NothingToDepositText
- db "@"
+ text_far _NothingToDepositText
+ text_end
NoRoomToStoreText:
- TX_FAR _NoRoomToStoreText
- db "@"
+ text_far _NoRoomToStoreText
+ text_end
WhatToWithdrawText:
- TX_FAR _WhatToWithdrawText
- db "@"
+ text_far _WhatToWithdrawText
+ text_end
WithdrawHowManyText:
- TX_FAR _WithdrawHowManyText
- db "@"
+ text_far _WithdrawHowManyText
+ text_end
WithdrewItemText:
- TX_FAR _WithdrewItemText
- db "@"
+ text_far _WithdrewItemText
+ text_end
NothingStoredText:
- TX_FAR _NothingStoredText
- db "@"
+ text_far _NothingStoredText
+ text_end
CantCarryMoreText:
- TX_FAR _CantCarryMoreText
- db "@"
+ text_far _CantCarryMoreText
+ text_end
WhatToTossText:
- TX_FAR _WhatToTossText
- db "@"
+ text_far _WhatToTossText
+ text_end
TossHowManyText:
- TX_FAR _TossHowManyText
- db "@"
+ text_far _TossHowManyText
+ text_end
diff --git a/engine/menu/pokedex.asm b/engine/menus/pokedex.asm
index bc2a7e9b..874fe50f 100755
--- a/engine/menu/pokedex.asm
+++ b/engine/menus/pokedex.asm
@@ -10,9 +10,9 @@ ShowPokedexMenu:
ld [wLastMenuItem], a
inc a
ld [wd11e], a
- ld [hJoy7], a
+ ldh [hJoy7], a
.setUpGraphics
- callab LoadPokedexTilePatterns
+ callfar LoadPokedexTilePatterns
.loop
ld b, SET_PAL_GENERIC
call RunPaletteCommand
@@ -36,7 +36,7 @@ ShowPokedexMenu:
ld [wMenuWatchMovingOutOfBounds], a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
- ld [hJoy7], a
+ ldh [hJoy7], a
ld [wWastedByteCD3A], a
ld [wOverrideSimulatedJoypadStatesMask], a
pop af
@@ -97,7 +97,7 @@ HandlePokedexSideMenu:
xor a
ld [hli], a ; old menu item ID
ld [wMenuWatchMovingOutOfBounds], a
- ld [hJoy7], a
+ ldh [hJoy7], a
.handleMenuInput
call HandleMenuInput
bit 1, a ; was the B button pressed?
@@ -126,9 +126,9 @@ HandlePokedexSideMenu:
pop af
ld [wCurrentMenuItem], a
ld a, $1
- ld [hJoy7], a
+ ldh [hJoy7], a
push bc
- coord hl, 0, 3
+ hlcoord 0, 3
ld de, 20
lb bc, " ", 13
call DrawTileLine ; cover up the menu cursor in the pokemon list
@@ -137,7 +137,7 @@ HandlePokedexSideMenu:
.buttonBPressed
push bc
- coord hl, 15, 8
+ hlcoord 15, 8
ld de, 20
lb bc, " ", 9
call DrawTileLine ; cover up the menu cursor in the side menu
@@ -162,18 +162,18 @@ HandlePokedexSideMenu:
jr .exitSideMenu
.chosePrint
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld a, [wd11e]
ld [wcf91], a
- callab PrintPokedexEntry
+ callfar PrintPokedexEntry
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call ClearScreen
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld b, $3
jr .exitSideMenu
@@ -257,45 +257,45 @@ HandlePokedexListMenu:
Pokedex_DrawInterface:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
; draw the horizontal line separating the seen and owned amounts from the menu
- coord hl, 15, 6
+ hlcoord 15, 6
ld a, "─"
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
- coord hl, 14, 0
+ hlcoord 14, 0
ld [hl], $71 ; vertical line tile
- coord hl, 14, 1
+ hlcoord 14, 1
call DrawPokedexVerticalLine
- coord hl, 14, 9
+ hlcoord 14, 9
call DrawPokedexVerticalLine
ld hl, wPokedexSeen
ld b, wPokedexSeenEnd - wPokedexSeen
call CountSetBits
ld de, wNumSetBits
- coord hl, 16, 2
+ hlcoord 16, 2
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, 5
+ hlcoord 16, 5
lb bc, 1, 3
call PrintNumber ; print number of owned pokemon
- coord hl, 16, 1
+ hlcoord 16, 1
ld de, PokedexSeenText
call PlaceString
- coord hl, 16, 4
+ hlcoord 16, 4
ld de, PokedexOwnText
call PlaceString
- coord hl, 1, 1
+ hlcoord 1, 1
ld de, PokedexContentsText
call PlaceString
- coord hl, 16, 8
+ hlcoord 16, 8
ld de, PokedexMenuItemsText
call PlaceString
; find the highest pokedex number among the pokemon the player has seen
@@ -347,11 +347,11 @@ PokedexMenuItemsText:
Pokedex_PlacePokemonList:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 4, 2
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 4, 2
lb bc, 14, 10
call ClearScreenArea
- coord hl, 1, 3
+ hlcoord 1, 3
ld a, [wListScrollOffset]
ld [wd11e], a
ld d, 7
@@ -411,7 +411,7 @@ Pokedex_PlacePokemonList:
dec d
jr nz, .printPokemonLoop
ld a, 01
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
ret
@@ -434,18 +434,18 @@ ShowPokedexData:
call GBPalWhiteOutWithDelay3
call ClearScreen
call UpdateSprites
- callab LoadPokedexTilePatterns ; load pokedex tiles
+ callfar 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
- ld a, [hTilesetType]
+ ldh [rNR50], a
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
call GBPalWhiteOut ; zero all palettes
ld a, [wd11e] ; pokemon ID
ld [wcf91], a
@@ -458,11 +458,11 @@ ShowPokedexDataInternal:
call c, Pokedex_PrintFlavorTextAtRow11
.waitForButtonPress
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and a, A_BUTTON | B_BUTTON
jr z, .waitForButtonPress
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
call GBPalWhiteOut
call ClearScreen
call RunDefaultPaletteCommand
@@ -471,11 +471,11 @@ ShowPokedexDataInternal:
ld hl, wd72c
res 1, [hl]
ld a, $77 ; max volume
- ld [rNR50], a
+ ldh [rNR50], a
ret
HeightWeightText:
- db "HT ?", $60, "??", $61
+ db "HT ?′??″"
next "WT ???lb@"
; XXX does anything point to this?
@@ -484,52 +484,50 @@ PokeText:
; 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 $68, $69, $6B, $69, $6B, $69, $6B, $69, $6B, $6B
+ db $6B, $6B, $69, $6B, $69, $6B, $69, $6B, $69, $6A
db "@"
DrawDexEntryOnScreen:
call ClearScreen
- coord hl, 0, 0
+ hlcoord 0, 0
ld de, 1
lb bc, $64, SCREEN_WIDTH
call DrawTileLine ; draw top border
- coord hl, 0, 17
+ hlcoord 0, 17
ld b, $6f
call DrawTileLine ; draw bottom border
- coord hl, 0, 1
+ hlcoord 0, 1
ld de, 20
lb bc, $66, $10
call DrawTileLine ; draw left border
- coord hl, 19, 1
+ hlcoord 19, 1
ld b, $67
call DrawTileLine ; draw right border
ld a, $63 ; upper left corner tile
- Coorda 0, 0
+ ldcoord_a 0, 0
ld a, $65 ; upper right corner tile
- Coorda 19, 0
+ ldcoord_a 19, 0
ld a, $6c ; lower left corner tile
- Coorda 0, 17
+ ldcoord_a 0, 17
ld a, $6e ; lower right corner tile
- Coorda 19, 17
+ ldcoord_a 19, 17
- coord hl, 0, 9
+ hlcoord 0, 9
ld de, PokedexDataDividerLine
call PlaceString ; draw horizontal divider line
- coord hl, 9, 6
+ hlcoord 9, 6
ld de, HeightWeightText
call PlaceString
call GetMonName
- coord hl, 9, 2
+ hlcoord 9, 2
call PlaceString
ld hl, PokedexEntryPointers
@@ -543,7 +541,7 @@ DrawDexEntryOnScreen:
ld e, a
ld d, [hl] ; de = address of pokedex entry
- coord hl, 9, 4
+ hlcoord 9, 4
call PlaceString ; print species name
ld h, b
@@ -553,10 +551,10 @@ DrawDexEntryOnScreen:
push af
call IndexToPokedex
- coord hl, 2, 8
+ hlcoord 2, 8
ld a, "№"
ld [hli], a
- ld a, "⠄"
+ ld a, "<DOT>"
ld [hli], a
ld de, wd11e
lb bc, LEADING_ZEROES | 1, 3
@@ -578,7 +576,7 @@ DrawDexEntryOnScreen:
call Delay3
call GBPalNormal
call GetMonHeader ; load pokemon picture location
- coord hl, 1, 1
+ hlcoord 1, 1
call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
ld a, [wcf91]
call PlayCry ; play pokemon cry
@@ -594,17 +592,17 @@ DrawDexEntryOnScreen:
inc de ; de = address of feet (height)
ld a, [de] ; reads feet, but a is overwritten without being used
- coord hl, 12, 6
+ hlcoord 12, 6
lb bc, 1, 2
call PrintNumber ; print feet (height)
- ld a, $60 ; feet symbol tile (one tick)
+ ld a, "′"
ld [hl], a
inc de
inc de ; de = address of inches (height)
- coord hl, 15, 6
+ hlcoord 15, 6
lb bc, LEADING_ZEROES | 1, 2
call PrintNumber ; print inches (height)
- ld a, $61 ; inches symbol tile (two ticks)
+ ld a, "″"
ld [hl], a
; now print the weight (note that weight is stored in tenths of pounds internally)
inc de
@@ -623,13 +621,13 @@ DrawDexEntryOnScreen:
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
+ hlcoord 11, 8
lb bc, 2, 5 ; 2 bytes, 5 digits
call PrintNumber ; print weight
- coord hl, 14, 8
- ld a, [hDexWeight + 1]
+ hlcoord 14, 8
+ ldh a, [hDexWeight + 1]
sub 10
- ld a, [hDexWeight]
+ ldh a, [hDexWeight]
sbc 0
jr nc, .next
ld [hl], "0" ; if the weight is less than 10, put a 0 before the decimal point
@@ -637,54 +635,54 @@ DrawDexEntryOnScreen:
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
+ ld [hl], "<DOT>" ; decimal point tile
pop af
- ld [hDexWeight + 1], a ; restore original value of [hDexWeight + 1]
+ ldh [hDexWeight + 1], a ; restore original value of [hDexWeight + 1]
pop af
- ld [hDexWeight], a ; restore original value of [hDexWeight]
+ ldh [hDexWeight], a ; restore original value of [hDexWeight]
pop hl
inc hl ; hl = address of pokedex description text
scf
ret
Pokedex_PrintFlavorTextAtRow11:
- coord bc, 1, 11
+ bccoord 1, 11
Pokedex_PrintFlavorTextAtBC:
- ld a, 2
- ld [$fff9], a
+ ld a, %10
+ ldh [hClearLetterPrintingDelayFlags], a
call TextCommandProcessor ; print pokedex description text
xor a
- ld [$fff9], a
+ ldh [hClearLetterPrintingDelayFlags], a
ret
Pokedex_PrepareDexEntryForPrinting:
- coord hl, 0, 0
+ hlcoord 0, 0
ld de, SCREEN_WIDTH
lb bc, $66, $d
call DrawTileLine
- coord hl, 19, 0
+ hlcoord 19, 0
ld b, $67
call DrawTileLine
- coord hl, 0, 13
+ hlcoord 0, 13
ld de, $1
lb bc, $6f, SCREEN_WIDTH
call DrawTileLine
ld a, $6c
- Coorda 0, 13
+ ldcoord_a 0, 13
ld a, $6e
- Coorda 19, 13
+ ldcoord_a 19, 13
ld a, [wPrinterPokedexEntryTextPointer]
ld l, a
ld a, [wPrinterPokedexEntryTextPointer + 1]
ld h, a
- coord bc, 1, 1
- ld a, [hFlags_0xFFFA]
+ bccoord 1, 1
+ ldh a, [hFlagsFFFA]
set 3, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
call Pokedex_PrintFlavorTextAtBC
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
res 3, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
ret
; draws a line of tiles
@@ -705,7 +703,7 @@ DrawTileLine:
pop bc
ret
-INCLUDE "data/pokedex_entries.asm"
+INCLUDE "data/pokemon/dex_entries.asm"
PokedexToIndex:
; converts the Pokédex number at wd11e to an index
@@ -744,4 +742,4 @@ IndexToPokedex:
pop bc
ret
-INCLUDE "data/pokedex_order.asm"
+INCLUDE "data/pokemon/dex_order.asm"
diff --git a/engine/save.asm b/engine/menus/save.asm
index 7f453bf0..bcb27ddf 100755
--- a/engine/save.asm
+++ b/engine/menus/save.asm
@@ -28,8 +28,8 @@ LoadSAV:
ret
FileDataDestroyedText:
- TX_FAR _FileDataDestroyedText
- db "@"
+ text_far _FileDataDestroyedText
+ text_end
LoadSAV0:
call EnableSRAMAndLatchClockData
@@ -68,7 +68,7 @@ LoadSAV0:
ld bc, wSpriteDataEnd - wSpriteDataStart
call CopyData
ld a, [sTilesetType]
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld hl, sCurBoxData
ld de, wBoxDataStart
ld bc, wBoxDataEnd - wBoxDataStart
@@ -130,7 +130,7 @@ LoadSAVIgnoreBadCheckSum:
jp LoadSAV2
SaveSAV:
- callba PrintSaveScreenText
+ farcall PrintSaveScreenText
ld c, 10
call DelayFrames
ld hl, WouldYouLikeToSaveText
@@ -156,7 +156,7 @@ SaveSAV:
call DelayFrames
ld hl, GameSavedText
call PrintText
- ld c,10
+ ld c, 10
call DelayFrames
ld a, SFX_SAVE
call PlaySoundWaitForCurrent
@@ -167,7 +167,7 @@ SaveSAV:
SaveSAVConfirm:
call PrintText
- coord hl, 0, 7
+ hlcoord 0, 7
lb bc, 8, 1
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -176,20 +176,20 @@ SaveSAVConfirm:
ret
WouldYouLikeToSaveText:
- TX_FAR _WouldYouLikeToSaveText
- db "@"
+ text_far _WouldYouLikeToSaveText
+ text_end
SavingText:
- TX_FAR _SavingText
- db "@"
+ text_far _SavingText
+ text_end
GameSavedText:
- TX_FAR _GameSavedText
- db "@"
+ text_far _GameSavedText
+ text_end
OlderFileWillBeErasedText:
- TX_FAR _OlderFileWillBeErasedText
- db "@"
+ text_far _OlderFileWillBeErasedText
+ text_end
SaveSAVtoSRAM0:
call EnableSRAMAndLatchClockData
@@ -211,7 +211,7 @@ SaveSAVtoSRAM0:
ld de, sCurBoxData
ld bc, wBoxDataEnd - wBoxDataStart
call CopyData
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
ld [sTilesetType], a
ld hl, sPlayerName
ld bc, sMainDataCheckSum - sPlayerName
@@ -262,7 +262,7 @@ SaveSAVtoSRAM2:
call DisableSRAMAndPrepareClockData
ret
-SaveSAVtoSRAM:
+SaveSAVtoSRAM::
ld a, $2
ld [wSaveFileStatus], a
call SaveSAVtoSRAM0
@@ -342,10 +342,10 @@ ChangeBox::
call z, EmptyAllSRAMBoxes ; if so, empty all boxes in SRAM
call DisplayChangeBoxMenu
call UpdateSprites
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 1, [hl]
bit 1, a ; pressed b
ret nz
@@ -377,8 +377,8 @@ ChangeBox::
ret
WhenYouChangeBoxText:
- TX_FAR _WhenYouChangeBoxText
- db "@"
+ text_far _WhenYouChangeBoxText
+ text_end
CopyBoxToOrFromSRAM:
; copy an entire box from hl to de with b as the SRAM bank
@@ -406,7 +406,7 @@ CopyBoxToOrFromSRAM:
DisplayChangeBoxMenu:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, A_BUTTON | B_BUTTON
ld [wMenuWatchedKeys], a
ld a, 11
@@ -421,39 +421,39 @@ DisplayChangeBoxMenu:
and $7f
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 2, 9
call TextBoxBorder
ld hl, ChooseABoxText
call PrintText
- coord hl, 11, 0
+ hlcoord 11, 0
lb bc, 12, 7
call TextBoxBorder
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 2, [hl]
ld de, BoxNames
- coord hl, 13, 1
+ hlcoord 13, 1
call PlaceString
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 2, [hl]
ld a, [wCurrentBoxNum]
and $7f
cp 9
jr c, .singleDigitBoxNum
sub 9
- coord hl, 8, 2
+ hlcoord 8, 2
ld [hl], "1"
add "0"
jr .next
.singleDigitBoxNum
add "1"
.next
- Coorda 9, 2
- coord hl, 1, 2
+ ldcoord_a 9, 2
+ hlcoord 1, 2
ld de, BoxNoText
call PlaceString
call GetMonCountsForAllBoxes
- coord hl, 18, 1
+ hlcoord 18, 1
ld de, wBoxMonCounts
ld bc, SCREEN_WIDTH
ld a, $c
@@ -470,12 +470,12 @@ DisplayChangeBoxMenu:
dec a
jr nz, .loop
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
ChooseABoxText:
- TX_FAR _ChooseABoxText
- db "@"
+ text_far _ChooseABoxText
+ text_end
BoxNames:
db "BOX 1"
@@ -575,11 +575,11 @@ GetMonCountsForBoxesInBank:
ret
SAVCheckRandomID:
-;checks if Sav file is the same by checking player's name 1st letter ($a598)
+; checks if Sav file is the same by checking player's name 1st letter
; and the two random numbers generated at game beginning
-;(which are stored at wPlayerID)s
+; (which are stored at wPlayerID)s
call EnableSRAMAndLatchClockData
- ld a, $1
+ ld a, $01
ld [MBC1SRamBank], a
ld a, [sPlayerName]
and a
@@ -663,8 +663,8 @@ ClearSAV:
PadSRAM_FF:
ld [MBC1SRamBank], a
- ld hl, $a000
- ld bc, $2000
+ ld hl, SRAM_Begin
+ ld bc, SRAM_End - SRAM_Begin
ld a, $ff
jp FillMemory
diff --git a/engine/menu/start_sub_menus.asm b/engine/menus/start_sub_menus.asm
index abc8f000..84583a69 100755
--- a/engine/menu/start_sub_menus.asm
+++ b/engine/menus/start_sub_menus.asm
@@ -1,4 +1,4 @@
-StartMenu_Pokedex:
+StartMenu_Pokedex::
predef ShowPokedexMenu
call LoadScreenTilesFromBuffer2 ; restore saved screen
call Delay3
@@ -6,7 +6,7 @@ StartMenu_Pokedex:
call UpdateSprites
jp RedisplayStartMenu
-StartMenu_Pokemon:
+StartMenu_Pokemon::
ld a, [wPartyCount]
and a
jp z, RedisplayStartMenu
@@ -50,7 +50,7 @@ StartMenu_Pokemon:
ld hl, wTopMenuItemY
ld a, c
ld [hli], a ; top menu item Y
- ld a, [hFieldMoveMonMenuTopMenuItemX]
+ ldh a, [hFieldMoveMonMenuTopMenuItemX]
ld [hli], a ; top menu item X
xor a
ld [hli], a ; current menu item ID
@@ -130,7 +130,7 @@ StartMenu_Pokemon:
dw .teleport
dw .softboiled
.fly
- bit 2, a ; does the player have the Thunder Badge?
+ bit BIT_THUNDERBADGE, a
jp z, .newBadgeRequired
call CheckIfInOutsideMap
jr z, .canFly
@@ -153,7 +153,7 @@ StartMenu_Pokemon:
call Func_1510
jp .goBackToMap
.cut
- bit 1, a ; does the player have the Cascade Badge?
+ bit BIT_CASCADEBADGE, a
jp z, .newBadgeRequired
predef UsedCut
ld a, [wActionResultOrTookBattleTurn]
@@ -161,9 +161,9 @@ StartMenu_Pokemon:
jp z, .loop
jp CloseTextDisplay
.surf
- bit 4, a ; does the player have the Soul Badge?
+ bit BIT_SOULBADGE, a
jp z, .newBadgeRequired
- callba IsSurfingAllowed
+ farcall IsSurfingAllowed
ld hl, wd728
bit 1, [hl]
res 1, [hl]
@@ -177,7 +177,7 @@ StartMenu_Pokemon:
ld a, $2
.continue
ld [wd473], a
- ld a,SURFBOARD
+ ld a, SURFBOARD
ld [wcf91], a
ld [wPseudoItemID], a
call UseItem
@@ -191,13 +191,13 @@ StartMenu_Pokemon:
ld [wd473], a
jp .loop
.strength
- bit 3, a ; does the player have the Rainbow Badge?
+ bit BIT_RAINBOWBADGE, a
jp z, .newBadgeRequired
predef PrintStrengthTxt
call GBPalWhiteOutWithDelay3
jp .goBackToMap
.flash
- bit 0, a ; does the player have the Boulder Badge?
+ bit BIT_BOULDERBADGE, a
jp z, .newBadgeRequired
xor a
ld [wMapPalOffset], a
@@ -206,8 +206,8 @@ StartMenu_Pokemon:
call GBPalWhiteOutWithDelay3
jp .goBackToMap
.flashLightsAreaText
- TX_FAR _FlashLightsAreaText
- db "@"
+ text_far _FlashLightsAreaText
+ text_end
.dig
ld a, ESCAPE_ROPE
ld [wcf91], a
@@ -242,35 +242,35 @@ StartMenu_Pokemon:
call GBPalWhiteOutWithDelay3
jp .goBackToMap
.warpToLastPokemonCenterText
- TX_FAR _WarpToLastPokemonCenterText
- db "@"
+ text_far _WarpToLastPokemonCenterText
+ text_end
.cannotUseTeleportNowText
- TX_FAR _CannotUseTeleportNowText
- db "@"
+ text_far _CannotUseTeleportNowText
+ text_end
.cannotFlyHereText
- TX_FAR _CannotFlyHereText
- db "@"
+ text_far _CannotFlyHereText
+ text_end
.softboiled
ld hl, wPartyMon1MaxHP
ld a, [wWhichPokemon]
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
ld a, [hli]
- ld [H_DIVIDEND], a
+ ldh [hDividend], a
ld a, [hl]
- ld [H_DIVIDEND + 1], a
+ ldh [hDividend + 1], a
ld a, 5
- ld [H_DIVISOR], a
+ ldh [hDivisor], 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]
+ ldh a, [hQuotient + 3]
sub b
ld b, [hl]
- ld a, [H_QUOTIENT + 2]
+ ldh a, [hQuotient + 2]
sbc b
jp nc, .notHealthyEnough
ld a, [wPartyAndBillsPCSavedMenuItem]
@@ -287,8 +287,8 @@ StartMenu_Pokemon:
call PrintText
jp .loop
.notHealthyEnoughText
- TX_FAR _NotHealthyEnoughText
- db "@"
+ text_far _NotHealthyEnoughText
+ text_end
.goBackToMap
call RestoreScreenTilesAndReloadTilePatterns
jp CloseTextDisplay
@@ -297,12 +297,12 @@ StartMenu_Pokemon:
call PrintText
jp .loop
.newBadgeRequiredText
- TX_FAR _NewBadgeRequiredText
- db "@"
+ text_far _NewBadgeRequiredText
+ text_end
; writes a blank tile to all possible menu cursor positions on the party menu
-ErasePartyMenuCursors:
- coord hl, 0, 1
+ErasePartyMenuCursors::
+ hlcoord 0, 1
ld bc, 2 * 20 ; menu cursor positions are 2 rows apart
ld a, 6 ; 6 menu cursor positions
.loop
@@ -316,7 +316,7 @@ ItemMenuLoop:
call LoadScreenTilesFromBuffer2DisableBGTransfer ; restore saved screen
call RunDefaultPaletteCommand
-StartMenu_Item:
+StartMenu_Item::
ld a, [wLinkState]
dec a ; is the player in the Colosseum or Trade Centre?
jr nz, .notInCableClubRoom
@@ -346,10 +346,10 @@ StartMenu_Item:
.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
+ ldcoord_a 5, 4
+ ldcoord_a 5, 6
+ ldcoord_a 5, 8
+ ldcoord_a 5, 10
call PlaceUnfilledArrowMenuCursor
xor a
ld [wMenuItemToSwap], a
@@ -400,7 +400,7 @@ StartMenu_Item:
; use item
ld [wPseudoItemID], a ; a must be 0 due to above conditional jump
ld a, [wcf91]
- cp HM_01
+ cp HM01
jr nc, .useItem_partyMenu
ld hl, UsableItems_CloseMenu
ld de, 1
@@ -455,71 +455,25 @@ StartMenu_Item:
jp ItemMenuLoop
CannotUseItemsHereText:
- TX_FAR _CannotUseItemsHereText
- db "@"
+ text_far _CannotUseItemsHereText
+ text_end
CannotGetOffHereText:
- TX_FAR _CannotGetOffHereText
- db "@"
+ text_far _CannotGetOffHereText
+ text_end
-; 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
+INCLUDE "data/items/use_party.asm"
-; 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
+INCLUDE "data/items/use_overworld.asm"
-StartMenu_TrainerInfo:
+StartMenu_TrainerInfo::
call GBPalWhiteOut
call ClearScreen
call UpdateSprites
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
call DrawTrainerInfo
predef DrawBadges ; draw badges
ld b, SET_PAL_TRAINER_CARD
@@ -531,10 +485,10 @@ StartMenu_TrainerInfo:
call LoadScreenTilesFromBuffer2 ; restore saved screen
call RunDefaultPaletteCommand
call ReloadMapData
- callba DrawStartMenu ; XXX what difference does this make?
+ farcall DrawStartMenu ; XXX what difference does this make?
call LoadGBPal
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
jp RedisplayStartMenu_DoNotDrawStartMenu
; loads tile patterns and draws everything except for gym leader faces / badges
@@ -543,44 +497,44 @@ DrawTrainerInfo:
lb bc, BANK(RedPicFront), $01
predef DisplayPicCenteredOrUpperRight
call DisableLCD
- coord hl, 0, 2
+ hlcoord 0, 2
ld a, " "
call TrainerInfo_DrawVerticalLine
- coord hl, 1, 2
+ hlcoord 1, 2
call TrainerInfo_DrawVerticalLine
- ld hl, vChars2 + $70
- ld de, vChars2
- ld bc, $70 * 4
+ ld hl, vChars2 tile $07
+ ld de, vChars2 tile $00
+ ld bc, $1c tiles
call CopyData
ld hl, TrainerInfoTextBoxTileGraphics ; trainer info text box tile patterns
- ld de, vChars2 + $770
- ld bc, $0080
+ ld de, vChars2 tile $77
+ ld bc, 8 tiles
push bc
call TrainerInfo_FarCopyData
ld hl, BlankLeaderNames
- ld de, vChars2 + $600
- ld bc, $0170
+ ld de, vChars2 tile $60
+ ld bc, $17 tiles
call TrainerInfo_FarCopyData
pop bc
ld hl, BadgeNumbersTileGraphics ; badge number tile patterns
- ld de, vChars1 + $580
+ ld de, vChars1 tile $58
call TrainerInfo_FarCopyData
ld hl, GymLeaderFaceAndBadgeTileGraphics ; gym leader face and badge tile patterns
- ld de, vChars2 + $200
- ld bc, $0400
- ld a, $03
+ ld de, vChars2 tile $20
+ ld bc, 8 * 8 tiles
+ ld a, BANK(GymLeaderFaceAndBadgeTileGraphics)
call FarCopyData
ld hl, TextBoxGraphics
- ld de, $00d0
+ ld de, 13 tiles
add hl, de ; hl = colon tile pattern
- ld de, vChars1 + $560
- ld bc, $0010
- ld a, $04
+ ld de, vChars1 tile $56
+ ld bc, 1 tiles
+ ld a, BANK(TextBoxGraphics)
push bc
call FarCopyData
pop bc
- ld hl, TrainerInfoTextBoxTileGraphics + $80 ; background tile pattern
- ld de, vChars1 + $570
+ ld hl, TrainerInfoTextBoxTileGraphics tile 8 ; background tile pattern
+ ld de, vChars1 tile $57
call TrainerInfo_FarCopyData
call EnableLCD
ld hl, wTrainerInfoTextBoxWidthPlus1
@@ -589,7 +543,7 @@ DrawTrainerInfo:
dec a
ld [hli], a
ld [hl], 1
- coord hl, 0, 0
+ hlcoord 0, 0
call TrainerInfo_DrawTextBox
ld hl, wTrainerInfoTextBoxWidthPlus1
ld a, 16 + 1
@@ -597,27 +551,27 @@ DrawTrainerInfo:
dec a
ld [hli], a
ld [hl], 3
- coord hl, 1, 10
+ hlcoord 1, 10
call TrainerInfo_DrawTextBox
- coord hl, 0, 10
+ hlcoord 0, 10
ld a, $d7
call TrainerInfo_DrawVerticalLine
- coord hl, 19, 10
+ hlcoord 19, 10
call TrainerInfo_DrawVerticalLine
- coord hl, 6, 9
+ hlcoord 6, 9
ld de, TrainerInfo_BadgesText
call PlaceString
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, TrainerInfo_NameMoneyTimeText
call PlaceString
- coord hl, 7, 2
+ hlcoord 7, 2
ld de, wPlayerName
call PlaceString
- coord hl, 8, 4
+ hlcoord 8, 4
ld de, wPlayerMoney
ld c, $e3
call PrintBCDNumber
- coord hl, 9, 6
+ hlcoord 9, 6
ld de, wPlayTimeHours ; hours
lb bc, LEFT_ALIGN | 1, 3
call PrintNumber
@@ -701,7 +655,7 @@ TrainerInfo_DrawVerticalLine:
jr nz, .loop
ret
-StartMenu_SaveReset:
+StartMenu_SaveReset::
ld a, [wd72e]
bit 6, a ; is the player using the link feature?
jp nz, Init
@@ -709,18 +663,18 @@ StartMenu_SaveReset:
call LoadScreenTilesFromBuffer2 ; restore saved screen
jp HoldTextDisplayOpen
-StartMenu_Option:
+StartMenu_Option::
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call ClearScreen
call UpdateSprites
- callab DisplayOptionMenu
+ callfar DisplayOptionMenu
call LoadScreenTilesFromBuffer2 ; restore saved screen
call LoadTextBoxTilePatterns
call UpdateSprites
jp RedisplayStartMenu
-SwitchPartyMon:
+SwitchPartyMon::
call SwitchPartyMon_InitVarOrSwapData ; swap data
ld a, [wSwappedMenuItem]
call SwitchPartyMon_ClearGfx
@@ -730,7 +684,7 @@ SwitchPartyMon:
SwitchPartyMon_ClearGfx:
push af
- coord hl, 0, 0
+ hlcoord 0, 0
ld bc, SCREEN_WIDTH * 2
call AddNTimes
ld c, SCREEN_WIDTH * 2
@@ -800,10 +754,10 @@ SwitchPartyMon_InitVarOrSwapData:
inc d
.noCarry2
ld a, [hl]
- ld [hSwapTemp], a
+ ldh [hSwapTemp], a
ld a, [de]
ld [hl], a
- ld a, [hSwapTemp]
+ ldh a, [hSwapTemp]
ld [de], a
ld hl, wPartyMons
ld bc, wPartyMon2 - wPartyMon1
diff --git a/engine/menu/swap_items.asm b/engine/menus/swap_items.asm
index 563fc7d5..2d506ce2 100644
--- a/engine/menu/swap_items.asm
+++ b/engine/menus/swap_items.asm
@@ -1,4 +1,4 @@
-HandleItemListSwapping:
+HandleItemListSwapping::
ld a, [wListMenuID]
cp ITEMLISTMENU
jp nz, DisplayListMenuIDLoop ; only rearrange item list menus
@@ -77,18 +77,18 @@ HandleItemListSwapping:
cp b
jr z, .swapSameItemType
.swapDifferentItems
- ld [$ff95], a ; [$ff95] = second item ID
+ ldh [hSwapItemID], a ; save second item ID
ld a, [hld]
- ld [$ff96], a ; [$ff96] = second item quantity
+ ldh [hSwapItemQuantity], a ; save second item quantity
ld a, [de]
ld [hli], a ; put first item ID in second item slot
inc de
ld a, [de]
ld [hl], a ; put first item quantity in second item slot
- ld a, [$ff96]
+ ldh a, [hSwapItemQuantity]
ld [de], a ; put second item quantity in first item slot
dec de
- ld a, [$ff95]
+ ldh a, [hSwapItemID]
ld [de], a ; put second item ID in first item slot
xor a
ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
diff --git a/engine/menus/text_box.asm b/engine/menus/text_box.asm
new file mode 100644
index 00000000..7a315af2
--- /dev/null
+++ b/engine/menus/text_box.asm
@@ -0,0 +1,533 @@
+; 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
+ hlcoord 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
+
+INCLUDE "data/text_boxes.asm"
+
+DisplayMoneyBox:
+ ld hl, wd730
+ set 6, [hl]
+ ld a, MONEY_BOX_TEMPLATE
+ ld [wTextBoxID], a
+ call DisplayTextBoxID
+ hlcoord 13, 1
+ lb bc, 1, 6
+ call ClearScreenArea
+ hlcoord 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
+ xor a
+ ld [wTwoOptionMenuID], a
+ ld hl, wd730
+ res 6, [hl] ; turn on the printing delay
+ 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
+
+INCLUDE "data/yes_no_menu_strings.asm"
+
+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
+ hlcoord 11, 11
+ lb bc, 5, 7
+ call TextBoxBorder
+ call UpdateSprites
+ ld a, 12
+ ldh [hFieldMoveMonMenuTopMenuItemX], a
+ hlcoord 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.
+ hlcoord 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.
+ hlcoord 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]
+ ldh [hFieldMoveMonMenuTopMenuItemX], a
+ hlcoord 0, 12
+ ld a, [wFieldMovesLeftmostXCoord]
+ inc a
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld de, PokemonMenuEntries
+ jp PlaceString
+
+INCLUDE "data/moves/field_move_names.asm"
+
+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
+
+INCLUDE "data/moves/field_moves.asm"
diff --git a/engine/mon_party_sprites.asm b/engine/mon_party_sprites.asm
deleted file mode 100755
index 6f17f876..00000000
--- a/engine/mon_party_sprites.asm
+++ /dev/null
@@ -1,445 +0,0 @@
-AnimatePartyMon_ForceSpeed1:
- xor a
- ld [wCurrentMenuItem], a
- ld b, a
- inc a
- jr GetAnimationSpeed
-
-; wPartyMenuHPBarColors contains the party mon's health bar colors
-; 0: green
-; 1: yellow
-; 2: red
-AnimatePartyMon:
- ld hl, wPartyMenuHPBarColors
- ld a, [wCurrentMenuItem]
- ld c, a
- ld b, 0
- add hl, bc
- ld a, [hl]
-
-GetAnimationSpeed:
- ld c, a
- ld hl, PartyMonSpeeds
- add hl, bc
- ld a, [wOnSGB]
- xor $1
- add [hl]
- ld c, a
- add a
- ld b, a
- ld a, [wAnimCounter]
- and a
- jr z, .resetSprites
- cp c
- jr z, .animateSprite
-.incTimer
- inc a
- cp b
- jr nz, .skipResetTimer
- xor a ; reset timer
-.skipResetTimer
- ld [wAnimCounter], a
- jp DelayFrame
-.resetSprites
- push bc
- ld hl, wMonPartySpritesSavedOAM
- ld de, wOAMBuffer
- ld bc, $60
- call CopyData
- pop bc
- xor a
- jr .incTimer
-.animateSprite
- push bc
- ld hl, wOAMBuffer + $02 ; OAM tile id
- ld bc, $10
- ld a, [wCurrentMenuItem]
- call AddNTimes
- ld c, $40 ; amount to increase the tile id by
- ld a, [hl]
- cp $4 ; tile ID for SPRITE_BALL_M
- jr z, .editCoords
- cp $8 ; tile ID for SPRITE_HELIX
- jr nz, .editTileIDS
-; SPRITE_BALL_M and SPRITE_HELIX only shake up and down
-.editCoords
- dec hl
- dec hl ; dec hl to the OAM y coord
- ld c, $1 ; amount to increase the y coord by
-; otherwise, load a second sprite frame
-.editTileIDS
- ld b, $4
- ld de, $4
-.loop
- ld a, [hl]
- add c
- ld [hl], a
- add hl, de
- dec b
- jr nz, .loop
- pop bc
- ld a, c
- jr .incTimer
-
-; Party mon animations cycle between 2 frames.
-; The members of the PartyMonSpeeds array specify the number of V-blanks
-; that each frame lasts for green HP, yellow HP, and red HP in order.
-; On the naming screen, the yellow HP speed is always used.
-PartyMonSpeeds:
- db 5, 16, 32
-
-LoadMonPartySpriteGfx:
-; Load mon party sprite tile patterns into VRAM during V-blank.
- ld hl, MonPartySpritePointers
- ld a, $1e
-
-LoadAnimSpriteGfx:
-; Load animated sprite tile patterns into VRAM during V-blank. hl is the address
-; of an array of structures that contain arguments for CopyVideoData and a is
-; the number of structures in the array.
- ld bc, $0
-.loop
- push af
- push bc
- push hl
- add hl, bc
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- ld a, [hli]
- ld c, a
- ld a, [hli]
- ld b, a
- ld a, [hli]
- ld h, [hl]
- ld l, a
- call CopyVideoData
- pop hl
- pop bc
- ld a, $6
- add c
- ld c, a
- pop af
- dec a
- jr nz, .loop
- ret
-
-LoadMonPartySpriteGfxWithLCDDisabled:
-; Load mon party sprite tile patterns into VRAM immediately by disabling the
-; LCD.
- call DisableLCD
- ld hl, MonPartySpritePointers
- ld a, $1e
- ld bc, $0
-.loop
- push af
- push bc
- push hl
- add hl, bc
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- push de
- ld a, [hli]
- ld c, a
- swap c
- ld b, $0
- ld a, [hli]
- ld e, [hl]
- inc hl
- ld d, [hl]
- pop hl
- call FarCopyData
- pop hl
- pop bc
- ld a, $6
- add c
- ld c, a
- pop af
- dec a
- jr nz, .loop
- jp EnableLCD
-
-MonPartySpritePointers:
- dw SlowbroSprite + $c0
- db $40 / $10 ; 40 bytes
- db BANK(SlowbroSprite)
- dw vSprites
-
- dw BallSprite
- db $80 / $10 ; $80 bytes
- db BANK(BallSprite)
- dw vSprites + $40
-
- dw ClefairySprite + $c0
- db $40 / $10 ; $40 bytes
- db BANK(ClefairySprite)
- dw vSprites + $c0
-
- dw BirdSprite + $c0
- db $40 / $10 ; $40 bytes
- db BANK(BirdSprite)
- dw vSprites + $100
-
- dw SeelSprite
- db $40 / $10 ; $40 bytes
- db BANK(SeelSprite)
- dw vSprites + $140
-
- dw MonPartySprites + $40
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $180
-
- dw MonPartySprites + $50
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $1a0
-
- dw MonPartySprites + $60
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $1c0
-
- dw MonPartySprites + $70
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $1e0
-
- dw MonPartySprites + $80
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $200
-
- dw MonPartySprites + $90
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $220
-
- dw MonPartySprites + $A0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $240
-
- dw MonPartySprites + $B0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $260
-
- dw PikachuSprite
- db $40 / $10 ; $40 bytes
- db BANK(PikachuSprite)
- dw vSprites + $280
-
- dw MonPartySprites + $100
- db $40 / $10 ; $40 bytes
- db BANK(MonPartySprites)
- dw vSprites + $380
-
- dw SlowbroSprite
- db $40 / $10 ; $40 bytes
- db BANK(SlowbroSprite)
- dw vSprites + $400
-
- dw BallSprite
- db $80 / $10 ; $80 bytes
- db BANK(BallSprite)
- dw vSprites + $440
-
- dw ClefairySprite
- db $40 / $10 ; $40 bytes
- db BANK(ClefairySprite)
- dw vSprites + $4c0
-
- dw BirdSprite
- db $40 / $10 ; $40 bytes
- db BANK(BirdSprite)
- dw vSprites + $500
-
- dw SeelSprite + $C0
- db $40 / $10 ; $40 bytes
- db BANK(SeelSprite)
- dw vSprites + $540
-
- dw MonPartySprites
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $580
-
- dw MonPartySprites + $10
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $5a0
-
- dw MonPartySprites + $20
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $5c0
-
- dw MonPartySprites + $30
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $5E0
-
- dw MonPartySprites + $C0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $600
-
- dw MonPartySprites + $D0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $620
-
- dw MonPartySprites + $E0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $640
-
- dw MonPartySprites + $F0
- db $10 / $10 ; $10 bytes
- db BANK(MonPartySprites)
- dw vSprites + $660
-
- dw PikachuSprite + $C0
- db $40 / $10 ; $40 bytes
- db BANK(PikachuSprite)
- dw vSprites + $680
-
- dw MonPartySprites + $140
- db $40 / $10 ; $40 bytes
- db BANK(MonPartySprites)
- dw vSprites + $780
-
-WriteMonPartySpriteOAMByPartyIndex:
-; Write OAM blocks for the party mon in [hPartyMonIndex].
- push hl
- push de
- push bc
- ld a, [hPartyMonIndex]
- cp $ff
- jr z, .asm_7191f
- ld hl, wPartySpecies
- ld e, a
- ld d, 0
- add hl, de
- ld a, [hl]
- call GetPartyMonSpriteID
- ld [wOAMBaseTile], a
- call WriteMonPartySpriteOAM
- pop bc
- pop de
- pop hl
- ret
-
-.asm_7191f
- ld hl, wOAMBuffer
- ld de, wMonPartySpritesSavedOAM
- ld bc, $60
- call CopyData
- pop bc
- pop de
- pop hl
- ret
-
-WriteMonPartySpriteOAMBySpecies:
-; Write OAM blocks for the party sprite of the species in
-; [wMonPartySpriteSpecies].
- xor a
- ld [hPartyMonIndex], a
- ld a, [wMonPartySpriteSpecies]
- call GetPartyMonSpriteID
- ld [wOAMBaseTile], a
- jr WriteMonPartySpriteOAM
-
-UnusedPartyMonSpriteFunction:
-; This function is unused and doesn't appear to do anything useful. It looks
-; like it may have been intended to load the tile patterns and OAM data for
-; the mon party sprite associated with the species in [wcf91].
-; However, its calculations are off and it loads garbage data.
- ld a, [wcf91]
- call GetPartyMonSpriteID
- push af
- ld hl, vSprites
- call .LoadTilePatterns
- pop af
- add $5A
- ld hl, vSprites + $40
- call .LoadTilePatterns
- xor a
- ld [wMonPartySpriteSpecies], a
- jr WriteMonPartySpriteOAMBySpecies
-
-.LoadTilePatterns
- push hl
- add a
- ld c, a
- ld b, 0
- ld hl, MonPartySpritePointers
- add hl, bc
- add hl, bc
- add hl, bc
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld d, a
- ld a, [hli]
- ld c, a
- ld a, [hli]
- ld b, a
- pop hl
- jp CopyVideoData
-
-WriteMonPartySpriteOAM:
-; Write the OAM blocks for the first animation frame into the OAM buffer and
-; make a copy at wMonPartySpritesSavedOAM.
- push af
- ld c, $10
- ld h, wOAMBuffer / $100
- ld a, [hPartyMonIndex]
- swap a
- ld l, a
- add $10
- ld b, a
- pop af
- cp SPRITE_HELIX << 2
- jr z, .helix
- call WriteSymmetricMonPartySpriteOAM
- jr .makeCopy
-.helix
- call WriteAsymmetricMonPartySpriteOAM
-; Make a copy of the OAM buffer with the first animation frame written so that
-; we can flip back to it from the second frame by copying it back.
-.makeCopy
- ld hl, wOAMBuffer
- ld de, wMonPartySpritesSavedOAM
- ld bc, $60
- jp CopyData
-
-GetPartyMonSpriteID:
- ld [wd11e], a
- predef IndexToPokedex
- ld a, [wd11e]
- ld c, a
- dec a
- srl a
- ld hl, MonPartyData
- ld e, a
- ld d, 0
- add hl, de
- ld a, [hl]
- bit 0, c
- jr nz, .skipSwap
- swap a ; use lower nybble if pokedex num is even
-.skipSwap
- and $f0
- srl a
- srl a
- ret
-
-INCLUDE "data/mon_party_sprites.asm"
-
-MonPartySprites:
- INCBIN "gfx/mon_ow_sprites.2bpp"
diff --git a/engine/movie/credits.asm b/engine/movie/credits.asm
new file mode 100755
index 00000000..938579f3
--- /dev/null
+++ b/engine/movie/credits.asm
@@ -0,0 +1,322 @@
+HallOfFamePC:
+ callfar AnimateHallOfFame
+ call ClearScreen
+ ld c, 100
+ call DelayFrames
+
+ call DisableLCD
+ ld a, $a7
+ ldh [rWX], a
+ xor a
+ ldh [rSCX], a
+ ldh [rSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
+ ldh [hWY], a
+ ldh [rWY], a
+ call CreditsLoadFont
+ hlcoord 0, 0
+ call FillFourRowsWithBlack
+ hlcoord 0, 14
+ call FillFourRowsWithBlack
+ ld a, %11000000
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ call EnableLCD
+ call StopAllMusic
+ ld hl, vBGMap1
+ call CreditsCopyTileMapToVRAM
+ ld hl, vBGMap0
+ call CreditsCopyTileMapToVRAM
+ ld c, BANK(Music_Credits)
+ ld a, MUSIC_CREDITS
+ call PlayMusic
+ ld c, 128
+ call DelayFrames
+ xor a
+ ld [wHoFMonSpecies], a
+ ld [wNumCreditsMonsDisplayed], a
+ jp Credits
+
+FadeInCreditsText:
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ ld hl, HoFGBPalettes
+ ld b, 4
+.loop
+ ld a, [hli]
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld c, 5
+ call DelayFrames
+ dec b
+ jr nz, .loop
+ ret
+
+HoFGBPalettes:
+ db %11000000
+ db %11010000
+ db %11100000
+ db %11110000
+
+DisplayCreditsMon:
+ ld hl, vBGMap1
+ call CreditsCopyTileMapToVRAM
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ld hl, rLCDC
+ set 3, [hl]
+ call SaveScreenTilesToBuffer2
+ call FillMiddleOfScreenWithWhite
+ call GetNextCreditsMon
+ ld hl, vBGMap0 + 12
+ call CreditsCopyTileMapToVRAM
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call LoadScreenTilesFromBuffer2DisableBGTransfer
+ ld hl, vBGMap0
+ call CreditsCopyTileMapToVRAM
+ ld a, %11111100 ; make the mon a black silhouette
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld hl, rLCDC
+ res 3, [hl]
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ ld b, 0
+ ld c, 10
+ call ScrollCreditsMonLeft
+ call FillLeftHalfOfScreenWithWhite
+ ld c, 10
+ call ScrollCreditsMonLeft
+ call FillRightHalfOfScreenWithWhite
+ ld c, 8
+ call ScrollCreditsMonLeft
+ ld a, %11000000
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ xor a
+ ldh [hSCX], a
+ ret
+
+ScrollCreditsMonLeft:
+ ld a, b
+ ldh [hSCX], a
+ add 8
+ ld b, a
+ call DelayFrame
+ dec c
+ jr nz, ScrollCreditsMonLeft
+ ret
+
+GetNextCreditsMon:
+ ld hl, wNumCreditsMonsDisplayed
+ ld c, [hl]
+ inc [hl]
+ ld b, 0
+ ld hl, CreditsMons
+ add hl, bc
+ ld a, [hl]
+ ld [wcf91], a
+ ld [wd0b5], a
+ hlcoord 8, 6
+ call GetMonHeader
+ call LoadFrontSpriteByMonIndex
+ ret
+
+INCLUDE "data/credits/credits_mons.asm"
+
+CreditsCopyTileMapToVRAM:
+ ld a, l
+ ldh [hAutoBGTransferDest], a
+ ld a, h
+ ldh [hAutoBGTransferDest + 1], a
+ ld a, 1
+ ldh [hAutoBGTransferEnabled], a
+ jp Delay3
+
+CreditsLoadFont:
+ call LoadFontTilePatterns
+ ld hl, vChars1
+ ld bc, ($80 tiles) / 2
+ call ZeroMemory
+
+ call LoadTextBoxTilePatterns
+ ld hl, vChars2 tile $60
+ ld bc, ($20 tiles) / 2
+ call ZeroMemory
+
+ ld hl, vChars2 tile $7e
+ ld bc, 1 tiles
+ ld a, $ff ; solid black
+ call FillMemory
+ ret
+
+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:
+ hlcoord 0, 4
+ ld bc, SCREEN_WIDTH * 10
+ ld a, " "
+ jp FillMemory
+
+FillLeftHalfOfScreenWithWhite:
+ hlcoord 0, 4
+ push bc
+ call FillHalfOfScreenWithWhite
+ pop bc
+ ret
+
+FillRightHalfOfScreenWithWhite:
+ hlcoord 10, 4
+ push bc
+ call FillHalfOfScreenWithWhite
+ pop bc
+ ret
+
+FillHalfOfScreenWithWhite:
+ ld b, 10
+ ld c, 10
+ ld a, " "
+.loop
+ push bc
+ push hl
+.innerLoop
+ ld [hli], a
+ dec c
+ jr nz, .innerLoop
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+Credits: ; Roll credits
+ ld de, CreditsOrder
+ push de
+.nextCreditsScreen
+ pop de
+ hlcoord 9, 6
+ push hl
+ call FillMiddleOfScreenWithWhite
+ pop hl
+.nextCreditsCommand
+ ld a, [de]
+ inc de
+ push de
+ cp CRED_TEXT_FADE_MON
+ jr z, .fadeInTextAndShowMon
+ cp CRED_TEXT_MON
+ jr z, .showTextAndShowMon
+ cp CRED_TEXT_FADE
+ jr z, .fadeInText
+ cp CRED_TEXT
+ jr z, .showText
+ cp CRED_COPYRIGHT
+ jr z, .showCopyrightText
+ cp CRED_THE_END
+ jr z, .showTheEnd
+ call PlaceCreditsText
+ pop de
+ jr .nextCreditsCommand
+
+.showCopyrightText
+ farcall LoadCopyrightTiles
+ pop de
+ jr .nextCreditsCommand
+
+
+.fadeInTextAndShowMon
+ call FadeInCreditsText
+ ld c, 102
+ jr .next1
+
+.showTextAndShowMon
+ ld c, 122
+.next1
+ call DelayFrames
+ call DisplayCreditsMon
+ jr .nextCreditsScreen
+
+.fadeInText
+ call FadeInCreditsText
+ ld c, 132
+ jr .next2
+
+.showText
+ ld c, 152
+.next2
+ call DelayFrames
+ jr .nextCreditsScreen
+.showTheEnd
+ call ShowTheEndGFX
+ pop de
+ ret
+
+ShowTheEndGFX:
+ ld c, 24
+ call DelayFrames
+ call FillMiddleOfScreenWithWhite
+ ld de, TheEndGfx
+ ld hl, vChars2 tile $60
+ lb bc, BANK(TheEndGfx), (TheEndGfxEnd - TheEndGfx) / $10
+ call CopyVideoData
+ hlcoord 4, 8
+ ld de, TheEndTextString
+ call PlaceString
+ hlcoord 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, "@"
+
+PlaceCreditsText:
+ push hl
+ push hl
+ ld hl, CreditsTextPointers
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ ld a, [de]
+ inc de
+ ld c, a
+ ld b, -1
+ add hl, bc
+ call PlaceString
+ pop hl
+ ld bc, SCREEN_WIDTH * 2
+ add hl, bc
+ ret
+
+INCLUDE "data/credits/credits_order.asm"
+
+INCLUDE "data/credits/credits_text.asm"
+
+TheEndGfx:
+ INCBIN "gfx/credits/the_end.2bpp"
+TheEndGfxEnd:
diff --git a/engine/evolution.asm b/engine/movie/evolution.asm
index 7277e991..624a7f5f 100755
--- a/engine/evolution.asm
+++ b/engine/movie/evolution.asm
@@ -11,13 +11,13 @@ EvolveMon:
ld [wChannelSoundIDs + Ch5], a
call StopAllMusic
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, SFX_TINK
call PlaySound
call Delay3
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [hTilesetType], a
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hTilesetType], a
ld a, [wEvoOldSpecies]
ld [wWholeScreenPaletteMonSpecies], a
ld c, 0
@@ -35,7 +35,7 @@ EvolveMon:
ld [wd0b5], a
call Evolution_LoadPic
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, [wEvoOldSpecies]
call PlayCry
call WaitForSoundToFinish
@@ -95,7 +95,7 @@ EvolutionSetWholeScreenPalette:
Evolution_LoadPic:
call GetMonHeader
- coord hl, 7, 2
+ hlcoord 7, 2
jp LoadFlippedFrontSpriteByMonIndex
Evolution_BackAndForthAnim:
@@ -113,8 +113,8 @@ Evolution_BackAndForthAnim:
Evolution_ChangeMonPic:
push bc
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 7, 2
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 7, 2
lb bc, 7, 7
ld de, SCREEN_WIDTH - 7
.loop
@@ -130,7 +130,7 @@ Evolution_ChangeMonPic:
dec b
jr nz, .loop
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
pop bc
ret
@@ -139,7 +139,7 @@ Evolution_CheckForCancel:
call DelayFrame
push bc
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
pop bc
and B_BUTTON
jr nz, .pressedB
diff --git a/engine/hall_of_fame.asm b/engine/movie/hall_of_fame.asm
index 39a7a2e3..616a72e3 100755
--- a/engine/hall_of_fame.asm
+++ b/engine/movie/hall_of_fame.asm
@@ -19,12 +19,12 @@ AnimateHallOfFame:
call FillMemory
xor a
ld [wUpdateSpritesEnabled], a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld [wSpriteFlipped], a
ld [wLetterPrintingDelayFlags], a ; no delay
ld [wHoFMonOrPlayer], a ; mon
inc a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld hl, wNumHoFTeams
ld a, [hl]
inc a
@@ -32,7 +32,7 @@ AnimateHallOfFame:
inc [hl]
.skipInc
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
ld c, BANK(Music_HallOfFame)
ld a, MUSIC_HALL_OF_FAME
call PlayMusic
@@ -57,10 +57,10 @@ AnimateHallOfFame:
call HoFDisplayAndRecordMonInfo
ld c, 80
call DelayFrames
- coord hl, 2, 13
+ hlcoord 2, 13
lb bc, 3, 14
call TextBoxBorder
- coord hl, 4, 15
+ hlcoord 4, 15
ld de, HallOfFameText
call PlaceString
ld c, 180
@@ -76,7 +76,7 @@ AnimateHallOfFame:
ld bc, HOF_MON
call AddNTimes
ld [hl], $ff
- callab SaveHallOfFameTeams ; useless since in same bank
+ callfar SaveHallOfFameTeams ; useless since in same bank
xor a
ld [wHoFMonSpecies], a
inc a
@@ -85,7 +85,7 @@ AnimateHallOfFame:
call HoFDisplayPlayerStats
call HoFFadeOutScreenAndMusic
xor a
- ld [hWY], a
+ ldh [hWY], a
ld hl, rLCDC
res 3, [hl]
ret
@@ -96,9 +96,9 @@ HallOfFameText:
HoFShowMonOrPlayer:
call ClearScreen
ld a, $d0
- ld [hSCY], a
+ ldh [hSCY], a
ld a, $c0
- ld [hSCX], a
+ ldh [hSCX], a
ld a, [wHoFMonSpecies]
ld [wcf91], a
ld [wd0b5], a
@@ -111,7 +111,7 @@ HoFShowMonOrPlayer:
call HoFLoadPlayerPics
jr .next1
.showMon
- coord hl, 12, 5
+ hlcoord 12, 5
call GetMonHeader
call LoadFrontSpriteByMonIndex
predef LoadMonBackPic
@@ -120,7 +120,7 @@ HoFShowMonOrPlayer:
ld c, 0
call RunPaletteCommand
ld a, %11100100
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, $31 ; back pic
call HoFLoadMonPlayerPicTileIDs
@@ -133,7 +133,7 @@ HoFShowMonOrPlayer:
.next2
call .ScrollPic ; scroll back pic left
xor a
- ld [hSCY], a
+ ldh [hSCY], a
ld c, a ; front pic
call HoFLoadMonPlayerPicTileIDs
ld d, 0
@@ -142,9 +142,9 @@ HoFShowMonOrPlayer:
.ScrollPic
call DelayFrame
- ld a, [hSCX]
+ ldh a, [hSCX]
add e
- ld [hSCX], a
+ ldh [hSCX], a
cp d
jr nz, .ScrollPic
ret
@@ -156,38 +156,38 @@ HoFDisplayAndRecordMonInfo:
call HoFDisplayMonInfo
ld a, [wHoFPartyMonIndex]
ld [wWhichPokemon], a
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .asm_70336
ld e, $22
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .asm_7033c
.asm_70336
- ld a,[wHoFMonSpecies]
+ ld a, [wHoFMonSpecies]
call PlayCry
.asm_7033c
jp HoFRecordMonInfo
Func_7033f:
call HoFDisplayMonInfo
- ld a,[wHoFMonSpecies]
+ ld a, [wHoFMonSpecies]
jp PlayCry
HoFDisplayMonInfo:
- coord hl, 0, 2
+ hlcoord 0, 2
lb bc, 9, 10
call TextBoxBorder
- coord hl, 2, 6
+ hlcoord 2, 6
ld de, HoFMonInfoText
call PlaceString
- coord hl, 1, 4
+ hlcoord 1, 4
ld de, wcd6d
call PlaceString
ld a, [wHoFMonLevel]
- coord hl, 8, 7
+ hlcoord 8, 7
call PrintLevelCommon
ld a, [wHoFMonSpecies]
ld [wd0b5], a
- coord hl, 3, 9
+ hlcoord 3, 9
predef PrintMonType
ret
@@ -200,7 +200,7 @@ HoFLoadPlayerPics:
ld de, RedPicFront
ld a, BANK(RedPicFront)
call UncompressSpriteFromDE
- ld a,$0
+ ld a, $0
call SwitchSRAMBankAndLatchClockData
ld hl, sSpriteBuffer1
ld de, sSpriteBuffer0
@@ -219,26 +219,26 @@ HoFLoadPlayerPics:
HoFLoadMonPlayerPicTileIDs:
; c = base tile ID
- ld b, 0
- coord hl, 12, 5
+ ld b, TILEMAP_MON_PIC
+ hlcoord 12, 5
predef_jump CopyTileIDsFromList
HoFDisplayPlayerStats:
SetEvent EVENT_HALL_OF_FAME_DEX_RATING
predef DisplayDexRating
- coord hl, 0, 4
+ hlcoord 0, 4
lb bc, 6, 10
call TextBoxBorder
- coord hl, 5, 0
+ hlcoord 5, 0
lb bc, 2, 9
call TextBoxBorder
- coord hl, 7, 2
+ hlcoord 7, 2
ld de, wPlayerName
call PlaceString
- coord hl, 1, 6
+ hlcoord 1, 6
ld de, HoFPlayTimeText
call PlaceString
- coord hl, 5, 7
+ hlcoord 5, 7
ld de, wPlayTimeHours
lb bc, 1, 3
call PrintNumber
@@ -247,10 +247,10 @@ HoFDisplayPlayerStats:
ld de, wPlayTimeMinutes
lb bc, LEADING_ZEROES | 1, 2
call PrintNumber
- coord hl, 1, 9
+ hlcoord 1, 9
ld de, HoFMoneyText
call PlaceString
- coord hl, 4, 10
+ hlcoord 4, 10
ld de, wPlayerMoney
ld c, $a3
call PrintBCDNumber
@@ -272,12 +272,12 @@ HoFMoneyText:
db "MONEY@"
DexSeenOwnedText:
- TX_FAR _DexSeenOwnedText
- db "@"
+ text_far _DexSeenOwnedText
+ text_end
DexRatingText:
- TX_FAR _DexRatingText
- db "@"
+ text_far _DexRatingText
+ text_end
HoFRecordMonInfo:
ld hl, wHallOfFame
diff --git a/engine/intro.asm b/engine/movie/intro.asm
index 00e892da..9165113f 100755
--- a/engine/intro.asm
+++ b/engine/movie/intro.asm
@@ -1,25 +1,20 @@
-const_value = -1
+ const_def -1
const MOVE_NIDORINO_RIGHT
const MOVE_GENGAR_RIGHT
const MOVE_GENGAR_LEFT
ANIMATION_END EQU 80
-const_value = 3
- const GENGAR_INTRO_TILES1
- const GENGAR_INTRO_TILES2
- const GENGAR_INTRO_TILES3
-
PlayIntro:
xor a
- ld [hJoyHeld], a
+ ldh [hJoyHeld], a
inc a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PlayShootingStar
- callab PlayIntroScene
+ callfar PlayIntroScene
xor a
- ld [hSCX], a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hSCX], a
+ ldh [hAutoBGTransferEnabled], a
call ClearSprites
call DelayFrame
ret
@@ -60,7 +55,7 @@ IntroClearScreen:
IntroClearMiddleOfScreen:
; clear the area of the tile map between the black bars on the top and bottom
- coord hl, 0, 4
+ hlcoord 0, 4
ld bc, SCREEN_WIDTH * 10
IntroClearCommon:
@@ -87,9 +82,9 @@ CopyTileIDsFromList_ZeroBaseTileID:
PlayShootingStar:
ld b, SET_PAL_GAME_FREAK_INTRO
call RunPaletteCommand
- callba LoadCopyrightAndTextBoxTiles
+ farcall LoadCopyrightAndTextBoxTiles
ldPal a, BLACK, DARK_GRAY, LIGHT_GRAY, WHITE
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 180
call DelayFrames
@@ -125,7 +120,7 @@ PlayShootingStar:
set 3, [hl]
ld c, 64
call DelayFrames
- callba AnimateShootingStar
+ farcall AnimateShootingStar
push af
pop af
jr c, .next ; skip the delay if the user interrupted the animation
@@ -139,26 +134,24 @@ PlayShootingStar:
IntroDrawBlackBars:
; clear the screen and draw black bars on the top and bottom
call IntroClearScreen
- coord hl, 0, 0
+ hlcoord 0, 0
ld c, SCREEN_WIDTH * 4
call IntroPlaceBlackTiles
- coord hl, 0, 14
+ hlcoord 0, 14
ld c, SCREEN_WIDTH * 4
call IntroPlaceBlackTiles
ld hl, vBGMap1
ld c, BG_MAP_WIDTH * 4
call IntroPlaceBlackTiles
- ld hl, vBGMap1 + BG_MAP_WIDTH * 14
+ hlbgcoord 0, 14, vBGMap1
ld c, BG_MAP_WIDTH * 4
jp IntroPlaceBlackTiles
-EmptyFunc4:
+EmptyFunc2:
ret
GameFreakIntro:
- INCBIN "gfx/gamefreak_intro.2bpp"
- INCBIN "gfx/gamefreak_logo.2bpp"
- rept 16
- db $00 ; blank tile
- endr
+ INCBIN "gfx/splash/gamefreak_presents.2bpp"
+ INCBIN "gfx/splash/gamefreak_logo.2bpp"
+ ds 16, $00 ; blank tile
GameFreakIntroEnd:
diff --git a/engine/clear_save.asm b/engine/movie/oak_speech/clear_save.asm
index f2acbf32..2dd5f4a7 100755
--- a/engine/clear_save.asm
+++ b/engine/movie/oak_speech/clear_save.asm
@@ -7,7 +7,7 @@ DoClearSaveDialogue:
call PrintText
ld a, B_BUTTON
ld [wJoyIgnore], a
- coord hl, 14, 7
+ hlcoord 14, 7
lb bc, 8, 15
ld a, NO_YES_MENU
ld [wTwoOptionMenuID], a
@@ -19,9 +19,9 @@ DoClearSaveDialogue:
ld a, [wCurrentMenuItem]
and a
jp z, Init
- callba ClearSAV
+ farcall ClearSAV
jp Init
ClearSaveDataText:
- TX_FAR _ClearSaveDataText
- db "@"
+ text_far _ClearSaveDataText
+ text_end
diff --git a/engine/init_player_data.asm b/engine/movie/oak_speech/init_player_data.asm
index 5883547c..d6745daf 100644
--- a/engine/init_player_data.asm
+++ b/engine/movie/oak_speech/init_player_data.asm
@@ -2,11 +2,11 @@ InitPlayerData:
InitPlayerData2:
call Random
- ld a, [hRandomSub]
+ ldh a, [hRandomSub]
ld [wPlayerID], a
call Random
- ld a, [hRandomAdd]
+ ldh a, [hRandomAdd]
ld [wPlayerID + 1], a
ld a, $ff
@@ -28,9 +28,9 @@ InitPlayerData2:
START_MONEY EQU $3000
ld hl, wPlayerMoney + 1
- ld a, START_MONEY / $100
+ ld a, HIGH(START_MONEY)
ld [hld], a
- xor a
+ xor a ; LOW(START_MONEY)
ld [hli], a
inc hl
ld [hl], a
diff --git a/engine/oak_speech.asm b/engine/movie/oak_speech/oak_speech.asm
index 8a537579..1a327def 100755
--- a/engine/oak_speech.asm
+++ b/engine/movie/oak_speech/oak_speech.asm
@@ -11,8 +11,8 @@ SetDefaultNames:
ld bc, wBoxDataEnd - wPlayerName
xor a
call FillMemory
- ld hl, wSpriteStateData1
- ld bc, $200
+ ld hl, wSpriteDataStart
+ ld bc, wSpriteDataEnd - wSpriteDataStart
xor a
call FillMemory
xor a
@@ -60,12 +60,12 @@ OakSpeech:
ld [wDestinationMap], a
call SpecialWarpIn
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld a, [wd732]
bit 1, a ; possibly a debug mode bit
jp nz, .skipChoosingNames
ld de, ProfOakPic
- lb bc, Bank(ProfOakPic), $00
+ lb bc, BANK(ProfOakPic), $00
call IntroDisplayPicCenteredOrUpperRight
call FadeInIntroPic
ld hl, OakSpeechText1
@@ -76,7 +76,7 @@ OakSpeech:
ld [wd0b5], a
ld [wcf91], a
call GetMonHeader
- coord hl, 6, 4
+ hlcoord 6, 4
call LoadFlippedFrontSpriteByMonIndex
call MovePicLeft
ld hl, OakSpeechText2
@@ -84,7 +84,7 @@ OakSpeech:
call GBFadeOutToWhite
call ClearScreen
ld de, RedPicFront
- lb bc, Bank(RedPicFront), $00
+ lb bc, BANK(RedPicFront), $00
call IntroDisplayPicCenteredOrUpperRight
call MovePicLeft
ld hl, IntroducePlayerText
@@ -93,7 +93,7 @@ OakSpeech:
call GBFadeOutToWhite
call ClearScreen
ld de, Rival1Pic
- lb bc, Bank(Rival1Pic), $00
+ lb bc, BANK(Rival1Pic), $00
call IntroDisplayPicCenteredOrUpperRight
call FadeInIntroPic
ld hl, IntroduceRivalText
@@ -103,7 +103,7 @@ OakSpeech:
call GBFadeOutToWhite
call ClearScreen
ld de, RedPicFront
- lb bc, Bank(RedPicFront), $00
+ lb bc, BANK(RedPicFront), $00
call IntroDisplayPicCenteredOrUpperRight
call GBFadeInFromWhite
ld a, [wd72d]
@@ -112,7 +112,7 @@ OakSpeech:
ld hl, OakSpeechText3
call PrintText
.next
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
ld a, SFX_SHRINK
call PlaySound
@@ -134,19 +134,19 @@ OakSpeech:
lb bc, BANK(ShrinkPic2), $00
call IntroDisplayPicCenteredOrUpperRight
call ResetPlayerSpriteData
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
ld a, BANK(Music_PalletTown)
ld [wAudioROMBank], a
ld [wAudioSavedROMBank], a
ld a, 10
ld [wAudioFadeOutControl], a
- call StopAllMusic ; stop music
+ call StopAllMusic
pop af
call BankswitchCommon
ld c, 20
call DelayFrames
- coord hl, 6, 5
+ hlcoord 6, 5
lb bc, 7, 7
call ClearScreenArea
call LoadTextBoxTilePatterns
@@ -159,29 +159,29 @@ OakSpeech:
ret
OakSpeechText1:
- TX_FAR _OakSpeechText1
- db "@"
+ text_far _OakSpeechText1
+ text_end
OakSpeechText2:
- TX_FAR _OakSpeechText2A
- TX_CRY_NIDORINA
- TX_FAR _OakSpeechText2B
- db "@"
+ text_far _OakSpeechText2A
+ sound_cry_pikachu
+ text_far _OakSpeechText2B
+ text_end
IntroducePlayerText:
- TX_FAR _IntroducePlayerText
- db "@"
+ text_far _IntroducePlayerText
+ text_end
IntroduceRivalText:
- TX_FAR _IntroduceRivalText
- db "@"
+ text_far _IntroduceRivalText
+ text_end
OakSpeechText3:
- TX_FAR _OakSpeechText3
- db "@"
+ text_far _OakSpeechText3
+ text_end
FadeInIntroPic:
ld hl, IntroFadePalettes
ld b, 6
.next
ld a, [hli]
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 10
call DelayFrames
@@ -199,19 +199,19 @@ IntroFadePalettes:
MovePicLeft:
ld a, 119
- ld [rWX], a
+ ldh [rWX], a
call DelayFrame
ld a, %11100100
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
.next
call DelayFrame
- ld a, [rWX]
+ ldh a, [rWX]
sub 8
cp $FF
ret z
- ld [rWX], a
+ ldh [rWX], a
jr .next
DisplayPicCenteredOrUpperRight:
@@ -235,10 +235,10 @@ IntroDisplayPicCenteredOrUpperRight:
pop bc
ld a, c
and a
- coord hl, 15, 1
+ hlcoord 15, 1
jr nz, .next
- coord hl, 6, 4
+ hlcoord 6, 4
.next
xor a
- ld [hStartTileID], a
+ ldh [hStartTileID], a
predef_jump CopyUncompressedPicToTilemap
diff --git a/engine/oak_speech2.asm b/engine/movie/oak_speech/oak_speech2.asm
index 80f1bafc..af31665b 100755
--- a/engine/oak_speech2.asm
+++ b/engine/movie/oak_speech/oak_speech2.asm
@@ -28,8 +28,8 @@ ChoosePlayerName:
jp PrintText
YourNameIsText:
- TX_FAR _YourNameIsText
- db "@"
+ text_far _YourNameIsText
+ text_end
ChooseRivalName:
call OakSpeechSlidePicRight
@@ -61,12 +61,12 @@ ChooseRivalName:
jp PrintText
HisNameIsText:
- TX_FAR _HisNameIsText
- db "@"
+ text_far _HisNameIsText
+ text_end
OakSpeechSlidePicLeft:
push de
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 12, 11
call ClearScreenArea ; clear the name list text box
ld c, 10
@@ -76,13 +76,13 @@ OakSpeechSlidePicLeft:
ld bc, NAME_LENGTH
call CopyData
call Delay3
- coord hl, 12, 4
+ hlcoord 12, 4
lb de, 6, 6 * SCREEN_WIDTH + 5
ld a, $ff
jr OakSpeechSlidePicCommon
OakSpeechSlidePicRight:
- coord hl, 5, 4
+ hlcoord 5, 4
lb de, 6, 6 * SCREEN_WIDTH + 5
xor a
@@ -90,13 +90,13 @@ OakSpeechSlidePicCommon:
push hl
push de
push bc
- ld [hSlideDirection], a
+ ldh [hSlideDirection], a
ld a, d
- ld [hSlideAmount], a
+ ldh [hSlideAmount], a
ld a, e
- ld [hSlidingRegionSize], a
+ ldh [hSlidingRegionSize], a
ld c, a
- ld a, [hSlideDirection]
+ ldh a, [hSlideDirection]
and a
jr nz, .next
; If sliding right, point hl to the end of the pic's tiles.
@@ -107,9 +107,9 @@ OakSpeechSlidePicCommon:
ld e, l
.loop
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [H_AUTOBGTRANSFERPORTION], a
- ld a, [hSlideDirection]
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hAutoBGTransferPortion], a
+ ldh a, [hSlideDirection]
and a
jr nz, .slideLeft
; sliding right
@@ -124,7 +124,7 @@ OakSpeechSlidePicCommon:
.next2
dec c
jr nz, .loop
- ld a, [hSlideDirection]
+ ldh a, [hSlideDirection]
and a
jr z, .next3
; If sliding left, we need to zero the last tile in the pic (there is no need
@@ -135,13 +135,13 @@ OakSpeechSlidePicCommon:
ld [hl], a
.next3
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
- ld a, [hSlidingRegionSize]
+ ldh a, [hSlidingRegionSize]
ld c, a
ld h, d
ld l, e
- ld a, [hSlideDirection]
+ ldh a, [hSlideDirection]
and a
jr nz, .slideLeft2
inc hl
@@ -151,9 +151,9 @@ OakSpeechSlidePicCommon:
.next4
ld d, h
ld e, l
- ld a, [hSlideAmount]
+ ldh a, [hSlideAmount]
dec a
- ld [hSlideAmount], a
+ ldh [hSlideAmount], a
jr nz, .loop
pop bc
pop de
@@ -162,14 +162,14 @@ OakSpeechSlidePicCommon:
DisplayIntroNameTextBox:
push de
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 10, 9
call TextBoxBorder
- coord hl, 3, 0
+ hlcoord 3, 0
ld de, .namestring
call PlaceString
pop de
- coord hl, 2, 2
+ hlcoord 2, 2
call PlaceString
call UpdateSprites
xor a
@@ -187,19 +187,7 @@ DisplayIntroNameTextBox:
.namestring
db "NAME@"
-DefaultNamesPlayer:
- db "NEW NAME"
- next "YELLOW"
- next "ASH"
- next "JACK"
- db "@"
-
-DefaultNamesRival:
- db "NEW NAME"
- next "BLUE"
- next "GARY"
- next "JOHN"
- db "@"
+INCLUDE "data/player_names.asm"
GetDefaultName:
; a = name index
@@ -225,17 +213,7 @@ GetDefaultName:
ld bc, $14
jp CopyData
-DefaultNamesPlayerList:
- db "NEW NAME@"
- db "YELLOW@"
- db "ASH@"
- db "JACK@"
-
-DefaultNamesRivalList:
- db "NEW NAME@"
- db "BLUE@"
- db "GARY@"
- db "JOHN@"
+INCLUDE "data/player_names_list.asm"
-TextTerminator_6b20:
- db "@"
+LinkMenuEmptyText:
+ text_end
diff --git a/engine/movie/splash.asm b/engine/movie/splash.asm
new file mode 100755
index 00000000..4cb0a59a
--- /dev/null
+++ b/engine/movie/splash.asm
@@ -0,0 +1,259 @@
+LoadShootingStarGraphics:
+ ld a, $f9
+ ldh [rOBP0], a
+ ld a, $a4
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP0
+ call UpdateGBCPal_OBP1
+ ld de, AnimationTileset2 tile 3 ; star tile (top left quadrant)
+ ld hl, vChars1 tile $20
+ lb bc, BANK(AnimationTileset2), $01
+ call CopyVideoData
+ ld de, AnimationTileset2 tile 19 ; star tile (bottom left quadrant)
+ ld hl, vChars1 tile $21
+ lb bc, BANK(AnimationTileset2), 1
+ call CopyVideoData
+ ld de, FallingStar
+ ld hl, vChars1 tile $22
+ lb bc, BANK(FallingStar), (FallingStarEnd - FallingStar) / $10
+ call CopyVideoData
+ ld hl, GameFreakLogoOAMData
+ ld de, wOAMBuffer + $60
+ ld bc, GameFreakLogoOAMDataEnd - GameFreakLogoOAMData
+ call CopyData
+ ld hl, GameFreakShootingStarOAMData
+ ld de, wOAMBuffer
+ ld bc, GameFreakShootingStarOAMDataEnd - GameFreakShootingStarOAMData
+ jp CopyData
+
+AnimateShootingStar:
+ call LoadShootingStarGraphics
+ ld a, SFX_SHOOTING_STAR
+ call PlaySound
+
+; Move the big star down and left across the screen.
+ ld hl, wOAMBuffer
+ lb bc, $a0, $4
+.bigStarLoop
+ push hl
+ push bc
+.bigStarInnerLoop
+ ld a, [hl] ; Y
+ add 4
+ ld [hli], a
+ ld a, [hl] ; X
+ add -4
+ ld [hli], a
+ inc hl
+ inc hl
+ dec c
+ jr nz, .bigStarInnerLoop
+ ld c, 1
+ call CheckForUserInterruption
+ pop bc
+ pop hl
+ ret c
+ ld a, [hl]
+ cp 80
+ jr nz, .next
+ jr .bigStarLoop
+.next
+ cp b
+ jr nz, .bigStarLoop
+
+; Clear big star OAM.
+ ld hl, wOAMBuffer
+ ld c, 4
+ ld de, 4
+.clearOAMLoop
+ ld [hl], 160
+ add hl, de
+ dec c
+ jr nz, .clearOAMLoop
+
+; Make Gamefreak logo flash.
+ ld b, 3
+.flashLogoLoop
+ ld hl, rOBP0
+ rrc [hl]
+ rrc [hl]
+ call UpdateGBCPal_OBP0
+ ld c, 10
+ call CheckForUserInterruption
+ ret c
+ dec b
+ jr nz, .flashLogoLoop
+
+; Copy 24 instances of the small stars OAM data.
+; Note that their coordinates put them off-screen.
+ ld de, wOAMBuffer
+ ld a, 24
+.initSmallStarsOAMLoop
+ push af
+ ld hl, SmallStarsOAM
+ ld bc, SmallStarsOAMEnd - SmallStarsOAM
+ call CopyData
+ pop af
+ dec a
+ jr nz, .initSmallStarsOAMLoop
+
+; Animate the small stars falling from the Gamefreak logo.
+ xor a
+ ld [wMoveDownSmallStarsOAMCount], a
+ ld hl, SmallStarsWaveCoordsPointerTable
+ ld c, 6
+.smallStarsLoop
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ push bc
+ push hl
+ ld hl, wOAMBuffer + $50
+ ld c, 4
+.smallStarsInnerLoop ; introduce new wave of 4 small stars OAM entries
+ ld a, [de]
+ cp -1
+ jr z, .next2
+ ld [hli], a ; Y
+ inc de
+ ld a, [de]
+ ld [hli], a ; X
+ inc de
+ inc hl
+ push bc
+ ld a, [de]
+ ld b, a
+ ld a, [hl]
+ and $f0
+ or b
+ ld [hl], a
+ inc de
+ pop bc
+ inc hl
+ dec c
+ jr nz, .smallStarsInnerLoop
+ ld a, [wMoveDownSmallStarsOAMCount]
+ cp 24
+ jr z, .next2
+ add 6 ; should be 4, but the extra 2 aren't visible on screen
+ ld [wMoveDownSmallStarsOAMCount], a
+.next2
+ call MoveDownSmallStars
+ push af
+
+; shift the existing OAM entries down to make room for the next wave
+ ld hl, wOAMBuffer + $10
+ ld de, wOAMBuffer
+ ld bc, $50
+ call CopyData
+
+ pop af
+ pop hl
+ pop bc
+ ret c
+ dec c
+ jr nz, .smallStarsLoop
+ and a
+ ret
+
+SmallStarsOAM:
+ dbsprite 0, 0, 0, 0, $A2, OAM_BEHIND_BG | OAM_OBP1
+SmallStarsOAMEnd:
+
+SmallStarsWaveCoordsPointerTable:
+ dw SmallStarsWave1Coords
+ dw SmallStarsWave2Coords
+ dw SmallStarsWave3Coords
+ dw SmallStarsWave4Coords
+ dw SmallStarsEmptyWave
+ dw SmallStarsEmptyWave
+
+; The stars that fall from the Gamefreak logo come in 4 waves of 4 OAM entries.
+; These arrays contain the Y and X coordinates of each OAM entry.
+
+SmallStarsWave1Coords:
+ db $68, $30
+ db $05, $68
+ db $40, $05
+ db $68, $58
+ db $04, $68
+ db $78, $07
+SmallStarsWave2Coords:
+ db $68, $38
+ db $05, $68
+ db $48, $06
+ db $68, $60
+ db $04, $68
+ db $70, $07
+SmallStarsWave3Coords:
+ db $68, $34
+ db $05, $68
+ db $4c, $06
+ db $68, $54
+ db $06, $68
+ db $64, $07
+SmallStarsWave4Coords:
+ db $68, $3c
+ db $05, $68
+ db $5c, $04
+ db $68, $6c
+ db $07, $68
+ db $74, $07
+SmallStarsEmptyWave:
+ db -1 ; end
+
+MoveDownSmallStars:
+ ld b, 8
+.loop
+ ld hl, wOAMBuffer + $5c
+ ld a, [wMoveDownSmallStarsOAMCount]
+ ld de, -4
+ ld c, a
+.innerLoop
+ inc [hl] ; Y
+ add hl, de
+ dec c
+ jr nz, .innerLoop
+; Toggle the palette so that the lower star in the small stars tile blinks in
+; and out.
+ ldh a, [rOBP1]
+ xor %10100000
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ ld c, 3
+ call CheckForUserInterruption
+ ret c
+ dec b
+ jr nz, .loop
+ ret
+
+GameFreakLogoOAMData:
+ dbsprite 10, 9, 0, 0, $8d, 0
+ dbsprite 11, 9, 0, 0, $8e, 0
+ dbsprite 10, 10, 0, 0, $8f, 0
+ dbsprite 11, 10, 0, 0, $90, 0
+ dbsprite 10, 11, 0, 0, $91, 0
+ dbsprite 11, 11, 0, 0, $92, 0
+ dbsprite 6, 12, 0, 0, $80, 0
+ dbsprite 7, 12, 0, 0, $81, 0
+ dbsprite 8, 12, 0, 0, $82, 0
+ dbsprite 9, 12, 0, 0, $83, 0
+ dbsprite 10, 12, 0, 0, $93, 0
+ dbsprite 11, 12, 0, 0, $84, 0
+ dbsprite 12, 12, 0, 0, $85, 0
+ dbsprite 13, 12, 0, 0, $83, 0
+ dbsprite 14, 12, 0, 0, $81, 0
+ dbsprite 15, 12, 0, 0, $86, 0
+GameFreakLogoOAMDataEnd:
+
+GameFreakShootingStarOAMData:
+ dbsprite 20, 0, 0, 0, $a0, OAM_OBP1 | %100
+ dbsprite 21, 0, 0, 0, $a0, OAM_OBP1 | OAM_HFLIP | %100
+ dbsprite 20, 1, 0, 0, $a1, OAM_OBP1 | %100
+ dbsprite 21, 1, 0, 0, $a1, OAM_OBP1 | OAM_HFLIP | %100
+GameFreakShootingStarOAMDataEnd:
+
+FallingStar:
+ INCBIN "gfx/splash/falling_star.2bpp"
+FallingStarEnd:
diff --git a/engine/movie/title.asm b/engine/movie/title.asm
new file mode 100755
index 00000000..1f2723a3
--- /dev/null
+++ b/engine/movie/title.asm
@@ -0,0 +1,370 @@
+SetDefaultNamesBeforeTitlescreen::
+ ld hl, NintenText
+ ld de, wPlayerName
+ call CopyFixedLengthText
+ ld hl, SonyText
+ ld de, wRivalName
+ call CopyFixedLengthText
+ xor a
+ ldh [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
+ ldh [hAutoBGTransferEnabled], a
+ xor a
+ ldh [hTilesetType], a
+ ldh [hSCX], a
+ ld a, $40
+ ldh [hSCY], a
+ ld a, $90
+ ldh [hWY], a
+ call ClearScreen
+ call DisableLCD
+ call LoadFontTilePatterns
+; todo: fix hl pointers
+ ld hl, NintendoCopyrightLogoGraphics
+ ld de, vTitleLogo tile $60
+ ld bc, 5 tiles
+ ld a, BANK(NintendoCopyrightLogoGraphics)
+ call FarCopyData
+ ld hl, NineTile
+ ld de, vTitleLogo tile $6e
+ ld bc, $10
+ ld a, BANK(NineTile)
+ call FarCopyData
+ ld hl, GamefreakLogoGraphics
+ ld de, vTitleLogo tile $65
+ ld bc, 9 tiles
+ ld a, BANK(GamefreakLogoGraphics)
+ call FarCopyData
+ callfar LoadYellowTitleScreenGFX
+ ld hl, vBGMap0
+ ld bc, (vBGMap1 tile $40) - vBGMap0
+ ld a, " "
+ call FillMemory
+ callfar TitleScreen_PlacePokemonLogo
+ call FillSpriteBuffer0WithAA
+ call .WriteCopyrightTiles
+ call SaveScreenTilesToBuffer2
+ call LoadScreenTilesFromBuffer2
+ call EnableLCD
+ callfar TitleScreen_PlacePikachu
+ ld a, HIGH(vBGMap0 + $300)
+ call TitleScreenCopyTileMapToVRAM
+ call SaveScreenTilesToBuffer1
+ ld a, $40
+ ldh [hWY], a
+ call LoadScreenTilesFromBuffer2
+ ld a, HIGH(vBGMap0)
+ call TitleScreenCopyTileMapToVRAM
+ ld b, SET_PAL_TITLE_SCREEN
+ call RunPaletteCommand
+ call GBPalNormal
+ ld a, %11100000
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+
+; 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
+
+; place tiles for title screen copyright
+.WriteCopyrightTiles
+ hlcoord 2, 17
+ ld de, .tileScreenCopyrightTiles
+.titleScreenCopyrightTilesLoop
+ ld a, [de]
+ inc de
+ cp $ff
+ ret z
+ ld [hli], a
+ jr .titleScreenCopyrightTilesLoop
+
+.tileScreenCopyrightTiles
+ db $e0,$e1,$e2,$e3,$e1,$e2,$ee,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ff ; ©1995-1999 GAME FREAK inc.
+
+.finishedBouncingPokemonLogo
+ call LoadScreenTilesFromBuffer1
+ ld c, 36
+ call DelayFrames
+ ld a, SFX_INTRO_WHOOSH
+ call PlaySound
+
+; scroll game version in from the right
+ callfar TitleScreen_PlacePikaSpeechBubble
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
+ call Delay3
+ ld e, 0
+ call TitleScreen_PlayPikachuPCM
+ call WaitForSoundToFinish
+ call StopAllMusic
+ ld a, MUSIC_TITLE_SCREEN
+ ld [wNewSoundID], a
+ call PlaySound
+.loop
+ xor a
+ ld [wUnusedCC5B], a
+ ld [wTitleScreenScene], a
+ ld [wTitleScreenScene + 1], a
+ ld [wTitleScreenScene + 2], a
+ ld [wTitleScreenScene + 3], a
+ ld a, $f
+ ld [wTitleScreenScene + 4], a
+.titleScreenLoop
+ call IncrementResetCounter
+ jp c, .doTitlescreenReset
+ call DelayFrame
+ call JoypadLowSensitivity
+ ldh a, [hJoyHeld]
+ cp D_UP | SELECT | B_BUTTON
+ jr z, .go_to_main_menu
+ and A_BUTTON | START
+ jr nz, .go_to_main_menu
+ call DoTitleScreenFunction
+ jr .titleScreenLoop
+
+.go_to_main_menu
+ ld e, $a
+ call TitleScreen_PlayPikachuPCM
+ call GBPalWhiteOutWithDelay3
+ call ClearSprites
+ xor a
+ ldh [hWY], a
+ inc a
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld a, HIGH(vBGMap0)
+ call TitleScreenCopyTileMapToVRAM
+ ld a, HIGH(vBGMap1)
+ call TitleScreenCopyTileMapToVRAM
+ call Delay3
+ call LoadGBPal
+ ldh a, [hJoyHeld]
+ ld b, a
+ and D_UP | SELECT | B_BUTTON
+ cp D_UP | SELECT | B_BUTTON
+ jp z, .doClearSaveDialogue
+ jp MainMenu
+
+.asm_42f0
+; unreferenced
+ callfar PrinterDebug
+ jp .loop
+
+.asm_42fb
+; unreferenced
+ ld a, [wTitleScreenScene + 4]
+ inc a
+ cp $2a
+ jr c, .asm_4305
+ ld a, $f
+.asm_4305
+ ld [wTitleScreenScene + 4], a
+ ld e, a
+ callfar PlayPikachuSoundClip
+ xor a
+ ld [wTitleScreenScene + 2], a
+ ld [wTitleScreenScene + 3], a
+ jp .titleScreenLoop
+
+.doTitlescreenReset
+ ld [wAudioFadeOutControl], a
+ call StopAllMusic
+.audioFadeLoop
+ ld a, [wAudioFadeOutControl]
+ and a
+ jr nz, .audioFadeLoop
+ jp Init
+
+.doClearSaveDialogue
+ farjp DoClearSaveDialogue
+
+
+TitleScreenCopyTileMapToVRAM:
+ ldh [hAutoBGTransferDest + 1], a
+ jp Delay3
+
+LoadCopyrightAndTextBoxTiles:
+ xor a
+ ldh [hWY], a
+ call ClearScreen
+ call LoadTextBoxTilePatterns
+
+LoadCopyrightTiles:
+ ld de, NintendoCopyrightLogoGraphics
+ ld hl, vChars2 tile $60
+ lb bc, BANK(NintendoCopyrightLogoGraphics), (TextBoxGraphics + $10 - NintendoCopyrightLogoGraphics) / $10 ; bug: overflows into text box graphics and copies the "A" tile
+ call CopyVideoData
+ hlcoord 2, 7
+ ld de, CopyrightTextString
+ jp PlaceString
+
+CopyrightTextString:
+ db $60,$61,$62,$63,$61,$62,$7c,$7f,$65,$66,$67,$68,$69,$6a ; ©1995-1999 Nintendo
+ next $60,$61,$62,$63,$61,$62,$7c,$7f,$6b,$6c,$6d,$6e,$6f,$70,$71,$72 ; ©1995-1999 Creatures inc.
+ next $60,$61,$62,$63,$61,$62,$7c,$7f,$73,$74,$75,$76,$77,$78,$79,$7a,$7b ; ©1995-1999 GAME FREAK inc.
+ db "@"
+
+TitleScreen_PlayPikachuPCM:
+ callfar PlayPikachuSoundClip
+ ret
+
+DoTitleScreenFunction:
+ call .CheckTimer
+ ld a, [wTitleScreenScene]
+ ld e, a
+ ld d, 0
+ ld hl, .Jumptable
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ jp hl
+
+
+.Jumptable:
+ dw .Nop
+ dw .BlinkHalf
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkClosed
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkHalf
+ dw .BlinkWait
+ dw .BlinkWait
+ dw .BlinkOpen
+ dw .GoBackToStart
+
+.GoBackToStart:
+ xor a
+ ld [wTitleScreenScene], a
+.Nop
+ ret
+
+.BlinkOpen:
+ ld e, 0
+ jr .LoadBlinkFrame
+
+.BlinkHalf:
+ ld e, 4
+ jr .LoadBlinkFrame
+
+.BlinkClosed:
+ ld e, 8
+.LoadBlinkFrame:
+ ld hl, wOAMBuffer + 2
+ ld c, 8
+.loop
+ ld a, [hl]
+ and $f3
+ or e
+ ld [hli], a
+ inc hl
+ inc hl
+ inc hl
+ dec c
+ jr nz, .loop
+.BlinkWait:
+ ld hl, wTitleScreenScene
+ inc [hl]
+ ret
+
+.CheckTimer:
+ ld hl, wTitleScreenTimer
+ ld a, [hl]
+ inc [hl]
+ and a
+ jr z, .restart
+ cp $80
+ jr z, .restart
+ cp $90
+ ret nz
+.restart
+ ld a, $1
+ ld [wTitleScreenScene], a
+ ret
+
+; copy text of fixed length NAME_LENGTH (like player name, rival name, mon names, ...)
+CopyFixedLengthText:
+ ld bc, NAME_LENGTH
+ jp CopyData
+
+NintenText: db "NINTEN@"
+SonyText: db "SONY@"
+
+IncrementResetCounter:
+ ld hl, wTitleScreenScene + 2
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ inc de
+ ld a, d
+ cp $c
+ jr z, .doReset
+ ld [hl], d
+ dec hl
+ ld [hl], e
+ and a
+ ret
+
+.doReset
+ scf
+ ret
+
+FillSpriteBuffer0WithAA:
+ xor a
+ call SwitchSRAMBankAndLatchClockData
+ ld hl, sSpriteBuffer0
+ ld bc, $20
+ ld a, $aa
+ call FillMemory
+ call PrepareRTCDataAndDisableSRAM
+ ret
diff --git a/engine/movie/title2.asm b/engine/movie/title2.asm
new file mode 100755
index 00000000..df630b53
--- /dev/null
+++ b/engine/movie/title2.asm
@@ -0,0 +1,122 @@
+; Leftover of Red/Blue. Seemingly unused
+
+TitleScroll_WaitBall:
+; Wait around for the TitleBall animation to play out.
+; hi: speed
+; lo: duration
+ db $05, $05, 0
+
+TitleScroll_In:
+; Scroll a TitleMon in from the right.
+; hi: speed
+; lo: duration
+ db $a2, $94, $84, $63, $52, $31, $11, 0
+
+TitleScroll_Out:
+; Scroll a TitleMon out to the left.
+; hi: speed
+; lo: duration
+ db $12, $22, $32, $42, $52, $62, $83, $93, 0
+
+TitleScroll:
+ ld a, d
+
+ ld bc, TitleScroll_In
+ ld d, $88
+ ld e, 0 ; don't animate titleball
+
+ and a
+ jr nz, .ok
+
+ ld bc, TitleScroll_Out
+ ld d, $00
+ ld e, 0 ; don't animate titleball
+.ok
+
+_TitleScroll:
+ ld a, [bc]
+ and a
+ ret z
+
+ inc bc
+ push bc
+
+ ld b, a
+ and $f
+ ld c, a
+ ld a, b
+ and $f0
+ swap a
+ ld b, a
+
+.loop
+ ld h, d
+ ld l, $48
+ call .ScrollBetween
+
+ ld h, $00
+ ld l, $88
+ call .ScrollBetween
+
+ ld a, d
+ add b
+ ld d, a
+
+ call GetTitleBallY
+ dec c
+ jr nz, .loop
+
+ pop bc
+ jr _TitleScroll
+
+.ScrollBetween:
+.wait
+ ldh a, [rLY] ; rLY
+ cp l
+ jr nz, .wait
+
+ ld a, h
+ ldh [rSCX], a
+
+.wait2
+ ldh a, [rLY] ; rLY
+ cp h
+ jr z, .wait2
+ ret
+
+TitleBallYTable:
+; OBJ y-positions for the Poke Ball held by Red in the title screen.
+; This is really two 0-terminated lists. Initiated with an index of 1.
+ db 0, $71, $6f, $6e, $6d, $6c, $6d, $6e, $6f, $71, $74, 0
+
+TitleScreenAnimateBallIfStarterOut:
+; Animate the TitleBall if a starter just got scrolled out.
+ ld a, [wTitleScreenScene]
+ cp STARTER1
+ jr z, .ok
+ cp STARTER2
+ jr z, .ok
+ cp STARTER3
+ ret nz
+.ok
+ ld e, 1 ; animate titleball
+ ld bc, TitleScroll_WaitBall
+ ld d, 0
+ jp _TitleScroll
+
+GetTitleBallY:
+; Get position e from TitleBallYTable
+ push de
+ push hl
+ xor a
+ ld d, a
+ ld hl, TitleBallYTable
+ add hl, de
+ ld a, [hl]
+ pop hl
+ pop de
+ and a
+ ret z
+ ld [wOAMBuffer + $28], a
+ inc e
+ ret
diff --git a/engine/movie/trade.asm b/engine/movie/trade.asm
new file mode 100755
index 00000000..7be100e0
--- /dev/null
+++ b/engine/movie/trade.asm
@@ -0,0 +1,859 @@
+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
+ and %110000 ; preserve speaker options
+ ld [wOptions], a
+ ldh a, [hSCY]
+ push af
+ ldh a, [hSCX]
+ push af
+ xor a
+ ldh [hSCY], a
+ ldh [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
+ ldh [hSCX], a
+ pop af
+ ldh [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 -1 ; end
+
+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 -1 ; end
+
+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
+ ldh [hAutoBGTransferEnabled], a
+ call Delay3
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_Delay80:
+ ld c, 80
+ jp DelayFrames
+
+Trade_ClearTileMap:
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, " "
+ jp FillMemory
+
+LoadTradingGFXAndMonNames:
+ call Trade_ClearTileMap
+ call DisableLCD
+ ld hl, TradingAnimationGraphics
+ ld de, vChars2 tile $31
+ ld bc, TradingAnimationGraphicsEnd - TradingAnimationGraphics
+ ld a, BANK(TradingAnimationGraphics)
+ call FarCopyData
+ ld hl, TradingAnimationGraphics2
+ ld de, vSprites tile $7c
+ ld bc, TradingAnimationGraphics2End - TradingAnimationGraphics2
+ ld a, BANK(TradingAnimationGraphics2)
+ call FarCopyData
+ 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
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ call EnableLCD
+ xor a
+ ldh [hAutoBGTransferEnabled], 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
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ farjp 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
+ ldh [rLCDC], a
+ ld a, $50
+ ldh [hWY], a
+ ld a, $86
+ ldh [rWX], a
+ ldh [hSCX], a
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 4, 0
+ lb bc, 6, 10
+ call TextBoxBorder
+ call Trade_PrintPlayerMonInfoText
+ ld b, HIGH(vBGMap0)
+ call CopyScreenTileBufferToVRAM
+ call ClearScreen
+ ld a, [wTradedPlayerMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, $7e
+.slideScreenLoop
+ push af
+ call DelayFrame
+ pop af
+ ldh [rWX], a
+ ldh [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
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_DrawOpenEndOfLinkCable:
+ call Trade_ClearTileMap
+ ld b, HIGH(vBGMap0)
+ 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
+ ldh [hSCX], a
+ call DelayFrame
+ ld a, %10001011
+ ldh [rLCDC], a
+ hlcoord 6, 2
+ ld b, TILEMAP_LINK_CABLE
+ call CopyTileIDsFromList_ZeroBaseTileID
+ call Trade_CopyTileMapToVRAM
+ ld a, SFX_HEAL_HP
+ call PlaySound
+ ld c, 20
+.loop
+ ldh a, [hSCX]
+ add 4
+ ldh [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
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ 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
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld b, $98
+ call CopyScreenTileBufferToVRAM
+ call Delay3
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ ret
+
+Trade_BallInsideLinkCableOAM:
+ dbsprite 0, 15, 0, 6, $7e, OAM_HFLIP
+ dbsprite 8, 15, 0, 6, $7e, OAM_HFLIP | OAM_VFLIP
+
+Trade_ShowEnemyMon:
+ ld a, TRADE_BALL_TILT_ANIM
+ call Trade_ShowAnimation
+ call Trade_ShowClearedWindow
+ hlcoord 4, 10
+ lb bc, 6, 10
+ call TextBoxBorder
+ call Trade_PrintEnemyMonInfoText
+ call Trade_CopyTileMapToVRAM
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wTradedEnemyMonSpecies]
+ call Trade_LoadMonSprite
+ ld a, TRADE_BALL_POOF_ANIM
+ call Trade_ShowAnimation
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, [wTradedEnemyMonSpecies]
+ call PlayCry
+ call Trade_Delay100
+ hlcoord 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
+ ldh [rOBP0], a
+ call UpdateGBCPal_OBP0
+ 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
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawRightGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ldh [hAutoBGTransferEnabled], 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
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_DrawCableAcrossScreen
+ ld b, $4
+ call Trade_AnimMonMoveHorizontal
+ call Trade_DrawLeftGameboy
+ ld b, $6
+ call Trade_AnimMonMoveHorizontal
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ jp ClearSprites
+
+Trade_InitGameboyTransferGfx:
+; Initialises the graphics for showing a mon moving between gameboys.
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld b, SET_PAL_GENERIC
+ call RunPaletteCommand
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ call Trade_LoadMonPartySpriteGfx
+ call DelayFrame
+ ld a, %10101011
+ ldh [rLCDC], a
+ xor a
+ ldh [hSCX], a
+ ld a, $90
+ ldh [hWY], a
+ ret
+
+Trade_DrawLeftGameboy:
+ call Trade_ClearTileMap
+
+; draw link cable
+ hlcoord 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
+ hlcoord 5, 3
+ ld b, TILEMAP_GAME_BOY
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with player name below gameboy pic
+ hlcoord 4, 12
+ lb bc, 2, 7
+ call TextBoxBorder
+ hlcoord 5, 14
+ ld de, wPlayerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawRightGameboy:
+ call Trade_ClearTileMap
+
+; draw horizontal segment of link cable
+ hlcoord 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
+ hlcoord 7, 8
+ ld b, TILEMAP_GAME_BOY
+ call CopyTileIDsFromList_ZeroBaseTileID
+
+; draw text box with enemy name above link cable
+ hlcoord 6, 0
+ lb bc, 2, 7
+ call TextBoxBorder
+ hlcoord 7, 2
+ ld de, wLinkEnemyTrainerName
+ call PlaceString
+
+ jp DelayFrame
+
+Trade_DrawCableAcrossScreen:
+; Draws the link cable across the screen.
+ call Trade_ClearTileMap
+ hlcoord 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
+ hlcoord 0, 4
+ call CopyToRedrawRowOrColumnSrcTiles
+ pop hl
+ ld a, h
+ ldh [hRedrawRowOrColumnDest + 1], a
+ ld a, l
+ ldh [hRedrawRowOrColumnDest], a
+ ld a, REDRAW_ROW
+ ldh [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
+ ldh a, [hSCX]
+ sub $2
+ jr .next
+.movingRight
+ ldh a, [hSCX]
+ add $2
+.next
+ ldh [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
+ ldh a, [rBGP]
+ xor $3c ; make link cable flash
+ ldh [rBGP], a
+ call UpdateGBCPal_BGP
+ ld hl, wOAMBuffer + $02
+ ld de, $4
+ ld c, $14
+.loop
+ ld a, [hl]
+ xor ICONOFFSET
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ pop hl
+ pop bc
+ pop de
+ ret
+
+Trade_WriteCircledMonOAM:
+ farcall WriteMonPartySpriteOAMBySpecies
+ call Trade_WriteCircleOAM
+
+Trade_AddOffsetsToOAMCoords:
+ ld hl, wOAMBuffer
+ ld c, $14 ; SCREEN_WIDTH?
+.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_circle_oam: MACRO
+ dw \1
+ db \2, \3
+ENDM
+
+Trade_CircleOAMPointers:
+ ; oam pointer, upper-left x coord, upper-left y coord
+ trade_circle_oam Trade_CircleOAM0, $08, $08
+ trade_circle_oam Trade_CircleOAM1, $18, $08
+ trade_circle_oam Trade_CircleOAM2, $08, $18
+ trade_circle_oam Trade_CircleOAM3, $18, $18
+
+Trade_CircleOAM0:
+ dbsprite 2, 7, 0, 0, ICON_TRADEBUBBLE << 2 + 1, OAM_OBP1
+ dbsprite 2, 7, 0, 2, ICON_TRADEBUBBLE << 2 + 3, OAM_OBP1
+
+Trade_CircleOAM1:
+ dbsprite 6, 7, 0, 1, ICON_TRADEBUBBLE << 2 + 0, OAM_OBP1 | OAM_HFLIP
+ dbsprite 6, 7, 0, 3, ICON_TRADEBUBBLE << 2 + 2, OAM_OBP1 | OAM_HFLIP
+
+Trade_CircleOAM2:
+ dbsprite 10, 7, 0, 2, ICON_TRADEBUBBLE << 2 + 3, OAM_OBP1 | OAM_VFLIP
+ dbsprite 10, 7, 0, 0, ICON_TRADEBUBBLE << 2 + 1, OAM_OBP1 | OAM_VFLIP
+
+Trade_CircleOAM3:
+ dbsprite 14, 7, 0, 3, ICON_TRADEBUBBLE << 2 + 2, OAM_OBP1 | OAM_HFLIP | OAM_VFLIP
+ dbsprite 14, 7, 0, 1, ICON_TRADEBUBBLE << 2 + 0, OAM_OBP1 | OAM_HFLIP | OAM_VFLIP
+
+; 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
+ ldh a, [hAutoBGTransferEnabled]
+ xor $1
+ ldh [hAutoBGTransferEnabled], a
+ call GetMonHeader
+ hlcoord 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
+ ldh [hAutoBGTransferEnabled], a
+ call ClearScreen
+ ld a, %11100011
+ ldh [rLCDC], a
+ ld a, $7
+ ldh [rWX], a
+ xor a
+ ldh [hWY], a
+ ld a, $90
+ ldh [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
+ ldh a, [rWX]
+ inc a
+ inc a
+ ldh [rWX], a
+ cp $a1
+ jr nz, .loop
+ call Trade_ClearTileMap
+ ld c, 10
+ call DelayFrames
+ ld a, $7
+ ldh [rWX], a
+ ret
+
+PrintTradeWentToText:
+ ld hl, TradeWentToText
+ call PrintText
+ ld c, 200
+ call DelayFrames
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWentToText:
+ text_far _TradeWentToText
+ text_end
+
+PrintTradeForSendsText:
+ ld hl, TradeForText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeSendsText
+ call PrintText
+ jp Trade_Delay80
+
+TradeForText:
+ text_far _TradeForText
+ text_end
+
+TradeSendsText:
+ text_far _TradeSendsText
+ text_end
+
+PrintTradeFarewellText:
+ ld hl, TradeWavesFarewellText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeTransferredText
+ call PrintText
+ call Trade_Delay80
+ jp Trade_SlideTextBoxOffScreen
+
+TradeWavesFarewellText:
+ text_far _TradeWavesFarewellText
+ text_end
+
+TradeTransferredText:
+ text_far _TradeTransferredText
+ text_end
+
+PrintTradeTakeCareText:
+ ld hl, TradeTakeCareText
+ call PrintText
+ jp Trade_Delay80
+
+TradeTakeCareText:
+ text_far _TradeTakeCareText
+ text_end
+
+PrintTradeWillTradeText:
+ ld hl, TradeWillTradeText
+ call PrintText
+ call Trade_Delay80
+ ld hl, TradeforText
+ call PrintText
+ jp Trade_Delay80
+
+TradeWillTradeText:
+ text_far _TradeWillTradeText
+ text_end
+
+TradeforText:
+ text_far _TradeforText
+ text_end
+
+Trade_ShowAnimation:
+ ld [wAnimationID], a
+ xor a
+ ld [wAnimationType], a
+ predef_jump MoveAnimation
diff --git a/engine/trade2.asm b/engine/movie/trade2.asm
index 2c79e077..f0d91846 100755
--- a/engine/trade2.asm
+++ b/engine/movie/trade2.asm
@@ -1,48 +1,49 @@
Trade_PrintPlayerMonInfoText:
- coord hl, 5, 0
+ hlcoord 5, 0
ld de, Trade_MonInfoText
call PlaceString
ld a, [wTradedPlayerMonSpecies]
ld [wd11e], a
predef IndexToPokedex
- coord hl, 9, 0
+ hlcoord 9, 0
ld de, wd11e
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber
- coord hl, 5, 2
+ hlcoord 5, 2
ld de, wcf4b
call PlaceString
- coord hl, 8, 4
+ hlcoord 8, 4
ld de, wTradedPlayerMonOT
call PlaceString
- coord hl, 8, 6
+ hlcoord 8, 6
ld de, wTradedPlayerMonOTID
lb bc, LEADING_ZEROES | 2, 5
jp PrintNumber
Trade_PrintEnemyMonInfoText:
- coord hl, 5, 10
+ hlcoord 5, 10
ld de, Trade_MonInfoText
call PlaceString
ld a, [wTradedEnemyMonSpecies]
ld [wd11e], a
predef IndexToPokedex
- coord hl, 9, 10
+ hlcoord 9, 10
ld de, wd11e
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber
- coord hl, 5, 12
+ hlcoord 5, 12
ld de, wcd6d
call PlaceString
- coord hl, 8, 14
+ hlcoord 8, 14
ld de, wTradedEnemyMonOT
call PlaceString
- coord hl, 8, 16
+ hlcoord 8, 16
ld de, wTradedEnemyMonOTID
lb bc, LEADING_ZEROES | 2, 5
jp PrintNumber
Trade_MonInfoText:
- db "──№⠄",$4E
+ db "──№<DOT>"
+ next ""
next "OT/"
- next $73,"№⠄","@"
+ next "<ID>№<DOT>@"
diff --git a/engine/multiply_divide.asm b/engine/multiply_divide.asm
deleted file mode 100755
index d664c9d4..00000000
--- a/engine/multiply_divide.asm
+++ /dev/null
@@ -1,144 +0,0 @@
-_Multiply:
- ld a, $8
- ld b, a
- xor a
- ld [H_PRODUCT], a
- ld [H_MULTIPLYBUFFER], a
- ld [H_MULTIPLYBUFFER+1], a
- ld [H_MULTIPLYBUFFER+2], a
- ld [H_MULTIPLYBUFFER+3], a
-.multiplyLoop
- ld a, [H_MULTIPLIER]
- srl a
- ld [H_MULTIPLIER], a
- jr nc, .smallMultiplier ; less than $80
-; code to possibly multiply the multiplicand by 2 and divide the multiplier by 2?
- ld a, [H_MULTIPLYBUFFER+3]
- ld c, a
- ld a, [H_MULTIPLICAND+2]
- add c
- ld [H_MULTIPLYBUFFER+3], a
- ld a, [H_MULTIPLYBUFFER+2]
- ld c, a
- ld a, [H_MULTIPLICAND+1]
- adc c
- ld [H_MULTIPLYBUFFER+2], a
- ld a, [H_MULTIPLYBUFFER+1]
- ld c, a
- ld a, [H_MULTIPLICAND]
- adc c
- ld [H_MULTIPLYBUFFER+1], a
- ld a, [H_MULTIPLYBUFFER]
- ld c, a
- ld a, [H_PRODUCT]
- adc c
- ld [H_MULTIPLYBUFFER], a
-.smallMultiplier
- dec b
- jr z, .done
- ld a, [H_MULTIPLICAND+2]
- sla a
- ld [H_MULTIPLICAND+2], a
- ld a, [H_MULTIPLICAND+1]
- rl a
- ld [H_MULTIPLICAND+1], a
- ld a, [H_MULTIPLICAND]
- rl a
- ld [H_MULTIPLICAND], a
- ld a, [H_PRODUCT]
- rl a
- ld [H_PRODUCT], a
- jr .multiplyLoop
-.done
- ld a, [H_MULTIPLYBUFFER+3]
- ld [H_PRODUCT+3], a
- ld a, [H_MULTIPLYBUFFER+2]
- ld [H_PRODUCT+2], a
- ld a, [H_MULTIPLYBUFFER+1]
- ld [H_PRODUCT+1], a
- ld a, [H_MULTIPLYBUFFER]
- ld [H_PRODUCT], a
- ret
-
-_Divide:
- xor a
- ld [H_DIVIDEBUFFER], a
- ld [H_DIVIDEBUFFER+1], a
- ld [H_DIVIDEBUFFER+2], a
- ld [H_DIVIDEBUFFER+3], a
- ld [H_DIVIDEBUFFER+4], a
- ld a, $9
- ld e, a
-.asm_f6680
- ld a, [H_DIVIDEBUFFER]
- ld c, a
- ld a, [H_DIVIDEND+1]
- sub c
- ld d, a
- ld a, [H_DIVISOR]
- ld c, a
- ld a, [H_DIVIDEND]
- sbc c
- jr c, .asm_f669b
- ld [H_DIVIDEND], a
- ld a, d
- ld [H_DIVIDEND+1], a
- ld a, [H_DIVIDEBUFFER+4]
- inc a
- ld [H_DIVIDEBUFFER+4], a
- jr .asm_f6680
-.asm_f669b
- ld a, b
- cp $1
- jr z, .done
- ld a, [H_DIVIDEBUFFER+4]
- sla a
- ld [H_DIVIDEBUFFER+4], a
- ld a, [H_DIVIDEBUFFER+3]
- rl a
- ld [H_DIVIDEBUFFER+3], a
- ld a, [H_DIVIDEBUFFER+2]
- rl a
- ld [H_DIVIDEBUFFER+2], a
- ld a, [H_DIVIDEBUFFER+1]
- rl a
- ld [H_DIVIDEBUFFER+1], a
- dec e
- jr nz, .asm_f66d1
- ld a, $8
- ld e, a
- ld a, [H_DIVIDEBUFFER]
- ld [H_DIVISOR], a
- xor a
- ld [H_DIVIDEBUFFER], a
- ld a, [H_DIVIDEND+1]
- ld [H_DIVIDEND], a
- ld a, [H_DIVIDEND+2]
- ld [H_DIVIDEND+1], a
- ld a, [H_DIVIDEND+3]
- ld [H_DIVIDEND+2], a
-.asm_f66d1
- ld a, e
- cp $1
- jr nz, .asm_f66d7
- dec b
-.asm_f66d7
- ld a, [H_DIVISOR]
- srl a
- ld [H_DIVISOR], a
- ld a, [H_DIVIDEBUFFER]
- rr a
- ld [H_DIVIDEBUFFER], a
- jr .asm_f6680
-.done
- ld a, [H_DIVIDEND+1]
- ld [H_REMAINDER], a
- ld a, [H_DIVIDEBUFFER+4]
- ld [H_QUOTIENT+3], a
- ld a, [H_DIVIDEBUFFER+3]
- ld [H_QUOTIENT+2], a
- ld a, [H_DIVIDEBUFFER+2]
- ld [H_QUOTIENT+1], a
- ld a, [H_DIVIDEBUFFER+1]
- ld [H_QUOTIENT], a
- ret
diff --git a/engine/oam_dma.asm b/engine/oam_dma.asm
deleted file mode 100644
index 7326445e..00000000
--- a/engine/oam_dma.asm
+++ /dev/null
@@ -1,26 +0,0 @@
-WriteDMACodeToHRAM:
-; Since no other memory is available during OAM DMA,
-; DMARoutine is copied to HRAM and executed there.
- ld c, $ff80 % $100
- ld b, DMARoutineEnd - DMARoutine
- ld hl, DMARoutine
-.copy
- ld a, [hli]
- ld [$ff00+c], a
- inc c
- dec b
- jr nz, .copy
- ret
-
-DMARoutine:
- ; initiate DMA
- ld a, wOAMBuffer / $100
- ld [rDMA], a
-
- ; wait for DMA to finish
- ld a, $28
-.wait
- dec a
- jr nz, .wait
- ret
-DMARoutineEnd:
diff --git a/engine/overworld/advance_player_sprite.asm b/engine/overworld/advance_player_sprite.asm
index 6b4a0cbb..4ebdac84 100644
--- a/engine/overworld/advance_player_sprite.asm
+++ b/engine/overworld/advance_player_sprite.asm
@@ -1,241 +1,244 @@
_AdvancePlayerSprite::
- ld a,[wSpriteStateData1 + 3] ; delta Y
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
- ld c,a
- ld hl,wWalkCounter ; walking animation counter
+ ld a, [wSpritePlayerStateData1YStepVector]
+ ld b, a
+ ld a, [wSpritePlayerStateData1XStepVector]
+ ld c, a
+ ld hl, wWalkCounter ; walking animation counter
dec [hl]
- jr nz,.afterUpdateMapCoords
+ jr nz, .afterUpdateMapCoords
; if it's the end of the animation, update the player's map coordinates
ld hl, wPikachuOverworldStateFlags
res 5, [hl]
- ld a,[wYCoord]
+ ld a, [wYCoord]
add b
- ld [wYCoord],a
- ld a,[wXCoord]
+ ld [wYCoord], a
+ ld a, [wXCoord]
add c
- ld [wXCoord],a
+ ld [wXCoord], a
.afterUpdateMapCoords
- ld a,[wWalkCounter] ; walking animation counter
- cp a,$07
- jp nz,.scrollBackgroundAndSprites
+ ld a, [wWalkCounter] ; walking animation counter
+ cp $07
+ jp nz, .scrollBackgroundAndSprites
; if this is the first iteration of the animation
- ld a,c
- cp a,$01
- jr nz,.checkIfMovingWest
+ ld a, c
+ cp $01
+ jr nz, .checkIfMovingWest
; moving east
- ld a,[wMapViewVRAMPointer]
- ld e,a
+ ld a, [wMapViewVRAMPointer]
+ ld e, a
and $e0
- ld d,a
- ld a,e
+ ld d, a
+ ld a, e
add $02
and $1f
or d
- ld [wMapViewVRAMPointer],a
+ ld [wMapViewVRAMPointer], a
jr .adjustXCoordWithinBlock
.checkIfMovingWest
- cp a,$ff
- jr nz,.checkIfMovingSouth
+ cp $ff
+ jr nz, .checkIfMovingSouth
; moving west
- ld a,[wMapViewVRAMPointer]
- ld e,a
- and a,$e0
- ld d,a
- ld a,e
+ ld a, [wMapViewVRAMPointer]
+ ld e, a
+ and $e0
+ ld d, a
+ ld a, e
sub $02
and $1f
or d
- ld [wMapViewVRAMPointer],a
+ ld [wMapViewVRAMPointer], a
jr .adjustXCoordWithinBlock
.checkIfMovingSouth
- ld a,b
- cp a,$01
- jr nz,.checkIfMovingNorth
+ ld a, b
+ cp $01
+ jr nz, .checkIfMovingNorth
; moving south
- ld a,[wMapViewVRAMPointer]
+ ld a, [wMapViewVRAMPointer]
add $40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
+ ld [wMapViewVRAMPointer], a
+ jr nc, .adjustXCoordWithinBlock
+ ld a, [wMapViewVRAMPointer + 1]
inc a
and $03
or $98
- ld [wMapViewVRAMPointer + 1],a
+ ld [wMapViewVRAMPointer + 1], a
jr .adjustXCoordWithinBlock
.checkIfMovingNorth
- cp a,$ff
- jr nz,.adjustXCoordWithinBlock
+ cp $ff
+ jr nz, .adjustXCoordWithinBlock
; moving north
- ld a,[wMapViewVRAMPointer]
+ ld a, [wMapViewVRAMPointer]
sub $40
- ld [wMapViewVRAMPointer],a
- jr nc,.adjustXCoordWithinBlock
- ld a,[wMapViewVRAMPointer + 1]
+ ld [wMapViewVRAMPointer], a
+ jr nc, .adjustXCoordWithinBlock
+ ld a, [wMapViewVRAMPointer + 1]
dec a
and $03
or $98
- ld [wMapViewVRAMPointer + 1],a
+ ld [wMapViewVRAMPointer + 1], a
.adjustXCoordWithinBlock
- ld a,c
+ ld a, c
and a
- jr z,.pointlessJump ; mistake?
+ jr z, .pointlessJump ; mistake?
.pointlessJump
- ld hl,wXBlockCoord
- ld a,[hl]
+ ld hl, wXBlockCoord
+ ld a, [hl]
add c
- ld [hl],a
+ ld [hl], a
cp $02
- jr nz,.checkForMoveToWestBlock
+ jr nz, .checkForMoveToWestBlock
; moved into the tile block to the east
xor a
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
+ ld [hl], a
+ ld hl, wXOffsetSinceLastSpecialWarp
inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
+ ld de, wCurrentTileBlockMapViewPointer
call MoveTileBlockMapPointerEast
jr .updateMapView
.checkForMoveToWestBlock
- cp a,$ff
- jr nz,.adjustYCoordWithinBlock
+ cp $ff
+ jr nz, .adjustYCoordWithinBlock
; moved into the tile block to the west
- ld a,$1
- ld [hl],a
- ld hl,wXOffsetSinceLastSpecialWarp
+ ld a, $01
+ ld [hl], a
+ ld hl, wXOffsetSinceLastSpecialWarp
dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
+ ld de, wCurrentTileBlockMapViewPointer
call MoveTileBlockMapPointerWest
jr .updateMapView
.adjustYCoordWithinBlock
- ld hl,wYBlockCoord
- ld a,[hl]
+ ld hl, wYBlockCoord
+ ld a, [hl]
add b
- ld [hl],a
- cp $2
- jr nz,.checkForMoveToNorthBlock
+ ld [hl], a
+ cp $02
+ jr nz, .checkForMoveToNorthBlock
; moved into the tile block to the south
xor a
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
+ ld [hl], a
+ ld hl, wYOffsetSinceLastSpecialWarp
inc [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[wCurMapWidth]
+ ld de, wCurrentTileBlockMapViewPointer
+ ld a, [wCurMapWidth]
call MoveTileBlockMapPointerSouth
jr .updateMapView
.checkForMoveToNorthBlock
- cp a,$ff
- jr nz,.updateMapView
+ cp $ff
+ jr nz, .updateMapView
; moved into the tile block to the north
- ld a,$1
- ld [hl],a
- ld hl,wYOffsetSinceLastSpecialWarp
+ ld a, $01
+ ld [hl], a
+ ld hl, wYOffsetSinceLastSpecialWarp
dec [hl]
- ld de,wCurrentTileBlockMapViewPointer
- ld a,[wCurMapWidth]
+ ld de, wCurrentTileBlockMapViewPointer
+ ld a, [wCurMapWidth]
call MoveTileBlockMapPointerNorth
.updateMapView
call LoadCurrentMapView
- ld a,[wSpriteStateData1 + 3] ; delta Y
- cp $1
- jr nz,.checkIfMovingNorth2
+ ld a, [wSpritePlayerStateData1YStepVector]
+ cp $01
+ jr nz, .checkIfMovingNorth2
; if moving south
call ScheduleSouthRowRedraw
jr .scrollBackgroundAndSprites
.checkIfMovingNorth2
cp $ff
- jr nz,.checkIfMovingEast2
+ jr nz, .checkIfMovingEast2
; if moving north
call ScheduleNorthRowRedraw
jr .scrollBackgroundAndSprites
.checkIfMovingEast2
- ld a,[wSpriteStateData1 + 5] ; delta X
- cp $1
- jr nz,.checkIfMovingWest2
+ ld a, [wSpritePlayerStateData1XStepVector]
+ cp $01
+ jr nz, .checkIfMovingWest2
; if moving east
call ScheduleEastColumnRedraw
jr .scrollBackgroundAndSprites
.checkIfMovingWest2
cp $ff
- jr nz,.scrollBackgroundAndSprites
+ jr nz, .scrollBackgroundAndSprites
; if moving west
call ScheduleWestColumnRedraw
.scrollBackgroundAndSprites
- ld a,[wSpriteStateData1 + 3] ; delta Y
+ ld a, [wSpritePlayerStateData1YStepVector]
add a
- ld b,a
- ld a,[wSpriteStateData1 + 5] ; delta X
+ ld b, a
+ ld a, [wSpritePlayerStateData1XStepVector]
add a
- ld c,a
+ ld c, a
; shift all the sprites in the direction opposite of the player's motion
; so that the player appears to move relative to them
- ld hl,wSpriteStateData1 + $14
- ld e,15
+ ld hl, wSprite01StateData1YPixels
+ ld e, 15
.spriteShiftLoop
- ld a,[hl]
+ ld a, [hl]
sub b
- ld [hli],a
+ ld [hli], a
inc l
- ld a,[hl]
+ ld a, [hl]
sub c
- ld [hl],a
- ld a,$0e
+ ld [hl], a
+ ld a, $0e
add l
- ld l,a
+ ld l, a
dec e
- jr nz,.spriteShiftLoop
+ jr nz, .spriteShiftLoop
.done
- ld a,[hSCY]
+ ldh a, [hSCY]
add b
- ld [hSCY],a ; update background scroll Y
- ld a,[hSCX]
+ ldh [hSCY], a ; update background scroll Y
+ ldh a, [hSCX]
add c
- ld [hSCX],a ; update background scroll X
+ ldh [hSCX], a ; update background scroll X
ret
+; the following four functions are used to move the pointer to the upper left
+; corner of the tile block map in the direction of motion
+
MoveTileBlockMapPointerEast::
- ld a,[de]
- add $1
- ld [de],a
+ ld a, [de]
+ add $01
+ ld [de], a
ret nc
inc de
- ld a,[de]
+ ld a, [de]
inc a
- ld [de],a
+ ld [de], a
ret
MoveTileBlockMapPointerWest::
- ld a,[de]
- sub $1
- ld [de],a
+ ld a, [de]
+ sub $01
+ ld [de], a
ret nc
inc de
- ld a,[de]
+ ld a, [de]
dec a
- ld [de],a
+ ld [de], a
ret
MoveTileBlockMapPointerSouth::
- add $6
- ld b,a
- ld a,[de]
+ add MAP_BORDER * 2
+ ld b, a
+ ld a, [de]
add b
- ld [de],a
+ ld [de], a
ret nc
inc de
- ld a,[de]
+ ld a, [de]
inc a
- ld [de],a
+ ld [de], a
ret
MoveTileBlockMapPointerNorth::
- add $6
- ld b,a
- ld a,[de]
+ add MAP_BORDER * 2
+ ld b, a
+ ld a, [de]
sub b
- ld [de],a
+ ld [de], a
ret nc
inc de
- ld a,[de]
+ ld a, [de]
dec a
- ld [de],a
+ ld [de], a
ret
diff --git a/engine/overworld/auto_movement.asm b/engine/overworld/auto_movement.asm
new file mode 100755
index 00000000..a68da55f
--- /dev/null
+++ b/engine/overworld/auto_movement.asm
@@ -0,0 +1,270 @@
+PlayerStepOutFromDoor::
+ ld hl, wd730
+ res 1, [hl]
+ call IsPlayerStandingOnDoorTile
+ jr nc, .notStandingOnDoor
+ ld a, $fc
+ ld [wJoyIgnore], a
+ ld hl, wd736
+ set 1, [hl]
+ ld a, $1
+ ld [wSimulatedJoypadStatesIndex], a
+ ld a, D_DOWN
+ ld [wSimulatedJoypadStatesEnd], a
+ xor a
+ ld [wSpritePlayerStateData1ImageIndex], a
+ call StartSimulatingJoypadStates
+ ret
+.notStandingOnDoor
+ xor a
+ ld [wWastedByteCD3A], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wSimulatedJoypadStatesEnd], a
+ ld hl, wd736
+ res 0, [hl]
+ res 1, [hl]
+ ld hl, wd730
+ res 7, [hl]
+ ret
+
+_EndNPCMovementScript::
+ ld hl, wd730
+ res 7, [hl]
+ ld hl, wd72e
+ res 7, [hl]
+ ld hl, wd736
+ res 0, [hl]
+ res 1, [hl]
+ xor a
+ ld [wNPCMovementScriptSpriteOffset], a
+ ld [wNPCMovementScriptFunctionNum], a
+ ld [wNPCMovementScriptPointerTableNum], a
+ ld [wWastedByteCD3A], a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld [wSimulatedJoypadStatesEnd], a
+ ret
+
+PalletMovementScriptPointerTable::
+ dw PalletMovementScript_OakMoveLeft
+ dw PalletMovementScript_PlayerMoveLeft
+ dw PalletMovementScript_WaitAndWalkToLab
+ dw PalletMovementScript_WalkToLab
+ dw PalletMovementScript_Done
+
+PalletMovementScript_OakMoveLeft:
+ ld a, [wXCoord]
+ sub $a
+ ld [wNumStepsToTake], a
+ jr z, .playerOnLeftTile
+; The player is on the right tile of the northern path out of Pallet Town and
+; Prof. Oak is below.
+; Make Prof. Oak step to the left.
+ ld b, 0
+ ld c, a
+ ld hl, wNPCMovementDirections2
+ ld a, NPC_MOVEMENT_LEFT
+ call FillMemory
+ ld [hl], $ff
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ ld de, wNPCMovementDirections2
+ call MoveSprite
+ ld a, $1
+ ld [wNPCMovementScriptFunctionNum], a
+ jr .done
+; The player is on the left tile of the northern path out of Pallet Town and
+; Prof. Oak is below.
+; Prof. Oak is already where he needs to be.
+.playerOnLeftTile
+ ld a, $3
+ ld [wNPCMovementScriptFunctionNum], a
+.done
+ ld a, BANK(Music_MuseumGuy)
+ ld c, a
+ ld a, MUSIC_MUSEUM_GUY
+ call PlayMusic
+ ld hl, wFlags_D733
+ set 1, [hl]
+ ld a, $fc
+ ld [wJoyIgnore], a
+ ret
+
+PalletMovementScript_PlayerMoveLeft:
+ ld a, [wd730]
+ bit 0, a ; is an NPC being moved by a script?
+ ret nz ; return if Oak is still moving
+ ld a, [wNumStepsToTake]
+ ld [wSimulatedJoypadStatesIndex], a
+ ldh [hNPCMovementDirections2Index], a
+ predef ConvertNPCMovementDirectionsToJoypadMasks
+ call StartSimulatingJoypadStates
+ ld a, $2
+ ld [wNPCMovementScriptFunctionNum], a
+ ret
+
+PalletMovementScript_WaitAndWalkToLab:
+ ld a, [wSimulatedJoypadStatesIndex]
+ and a ; is the player done moving left yet?
+ ret nz
+
+PalletMovementScript_WalkToLab:
+ xor a
+ ld [wOverrideSimulatedJoypadStatesMask], a
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wNPCMovementScriptSpriteOffset], a
+ xor a
+ ld [wSpritePlayerStateData2MovementByte1], a
+ ld hl, wSimulatedJoypadStatesEnd
+ ld de, RLEList_PlayerWalkToLab
+ call DecodeRLEList
+ dec a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld hl, wNPCMovementDirections2
+ ld de, RLEList_ProfOakWalkToLab
+ call DecodeRLEList
+ ld hl, wd72e
+ res 7, [hl]
+ ld hl, wd730
+ set 7, [hl]
+ ld a, $4
+ ld [wNPCMovementScriptFunctionNum], a
+ ret
+
+
+RLEList_ProfOakWalkToLab:
+ db NPC_MOVEMENT_DOWN, 6 ; differs from red
+ db NPC_MOVEMENT_LEFT, 1
+ db NPC_MOVEMENT_DOWN, 5
+ db NPC_MOVEMENT_RIGHT, 3
+ db NPC_MOVEMENT_UP, 1
+ db NPC_CHANGE_FACING, 1
+ db -1 ; end
+
+RLEList_PlayerWalkToLab:
+ db D_UP, 2
+ db D_RIGHT, 3
+ db D_DOWN, 5
+ db D_LEFT, 1
+ db D_DOWN, 7 ; differs from red
+ db -1 ; end
+
+PalletMovementScript_Done:
+ ld a, [wSimulatedJoypadStatesIndex]
+ and a
+ ret nz
+ ld a, HS_PALLET_TOWN_OAK
+ ld [wMissableObjectIndex], a
+ predef HideObject
+ ld hl, wd730
+ res 7, [hl]
+ ld hl, wd72e
+ res 7, [hl]
+ jp EndNPCMovementScript
+
+PewterMuseumGuyMovementScriptPointerTable::
+ dw PewterMovementScript_WalkToMuseum
+ dw PewterMovementScript_Done
+
+PewterMovementScript_WalkToMuseum:
+ ld a, BANK(Music_MuseumGuy)
+ ld c, a
+ ld a, MUSIC_MUSEUM_GUY
+ call PlayMusic
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wNPCMovementScriptSpriteOffset], a
+ call StartSimulatingJoypadStates
+ ld hl, wSimulatedJoypadStatesEnd
+ ld de, RLEList_PewterMuseumPlayer
+ call DecodeRLEList
+ dec a
+ ld [wSimulatedJoypadStatesIndex], a
+ xor a
+ ld [wWhichPewterGuy], a
+ call PewterGuys
+ ld hl, wNPCMovementDirections2
+ ld de, RLEList_PewterMuseumGuy
+ call DecodeRLEList
+ ld hl, wd72e
+ res 7, [hl]
+ ld a, $1
+ ld [wNPCMovementScriptFunctionNum], a
+ ret
+
+RLEList_PewterMuseumPlayer:
+ db NO_INPUT, 1
+ db D_UP, 3
+ db D_LEFT, 13
+ db D_UP, 6
+ db -1 ; end
+
+RLEList_PewterMuseumGuy:
+ db NPC_MOVEMENT_UP, 6
+ db NPC_MOVEMENT_LEFT, 13
+ db NPC_MOVEMENT_UP, 3
+ db NPC_MOVEMENT_LEFT, 1
+ db -1 ; end
+
+PewterMovementScript_Done:
+ ld a, [wSimulatedJoypadStatesIndex]
+ and a
+ ret nz
+ ld hl, wd730
+ res 7, [hl]
+ ld hl, wd72e
+ res 7, [hl]
+ jp EndNPCMovementScript
+
+PewterGymGuyMovementScriptPointerTable::
+ dw PewterMovementScript_WalkToGym
+ dw PewterMovementScript_Done
+
+PewterMovementScript_WalkToGym:
+ ld a, BANK(Music_MuseumGuy)
+ ld c, a
+ ld a, MUSIC_MUSEUM_GUY
+ call PlayMusic
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wNPCMovementScriptSpriteOffset], a
+ xor a
+ ld [wSpritePlayerStateData2MovementByte1], a
+ ld hl, wSimulatedJoypadStatesEnd
+ ld de, RLEList_PewterGymPlayer
+ call DecodeRLEList
+ dec a
+ ld [wSimulatedJoypadStatesIndex], a
+ ld a, 1
+ ld [wWhichPewterGuy], a
+ call PewterGuys
+ ld hl, wNPCMovementDirections2
+ ld de, RLEList_PewterGymGuy
+ call DecodeRLEList
+ ld hl, wd72e
+ res 7, [hl]
+ ld hl, wd730
+ set 7, [hl]
+ ld a, $1
+ ld [wNPCMovementScriptFunctionNum], a
+ ret
+
+RLEList_PewterGymPlayer:
+ db NO_INPUT, 1
+ db D_RIGHT, 2
+ db D_DOWN, 5
+ db D_LEFT, 11
+ db D_UP, 5
+ db D_LEFT, 15
+ db -1 ; end
+
+RLEList_PewterGymGuy:
+ db NPC_MOVEMENT_DOWN, 2
+ db NPC_MOVEMENT_LEFT, 15
+ db NPC_MOVEMENT_UP, 5
+ db NPC_MOVEMENT_LEFT, 11
+ db NPC_MOVEMENT_DOWN, 5
+ db NPC_MOVEMENT_RIGHT, 3
+ db -1 ; end
+
+INCLUDE "engine/events/pewter_guys.asm"
diff --git a/engine/overworld/card_key.asm b/engine/overworld/card_key.asm
deleted file mode 100755
index a4452b4a..00000000
--- a/engine/overworld/card_key.asm
+++ /dev/null
@@ -1,113 +0,0 @@
-PrintCardKeyText:
- ld hl, SilphCoMapList
- ld a, [wCurMap]
- ld b, a
-.silphCoMapListLoop
- ld a, [hli]
- cp $ff
- ret z
- cp b
- jr nz, .silphCoMapListLoop
-; does not check for tile in front of player. This might be buggy
- ;predef GetTileAndCoordsInFrontOfPlayer
- ld a, [wTileInFrontOfPlayer]
- cp $18
- jr z, .cardKeyDoorInFrontOfPlayer
- cp $24
- jr z, .cardKeyDoorInFrontOfPlayer
- ld b, a
- ld a, [wCurMap]
- cp SILPH_CO_11F
- ret nz
- ld a, b
- cp $5e
- ret nz
-.cardKeyDoorInFrontOfPlayer
- ld b, CARD_KEY
- call IsItemInBag
- jr z, .noCardKey
- xor a
- ld [wPlayerMovingDirection], a
- tx_pre_id CardKeySuccessText
- ld [hSpriteIndexOrTextID], a
- call PrintPredefTextID
- call GetCoordsInFrontOfPlayer
- srl d
- ld a, d
- ld b, a
- ld [wCardKeyDoorY], a
- srl e
- ld a, e
- ld c, a
- ld [wCardKeyDoorX], a
- ld a, [wCurMap]
- cp SILPH_CO_11F
- jr nz, .notSilphCo11F
- ld a, $3
- jr .replaceCardKeyDoorTileBlock
-.notSilphCo11F
- ld a, $e
-.replaceCardKeyDoorTileBlock
- ld [wNewTileBlockID], a
- predef ReplaceTileBlock
- ld hl, wCurrentMapScriptFlags
- set 5, [hl]
- ld a, SFX_GO_INSIDE
- jp PlaySound
-.noCardKey
- tx_pre_id CardKeyFailText
- ld [hSpriteIndexOrTextID], a
- jp PrintPredefTextID
-
-SilphCoMapList:
- db SILPH_CO_2F
- db SILPH_CO_3F
- db SILPH_CO_4F
- db SILPH_CO_5F
- db SILPH_CO_6F
- db SILPH_CO_7F
- db SILPH_CO_8F
- db SILPH_CO_9F
- db SILPH_CO_10F
- db SILPH_CO_11F
- db $FF
-
-CardKeySuccessText:
- TX_FAR _CardKeySuccessText1
- TX_SFX_ITEM_1
- TX_FAR _CardKeySuccessText2
- db "@"
-
-CardKeyFailText:
- TX_FAR _CardKeyFailText
- db "@"
-
-; d = Y
-; e = X
-GetCoordsInFrontOfPlayer:
- ld a, [wYCoord]
- ld d, a
- ld a, [wXCoord]
- ld e, a
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
- and a
- jr nz, .notFacingDown
-; facing down
- inc d
- ret
-.notFacingDown
- cp SPRITE_FACING_UP
- jr nz, .notFacingUp
-; facing up
- dec d
- ret
-.notFacingUp
- cp SPRITE_FACING_LEFT
- jr nz, .notFacingLeft
-; facing left
- dec e
- ret
-.notFacingLeft
-; facing right
- inc e
- ret
diff --git a/engine/overworld/clear_variables.asm b/engine/overworld/clear_variables.asm
index 9a59cc7c..bbb7c986 100644
--- a/engine/overworld/clear_variables.asm
+++ b/engine/overworld/clear_variables.asm
@@ -1,14 +1,14 @@
-ClearVariablesOnEnterMap:
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
- ld [rWY], a
+ClearVariablesOnEnterMap::
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
+ ldh [rWY], a
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld [wStepCounter], a
ld [wLoneAttackNo], a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
- ld [hJoyHeld], a
+ ldh [hJoyPressed], a
+ ldh [hJoyReleased], a
+ ldh [hJoyHeld], a
ld [wActionResultOrTookBattleTurn], a
ld [wUnusedD5A3], a
ld hl, wCardKeyDoorY
diff --git a/engine/overworld/cut.asm b/engine/overworld/cut.asm
index bc7d092d..e36b8d88 100755
--- a/engine/overworld/cut.asm
+++ b/engine/overworld/cut.asm
@@ -22,8 +22,8 @@ UsedCut:
jp PrintText
.NothingToCutText
- TX_FAR _NothingToCutText
- db "@"
+ text_far _NothingToCutText
+ text_end
.canCut
ld [wCutTile], a
@@ -37,15 +37,15 @@ UsedCut:
call GBPalWhiteOutWithDelay3
call ClearSprites
call RestoreScreenTilesAndReloadTilePatterns
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
+ ld a, SCREEN_HEIGHT_PX
+ ldh [hWY], a
call Delay3
call LoadGBPal
call LoadCurrentMapView
call SaveScreenTilesToBuffer2
call Delay3
xor a
- ld [hWY], a
+ ldh [hWY], a
ld hl, UsedCutText
call PrintText
call LoadScreenTilesFromBuffer2
@@ -57,47 +57,47 @@ UsedCut:
ld de, CutTreeBlockSwaps
call ReplaceTreeTileBlock
call RedrawMapView
- callba AnimCut
+ farcall AnimCut
ld a, $1
ld [wUpdateSpritesEnabled], a
ld a, SFX_CUT
call PlaySound
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
call UpdateSprites
jp RedrawMapView
UsedCutText:
- TX_FAR _UsedCutText
- db "@"
+ text_far _UsedCutText
+ text_end
InitCutAnimOAM:
xor a
ld [wWhichAnimationOffsets], a
ld a, %11100100
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
ld a, [wCutTile]
cp $52
jr z, .grass
; tree
- ld de, Overworld_GFX + $2d0 ; cuttable tree sprite top row
- ld hl, vChars1 + $7c0
- lb bc, BANK(Overworld_GFX), $02
+ ld de, Overworld_GFX tile $2d ; cuttable tree sprite top row
+ ld hl, vChars1 tile $7c
+ lb bc, BANK(Overworld_GFX), 2
call CopyVideoData
- ld de, Overworld_GFX + $3d0 ; cuttable tree sprite bottom row
- ld hl, vChars1 + $7e0
- lb bc, BANK(Overworld_GFX), $02
+ ld de, Overworld_GFX tile $3d ; cuttable tree sprite bottom row
+ ld hl, vChars1 tile $7e
+ lb bc, BANK(Overworld_GFX), 2
call CopyVideoData
jr WriteCutOrBoulderDustAnimationOAMBlock
.grass
- ld hl, vChars1 + $7c0
+ ld hl, vChars1 tile $7c
call LoadCutGrassAnimationTilePattern
- ld hl, vChars1 + $7d0
+ ld hl, vChars1 tile $7d
call LoadCutGrassAnimationTilePattern
- ld hl, vChars1 + $7e0
+ ld hl, vChars1 tile $7e
call LoadCutGrassAnimationTilePattern
- ld hl, vChars1 + $7f0
+ ld hl, vChars1 tile $7f
call LoadCutGrassAnimationTilePattern
call WriteCutOrBoulderDustAnimationOAMBlock
ld hl, wOAMBuffer + $93
@@ -113,8 +113,8 @@ InitCutAnimOAM:
ret
LoadCutGrassAnimationTilePattern:
- ld de, AnimationTileset2 + $60 ; tile depicting a leaf
- lb bc, BANK(AnimationTileset2), $01
+ ld de, AnimationTileset2 tile 6 ; tile depicting a leaf
+ lb bc, BANK(AnimationTileset2), 1
jp CopyVideoData
WriteCutOrBoulderDustAnimationOAMBlock:
@@ -124,11 +124,11 @@ WriteCutOrBoulderDustAnimationOAMBlock:
jp WriteOAMBlock
CutOrBoulderDustAnimationTilesAndAttributes:
- db $FC,$14,$FD,$14
- db $FE,$14,$FF,$14
+ dbsprite 2, -1, 4, 4, $fd, OAM_OBP1 | %100
+ dbsprite 2, -1, 4, 6, $ff, OAM_OBP1 | %100
GetCutOrBoulderDustAnimationOffsets:
- ld hl, wSpriteStateData1 + 4
+ ld hl, wSpritePlayerStateData1YPixels
ld a, [hli] ; player's sprite screen Y position
ld b, a
inc hl
@@ -188,7 +188,7 @@ ReplaceTreeTileBlock:
ld h, [hl]
ld l, a
add hl, bc
- ld a, [wSpritePlayerStateData1FacingDirection] ; player sprite's facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
and a
jr z, .down
cp SPRITE_FACING_UP
@@ -249,16 +249,4 @@ ReplaceTreeTileBlock:
ld [hl], a
ret
-CutTreeBlockSwaps:
-; first byte = tileset block containing the cut tree
-; second byte = corresponding tileset block after the cut animation happens
- db $32, $6D
- db $33, $6C
- db $34, $6F
- db $35, $4C
- db $60, $6E
- db $0B, $0A
- db $3C, $35
- db $3F, $35
- db $3D, $36
- db $FF ; list terminator
+INCLUDE "data/tilesets/cut_tree_blocks.asm"
diff --git a/engine/overworld/cut2.asm b/engine/overworld/cut2.asm
index 37490f95..1f691eef 100755
--- a/engine/overworld/cut2.asm
+++ b/engine/overworld/cut2.asm
@@ -15,9 +15,9 @@ AnimCut:
ld [wCoordAdjustmentAmount], a
ld c, 2
call AdjustOAMBlockXPos2
- ld a, [rOBP1]
+ ldh a, [rOBP1]
xor $64
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
call DelayFrame
pop bc
@@ -66,9 +66,9 @@ AnimCutGrass_UpdateOAMEntries:
ld [wCoordAdjustmentAmount], a
ld c, 1
call AdjustOAMBlockXPos2
- ld a, [rOBP1]
+ ldh a, [rOBP1]
xor $64
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
call DelayFrame
pop bc
diff --git a/engine/overworld/doors.asm b/engine/overworld/doors.asm
index 8bde8600..d38818fa 100755
--- a/engine/overworld/doors.asm
+++ b/engine/overworld/doors.asm
@@ -11,7 +11,7 @@ IsPlayerStandingOnDoorTile:
ld a, [hli]
ld h, [hl]
ld l, a
- aCoord 8, 9 ; a = lower left background tile under player's sprite
+ lda_coord 8, 9 ; a = lower left background tile under player's sprite
ld b, a
.loop
ld a, [hli]
@@ -25,55 +25,4 @@ IsPlayerStandingOnDoorTile:
and a
ret
-DoorTileIDPointers:
- dbw OVERWORLD, OverworldDoorTileIDs
- dbw FOREST, ForestDoorTileIDs
- dbw MART, MartDoorTileIDs
- dbw HOUSE, HouseDoorTileIDs
- dbw FOREST_GATE, TilesetMuseumDoorTileIDs
- dbw MUSEUM, TilesetMuseumDoorTileIDs
- dbw GATE, TilesetMuseumDoorTileIDs
- dbw SHIP, ShipDoorTileIDs
- dbw LOBBY, LobbyDoorTileIDs
- dbw MANSION, MansionDoorTileIDs
- dbw LAB, LabDoorTileIDs
- dbw FACILITY, FacilityDoorTileIDs
- dbw PLATEAU, PlateauDoorTileIDs
- dbw INTERIOR, InteriorDoorTileIDs
- db $ff
-
-OverworldDoorTileIDs:
- db $1B,$58,$00
-
-ForestDoorTileIDs:
- db $3a,$00
-
-MartDoorTileIDs:
- db $5e,$00
-
-HouseDoorTileIDs:
- db $54,$00
-
-TilesetMuseumDoorTileIDs:
- db $3b,$00
-
-ShipDoorTileIDs:
- db $1e,$00
-
-LobbyDoorTileIDs:
- db $1c,$38,$1a,$00
-
-MansionDoorTileIDs:
- db $1a,$1c,$53,$00
-
-LabDoorTileIDs:
- db $34,$00
-
-FacilityDoorTileIDs:
- db $43,$58,$1b,$00
-
-PlateauDoorTileIDs:
- db $3b,$1b,$00
-
-InteriorDoorTileIDs:
- db $04,$15,$00
+INCLUDE "data/tilesets/door_tile_ids.asm"
diff --git a/engine/overworld/dungeon_warps.asm b/engine/overworld/dungeon_warps.asm
index f47dfb01..7641c688 100644
--- a/engine/overworld/dungeon_warps.asm
+++ b/engine/overworld/dungeon_warps.asm
@@ -1,4 +1,4 @@
-IsPlayerOnDungeonWarp:
+IsPlayerOnDungeonWarp::
xor a
ld [wWhichDungeonWarp], a
ld a, [wd72d]
diff --git a/engine/overworld/dust_smoke.asm b/engine/overworld/dust_smoke.asm
new file mode 100755
index 00000000..773def96
--- /dev/null
+++ b/engine/overworld/dust_smoke.asm
@@ -0,0 +1,95 @@
+AnimateBoulderDust:
+ ld a, $1
+ ld [wWhichAnimationOffsets], a ; select the boulder dust offsets
+ ld a, [wUpdateSpritesEnabled]
+ push af
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ ld a, %11100100
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ call LoadSmokeTileFourTimes
+ farcall WriteCutOrBoulderDustAnimationOAMBlock
+ ld c, 8 ; number of steps in animation
+.loop
+ push bc
+ call GetMoveBoulderDustFunctionPointer
+ ld bc, .returnAddress
+ push bc
+ ld c, 4
+ jp hl
+.returnAddress
+ ldh a, [rOBP1]
+ xor %01100100
+ ldh [rOBP1], a
+ call UpdateGBCPal_OBP1
+ call Delay3
+ pop bc
+ dec c
+ jr nz, .loop
+ pop af
+ ld [wUpdateSpritesEnabled], a
+ jp LoadPlayerSpriteGraphics
+
+GetMoveBoulderDustFunctionPointer:
+ ld a, [wSpritePlayerStateData1FacingDirection]
+ ld hl, MoveBoulderDustFunctionPointerTable
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hli]
+ ld [wCoordAdjustmentAmount], a
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ ld hl, wOAMBuffer + $90
+ ld d, $0
+ add hl, de
+ ld e, l
+ ld d, h
+ pop hl
+ ret
+
+MoveBoulderDustFunctionPointerTable:
+; facing down
+ db $FF,$00
+ dw AdjustOAMBlockYPos
+
+; facing up
+ db $01,$00
+ dw AdjustOAMBlockYPos
+
+; facing left
+ db $01,$01
+ dw AdjustOAMBlockXPos
+
+; facing right
+ db $FF,$01
+ dw AdjustOAMBlockXPos
+
+LoadSmokeTileFourTimes::
+ ld hl, vChars1 tile $7c
+ ld c, 4
+.loop
+ push bc
+ push hl
+ call LoadSmokeTile
+ pop hl
+ ld bc, 1 tiles
+ add hl, bc
+ pop bc
+ dec c
+ jr nz, .loop
+ ret
+
+LoadSmokeTile:
+ ld de, SSAnneSmokePuffTile
+ lb bc, BANK(SSAnneSmokePuffTile), (SSAnneSmokePuffTileEnd - SSAnneSmokePuffTile) / $10
+ jp CopyVideoData
+
+SSAnneSmokePuffTile:
+ INCBIN "gfx/overworld/smoke.2bpp"
+SSAnneSmokePuffTileEnd:
diff --git a/engine/overworld/elevator.asm b/engine/overworld/elevator.asm
index 47ec78f9..b873ffad 100755
--- a/engine/overworld/elevator.asm
+++ b/engine/overworld/elevator.asm
@@ -1,11 +1,11 @@
-ShakeElevator:
+ShakeElevator::
ld de, -$20
call ShakeElevatorRedrawRow
ld de, SCREEN_HEIGHT * $20
call ShakeElevatorRedrawRow
call Delay3
call StopAllMusic
- ld a, [hSCY]
+ ldh a, [hSCY]
ld d, a
ld e, $1
ld b, 100
@@ -14,7 +14,7 @@ ShakeElevator:
xor $fe
ld e, a
add d
- ld [hSCY], a
+ ldh [hSCY], a
push bc
ld c, BANK(SFX_Collision_1)
ld a, SFX_COLLISION
@@ -25,7 +25,7 @@ ShakeElevator:
dec b
jr nz, .shakeLoop
ld a, d
- ld [hSCY], a
+ ldh [hSCY], a
call StopAllMusic
ld c, BANK(SFX_Safari_Zone_PA)
ld a, SFX_SAFARI_ZONE_PA
@@ -54,7 +54,7 @@ ShakeElevatorRedrawRow:
add hl, de
ld a, h
and $3
- or vBGMap0 / $100
+ or HIGH(vBGMap0)
ld d, a
ld a, l
pop hl
diff --git a/engine/overworld/emotion_bubbles.asm b/engine/overworld/emotion_bubbles.asm
index 3b02fd55..3ad714e9 100755
--- a/engine/overworld/emotion_bubbles.asm
+++ b/engine/overworld/emotion_bubbles.asm
@@ -11,8 +11,8 @@ EmotionBubble:
add hl, bc
ld e, l
ld d, h
- ld hl, vChars1 + $780
- lb bc, BANK(EmotionBubbles), $04
+ ld hl, vChars1 tile $78
+ lb bc, BANK(EmotionBubbles), 4
call CopyVideoData
ld a, [wUpdateSpritesEnabled]
push af
@@ -41,7 +41,7 @@ EmotionBubble:
jr nz, .loop
; get the screen coordinates of the sprite the bubble is to be displayed above
- ld hl, wSpriteStateData1 + 4
+ ld hl, wSpritePlayerStateData1YPixels
ld a, [wEmotionBubbleSpriteIndex]
swap a
ld c, a
@@ -67,8 +67,15 @@ EmotionBubble:
EmotionBubblesOAM:
- db $F8,$00,$F9,$00
- db $FA,$00,$FB,$00
+ dbsprite 0, -1, 0, 0, $f9, 0
+ dbsprite 0, -1, 0, 2, $fb, 0
EmotionBubbles:
- INCBIN "gfx/emotion_bubbles.2bpp"
+ShockEmote: INCBIN "gfx/emotes/shock.2bpp"
+QuestionEmote: INCBIN "gfx/emotes/question.2bpp"
+HappyEmote: INCBIN "gfx/emotes/happy.2bpp"
+SkullEmote: INCBIN "gfx/emotes/skull.2bpp"
+HeartEmote: INCBIN "gfx/emotes/heart.2bpp"
+BoltEmote: INCBIN "gfx/emotes/bolt.2bpp"
+ZzzEmote: INCBIN "gfx/emotes/zzz.2bpp"
+FishEmote: INCBIN "gfx/emotes/fish.2bpp"
diff --git a/engine/overworld/field_move_messages.asm b/engine/overworld/field_move_messages.asm
index 1d111917..520ef8ad 100644
--- a/engine/overworld/field_move_messages.asm
+++ b/engine/overworld/field_move_messages.asm
@@ -7,16 +7,16 @@ PrintStrengthTxt:
jp PrintText
UsedStrengthText:
- TX_FAR _UsedStrengthText
- TX_ASM
+ text_far _UsedStrengthText
+ text_asm
ld a, [wcf91]
call PlayCry
call Delay3
jp TextScriptEnd
CanMoveBouldersText:
- TX_FAR _CanMoveBouldersText
- db "@"
+ text_far _CanMoveBouldersText
+ text_end
IsSurfingAllowed:
; Returns whether surfing is allowed in bit 1 of wd728.
@@ -32,7 +32,7 @@ IsSurfingAllowed:
ret nz
CheckBothEventsSet EVENT_SEAFOAM4_BOULDER1_DOWN_HOLE, EVENT_SEAFOAM4_BOULDER2_DOWN_HOLE
ret z
- ld hl, CoordsData_f5b64
+ ld hl, CoordsData_cdf7
call ArePlayerCoordsInArray
ret nc
ld hl, wd728
@@ -45,13 +45,14 @@ IsSurfingAllowed:
ld hl, CyclingIsFunText
jp PrintText
-CoordsData_f5b64:
- db $0B,$07,$FF
+CoordsData_cdf7:
+ dbmapcoord 7, 11
+ db -1 ; end
CurrentTooFastText:
- TX_FAR _CurrentTooFastText
- db "@"
+ text_far _CurrentTooFastText
+ text_end
CyclingIsFunText:
- TX_FAR _CyclingIsFunText
- db "@"
+ text_far _CyclingIsFunText
+ text_end
diff --git a/engine/overworld/healing_machine.asm b/engine/overworld/healing_machine.asm
index e5ba004e..e5fba7e1 100755
--- a/engine/overworld/healing_machine.asm
+++ b/engine/overworld/healing_machine.asm
@@ -1,17 +1,17 @@
AnimateHealingMachine:
ld de, PokeCenterFlashingMonitorAndHealBall
- ld hl, vChars0 + $7c0
- lb bc, BANK(PokeCenterFlashingMonitorAndHealBall), $03 ; loads one too many tiles
+ ld hl, vChars0 tile $7c
+ lb bc, BANK(PokeCenterFlashingMonitorAndHealBall), 3 ; should be 2
call CopyVideoData
ld hl, wUpdateSpritesEnabled
ld a, [hl]
push af
ld [hl], $ff
push hl
- ld a, [rOBP1]
+ ldh a, [rOBP1]
push af
ld a, $e0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
ld hl, wOAMBuffer + $84
ld de, PokeCenterOAMData
@@ -53,7 +53,7 @@ AnimateHealingMachine:
ld c, 32
call DelayFrames
pop af
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
pop hl
pop af
@@ -61,24 +61,26 @@ AnimateHealingMachine:
jp UpdateSprites
PokeCenterFlashingMonitorAndHealBall:
- INCBIN "gfx/pokecenter_ball.2bpp"
+ INCBIN "gfx/overworld/heal_machine.2bpp"
PokeCenterOAMData:
- db $24,$34,$7C,$14 ; heal machine monitor
- db $2B,$30,$7D,$14 ; pokeballs 1-6
- db $2B,$38,$7D,$34
- db $30,$30,$7D,$14
- db $30,$38,$7D,$34
- db $35,$30,$7D,$14
- db $35,$38,$7D,$34
+ ; heal machine monitor
+ dbsprite 6, 4, 4, 4, $7c, OAM_OBP1 | %100
+ ; poke balls 1-6
+ dbsprite 6, 5, 0, 3, $7d, OAM_OBP1 | %100
+ dbsprite 7, 5, 0, 3, $7d, OAM_OBP1 | OAM_HFLIP | %100
+ dbsprite 6, 6, 0, 0, $7d, OAM_OBP1 | %100
+ dbsprite 7, 6, 0, 0, $7d, OAM_OBP1 | OAM_HFLIP | %100
+ dbsprite 6, 6, 0, 5, $7d, OAM_OBP1 | %100
+ dbsprite 7, 6, 0, 5, $7d, OAM_OBP1 | OAM_HFLIP | %100
; d = value to xor with palette
FlashSprite8Times:
ld b, 8
.loop
- ld a, [rOBP1]
+ ldh a, [rOBP1]
xor d
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP1
ld c, 10
call DelayFrames
@@ -88,16 +90,9 @@ FlashSprite8Times:
CopyHealingMachineOAM:
; copy one OAM entry and advance the pointers
+ REPT 4
ld a, [de]
inc de
ld [hli], a
- ld a, [de]
- inc de
- ld [hli], a
- ld a, [de]
- inc de
- ld [hli], a
- ld a, [de]
- inc de
- ld [hli], a
+ ENDR
ret
diff --git a/engine/overworld/hidden_objects.asm b/engine/overworld/hidden_objects.asm
index 66815b60..84108986 100755
--- a/engine/overworld/hidden_objects.asm
+++ b/engine/overworld/hidden_objects.asm
@@ -1,11 +1,11 @@
; if a hidden object was found, stores $00 in [hDidntFindAnyHiddenObject], else stores $ff
-CheckForHiddenObject:
+CheckForHiddenObject::
ld hl, hItemAlreadyFound
xor a
- ld [hli], a
- ld [hli], a
- ld [hli], a
- ld [hl], a
+ ld [hli], a ; [hItemAlreadyFound]
+ ld [hli], a ; [hSavedMapTextPtr]
+ ld [hli], a ; [hSavedMapTextPtr + 1]
+ ld [hl], a ; [hDidntFindAnyHiddenObject]
ld hl, HiddenObjectMaps
ld de, 3
ld a, [wCurMap]
@@ -32,7 +32,7 @@ CheckForHiddenObject:
ld [wHiddenObjectX], a
ld c, a
call CheckIfCoordsInFrontOfPlayerMatch
- ld a, [hCoordsInFrontOfPlayerMatch]
+ ldh a, [hCoordsInFrontOfPlayerMatch]
and a
jr z, .foundMatchingObject
inc hl
@@ -55,13 +55,13 @@ CheckForHiddenObject:
ret
.noMatch
ld a, $ff
- ld [hDidntFindAnyHiddenObject], a
+ ldh [hDidntFindAnyHiddenObject], a
ret
; checks if the coordinates in front of the player's sprite match Y in b and X in c
; [hCoordsInFrontOfPlayerMatch] = $00 if they match, $ff if they don't match
CheckIfCoordsInFrontOfPlayerMatch:
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
cp SPRITE_FACING_UP
jr z, .facingUp
cp SPRITE_FACING_LEFT
@@ -101,7 +101,7 @@ CheckIfCoordsInFrontOfPlayerMatch:
.didNotMatch
ld a, $ff
.done
- ld [hCoordsInFrontOfPlayerMatch], a
+ ldh [hCoordsInFrontOfPlayerMatch], a
ret
-INCLUDE "data/hidden_objects.asm"
+INCLUDE "data/events/hidden_objects.asm"
diff --git a/engine/overworld/item.asm b/engine/overworld/item.asm
deleted file mode 100644
index 9f19100a..00000000
--- a/engine/overworld/item.asm
+++ /dev/null
@@ -1,54 +0,0 @@
-PickUpItem:
- call EnableAutoTextBoxDrawing
-
- ld a, [hSpriteIndexOrTextID]
- ld b, a
- ld hl, wMissableObjectList
-.missableObjectsListLoop
- ld a, [hli]
- cp $ff
- ret z
- cp b
- jr z, .isMissable
- inc hl
- jr .missableObjectsListLoop
-
-.isMissable
- ld a, [hl]
- ld [$ffdb], a
-
- ld hl, wMapSpriteExtraData
- ld a, [hSpriteIndexOrTextID]
- dec a
- add a
- ld d, 0
- ld e, a
- add hl, de
- ld a, [hl]
- ld b, a ; item
- ld c, 1 ; quantity
- call GiveItem
- jr nc, .BagFull
-
- ld a, [$ffdb]
- ld [wMissableObjectIndex], a
- predef HideObject
- ld a, 1
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a
- ld hl, FoundItemText
- jr .print
-
-.BagFull
- ld hl, NoMoreRoomForItemText
-.print
- call PrintText
- ret
-
-FoundItemText:
- TX_FAR _FoundItemText
- TX_SFX_ITEM_1
- db "@"
-
-NoMoreRoomForItemText:
- TX_FAR _NoMoreRoomForItemText
- db "@"
diff --git a/engine/overworld/ledges.asm b/engine/overworld/ledges.asm
index a44ddf8b..9925c528 100755
--- a/engine/overworld/ledges.asm
+++ b/engine/overworld/ledges.asm
@@ -1,4 +1,4 @@
-HandleLedges:
+HandleLedges::
ld a, [wd736]
bit 6, a ; already jumping down ledge
ret nz
@@ -8,7 +8,7 @@ HandleLedges:
predef GetTileAndCoordsInFrontOfPlayer
ld a, [wSpritePlayerStateData1FacingDirection]
ld b, a
- aCoord 8, 9
+ lda_coord 8, 9
ld c, a
ld a, [wTileInFrontOfPlayer]
ld d, a
@@ -36,7 +36,7 @@ HandleLedges:
inc hl
jr .loop
.foundMatch
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
and e
ret z
ld a, $ff
@@ -54,20 +54,10 @@ HandleLedges:
call PlaySound
ret
- ; (player direction) (tile player standing on) (ledge tile) (input required)
-LedgeTiles:
- db SPRITE_FACING_DOWN, $2C,$37,D_DOWN
- db SPRITE_FACING_DOWN, $39,$36,D_DOWN
- db SPRITE_FACING_DOWN, $39,$37,D_DOWN
- db SPRITE_FACING_LEFT, $2C,$27,D_LEFT
- db SPRITE_FACING_LEFT, $39,$27,D_LEFT
- db SPRITE_FACING_RIGHT,$2C,$0D,D_RIGHT
- db SPRITE_FACING_RIGHT,$2C,$1D,D_RIGHT
- db SPRITE_FACING_RIGHT,$39,$0D,D_RIGHT
- db $FF
+INCLUDE "data/tilesets/ledge_tiles.asm"
LoadHoppingShadowOAM:
- ld hl, vChars1 + $7f0
+ ld hl, vChars1 tile $7f
ld de, LedgeHoppingShadow
lb bc, BANK(LedgeHoppingShadow), (LedgeHoppingShadowEnd - LedgeHoppingShadow) / $8
call CopyVideoDataDouble
@@ -81,10 +71,10 @@ LoadHoppingShadowOAM:
ret
LedgeHoppingShadow:
- INCBIN "gfx/ledge_hopping_shadow.1bpp"
+ INCBIN "gfx/overworld/shadow.1bpp"
LedgeHoppingShadowEnd:
LedgeHoppingShadowOAM:
- db $58,$48,$FF,$00
- db $58,$50,$FF,$20
+ dbsprite 9, 11, 0, 0, $ff, 0
+ dbsprite 10, 11, 0, 0, $ff, OAM_HFLIP
LedgeHoppingShadowOAMEnd:
diff --git a/engine/overworld/map_sprite_functions1.asm b/engine/overworld/map_sprite_functions1.asm
deleted file mode 100644
index 2ad923fb..00000000
--- a/engine/overworld/map_sprite_functions1.asm
+++ /dev/null
@@ -1,390 +0,0 @@
-_UpdateSprites:
- ld h, wSpriteStateData1 / $100
- inc h
- ld a, $e ; (wSpriteStateData2 + $0e) & $ff
-.spriteLoop
- ld l, a
- sub $e
- ld c, a
- ld [H_CURRENTSPRITEOFFSET], a
- ld a, [hl]
- and a
- jr z, .skipSprite ; tests $c2Xe
- push hl
- push de
- push bc
- call .updateCurrentSprite
- pop bc
- pop de
- pop hl
-.skipSprite
- ld a, l
- add $10 ; move to next sprite
- cp $e ; test for overflow (back at $0e)
- jr nz, .spriteLoop
- ret
-.updateCurrentSprite
- ld a, [H_CURRENTSPRITEOFFSET]
- and a
- jp z, UpdatePlayerSprite
- cp $f0 ; pikachu
- jp z, SpawnPikachu
- ld a, [hl]
-
-UpdateNonPlayerSprite:
- dec a
- swap a
- ld [$ff93], a ; $10 * sprite#
- ld a, [wNPCMovementScriptSpriteOffset] ; some sprite offset?
- ld b, a
- ld a, [H_CURRENTSPRITEOFFSET]
- cp b
- jr nz, .unequal
- jp DoScriptedNPCMovement
-.unequal
- jp UpdateNPCSprite
-
-; This detects if the current sprite (whose offset is at H_CURRENTSPRITEOFFSET)
-; is going to collide with another sprite by looping over the other sprites.
-; The current sprite's offset will be labelled with i (e.g. $c1i0).
-; The loop sprite's offset will labelled with j (e.g. $c1j0).
-;
-; Note that the Y coordinate of the sprite (in [$c1k4]) is one of the following
-; 9 values when the sprite is aligned with the grid: $fc, $0c, $1c, $2c, ..., $7c.
-; The reason that 4 is added below to the coordinate is to make it align with a
-; multiple of $10 to make comparisons easier.
-DetectCollisionBetweenSprites:
- ; nop
-
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- ld l, a
-
- ld a, [hl] ; a = [$c1i0] (picture) (0 if slot is unused)
- and a ; is this sprite slot slot used?
- ret z ; return if not used
-
- ld a, l
- add 3
- ld l, a
-
- ld a, [hli] ; a = [$c1i3] (delta Y) (-1, 0, or 1)
- call SetSpriteCollisionValues
-
- ld a, [hli] ; a = [$C1i4] (Y screen coordinate)
- add 4 ; align with multiple of $10
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving south or
-; subtract 7 from a if moving north.
- add b
- and $f0
- or c
-
- ld [$ff90], a ; store Y coordinate adjusted for direction of movement
-
- ld a, [hli] ; a = [$c1i5] (delta X) (-1, 0, or 1)
- call SetSpriteCollisionValues
- ld a, [hl] ; a = [$C1i6] (X screen coordinate)
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving east or
-; subtract 7 from a if moving west.
- add b
- and $f0
- or c
-
- ld [$ff91], a ; store X coordinate adjusted for direction of movement
-
- ld a, l
- add 7
- ld l, a
-
- xor a
- ld [hld], a ; zero [$c1id] XXX what's [$c1id] for?
- ld [hld], a ; zero [$c1ic] (directions in which collisions occurred)
-
- ld a, [$ff91]
- ld [hld], a ; [$c1ib] = adjusted X coordinate
- ld a, [$ff90]
- ld [hl], a ; [$c1ia] = adjusted Y coordinate
-
- xor a ; zero the loop counter
-
-.loop
- ld [$ff8f], a ; store loop counter
- swap a
- ld e, a
- ld a, [H_CURRENTSPRITEOFFSET]
- cp e ; does the loop sprite match the current sprite?
- jp z, .next ; go to the next sprite if they match
-
- ld d, h
- ld a, [de] ; a = [$c1j0] (picture) (0 if slot is unused)
- and a ; is this sprite slot slot used?
- jp z, .next ; go the next sprite if not used
-
- inc e
- inc e
- ld a, [de] ; a = [$c1j2] ($ff means the sprite is offscreen)
- inc a
- jp z, .next ; go the next sprite if offscreen
-
- ld a, [H_CURRENTSPRITEOFFSET]
- add 10
- ld l, a
-
- inc e
- ld a, [de] ; a = [$c1j3] (delta Y)
- call SetSpriteCollisionValues
-
- inc e
- ld a, [de] ; a = [$C1j4] (Y screen coordinate)
- add 4 ; align with multiple of $10
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving south or
-; subtract 7 from a if moving north.
- add b
- and $f0
- or c
-
- sub [hl] ; subtract the adjusted Y coordinate of sprite i ([$c1ia]) from that of sprite j
-
-; calculate the absolute value of the difference to get the distance
- jr nc, .noCarry1
- cpl
- inc a
-.noCarry1
- ld [$ff90], a ; store the distance between the two sprites' adjusted Y values
-
-; Use the carry flag set by the above subtraction to determine which sprite's
-; Y coordinate is larger. This information is used later to set [$c1ic],
-; which stores which direction the collision occurred in.
-; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2.
-; If sprite i's Y is larger, set lowest 2 bits of c to 10.
-; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01.
- push af
- rl c
- pop af
- ccf
- rl c
-
-; If sprite i's delta Y is 0, then b = 7, else b = 9.
- ld b, 7
- ld a, [hl] ; a = [$c1ia] (adjusted Y coordinate)
- and $f
- jr z, .next1
- ld b, 9
-
-.next1
- ld a, [$ff90] ; a = distance between adjusted Y coordinates
- sub b
- ld [$ff92], a ; store distance adjusted using sprite i's direction
- ld a, b
- ld [$ff90], a ; store 7 or 9 depending on sprite i's delta Y
- jr c, .checkXDistance
-
-; If sprite j's delta Y is 0, then b = 7, else b = 9.
- ld b, 7
- dec e
- ld a, [de] ; a = [$c1j3] (delta Y)
- inc e
- and a
- jr z, .next2
- ld b, 9
-
-.next2
- ld a, [$ff92] ; a = distance adjusted using sprite i's direction
- sub b ; adjust distance using sprite j's direction
- jr z, .checkXDistance
- jr nc, .next ; go to next sprite if distance is still positive after both adjustments
-
-.checkXDistance
- inc e
- inc l
- ld a, [de] ; a = [$c1j5] (delta X)
-
- push bc
-
- call SetSpriteCollisionValues
- inc e
- ld a, [de] ; a = [$c1j6] (X screen coordinate)
-
-; The effect of the following 3 lines is to
-; add 7 to a if moving east or
-; subtract 7 from a if moving west.
- add b
- and $f0
- or c
-
- pop bc
-
- sub [hl] ; subtract the adjusted X coordinate of sprite i ([$c1ib]) from that of sprite j
-
-; calculate the absolute value of the difference to get the distance
- jr nc, .noCarry2
- cpl
- inc a
-.noCarry2
- ld [$ff91], a ; store the distance between the two sprites' adjusted X values
-
-; Use the carry flag set by the above subtraction to determine which sprite's
-; X coordinate is larger. This information is used later to set [$c1ic],
-; which stores which direction the collision occurred in.
-; The following 5 lines set the lowest 2 bits of c.
-; If sprite i's X is larger, set lowest 2 bits of c to 10.
-; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01.
- push af
- rl c
- pop af
- ccf
- rl c
-
-; If sprite i's delta X is 0, then b = 7, else b = 9.
- ld b, 7
- ld a, [hl] ; a = [$c1ib] (adjusted X coordinate)
- and $f
- jr z, .next3
- ld b, 9
-
-.next3
- ld a, [$ff91] ; a = distance between adjusted X coordinates
- sub b
- ld [$ff92], a ; store distance adjusted using sprite i's direction
- ld a, b
- ld [$ff91], a ; store 7 or 9 depending on sprite i's delta X
- jr c, .collision
-
-; If sprite j's delta X is 0, then b = 7, else b = 9.
- ld b, 7
- dec e
- ld a, [de] ; a = [$c1j5] (delta X)
- inc e
- and a
- jr z, .next4
- ld b, 9
-
-.next4
- ld a, [$ff92] ; a = distance adjusted using sprite i's direction
- sub b ; adjust distance using sprite j's direction
- jr z, .collision
- jr nc, .next ; go to next sprite if distance is still positive after both adjustments
-
-.collision
- ld a, l
- and $f0 ; collision with pikachu?
- jr nz, .asm_4cd9
- xor a
- ld [wd434], a
- ld a, [$ff8f]
- cp $f
- jr nz, .asm_4cd9
- call Func_4d0a
- jr .asm_4cef
-.asm_4cd9
- ld a, [$ff91] ; a = 7 or 9 depending on sprite i's delta X
- ld b, a
- ld a, [$ff90] ; a = 7 or 9 depending on sprite i's delta Y
- inc l
-
-; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100.
-; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa)
- cp b
- jr c, .next5
- ld b, %1100
- jr .next6
-.next5
- ld b, %0011
-
-.next6
- ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis)
- and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above
- or [hl] ; or with existing collision direction bits in [$c1ic]
- ld [hl], a ; store new value
- ld a, c ; useless code because a is overwritten before being used again
-
-; set bit in [$c1ie] or [$c1if] to indicate which sprite the collision occurred with
- inc l
- inc l
-.asm_4cef
- ld a, [$ff8f] ; a = loop counter
- ld de, SpriteCollisionBitTable
- add a
- add e
- ld e, a
- jr nc, .noCarry3
- inc d
-.noCarry3
- ld a, [de]
- or [hl]
- ld [hli], a
- inc de
- ld a, [de]
- or [hl]
- ld [hl], a
-
-.next
- ld a, [$ff8f] ; a = loop counter
- inc a
- cp $10
- jp nz, .loop
- ret
-
-; takes delta X or delta Y in a
-; b = delta X/Y
-; c = 0 if delta X/Y is 0
-; c = 7 if delta X/Y is 1
-; c = 9 if delta X/Y is -1
-Func_4d0a:
- ld a, [$ff91]
- ld b, a
- ld a, [$ff90]
- inc l
- cp b
- jr c, .asm_4d17
- ld b, %1100
- jr .asm_4d19
-.asm_4d17
- ld b, %11
-.asm_4d19
- ld a, c
- and b
- ld [wd434], a
- ld a, c
- inc l
- inc l
- ret
-
-SetSpriteCollisionValues:
- and a
- ld b, 0
- ld c, 0
- jr z, .done
- ld c, 9
- cp -1
- jr z, .ok
- ld c, 7
- ld a, 0
-.ok
- ld b, a
-.done
- ret
-
-SpriteCollisionBitTable:
- db %00000000,%00000001
- db %00000000,%00000010
- db %00000000,%00000100
- db %00000000,%00001000
- db %00000000,%00010000
- db %00000000,%00100000
- db %00000000,%01000000
- db %00000000,%10000000
- db %00000001,%00000000
- db %00000010,%00000000
- db %00000100,%00000000
- db %00001000,%00000000
- db %00010000,%00000000
- db %00100000,%00000000
- db %01000000,%00000000
- db %10000000,%00000000
diff --git a/engine/overworld/map_sprites.asm b/engine/overworld/map_sprites.asm
index 3e2c3912..e31c0bd2 100755
--- a/engine/overworld/map_sprites.asm
+++ b/engine/overworld/map_sprites.asm
@@ -8,7 +8,7 @@
; fields, respectively, within loops. The X is the loop index.
; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y*
; denote fields of the sprite slots iterated over in the inner loop.
-_InitMapSprites:
+_InitMapSprites::
call InitOutsideMapSprites
ret c ; return if the map is an outside map (already handled by above call)
; if the map is an inside map (i.e. mapID >= $25)
@@ -21,7 +21,7 @@ _InitMapSprites:
; sets carry if the map is a city or route, unsets carry if not
InitOutsideMapSprites:
ld a, [wCurMap]
- cp a, REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)?
+ cp FIRST_INDOOR_MAP ; is the map a city or a route?
ret nc ; if not, return
call GetSplitMapSpriteSetID
; if so, choose the appropriate one
@@ -68,7 +68,7 @@ LoadSpriteSetFromMapHeader:
ld a, 14
.storeVRAMSlotsLoop
push af
- ld a, [hl] ; $C1X0 (picture ID) (zero if sprite slot is not used)
+ ld a, [hl] ; [x#SPRITESTATEDATA1_PICTUREID] (zero if sprite slot is not used)
and a ; is the sprite slot used?
jr z, .continue ; if the sprite slot is not used
ld c, a
@@ -125,7 +125,7 @@ CheckForFourTileSprite:
cp SPRITE_PIKACHU ; is this the Pikachu Sprite?
ret z ; return if yes
- cp SPRITE_BALL ; is this a four tile sprite?
+ cp FIRST_STILL_SPRITE ; is this a four tile sprite?
jr nc, .notYellowSprite ; set carry if yes
; regular sprite
and a
@@ -138,7 +138,7 @@ CheckForFourTileSprite:
LoadMapSpriteTilePatterns:
ld a, 0
.loop
- ld [hVRAMSlot], a
+ ldh [hVRAMSlot], a
cp 9
jr nc, .fourTileSprite
call LoadStillTilePattern
@@ -148,7 +148,7 @@ LoadMapSpriteTilePatterns:
.fourTileSprite
call LoadStillTilePattern
.continue
- ld a, [hVRAMSlot]
+ ldh a, [hVRAMSlot]
inc a
cp 11
jr nz, .loop
@@ -157,12 +157,12 @@ LoadMapSpriteTilePatterns:
ReloadWalkingTilePatterns:
xor a
.loop
- ld [hVRAMSlot], a
+ ldh [hVRAMSlot], a
cp 9
jr nc, .fourTileSprite
call LoadWalkingTilePattern
.fourTileSprite
- ld a, [hVRAMSlot]
+ ldh a, [hVRAMSlot]
inc a
cp 11
jr nz, .loop
@@ -192,7 +192,7 @@ LoadWalkingTilePattern:
GetSpriteVRAMAddress:
push bc
- ld a, [hVRAMSlot]
+ ldh a, [hVRAMSlot]
ld c, a
ld b, 0
ld hl, SpriteVRAMAddresses
@@ -220,7 +220,7 @@ SpriteVRAMAddresses:
dw vChars0 + $7c0 ; 4-tile sprites
ReadSpriteSheetData:
- ld a, [hVRAMSlot]
+ ldh a, [hVRAMSlot]
ld e, a
ld d, 0
ld hl, wSpriteSet
@@ -257,20 +257,20 @@ Func_14150:
ld a, $e
ld hl, wSprite01StateData1
.loop
- ld [hVRAMSlot], a ; store current sprite set slot as a counter
- ld a, [hl] ; $c1x0 (picture ID)
+ ldh [hVRAMSlot], a ; store current sprite set slot as a counter
+ ld a, [hl] ; [x#SPRITESTATEDATA1_PICTUREID]
and a ; is the sprite unused?
jr z, .spriteUnused
call Func_14179
push hl
ld de, (wSpritePlayerStateData2ImageBaseOffset) - (wSpriteStateData1) ; $10e
- add hl, de ; get $c2xe (sprite image base offset)
+ add hl, de ; [x#SPRITESTATEDATA2_IMAGEBASEOFFSET]
ld [hl], a ; write offset
pop hl
.spriteUnused
ld de, wSprite02StateData1 - wSprite01StateData1
add hl, de
- ld a, [hVRAMSlot]
+ ldh a, [hVRAMSlot]
dec a
jr nz, .loop
ret
@@ -364,4 +364,6 @@ GetSplitMapSpriteSetID:
ld a, $01
ret
-INCLUDE "data/sprite_sets.asm"
+INCLUDE "data/maps/sprite_sets.asm"
+
+INCLUDE "data/sprites/sprites.asm"
diff --git a/engine/overworld/missable_objects.asm b/engine/overworld/missable_objects.asm
index dd601451..358a9b9f 100644
--- a/engine/overworld/missable_objects.asm
+++ b/engine/overworld/missable_objects.asm
@@ -1,6 +1,6 @@
-MarkTownVisitedAndLoadMissableObjects:
+MarkTownVisitedAndLoadMissableObjects::
ld a, [wCurMap]
- cp ROUTE_1
+ cp FIRST_ROUTE_MAP
jr nc, .notInTown
ld c, a
ld b, FLAG_SET
@@ -22,31 +22,31 @@ MarkTownVisitedAndLoadMissableObjects:
ld l, a
push hl
ld a, l
- sub MapHS00 & $ff ; calculate difference between out pointer and the base pointer
+ sub MissableObjects & $ff ; calculate difference between out pointer and the base pointer
ld l, a
ld a, h
- sbc MapHS00 / $100
+ sbc MissableObjects / $100
ld h, a
ld a, h
- ld [H_DIVIDEND], a
+ ldh [hDividend], a
ld a, l
- ld [H_DIVIDEND + 1], a
+ ldh [hDividend+1], a
xor a
- ld [H_DIVIDEND + 2], a
- ld [H_DIVIDEND + 3], a
+ ldh [hDividend+2], a
+ ldh [hDividend+3], a
ld a, $3
- ld [H_DIVISOR], a
+ ldh [hDivisor], a
ld b, $2
call Divide ; divide difference by 3, resulting in the global offset (number of missable items before ours)
ld a, [wCurMap]
ld b, a
- ld a, [H_DIVIDEND + 3]
+ ldh a, [hDividend+3]
ld c, a ; store global offset in c
ld de, wMissableObjectList
pop hl
.writeMissableObjectsListLoop
ld a, [hli]
- cp $ff
+ cp -1
jr z, .done ; end of list
cp b
jr nz, .done ; not for current map anymore
@@ -60,7 +60,7 @@ MarkTownVisitedAndLoadMissableObjects:
inc de
jr .writeMissableObjectsListLoop
.done
- ld a, $ff
+ ld a, -1
ld [de], a ; write sentinel
ret
@@ -69,17 +69,17 @@ InitializeMissableObjectsFlags:
ld bc, wMissableObjectFlagsEnd - wMissableObjectFlags
xor a
call FillMemory ; clear missable objects flags
- ld hl, MapHS00
+ ld hl, MissableObjects
xor a
ld [wMissableObjectCounter], a
.missableObjectsLoop
ld a, [hli]
- cp $ff ; end of list
+ cp -1 ; end of list
ret z
push hl
inc hl
ld a, [hl]
- cp Hide
+ cp HIDE
jr nz, .skip
ld hl, wMissableObjectFlags
ld a, [wMissableObjectCounter]
@@ -96,13 +96,13 @@ InitializeMissableObjectsFlags:
; tests if current sprite is a missable object that is hidden/has been removed
IsObjectHidden:
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
swap a
ld b, a
ld hl, wMissableObjectList
.loop
ld a, [hli]
- cp $ff
+ cp -1
jr z, .notHidden ; not missable -> not hidden
cp b
ld a, [hli]
@@ -117,7 +117,7 @@ IsObjectHidden:
.notHidden
xor a
.hidden
- ld [$ffe5], a
+ ldh [hIsHiddenMissableObject], a
ret
; adds missable object (items, leg. pokemon, etc.) to the map
diff --git a/engine/overworld/movement.asm b/engine/overworld/movement.asm
index f2334479..dadf2194 100644
--- a/engine/overworld/movement.asm
+++ b/engine/overworld/movement.asm
@@ -1,25 +1,25 @@
MAP_TILESET_SIZE EQU $60
UpdatePlayerSprite:
- ld a, [wSpriteStateData2]
+ ld a, [wSpritePlayerStateData2WalkAnimationCounter]
and a
jr z, .checkIfTextBoxInFrontOfSprite
cp $ff
jr z, .disableSprite
dec a
- ld [wSpriteStateData2], a
+ ld [wSpritePlayerStateData2WalkAnimationCounter], 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
+ lda_coord 8, 9
+ ldh [hTilePlayerStandingOn], a
cp MAP_TILESET_SIZE
jr c, .lowerLeftTileIsMapTile
.disableSprite
ld a, $ff
- ld [wSpriteStateData1 + 2], a
+ ld [wSpritePlayerStateData1ImageIndex], a
ret
.lowerLeftTileIsMapTile
ld a, [wUpdateSpritesEnabled]
@@ -29,7 +29,7 @@ UpdatePlayerSprite:
call DetectCollisionBetweenSprites
pop af
ld [wUpdateSpritesEnabled], a
- ld h, wSpriteStateData1 / $100
+ ld h, HIGH(wSpriteStateData1)
ld a, [wWalkCounter]
and a
jr nz, .moving
@@ -62,8 +62,8 @@ UpdatePlayerSprite:
.notMoving
; zero the animation counters
xor a
- ld [wSpriteStateData1 + 7], a
- ld [wSpriteStateData1 + 8], a
+ ld [wSpritePlayerStateData1IntraAnimFrameCounter], a
+ ld [wSpritePlayerStateData1AnimFrameCounter], a
call Func_4e32
jr .skipSpriteAnim
.moving
@@ -77,27 +77,27 @@ UpdatePlayerSprite:
; 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]
+ ldh a, [hTilePlayerStandingOn]
ld c, a
ld a, [wGrassTile]
cp c
- ld a, $0
+ ld a, 0
jr nz, .next2
- ld a, $80
+ ld a, OAM_BEHIND_BG
.next2
- ld [wSpriteStateData2 + $07], a
+ ld [wSpritePlayerStateData2GrassPriority], a
ret
Func_4e32:
- ld a, [wSpriteStateData1 + 8]
+ ld a, [wSpritePlayerStateData1AnimFrameCounter]
ld b, a
ld a, [wSpritePlayerStateData1FacingDirection]
add b
- ld [wSpriteStateData1 + 2], a
+ ld [wSpritePlayerStateData1ImageIndex], a
ret
UpdateNPCSprite:
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
swap a
dec a
add a
@@ -106,20 +106,20 @@ UpdateNPCSprite:
ld l, a
ld a, [hl] ; read movement byte 2
ld [wCurSpriteMovement2], a
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
ld l, a
inc l
- ld a, [hl] ; c1x1
+ ld a, [hl] ; x#SPRITESTATEDATA1_MOVEMENTSTATUS
and a
jp z, InitializeSpriteStatus
call CheckSpriteAvailability
ret c ; if sprite is invisible, on tile >=MAP_TILESET_SIZE, in grass or player is currently walking
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
ld l, a
inc l
- ld a, [hl] ; c1x1
+ ld a, [hl] ; x#SPRITESTATEDATA1_MOVEMENTSTATUS
bit 7, a ; is the face player flag set?
jp nz, MakeNPCFacePlayer
ld b, a
@@ -128,24 +128,24 @@ UpdateNPCSprite:
jp nz, notYetMoving
ld a, b
cp $2
- jp z, UpdateSpriteMovementDelay ; c1x1 == 2
+ jp z, UpdateSpriteMovementDelay ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] == 2
cp $3
- jp z, UpdateSpriteInWalkingAnimation ; c1x1 == 3
+ jp z, UpdateSpriteInWalkingAnimation ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] == 3
cp $4
jp z, Func_5357
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, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
add $6
ld l, a
- ld a, [hl] ; c2x6: movement byte 1
+ ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
inc a
- jp z, .randomMovement ; value $FF
+ jp z, .randomMovement ; value STAY
inc a
- jp z, .randomMovement ; value $FE
+ jp z, .randomMovement ; value WALK
; scripted movement
dec a
ld [hl], a ; increment movement byte 1 (movement data index)
@@ -156,7 +156,7 @@ UpdateNPCSprite:
pop hl
ld de, wNPCMovementDirections
call LoadDEPlusA ; a = [wNPCMovementDirections + movement byte 1]
- cp $e0
+ cp NPC_CHANGE_FACING
jp z, ChangeFacingDirection
cp STAY
jr nz, .next
@@ -171,7 +171,7 @@ UpdateNPCSprite:
.next
cp WALK
jr nz, .asm_4ecb
-; current NPC movement data is $fe. this seems buggy
+; current NPC movement data is WALK ($fe). this seems buggy
ld [hl], $1 ; set movement byte 1 to $1
ld de, wNPCMovementDirections
call LoadDEPlusA ; a = [wNPCMovementDirections + $fe] (?)
@@ -188,20 +188,20 @@ UpdateNPCSprite:
.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
+ cp DOWN
+ jr z, .moveDown
+ cp UP
+ jr z, .moveUp
+ cp LEFT
+ jr z, .moveLeft
+ cp RIGHT
+ jr z, .moveRight
ld a, b
- cp $40 ; a < $40: down (or left)
+ cp NPC_MOVEMENT_UP ; NPC_MOVEMENT_DOWN <= a < NPC_MOVEMENT_UP: down (or left)
jr nc, .notDown
ld a, [wCurSpriteMovement2]
- cp $2
- jr z, .moveLeft ; movement byte 2 = $2 only allows left or right
+ cp LEFT_RIGHT
+ jr z, .moveLeft
.moveDown
ld de, 2*SCREEN_WIDTH
add hl, de ; move tile pointer two rows down
@@ -209,11 +209,11 @@ UpdateNPCSprite:
lb bc, 4, SPRITE_FACING_DOWN
jr TryWalking
.notDown
- cp $80 ; $40 <= a < $80: up (or right)
+ cp NPC_MOVEMENT_LEFT ; NPC_MOVEMENT_UP <= a < NPC_MOVEMENT_LEFT: up (or right)
jr nc, .notUp
ld a, [wCurSpriteMovement2]
- cp $2
- jr z, .moveRight ; movement byte 2 = $2 only allows left or right
+ cp LEFT_RIGHT
+ jr z, .moveRight
.moveUp
ld de, -2*SCREEN_WIDTH
add hl, de ; move tile pointer two rows up
@@ -221,21 +221,21 @@ UpdateNPCSprite:
lb bc, 8, SPRITE_FACING_UP
jr TryWalking
.notUp
- cp $c0 ; $80 <= a < $c0: left (or up)
+ cp NPC_MOVEMENT_RIGHT ; NPC_MOVEMENT_LEFT <= a < NPC_MOVEMENT_RIGHT: left (or up)
jr nc, .notLeft
ld a, [wCurSpriteMovement2]
- cp $1
- jr z, .moveUp ; movement byte 2 = $1 only allows up or down
+ cp UP_DOWN
+ jr z, .moveUp
.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)
+.notLeft ; NPC_MOVEMENT_RIGHT <= a: right (or down)
ld a, [wCurSpriteMovement2]
- cp $1
- jr z, .moveDown ; movement byte 2 = $1 only allows up or down
+ cp UP_DOWN
+ jr z, .moveDown
.moveRight
inc hl
inc hl ; move tile pointer two columns right
@@ -262,103 +262,104 @@ TryWalking:
ld c, [hl]
call CanWalkOntoTile
pop de
- ret c
+ ret c ; cannot walk there (reinitialization of delay values already done)
call Func_5349
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
- ld [hl], $10 ; c1x9 (update facing direction)
+ ld [hl], $10 ; [x#SPRITESTATEDATA2_WALKANIMATIONCOUNTER] = 16
dec h
inc l
- ld [hl], $3
+ ld [hl], $3 ; x#SPRITESTATEDATA1_MOVEMENTSTATUS
jp UpdateSpriteImage
; update the walking animation parameters for a sprite that is currently walking
UpdateSpriteInWalkingAnimation:
call Func_5274
-.noNextAnimationFrame
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $3
ld l, a
- ld a, [hli] ; c1x3 (movement Y delta)
+ ld a, [hli] ; x#SPRITESTATEDATA1_YSTEPVECTOR
ld b, a
- ld a, [hl] ; c1x4 (screen Y position)
+ ld a, [hl] ; x#SPRITESTATEDATA1_YPIXELS
add b
- ld [hli], a ; update screen Y position
- ld a, [hli] ; c1x5 (movement X delta)
+ ld [hli], a ; update [x#SPRITESTATEDATA1_YPIXELS]
+ ld a, [hli] ; x#SPRITESTATEDATA1_XSTEPVECTOR
ld b, a
- ld a, [hl] ; c1x6 (screen X position)
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
add b
- ld [hl], a ; update screen X position
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld [hl], a ; update [x#SPRITESTATEDATA1_XPIXELS]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
inc h
- ld a, [hl] ; c2x0 (walk animation counter)
+ ld a, [hl] ; x#SPRITESTATEDATA2_WALKANIMATIONCOUNTER
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]
+ ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
+ cp WALK
+ jr nc, .initNextMovementCounter ; values WALK or STAY
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
dec h
- ld [hl], $1 ; c1x1 = 1 (movement status ready)
+ ld [hl], $1 ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] = 1 (movement status ready)
ret
.initNextMovementCounter
call Random
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $8
ld l, a
- ld a, [hRandomAdd]
+ ldh 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]
+ ld [hl], a ; x#SPRITESTATEDATA2_MOVEMENTDELAY:
+ ; set next movement delay to a random value in [0,$7f]
+ ; note that value 0 actually makes the delay $100 (bug?)
+ dec h ; HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
- ld [hl], $2 ; c1x1 = 2 (movement status)
+ ld [hl], $2 ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] = 2 (movement status)
inc l
inc l
xor a
- ld b, [hl] ; c1x3 (movement Y delta)
- ld [hli], a ; reset movement Y delta
+ ld b, [hl] ; x#SPRITESTATEDATA1_YSTEPVECTOR
+ ld [hli], a ; [x#SPRITESTATEDATA1_YSTEPVECTOR] = 0
inc l
- ld c, [hl] ; c1x5 (movement X delta)
- ld [hl], a ; reset movement X delta
+ ld c, [hl] ; x#SPRITESTATEDATA1_XSTEPVECTOR
+ ld [hl], a ; [x#SPRITESTATEDATA1_XSTEPVECTOR] = 0
ret
-; update delay value (c2x8) for sprites in the delayed state (c1x1)
+; update [x#SPRITESTATEDATA2_MOVEMENTDELAY] for sprites in the delayed state (x#SPRITESTATEDATA1_MOVEMENTSTATUS)
UpdateSpriteMovementDelay:
- ld h, $c2
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
add $6
ld l, a
- ld a, [hl] ; c2x6: movement byte 1
+ ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
inc l
inc l
- cp $fe
- jr nc, .tickMoveCounter ; values $fe or $ff
+ cp WALK
+ jr nc, .tickMoveCounter ; values WALK or STAY
ld [hl], $0
jr .moving
.tickMoveCounter
- dec [hl] ; c2x8: frame counter until next movement
+ dec [hl] ; x#SPRITESTATEDATA2_MOVEMENTDELAY
jr nz, notYetMoving
.moving
dec h
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
- ld [hl], $1 ; c1x1 = 1 (mark as ready to move)
+ ld [hl], $1 ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] = 1 (mark as ready to move)
notYetMoving:
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- add $8
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_ANIMFRAMECOUNTER
ld l, a
- ld [hl], $0 ; c1x8 = 0 (walk animation frame)
+ ld [hl], $0 ; [x#SPRITESTATEDATA1_ANIMFRAMECOUNTER] = 0 (walk animation frame)
jp UpdateSpriteImage
MakeNPCFacePlayer:
@@ -388,48 +389,48 @@ MakeNPCFacePlayer:
.notFacingRight
ld c, SPRITE_FACING_LEFT
.facingDirectionDetermined
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $9
ld l, a
- ld [hl], c ; c1x9: set facing direction
+ ld [hl], c ; [x#SPRITESTATEDATA1_FACINGDIRECTION]: set facing direction
jr notYetMoving
InitializeSpriteStatus:
- ld [hl], $1 ; $c1x1: set movement status to ready
+ ld [hl], $1 ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] = ready
inc l
- ld [hl], $ff ; $c1x2: set sprite image to $ff (invisible/off screen)
- inc h
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld [hl], $ff ; [x#SPRITESTATEDATA1_IMAGEINDEX] = invisible/off screen
+ inc h ; HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
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
+ ld [hli], a ; [x#SPRITESTATEDATA2_YDISPLACEMENT] = 8
+ ld [hl], a ; [x#SPRITESTATEDATA2_XDISPLACEMENT] = 8
call InitializeSpriteScreenPosition ; could have done fallthrough here
ret
-; calculates the sprite's screen position form its map position and the player position
+; calculates the sprite's screen position from its map position and the player position
InitializeSpriteScreenPosition:
- ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- add $4
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_MAPY
ld l, a
ld a, [wYCoord]
ld b, a
- ld a, [hl] ; c2x4 (Y position + 4)
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPY
sub b ; relative to player position
call Func_5033
sub $4 ; - 4
dec h
- ld [hli], a ; c1x4 (screen Y position)
+ ld [hli], a ; [x#SPRITESTATEDATA1_YPIXELS]
inc h
ld a, [wXCoord]
ld b, a
- ld a, [hli] ; c2x6 (X position + 4)
+ ld a, [hli] ; x#SPRITESTATEDATA2_MAPX
sub b ; relative to player position
call Func_5033
dec h
- ld [hl], a ; c1x6 (screen X position)
+ ld [hl], a ; [x#SPRITESTATEDATA1_XPIXELS]
ret
Func_5033:
@@ -447,35 +448,35 @@ Func_5033:
; tests if sprite is off screen or otherwise unable to do anything
CheckSpriteAvailability:
predef IsObjectHidden
- ld a, [$ffe5]
+ ldh a, [hIsHiddenMissableObject]
and a
jp nz, .spriteInvisible
- ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- add $6
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_MOVEMENTBYTE1
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 a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
+ cp WALK
+ jr c, .skipXVisibilityTest ; movement byte 1 < WALK (i.e. the sprite's movement is scripted)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_MAPY
ld l, a
- ld b, [hl] ; c2x4: Y pos (+4)
+ ld b, [hl] ; x#SPRITESTATEDATA2_MAPY
ld a, [wYCoord]
cp b
jr z, .skipYVisibilityTest
jr nc, .spriteInvisible ; above screen region
- add $8 ; screen is 9 tiles high
+ add SCREEN_HEIGHT / 2 - 1
cp b
jr c, .spriteInvisible ; below screen region
.skipYVisibilityTest
inc l
- ld b, [hl] ; c2x5: X pos (+4)
+ ld b, [hl] ; x#SPRITESTATEDATA2_MAPX
ld a, [wXCoord]
cp b
jr z, .skipXVisibilityTest
jr nc, .spriteInvisible ; left of screen region
- add $9 ; screen is 10 tiles wide
+ add SCREEN_WIDTH / 2 - 1
cp b
jr c, .spriteInvisible ; right of screen region
.skipXVisibilityTest
@@ -489,7 +490,7 @@ CheckSpriteAvailability:
ld a, [hld]
cp d
jr nc, .spriteInvisible ; standing on tile with ID >=MAP_TILESET_SIZE (bottom right tile)
- ld bc, -20
+ ld bc, -SCREEN_WIDTH
add hl, bc ; go back one row of tiles
ld a, [hli]
cp d
@@ -498,11 +499,11 @@ CheckSpriteAvailability:
cp d
jr c, .spriteVisible ; standing on tile with ID >=MAP_TILESET_SIZE (top right tile)
.spriteInvisible
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_IMAGEINDEX
ld l, a
- ld [hl], $ff ; c1x2
+ ld [hl], $ff ; x#SPRITESTATEDATA1_IMAGEINDEX
scf
jr .done
.spriteVisible
@@ -512,37 +513,37 @@ CheckSpriteAvailability:
jr nz, .done ; if player is currently walking, we're done
call UpdateSpriteImage
inc h
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $7
ld l, a
ld a, [wGrassTile]
cp c
- ld a, $0
+ ld a, 0
jr nz, .notInGrass
- ld a, $80
+ ld a, OAM_BEHIND_BG
.notInGrass
- ld [hl], a ; c2x7
+ ld [hl], a ; x#SPRITESTATEDATA2_GRASSPRIORITY
and a
.done
ret
UpdateSpriteImage:
- ld h, $c1
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
add $8
ld l, a
- ld a, [hli] ; c1x8: walk animation frame
+ ld a, [hli] ; x#SPRITESTATEDATA1_ANIMFRAMECOUNTER
ld b, a
- ld a, [hl] ; c1x9: facing direction
+ ld a, [hl] ; x#SPRITESTATEDATA1_FACINGDIRECTION
add b
ld b, a
- ld a, [$ff93] ; current sprite offset
+ ldh a, [hTilePlayerStandingOn]
add b
ld b, a
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $2
ld l, a
- ld [hl], b ; c1x2: sprite to display
+ ld [hl], b ; x#SPRITESTATEDATA1_IMAGEINDEX
ret
; tests if sprite can walk the specified direction
@@ -552,37 +553,37 @@ UpdateSpriteImage:
; 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 h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_MOVEMENTBYTE1
ld l, a
- ld a, [hl] ; c2x6 (movement byte 1)
- cp $fe
- jr nc, .notScripted ; values $fe and $ff
+ ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
+ cp WALK
+ jr nc, .notScripted ; values WALK or STAY
; always allow walking if the movement is scripted
and a
ret
.notScripted
call _IsTilePassable
jr c, .impassable
- ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
add $6
ld l, a
- ld a, [hl] ; $c2x6 (movement byte 1)
+ ld a, [hl] ; x#SPRITESTATEDATA2_MOVEMENTBYTE1
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 h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_YPIXELS
ld l, a
- ld a, [hli] ; c1x4 (screen Y pos)
+ ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
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)
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
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
@@ -597,30 +598,36 @@ CanWalkOntoTile:
ld [wUpdateSpritesEnabled], a
pop bc
pop de
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
add $c
ld l, a
- ld a, [hl] ; c1xc (directions in which sprite collision would occur)
+ ld a, [hl] ; x#SPRITESTATEDATA1_COLLISIONDATA (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 h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_YDISPLACEMENT
ld l, a
- ld a, [hli] ; c2x2 (sprite Y displacement, initialized at $8, keep track of where a sprite did go)
+ ld a, [hli] ; x#SPRITESTATEDATA2_YDISPLACEMENT (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
+ ; bug: these tests against $5 probably were supposed to prevent
+ ; sprites from walking out too far, but this line makes sprites get
+ ; stuck whenever they walked upwards 5 steps
+ ; on the other hand, the amount a sprite can walk out to the
+ ; right of bottom is not limited (until the counter overflows)
+ ; this was fixed in Yellow
cp $5
- ;jr c, .impassable (bugfix) ; 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)
+ ;jr c, .impassable ; if [x#SPRITESTATEDATA2_YDISPLACEMENT]+d < 5, don't go
+ jr .checkHorizontal
+.upwards
+ sub $1
+ jr c, .impassable ; if [x#SPRITESTATEDATA2_YDISPLACEMENT] == 0, don't go
.checkHorizontal
ld d, a
- ld a, [hl] ; c2x3 (sprite X displacement, initialized at $8, keep track of where a sprite did go)
+ ld a, [hl] ; x#SPRITESTATEDATA2_XDISPLACEMENT (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
@@ -628,32 +635,32 @@ CanWalkOntoTile:
jr .passable
.left
sub $1
- jr c, .impassable ; if d2x3 == 0, don't go
+ jr c, .impassable ; if [x#SPRITESTATEDATA2_XDISPLACEMENT] == 0, don't go
.passable
- ld [hld], a ; update c2x3
- ld [hl], d ; update c2x2
+ ld [hld], a ; update x#SPRITESTATEDATA2_XDISPLACEMENT
+ ld [hl], d ; update x#SPRITESTATEDATA2_YDISPLACEMENT
and a ; clear carry (marking success)
ret
.impassable
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
- ld [hl], $2 ; c1x1 = 2 (set movement status to delayed)
+ ld [hl], $2 ; [x#SPRITESTATEDATA1_MOVEMENTSTATUS] = 2 (delayed)
inc l
inc l
xor a
- ld [hli], a ; c1x3 = 0 (clear Y movement delta)
+ ld [hli], a ; [x#SPRITESTATEDATA1_YSTEPVECTOR] = 0
inc l
- ld [hl], a ; c1x5 = 0 (clear X movement delta)
+ ld [hl], a ; [x#SPRITESTATEDATA1_XSTEPVECTOR] = 0
inc h
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $8
ld l, a
call Random
- ld a, [hRandomAdd]
+ ldh 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)
+ ld [hl], a ; x#SPRITESTATEDATA2_MOVEMENTDELAY: set to a random value in [0,$7f] (again with delay $100 if value is 0)
scf ; set carry (marking failure to walk)
ret
@@ -661,25 +668,25 @@ CanWalkOntoTile:
; 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 h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_YPIXELS
ld l, a
- ld a, [hli] ; c1x4: screen Y position
+ ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
add $4 ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
and $f8 ; in case object is currently moving (XXX why changed to $f8?)
srl a ; screen Y tile * 4
ld c, a
ld b, $0
inc l
- ld a, [hl] ; c1x6: screen X position
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
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
+ hlcoord 0, 0
add hl, bc
add hl, bc
add hl, bc
@@ -754,7 +761,7 @@ DoScriptedNPCMovement:
ld a, [hl]
add b
ld [hl], a
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $9
ld l, a
ld a, c
@@ -777,17 +784,17 @@ InitScriptedNPCMovement:
jp AnimScriptedNPCMovement
GetSpriteScreenYPointer:
- ld a, $4
+ ld a, SPRITESTATEDATA1_YPIXELS
ld b, a
jr GetSpriteScreenXYPointerCommon
GetSpriteScreenXPointer:
- ld a, $6
+ ld a, SPRITESTATEDATA1_XPIXELS
ld b, a
GetSpriteScreenXYPointerCommon:
ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add l
add b
ld l, a
@@ -795,16 +802,16 @@ GetSpriteScreenXYPointerCommon:
AnimScriptedNPCMovement:
ld hl, wSpriteStateData2
- ld a, [H_CURRENTSPRITEOFFSET]
- add $e
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA2_IMAGEBASEOFFSET
ld l, a
ld a, [hl] ; VRAM slot
dec a
swap a
ld b, a
ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $9
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_FACINGDIRECTION
ld l, a
ld a, [hl] ; facing direction
cp SPRITE_FACING_DOWN
@@ -819,42 +826,42 @@ AnimScriptedNPCMovement:
.anim
add b
ld b, a
- ld [hSpriteVRAMSlotAndFacing], a
+ ldh [hSpriteVRAMSlotAndFacing], a
call AdvanceScriptedNPCAnimFrameCounter
ld hl, wSpriteStateData1
- ld a, [H_CURRENTSPRITEOFFSET]
- add $2
+ ldh a, [hCurrentSpriteOffset]
+ add SPRITESTATEDATA1_IMAGEINDEX
ld l, a
- ld a, [hSpriteVRAMSlotAndFacing]
+ ldh a, [hSpriteVRAMSlotAndFacing]
ld b, a
- ld a, [hSpriteAnimFrameCounter]
+ ldh a, [hSpriteAnimFrameCounter]
add b
ld [hl], a
ret
AdvanceScriptedNPCAnimFrameCounter:
call Func_5274
- ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
add $8
ld l, a
ld a, [hl] ; intra-animation frame counter
and $3
- ld [hSpriteAnimFrameCounter], a
+ ldh [hSpriteAnimFrameCounter], a
ret
Func_5274:
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $7
ld l, a
- ld h, wSpriteStateData1 / $100
- ld a, [hl] ; c1x7 (counter until next walk animation frame)
+ ld h, HIGH(wSpriteStateData1)
+ ld a, [hl] ; x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER
inc a
and $3
- ld [hl], a ; c1x7 += 1
- ret nz ; c1x7 = 0
+ ld [hl], a ; [x#SPRITESTATEDATA1_INTRAANIMFRAMECOUNTER]++
+ ret nz
inc l
- ld a, [hl] ; c1x8 (walk animation frame)
+ ld a, [hl] ; x#SPRITESTATEDATA1_ANIMFRAMECOUNTER
inc a
and $3
ld [hl], a ; advance to next animation frame every 4 ticks (16 ticks total for one step)
@@ -924,7 +931,7 @@ Func_5288:
.asm_52e6
call Func_5337
call Func_5349
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
ld [hl], $8
dec h
@@ -936,7 +943,7 @@ Func_5288:
.asm_52fa
call Func_5337
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
ld [hl], $8
dec h
@@ -949,7 +956,7 @@ Func_5288:
.asm_530b
call Func_5337
call Func_5349
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
ld [hl], $8
dec h
@@ -980,39 +987,39 @@ Func_5331:
ret
Func_5337:
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $9
ld l, a
- ld h, wSpriteStateData1 / $100
- ld [hl], c ; c1x9 (update facing direction)
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData1)
+ ld [hl], c ; x#SPRITESTATEDATA1_FACINGDIRECTION
+ ldh a, [hCurrentSpriteOffset]
add $3
ld l, a
- ld [hl], d ; c1x3 (update Y movement delta)
+ ld [hl], d ; x#SPRITESTATEDATA1_YSTEPVECTOR
inc l
inc l
- ld [hl], e ; c1x5 (update X movement delta)
+ ld [hl], e ; x#SPRITESTATEDATA1_XSTEPVECTOR
ret
Func_5349:
- ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hCurrentSpriteOffset]
add $4
ld l, a
- ld a, [hl] ; c2x4: Y position
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPY
add d
ld [hli], a ; update Y position
- ld a, [hl] ; c2x5: X position
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
add e
ld [hl], a ; update X position
ret
Func_5357:
call Func_5274
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $3
ld l, a
- ld h, wSpriteStateData1 / $100
+ ld h, HIGH(wSpriteStateData1)
ld a, [hli]
add a
ld b, a
@@ -1025,9 +1032,9 @@ Func_5357:
ld a, [hl]
add b
ld [hl], a
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
ld l, a
- ld h, wSpriteStateData2 / $100
+ ld h, HIGH(wSpriteStateData2)
dec [hl]
ret nz
ld a, $6
@@ -1036,23 +1043,23 @@ Func_5357:
ld a, [hl]
cp $fe
jr nc, .asm_5386
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
- ld h, wSpriteStateData1 / $100
+ ld h, HIGH(wSpriteStateData1)
ld [hl], $1
ret
.asm_5386
call Random
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add $8
ld l, a
- ld h, wSpriteStateData2 / $100
- ld a, [hRandomAdd]
+ ld h, HIGH(wSpriteStateData2)
+ ldh a, [hRandomAdd]
and $7f
ld [hl], a
dec h
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
inc a
ld l, a
ld [hl], $2
diff --git a/engine/overworld/npc_movement.asm b/engine/overworld/npc_movement.asm
deleted file mode 100755
index 670cb121..00000000
--- a/engine/overworld/npc_movement.asm
+++ /dev/null
@@ -1,270 +0,0 @@
-PlayerStepOutFromDoor:
- ld hl, wd730
- res 1, [hl]
- call IsPlayerStandingOnDoorTile
- jr nc, .notStandingOnDoor
- ld a, $fc
- ld [wJoyIgnore], a
- ld hl, wd736
- set 1, [hl]
- ld a, $1
- ld [wSimulatedJoypadStatesIndex], a
- ld a, D_DOWN
- ld [wSimulatedJoypadStatesEnd], a
- xor a
- ld [wSpriteStateData1 + 2], a
- call StartSimulatingJoypadStates
- ret
-.notStandingOnDoor
- xor a
- ld [wWastedByteCD3A], a
- ld [wSimulatedJoypadStatesIndex], a
- ld [wSimulatedJoypadStatesEnd], a
- ld hl, wd736
- res 0, [hl]
- res 1, [hl]
- ld hl, wd730
- res 7, [hl]
- ret
-
-_EndNPCMovementScript:
- ld hl, wd730
- res 7, [hl]
- ld hl, wd72e
- res 7, [hl]
- ld hl, wd736
- res 0, [hl]
- res 1, [hl]
- xor a
- ld [wNPCMovementScriptSpriteOffset], a
- ld [wNPCMovementScriptFunctionNum], a
- ld [wNPCMovementScriptPointerTableNum], a
- ld [wWastedByteCD3A], a
- ld [wSimulatedJoypadStatesIndex], a
- ld [wSimulatedJoypadStatesEnd], a
- ret
-
-PalletMovementScriptPointerTable:
- dw PalletMovementScript_OakMoveLeft
- dw PalletMovementScript_PlayerMoveLeft
- dw PalletMovementScript_WaitAndWalkToLab
- dw PalletMovementScript_WalkToLab
- dw PalletMovementScript_Done
-
-PalletMovementScript_OakMoveLeft:
- ld a, [wXCoord]
- sub $a
- ld [wNumStepsToTake], a
- jr z, .playerOnLeftTile
-; The player is on the right tile of the northern path out of Pallet Town and
-; Prof. Oak is below.
-; Make Prof. Oak step to the left.
- ld b, 0
- ld c, a
- ld hl, wNPCMovementDirections2
- ld a, NPC_MOVEMENT_LEFT
- call FillMemory
- ld [hl], $ff
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- ld de, wNPCMovementDirections2
- call MoveSprite
- ld a, $1
- ld [wNPCMovementScriptFunctionNum], a
- jr .done
-; The player is on the left tile of the northern path out of Pallet Town and
-; Prof. Oak is below.
-; Prof. Oak is already where he needs to be.
-.playerOnLeftTile
- ld a, $3
- ld [wNPCMovementScriptFunctionNum], a
-.done
- ld a, BANK(Music_MuseumGuy)
- ld c, a
- ld a, MUSIC_MUSEUM_GUY
- call PlayMusic
- ld hl, wFlags_D733
- set 1, [hl]
- ld a, $fc
- ld [wJoyIgnore], a
- ret
-
-PalletMovementScript_PlayerMoveLeft:
- ld a, [wd730]
- bit 0, a ; is an NPC being moved by a script?
- ret nz ; return if Oak is still moving
- ld a, [wNumStepsToTake]
- ld [wSimulatedJoypadStatesIndex], a
- ld [hNPCMovementDirections2Index], a
- predef ConvertNPCMovementDirectionsToJoypadMasks
- call StartSimulatingJoypadStates
- ld a, $2
- ld [wNPCMovementScriptFunctionNum], a
- ret
-
-PalletMovementScript_WaitAndWalkToLab:
- ld a, [wSimulatedJoypadStatesIndex]
- and a ; is the player done moving left yet?
- ret nz
-
-PalletMovementScript_WalkToLab:
- xor a
- ld [wOverrideSimulatedJoypadStatesMask], a
- ld a, [wSpriteIndex]
- swap a
- ld [wNPCMovementScriptSpriteOffset], a
- xor a
- ld [wSpriteStateData2 + $06], a
- ld hl, wSimulatedJoypadStatesEnd
- ld de, RLEList_PlayerWalkToLab
- call DecodeRLEList
- dec a
- ld [wSimulatedJoypadStatesIndex], a
- ld hl, wNPCMovementDirections2
- ld de, RLEList_ProfOakWalkToLab
- call DecodeRLEList
- ld hl, wd72e
- res 7, [hl]
- ld hl, wd730
- set 7, [hl]
- ld a, $4
- ld [wNPCMovementScriptFunctionNum], a
- ret
-
-
-RLEList_ProfOakWalkToLab:
- db NPC_MOVEMENT_DOWN, $06 ; differs from red
- db NPC_MOVEMENT_LEFT, $01
- db NPC_MOVEMENT_DOWN, $05
- db NPC_MOVEMENT_RIGHT, $03
- db NPC_MOVEMENT_UP, $01
- db $E0, $01 ; stand still
- db $FF
-
-RLEList_PlayerWalkToLab:
- db D_UP, $02
- db D_RIGHT, $03
- db D_DOWN, $05
- db D_LEFT, $01
- db D_DOWN, $07 ; differs from red
- db $FF
-
-PalletMovementScript_Done:
- ld a, [wSimulatedJoypadStatesIndex]
- and a
- ret nz
- ld a, HS_PALLET_TOWN_OAK
- ld [wMissableObjectIndex], a
- predef HideObject
- ld hl, wd730
- res 7, [hl]
- ld hl, wd72e
- res 7, [hl]
- jp EndNPCMovementScript
-
-PewterMuseumGuyMovementScriptPointerTable:
- dw PewterMovementScript_WalkToMuseum
- dw PewterMovementScript_Done
-
-PewterMovementScript_WalkToMuseum:
- ld a, BANK(Music_MuseumGuy)
- ld c, a
- ld a, MUSIC_MUSEUM_GUY
- call PlayMusic
- ld a, [wSpriteIndex]
- swap a
- ld [wNPCMovementScriptSpriteOffset], a
- call StartSimulatingJoypadStates
- ld hl, wSimulatedJoypadStatesEnd
- ld de, RLEList_PewterMuseumPlayer
- call DecodeRLEList
- dec a
- ld [wSimulatedJoypadStatesIndex], a
- xor a
- ld [wWhichPewterGuy], a
- call PewterGuys
- ld hl, wNPCMovementDirections2
- ld de, RLEList_PewterMuseumGuy
- call DecodeRLEList
- ld hl, wd72e
- res 7, [hl]
- ld a, $1
- ld [wNPCMovementScriptFunctionNum], a
- ret
-
-RLEList_PewterMuseumPlayer:
- db 0, $01
- db D_UP, $03
- db D_LEFT, $0D
- db D_UP, $06
- db $FF
-
-RLEList_PewterMuseumGuy:
- db NPC_MOVEMENT_UP, $06
- db NPC_MOVEMENT_LEFT, $0D
- db NPC_MOVEMENT_UP, $03
- db NPC_MOVEMENT_LEFT, $01
- db $FF
-
-PewterMovementScript_Done:
- ld a, [wSimulatedJoypadStatesIndex]
- and a
- ret nz
- ld hl, wd730
- res 7, [hl]
- ld hl, wd72e
- res 7, [hl]
- jp EndNPCMovementScript
-
-PewterGymGuyMovementScriptPointerTable:
- dw PewterMovementScript_WalkToGym
- dw PewterMovementScript_Done
-
-PewterMovementScript_WalkToGym:
- ld a, BANK(Music_MuseumGuy)
- ld c, a
- ld a, MUSIC_MUSEUM_GUY
- call PlayMusic
- ld a, [wSpriteIndex]
- swap a
- ld [wNPCMovementScriptSpriteOffset], a
- xor a
- ld [wSpriteStateData2 + $06], a
- ld hl, wSimulatedJoypadStatesEnd
- ld de, RLEList_PewterGymPlayer
- call DecodeRLEList
- dec a
- ld [wSimulatedJoypadStatesIndex], a
- ld a, 1
- ld [wWhichPewterGuy], a
- call PewterGuys
- ld hl, wNPCMovementDirections2
- ld de, RLEList_PewterGymGuy
- call DecodeRLEList
- ld hl, wd72e
- res 7, [hl]
- ld hl, wd730
- set 7, [hl]
- ld a, $1
- ld [wNPCMovementScriptFunctionNum], a
- ret
-
-RLEList_PewterGymPlayer:
- db 0, $01
- db D_RIGHT, $02
- db D_DOWN, $05
- db D_LEFT, $0B
- db D_UP, $05
- db D_LEFT, $0F
- db $FF
-
-RLEList_PewterGymGuy:
- db NPC_MOVEMENT_DOWN, $02
- db NPC_MOVEMENT_LEFT, $0F
- db NPC_MOVEMENT_UP, $05
- db NPC_MOVEMENT_LEFT, $0B
- db NPC_MOVEMENT_DOWN, $05
- db NPC_MOVEMENT_RIGHT, $03
- db $FF
-
-INCLUDE "engine/overworld/pewter_guys.asm"
diff --git a/engine/overworld/npc_movement_2.asm b/engine/overworld/npc_movement_2.asm
index 93d1afce..2ced9da6 100755
--- a/engine/overworld/npc_movement_2.asm
+++ b/engine/overworld/npc_movement_2.asm
@@ -1,4 +1,4 @@
-FreezeEnemyTrainerSprite:
+FreezeEnemyTrainerSprite::
ld a, [wCurMap]
cp POKEMON_TOWER_7F
ret z ; the Rockets on Pokemon Tower 7F leave after battling, so don't freeze them
@@ -7,18 +7,18 @@ FreezeEnemyTrainerSprite:
ld b, a
.loop
ld a, [hli]
- cp $ff
+ cp -1
jr z, .notRival
cp b
ret z ; the rival leaves after battling, so don't freeze him
jr .loop
.notRival
ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
+ ldh [hSpriteIndex], a
jp SetSpriteMovementBytesToFF
RivalIDs:
- db OPP_SONY1
- db OPP_SONY2
- db OPP_SONY3
- db $ff
+ db OPP_RIVAL1
+ db OPP_RIVAL2
+ db OPP_RIVAL3
+ db -1 ; end
diff --git a/engine/overworld/oaks_aide.asm b/engine/overworld/oaks_aide.asm
deleted file mode 100755
index f5068fda..00000000
--- a/engine/overworld/oaks_aide.asm
+++ /dev/null
@@ -1,71 +0,0 @@
-OaksAideScript:
- ld hl, OaksAideHiText
- call PrintText
- call YesNoChoice
- ld a, [wCurrentMenuItem]
- and a
- jr nz, .choseNo
- ld hl, wPokedexOwned
- ld b, wPokedexOwnedEnd - wPokedexOwned
- call CountSetBits
- ld a, [wNumSetBits]
- ld [hOaksAideNumMonsOwned], a
- ld b, a
- ld a, [hOaksAideRequirement]
- cp b
- jr z, .giveItem
- jr nc, .notEnoughOwnedMons
-.giveItem
- ld hl, OaksAideHereYouGoText
- call PrintText
- ld a, [hOaksAideRewardItem]
- ld b, a
- ld c, 1
- call GiveItem
- jr nc, .bagFull
- ld hl, OaksAideGotItemText
- call PrintText
- ld a, $1
- jr .done
-.bagFull
- ld hl, OaksAideNoRoomText
- call PrintText
- xor a
- jr .done
-.notEnoughOwnedMons
- ld hl, OaksAideUhOhText
- call PrintText
- ld a, $80
- jr .done
-.choseNo
- ld hl, OaksAideComeBackText
- call PrintText
- ld a, $ff
-.done
- ld [hOaksAideResult], a
- ret
-
-OaksAideHiText:
- TX_FAR _OaksAideHiText
- db "@"
-
-OaksAideUhOhText:
- TX_FAR _OaksAideUhOhText
- db "@"
-
-OaksAideComeBackText:
- TX_FAR _OaksAideComeBackText
- db "@"
-
-OaksAideHereYouGoText:
- TX_FAR _OaksAideHereYouGoText
- db "@"
-
-OaksAideGotItemText:
- TX_FAR _OaksAideGotItemText
- TX_SFX_ITEM_1
- db "@"
-
-OaksAideNoRoomText:
- TX_FAR _OaksAideNoRoomText
- db "@"
diff --git a/engine/overworld/oam.asm b/engine/overworld/oam.asm
deleted file mode 100644
index 5a831327..00000000
--- a/engine/overworld/oam.asm
+++ /dev/null
@@ -1,232 +0,0 @@
-PrepareOAMData:
-; Determine OAM data for currently visible
-; sprites and write it to wOAMBuffer.
-; Yellow code has been changed to use registers more efficiently
-; as well as tweaking the code to show gbc palettes
-
- ld a, [wUpdateSpritesEnabled]
- dec a
- jr z, .updateEnabled
-
- cp -1
- ret nz
- ld [wUpdateSpritesEnabled], a
- jp HideSprites
-
-.updateEnabled
- xor a
- ld [hOAMBufferOffset], a
-
-.spriteLoop
- ld [hSpriteOffset2], a
-
- ld e, a
- ld d, wSpriteStateData1 / $100
-
- ld a, [de] ; c1x0
- and a
- jp z, .nextSprite
-
- inc e
- inc e
- ld a, [de] ; c1x2 (facing/anim)
- ld [wd5cd], a
- cp $ff ; off-screen (don't draw)
- jr nz, .visible
-
- call GetSpriteScreenXY
- jr .nextSprite
-
-.visible
- cp $a0 ; is the sprite unchanging like an item ball or boulder?
- jr c, .usefacing
-
-; unchanging
- ld a, $0
- jr .next
-
-.usefacing
- and $f
-
-.next
-; read the entry from the table
- ld c, a
- ld b, 0
- ld hl, SpriteFacingAndAnimationTable
- add hl, bc
- add hl, bc
- ld a, [hli]
- ld h, [hl]
- ld l, a
-; get sprite priority
- push de
- inc d
- ld a, e
- add $5
- ld e, a
- ld a, [de] ; c2x7
- and $80
- ld [hSpritePriority], a ; temp store sprite priority
- pop de
-
-
- call GetSpriteScreenXY
-
- ld a, [hOAMBufferOffset]
- add [hl]
- cp $a0
- jr z, .hidden
- jr nc, .asm_4a41
-.hidden
- call Func_4a7b
- ld [wd5cd], a
- ld a, [hOAMBufferOffset]
-
- ld e, a
- ld d, wOAMBuffer / $100
-
-.tileLoop
- ld a, [hli]
- ld c, a
-.loop
- ld a, [hSpriteScreenY] ; temp for sprite Y position
- add $10 ; Y=16 is top of screen (Y=0 is invisible)
- add [hl] ; add Y offset from table
- ld [de], a ; write new sprite OAM Y position
- inc hl
- inc e
- ld a, [hSpriteScreenX] ; temp for sprite X position
- add $8 ; X=8 is left of screen (X=0 is invisible)
- add [hl] ; add X offset from table
- ld [de], a
- inc hl
- inc e
- ld a, [wd5cd]
- add [hl]
- cp $80
- jr c, .asm_4a1c
- ld b, a
- ld a, [$fffc]
- add b
-.asm_4a1c
- ld [de], a ; tile id
- inc hl
- inc e
- ld a, [hl]
- bit 1, a ; is the tile allowed to set the sprite priority bit?
- jr z, .skipPriority
- ld a, [hSpritePriority]
- or [hl]
-.skipPriority
- and $f0
- bit 4, a ; OBP0 or OBP1
- jr z, .spriteusesOBP0
- or %100 ; palettes 4-7 are OBP1
-.spriteusesOBP0
- ld [de], a
- inc hl
- inc e
- dec c
- jr nz, .loop
-
- ld a, e
- ld [hOAMBufferOffset], a
-.nextSprite
- ld a, [hSpriteOffset2]
- add $10
- cp $100 % $100
- jp nz, .spriteLoop
-
- ; Clear unused OAM.
-.asm_4a41
- ld a, [wd736]
- bit 6, a ; jumping down ledge or fishing animation?
- ld c, $a0
- jr z, .clear
-
-; Don't clear the last 4 entries because they are used for the shadow in the
-; jumping down ledge animation and the rod in the fishing animation.
- ld c, $90
-
-.clear
- ld a, [hOAMBufferOffset]
- cp c
- ret nc
- ld l, a
- ld h, wOAMBuffer / $100
- ld a, c
- ld de, $4 ; entry size
- ld b, $a0
-.clearLoop
- ld [hl], b
- add hl, de
- cp l
- jr nz, .clearLoop
- ret
-
-GetSpriteScreenXY:
- inc e
- inc e
- ld a, [de] ; c1x4
- ld [hSpriteScreenY], a
- inc e
- inc e
- ld a, [de] ; c1x6
- ld [hSpriteScreenX], a
- ld a, 4
- add e
- ld e, a
- ld a, [hSpriteScreenY]
- add 4
- and $f0
- ld [de], a ; c1xa (y)
- inc e
- ld a, [hSpriteScreenX]
- and $f0
- ld [de], a ; c1xb (x)
- ret
-
-Func_4a7b:
- push bc
- ld a, [wd5cd] ; temp copy of c1x2
- swap a ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
- and $f
-
- ; Sprites $a and $b have one face (and therefore 4 tiles instead of 12).
- ; As a result, sprite $b's tile offset is less than normal.
- cp $b
- jr nz, .notFourTileSprite
- ld a, $a * 12 + 4 ; $7c
- jr .done
-
-.notFourTileSprite
- ; a *= 12
- add a
- add a
- ld c, a
- add a
- add c
-.done
- pop bc
- ret
-
-INCLUDE "engine/oam_dma.asm"
-
-_IsTilePassable::
- ld hl,wTilesetCollisionPtr ; pointer to list of passable tiles
- ld a,[hli]
- ld h,[hl]
- ld l,a ; hl now points to passable tiles
-.loop
- ld a,[hli]
- cp a,$ff
- jr z,.tileNotPassable
- cp c
- jr nz,.loop
- xor a
- ret
-.tileNotPassable
- scf
- ret
-
-INCLUDE "data/collision.asm" ; probably
diff --git a/engine/overworld/pathfinding.asm b/engine/overworld/pathfinding.asm
new file mode 100644
index 00000000..a824d337
--- /dev/null
+++ b/engine/overworld/pathfinding.asm
@@ -0,0 +1,201 @@
+FindPathToPlayer:
+ xor a
+ ld hl, hFindPathNumSteps
+ ld [hli], a ; hFindPathNumSteps
+ ld [hli], a ; hFindPathFlags
+ ld [hli], a ; hFindPathYProgress
+ ld [hl], a ; hFindPathXProgress
+ ld hl, wNPCMovementDirections2
+ ld de, $0
+.loop
+ ldh a, [hFindPathYProgress]
+ ld b, a
+ ldh a, [hNPCPlayerYDistance] ; Y distance in steps
+ call CalcDifference
+ ld d, a
+ and a
+ jr nz, .asm_f76a
+ ldh a, [hFindPathFlags]
+ set 0, a ; current end of path matches the player's Y coordinate
+ ldh [hFindPathFlags], a
+.asm_f76a
+ ldh a, [hFindPathXProgress]
+ ld b, a
+ ldh a, [hNPCPlayerXDistance] ; X distance in steps
+ call CalcDifference
+ ld e, a
+ and a
+ jr nz, .asm_f77c
+ ldh a, [hFindPathFlags]
+ set 1, a ; current end of path matches the player's X coordinate
+ ldh [hFindPathFlags], a
+.asm_f77c
+ ldh a, [hFindPathFlags]
+ cp $3 ; has the end of the path reached the player's position?
+ jr z, .done
+; Compare whether the X distance between the player and the current of the path
+; is greater or if the Y distance is. Then, try to reduce whichever is greater.
+ ld a, e
+ cp d
+ jr c, .yDistanceGreater
+; x distance is greater
+ ldh a, [hNPCPlayerRelativePosFlags]
+ bit 1, a
+ jr nz, .playerIsLeftOfNPC
+ ld d, NPC_MOVEMENT_RIGHT
+ jr .next1
+.playerIsLeftOfNPC
+ ld d, NPC_MOVEMENT_LEFT
+.next1
+ ldh a, [hFindPathXProgress]
+ add 1
+ ldh [hFindPathXProgress], a
+ jr .storeDirection
+.yDistanceGreater
+ ldh a, [hNPCPlayerRelativePosFlags]
+ bit 0, a
+ jr nz, .playerIsAboveNPC
+ ld d, NPC_MOVEMENT_DOWN
+ jr .next2
+.playerIsAboveNPC
+ ld d, NPC_MOVEMENT_UP
+.next2
+ ldh a, [hFindPathYProgress]
+ add 1
+ ldh [hFindPathYProgress], a
+.storeDirection
+ ld a, d
+ ld [hli], a
+ ldh a, [hFindPathNumSteps]
+ inc a
+ ldh [hFindPathNumSteps], a
+ jp .loop
+.done
+ ld [hl], $ff
+ ret
+
+CalcPositionOfPlayerRelativeToNPC:
+ xor a
+ ldh [hNPCPlayerRelativePosFlags], a
+ ld a, [wSpritePlayerStateData1YPixels]
+ ld d, a
+ ld a, [wSpritePlayerStateData1XPixels]
+ ld e, a
+ ld hl, wSpriteStateData1
+ ldh a, [hNPCSpriteOffset]
+ add l
+ add SPRITESTATEDATA1_YPIXELS
+ ld l, a
+ jr nc, .noCarry
+ inc h
+.noCarry
+ ld a, d
+ ld b, a
+ ld a, [hli] ; NPC sprite screen Y position in pixels
+ call CalcDifference
+ jr nc, .NPCSouthOfOrAlignedWithPlayer
+.NPCNorthOfPlayer
+ push hl
+ ld hl, hNPCPlayerRelativePosFlags
+ bit 0, [hl]
+ set 0, [hl]
+ pop hl
+ jr .divideYDistance
+.NPCSouthOfOrAlignedWithPlayer
+ push hl
+ ld hl, hNPCPlayerRelativePosFlags
+ bit 0, [hl]
+ res 0, [hl]
+ pop hl
+.divideYDistance
+ push hl
+ ld hl, hDividend2
+ ld [hli], a
+ ld a, 16
+ ld [hli], a
+ call DivideBytes ; divide Y absolute distance by 16
+ ld a, [hl] ; quotient
+ ldh [hNPCPlayerYDistance], a
+ pop hl
+ inc hl
+ ld b, e
+ ld a, [hl] ; NPC sprite screen X position in pixels
+ call CalcDifference
+ jr nc, .NPCEastOfOrAlignedWithPlayer
+.NPCWestOfPlayer
+ push hl
+ ld hl, hNPCPlayerRelativePosFlags
+ bit 1, [hl]
+ set 1, [hl]
+ pop hl
+ jr .divideXDistance
+.NPCEastOfOrAlignedWithPlayer
+ push hl
+ ld hl, hNPCPlayerRelativePosFlags
+ bit 1, [hl]
+ res 1, [hl]
+ pop hl
+.divideXDistance
+ ldh [hDividend2], a
+ ld a, 16
+ ldh [hDivisor2], a
+ call DivideBytes ; divide X absolute distance by 16
+ ldh a, [hQuotient2]
+ ldh [hNPCPlayerXDistance], a
+ ldh a, [hNPCPlayerRelativePosPerspective]
+ and a
+ ret z
+ ldh a, [hNPCPlayerRelativePosFlags]
+ cpl
+ and $3
+ ldh [hNPCPlayerRelativePosFlags], a
+ ret
+
+ConvertNPCMovementDirectionsToJoypadMasks:
+ ldh a, [hNPCMovementDirections2Index]
+ ld [wNPCMovementDirections2Index], a
+ dec a
+ ld de, wSimulatedJoypadStatesEnd
+ ld hl, wNPCMovementDirections2
+ add l
+ ld l, a
+ jr nc, .loop
+ inc h
+.loop
+ ld a, [hld]
+ call ConvertNPCMovementDirectionToJoypadMask
+ ld [de], a
+ inc de
+ ldh a, [hNPCMovementDirections2Index]
+ dec a
+ ldh [hNPCMovementDirections2Index], a
+ jr nz, .loop
+ ret
+
+ConvertNPCMovementDirectionToJoypadMask:
+ push hl
+ ld b, a
+ ld hl, NPCMovementDirectionsToJoypadMasksTable
+.loop
+ ld a, [hli]
+ cp $ff
+ jr z, .done
+ cp b
+ jr z, .loadJoypadMask
+ inc hl
+ jr .loop
+.loadJoypadMask
+ ld a, [hl]
+.done
+ pop hl
+ ret
+
+NPCMovementDirectionsToJoypadMasksTable:
+ db NPC_MOVEMENT_UP, D_UP
+ db NPC_MOVEMENT_DOWN, D_DOWN
+ db NPC_MOVEMENT_LEFT, D_LEFT
+ db NPC_MOVEMENT_RIGHT, D_RIGHT
+ db $ff
+
+; unreferenced
+ ret
diff --git a/engine/overworld/player_animations.asm b/engine/overworld/player_animations.asm
index d4ecec53..5056c0b2 100755
--- a/engine/overworld/player_animations.asm
+++ b/engine/overworld/player_animations.asm
@@ -1,7 +1,7 @@
-EnterMapAnim:
+EnterMapAnim::
call InitFacingDirectionList
ld a, $ec
- ld [wSpriteStateData1 + 4], a ; player's sprite Y screen position
+ ld [wSpritePlayerStateData1YPixels], a
call Delay3
push hl
call GBFadeInFromWhite
@@ -94,7 +94,7 @@ PlayerSpinWhileMovingDown:
jp PlayerSpinWhileMovingUpOrDown
-_LeaveMapAnim:
+_LeaveMapAnim::
call Func_1510
call InitFacingDirectionList
call IsPlayerStandingOnWarpPadOrHole
@@ -232,19 +232,19 @@ DoFlyAnimation:
ld a, [wFlyAnimBirdSpriteImageIndex]
xor $1 ; make the bird flap its wings
ld [wFlyAnimBirdSpriteImageIndex], a
- ld [wSpriteStateData1 + 2], a
+ ld [wSpritePlayerStateData1ImageIndex], a
call Delay3
ld a, [wFlyAnimUsingCoordList]
cp $ff
jr z, .skipCopyingCoords ; if the bird is flapping its wings in place
- ld hl, wSpriteStateData1 + 4
+ ld hl, wSpritePlayerStateData1YPixels
ld a, [de]
inc de
- ld [hli], a
+ ld [hli], a ; y
inc hl
ld a, [de]
inc de
- ld [hl], a
+ ld [hl], a ; x
.skipCopyingCoords
ld a, [wFlyAnimCounter]
dec a
@@ -258,22 +258,22 @@ LoadBirdSpriteGraphics:
ld c, $c
ld hl, vNPCSprites
call CopyVideoData
- ld de, BirdSprite + $c0 ; moving animation sprite
+ ld de, BirdSprite tile 12 ; moving animation sprite
ld b, BANK(BirdSprite)
- ld c, $0c
+ ld c, 12
ld hl, vNPCSprites2
jp CopyVideoData
InitFacingDirectionList:
- ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction (image index is locked to standing images)
+ ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
ld [wSavedPlayerFacingDirection], a
- ld a, [wSpriteStateData1 + 4] ; player's sprite Y screen position
+ ld a, [wSpritePlayerStateData1YPixels]
ld [wSavedPlayerScreenY], a
ld hl, PlayerSpinningFacingOrder
ld de, wFacingDirectionList
ld bc, 4
call CopyData
- ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction (image index is locked to standing images)
+ ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
ld hl, wFacingDirectionList
; find the place in the list that matches the current facing direction
.loop
@@ -291,7 +291,7 @@ PlayerSpinningFacingOrder:
SpinPlayerSprite:
; copy the current value from the list into the sprite data and rotate the list
ld a, [hl]
- ld [wSpriteStateData1 + 2], a ; player's sprite facing direction (image index is locked to standing images)
+ ld [wSpritePlayerStateData1ImageIndex], a ; (image index is locked to standing images)
push hl
ld hl, wFacingDirectionList
ld de, wFacingDirectionList - 1
@@ -327,9 +327,9 @@ PlayerSpinWhileMovingUpOrDown:
call SpinPlayerSprite
ld a, [wPlayerSpinWhileMovingUpOrDownAnimDeltaY]
ld c, a
- ld a, [wSpriteStateData1 + 4] ; player's sprite Y screen position
+ ld a, [wSpritePlayerStateData1YPixels]
add c
- ld [wSpriteStateData1 + 4], a
+ ld [wSpritePlayerStateData1YPixels], a
ld c, a
ld a, [wPlayerSpinWhileMovingUpOrDownAnimMaxY]
cp c
@@ -341,9 +341,9 @@ PlayerSpinWhileMovingUpOrDown:
RestoreFacingDirectionAndYScreenPos:
ld a, [wSavedPlayerScreenY]
- ld [wSpriteStateData1 + 4], a
+ ld [wSpritePlayerStateData1YPixels], a
ld a, [wSavedPlayerFacingDirection]
- ld [wSpriteStateData1 + 2], a
+ ld [wSpritePlayerStateData1ImageIndex], a ; (image index is locked to standing images)
ret
; if SGB, 2 frames, else 3 frames
@@ -354,9 +354,9 @@ GetPlayerTeleportAnimFrameDelay:
inc a
ret
-IsPlayerStandingOnWarpPadOrHole:
+IsPlayerStandingOnWarpPadOrHole::
ld b, 0
- ld hl, .warpPadAndHoleData
+ ld hl, WarpPadAndHoleData
ld a, [wCurMapTileset]
ld c, a
.loop
@@ -365,7 +365,7 @@ IsPlayerStandingOnWarpPadOrHole:
jr z, .done
cp c
jr nz, .nextEntry
- aCoord 8, 9
+ lda_coord 8, 9
cp [hl]
jr z, .foundMatch
.nextEntry
@@ -380,13 +380,7 @@ IsPlayerStandingOnWarpPadOrHole:
ld [wStandingOnWarpPadOrHole], a
ret
-; format: db tileset id, tile id, value to be put in [wStandingOnWarpPadOrHole]
-.warpPadAndHoleData:
- db FACILITY, $20, 1 ; warp pad
- db FACILITY, $11, 2 ; hole
- db CAVERN, $22, 2 ; hole
- db INTERIOR, $55, 1 ; warp pad
- db $FF
+INCLUDE "data/tilesets/warp_pad_hole_tile_ids.asm"
FishingAnim:
ld c, 10
@@ -396,12 +390,12 @@ FishingAnim:
ld hl, vNPCSprites
ld de, RedSprite
ld b, BANK(RedSprite)
- ld c, $c
+ ld c, 12
call CopyVideoData
ld a, $4
ld hl, RedFishingTiles
call LoadAnimSpriteGfx
- ld a, [wSpriteStateData1 + 2]
+ ld a, [wSpritePlayerStateData1ImageIndex]
ld c, a
ld b, $0
ld hl, FishingRodOAM
@@ -424,7 +418,7 @@ FishingAnim:
; shake the player's sprite vertically
ld b, 10
.loop
- ld hl, wSpriteStateData1 + 4 ; player's sprite Y screen position
+ ld hl, wSpritePlayerStateData1YPixels
call .ShakePlayerSprite
ld hl, wOAMBuffer + $9c
call .ShakePlayerSprite
@@ -434,7 +428,7 @@ FishingAnim:
; If the player is facing up, hide the fishing rod so it doesn't overlap with
; the exclamation bubble that will be shown next.
- ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
cp SPRITE_FACING_UP
jr nz, .skipHidingFishingRod
ld a, $a0
@@ -448,7 +442,7 @@ FishingAnim:
predef EmotionBubble
; If the player is facing up, unhide the fishing rod.
- ld a, [wSpriteStateData1 + 2] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1ImageIndex] ; (image index is locked to standing images)
cp SPRITE_FACING_UP
jr nz, .skipUnhidingFishingRod
ld a, $44
@@ -471,46 +465,38 @@ FishingAnim:
ret
NoNibbleText:
- TX_FAR _NoNibbleText
- db "@"
+ text_far _NoNibbleText
+ text_end
NothingHereText:
- TX_FAR _NothingHereText
- db "@"
+ text_far _NothingHereText
+ text_end
ItsABiteText:
- TX_FAR _ItsABiteText
- db "@"
+ text_far _ItsABiteText
+ text_end
FishingRodOAM:
; specifies how the fishing rod should be drawn on the screen
-; first byte = screen y coordinate
-; second byte = screen x coordinate
-; third byte = tile number
-; fourth byte = sprite properties
- db $5B, $4C, $FD, $00 ; player facing down
- db $44, $4C, $FD, $00 ; player facing up
- db $50, $40, $FE, $00 ; player facing left
- db $50, $58, $FE, $20 ; player facing right ($20 means "horizontally flip the tile")
-
-RedFishingTiles:
- dw RedFishingTilesFront
- db 2, BANK(RedFishingTilesFront)
- dw vNPCSprites + $20
-
- dw RedFishingTilesBack
- db 2, BANK(RedFishingTilesBack)
- dw vNPCSprites + $60
+ dbsprite 9, 11, 4, 3, $fd, 0 ; down
+ dbsprite 9, 8, 4, 4, $fd, 0 ; up
+ dbsprite 8, 10, 0, 0, $fe, 0 ; left
+ dbsprite 11, 10, 0, 0, $fe, OAM_HFLIP ; right
- dw RedFishingTilesSide
- db 2, BANK(RedFishingTilesSide)
- dw vNPCSprites + $a0
+fishing_gfx: MACRO
+ dw \1
+ db \2
+ db BANK(\1)
+ dw vNPCSprites tile \3
+ENDM
- dw RedFishingRodTiles
- db 3, BANK(RedFishingRodTiles)
- dw vNPCSprites2 + $7d0
+RedFishingTiles:
+ fishing_gfx RedFishingTilesFront, 2, $02
+ fishing_gfx RedFishingTilesBack, 2, $06
+ fishing_gfx RedFishingTilesSide, 2, $0a
+ fishing_gfx RedFishingRodTiles, 3, $fd
-_HandleMidJump:
+_HandleMidJump::
ld a, [wPlayerJumpingYScreenCoordsIndex]
ld c, a
inc a
@@ -521,7 +507,7 @@ _HandleMidJump:
ld hl, PlayerJumpingYScreenCoords
add hl, bc
ld a, [hl]
- ld [wSpriteStateData1 + 4], a ; player's sprite y coordinate
+ ld [wSpritePlayerStateData1YPixels], a
ret
.finishedJump
ld a, [wWalkCounter]
@@ -530,9 +516,9 @@ _HandleMidJump:
call UpdateSprites
call Delay3
xor a
- ld [hJoyHeld], a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
+ ldh [hJoyHeld], a
+ ldh [hJoyPressed], a
+ ldh [hJoyReleased], a
ld [wPlayerJumpingYScreenCoordsIndex], a
ld hl, wd736
res 6, [hl] ; not jumping down a ledge any more
diff --git a/engine/overworld/player_state.asm b/engine/overworld/player_state.asm
index 8cbacc61..c966c128 100644
--- a/engine/overworld/player_state.asm
+++ b/engine/overworld/player_state.asm
@@ -1,5 +1,5 @@
; only used for setting bit 2 of wd736 upon entering a new map
-IsPlayerStandingOnWarp:
+IsPlayerStandingOnWarp::
ld a, [wNumberOfWarps]
and a
ret z
@@ -17,7 +17,7 @@ IsPlayerStandingOnWarp:
ld a, [hli] ; target warp
ld [wDestinationWarpID], a
ld a, [hl] ; target map
- ld [hWarpDestinationMap], a
+ ldh [hWarpDestinationMap], a
ld hl, wd736
set 2, [hl] ; standing on warp flag
ret
@@ -31,7 +31,7 @@ IsPlayerStandingOnWarp:
jr nz, .loop
ret
-CheckForceBikeOrSurf:
+CheckForceBikeOrSurf::
ld hl, wd732
bit 5, [hl]
ret nz
@@ -84,13 +84,13 @@ CheckForceBikeOrSurf:
call ForceBikeOrSurf
ret
-INCLUDE "data/force_bike_surf.asm"
+INCLUDE "data/maps/force_bike_surf.asm"
-IsPlayerFacingEdgeOfMap:
+IsPlayerFacingEdgeOfMap::
push hl
push de
push bc
- ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
srl a
ld c, a
ld b, $0
@@ -152,19 +152,19 @@ IsPlayerFacingEdgeOfMap:
scf
ret
-IsWarpTileInFrontOfPlayer:
+IsWarpTileInFrontOfPlayer::
push hl
push de
push bc
call _GetTileAndCoordsInFrontOfPlayer
ld a, [wCurMap]
cp SS_ANNE_BOW
- jr z, .ssAnne5
- ld a, [wSpriteStateData1 + 9] ; player sprite's facing direction
+ jr z, IsSSAnneBowWarpTileInFrontOfPlayer
+ ld a, [wSpritePlayerStateData1FacingDirection]
srl a
ld c, a
ld b, 0
- ld hl, .warpTileListPointers
+ ld hl, WarpTileListPointers
add hl, bc
ld a, [hli]
ld h, [hl]
@@ -178,39 +178,23 @@ IsWarpTileInFrontOfPlayer:
pop hl
ret
-.warpTileListPointers:
- dw .facingDownWarpTiles
- dw .facingUpWarpTiles
- dw .facingLeftWarpTiles
- dw .facingRightWarpTiles
+INCLUDE "data/tilesets/warp_carpet_tile_ids.asm"
-.facingDownWarpTiles
- db $01,$12,$17,$3D,$04,$18,$33,$FF
-
-.facingUpWarpTiles
- db $01,$5C,$FF
-
-.facingLeftWarpTiles
- db $1A,$4B,$FF
-
-.facingRightWarpTiles
- db $0F,$4E,$FF
-
-.ssAnne5
+IsSSAnneBowWarpTileInFrontOfPlayer:
ld a, [wTileInFrontOfPlayer]
cp $15
jr nz, .notSSAnne5Warp
scf
- jr .done
+ jr IsWarpTileInFrontOfPlayer.done
.notSSAnne5Warp
and a
- jr .done
+ jr IsWarpTileInFrontOfPlayer.done
-IsPlayerStandingOnDoorTileOrWarpTile:
+IsPlayerStandingOnDoorTileOrWarpTile::
push hl
push de
push bc
- callba IsPlayerStandingOnDoorTile
+ farcall IsPlayerStandingOnDoorTile
jr c, .done
ld a, [wCurMapTileset]
add a
@@ -222,7 +206,7 @@ IsPlayerStandingOnDoorTileOrWarpTile:
ld h, [hl]
ld l, a
ld de, $1
- aCoord 8, 9
+ lda_coord 8, 9
call IsInArray
jr nc, .done
ld hl, wd736
@@ -233,35 +217,35 @@ IsPlayerStandingOnDoorTileOrWarpTile:
pop hl
ret
-INCLUDE "data/warp_tile_ids.asm"
+INCLUDE "data/tilesets/warp_tile_ids.asm"
-PrintSafariZoneSteps:
+PrintSafariZoneSteps::
ld a, [wCurMap]
cp SAFARI_ZONE_EAST
ret c
cp CERULEAN_CAVE_2F
ret nc
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 3, 7
call TextBoxBorder
- coord hl, 1, 1
+ hlcoord 1, 1
ld de, wSafariSteps
lb bc, 2, 3
call PrintNumber
- coord hl, 4, 1
+ hlcoord 4, 1
ld de, SafariSteps
call PlaceString
- coord hl, 1, 3
+ hlcoord 1, 3
ld de, SafariBallText
call PlaceString
ld a, [wNumSafariBalls]
cp 10
jr nc, .numSafariBallsTwoDigits
- coord hl, 5, 3
+ hlcoord 5, 3
ld a, " "
ld [hl], a
.numSafariBallsTwoDigits
- coord hl, 6, 3
+ hlcoord 6, 3
ld de, wNumSafariBalls
lb bc, 1, 2
jp PrintNumber
@@ -280,32 +264,32 @@ _GetTileAndCoordsInFrontOfPlayer:
ld d, a
ld a, [wXCoord]
ld e, a
- ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
and a ; cp SPRITE_FACING_DOWN
jr nz, .notFacingDown
; facing down
- aCoord 8, 11
+ lda_coord 8, 11
inc d
jr .storeTile
.notFacingDown
cp SPRITE_FACING_UP
jr nz, .notFacingUp
; facing up
- aCoord 8, 7
+ lda_coord 8, 7
dec d
jr .storeTile
.notFacingUp
cp SPRITE_FACING_LEFT
jr nz, .notFacingLeft
; facing left
- aCoord 6, 9
+ lda_coord 6, 9
dec e
jr .storeTile
.notFacingLeft
cp SPRITE_FACING_RIGHT
jr nz, .storeTile
; facing right
- aCoord 10, 9
+ lda_coord 10, 9
inc e
.storeTile
ld c, a
@@ -314,45 +298,45 @@ _GetTileAndCoordsInFrontOfPlayer:
GetTileTwoStepsInFrontOfPlayer:
xor a
- ld [$ffdb], a
+ ldh [hPlayerFacing], a
ld hl, wYCoord
ld a, [hli]
ld d, a
ld e, [hl]
- ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
and a ; cp SPRITE_FACING_DOWN
jr nz, .notFacingDown
; facing down
- ld hl, $ffdb
+ ld hl, hPlayerFacing
set 0, [hl]
- aCoord 8, 13
+ lda_coord 8, 13
inc d
jr .storeTile
.notFacingDown
cp SPRITE_FACING_UP
jr nz, .notFacingUp
; facing up
- ld hl, $ffdb
+ ld hl, hPlayerFacing
set 1, [hl]
- aCoord 8, 5
+ lda_coord 8, 5
dec d
jr .storeTile
.notFacingUp
cp SPRITE_FACING_LEFT
jr nz, .notFacingLeft
; facing left
- ld hl, $ffdb
+ ld hl, hPlayerFacing
set 2, [hl]
- aCoord 4, 9
+ lda_coord 4, 9
dec e
jr .storeTile
.notFacingLeft
cp SPRITE_FACING_RIGHT
jr nz, .storeTile
; facing right
- ld hl, $ffdb
+ ld hl, hPlayerFacing
set 3, [hl]
- aCoord 12, 9
+ lda_coord 12, 9
inc e
.storeTile
ld c, a
@@ -384,36 +368,36 @@ CheckForBoulderCollisionWithSprites:
swap a
ld d, 0
ld e, a
- ld hl, wSpriteStateData2 + $14
+ ld hl, wSprite01StateData2MapY
add hl, de
ld a, [hli] ; map Y position
- ld [$ffdc], a
+ ldh [hPlayerYCoord], a
ld a, [hl] ; map X position
- ld [$ffdd], a
+ ldh [hPlayerXCoord], a
ld a, [wNumSprites]
ld c, a
ld de, $f
- ld hl, wSpriteStateData2 + $14
- ld a, [$ffdb]
+ ld hl, wSprite01StateData2MapY
+ ldh a, [hPlayerFacing]
and $3 ; facing up or down?
jr z, .pushingHorizontallyLoop
.pushingVerticallyLoop
inc hl
- ld a, [$ffdd]
+ ldh a, [hPlayerXCoord]
cp [hl]
jr nz, .nextSprite1 ; if X coordinates don't match
dec hl
ld a, [hli]
ld b, a
- ld a, [$ffdb]
+ ldh a, [hPlayerFacing]
rrca
jr c, .pushingDown
; pushing up
- ld a, [$ffdc]
+ ldh a, [hPlayerYCoord]
dec a
jr .compareYCoords
.pushingDown
- ld a, [$ffdc]
+ ldh a, [hPlayerYCoord]
inc a
.compareYCoords
cp b
@@ -426,19 +410,19 @@ CheckForBoulderCollisionWithSprites:
.pushingHorizontallyLoop
ld a, [hli]
ld b, a
- ld a, [$ffdc]
+ ldh a, [hPlayerYCoord]
cp b
jr nz, .nextSprite2
ld b, [hl]
- ld a, [$ffdb]
+ ldh a, [hPlayerFacing]
bit 2, a
jr nz, .pushingLeft
; pushing right
- ld a, [$ffdd]
+ ldh a, [hPlayerXCoord]
inc a
jr .compareXCoords
.pushingLeft
- ld a, [$ffdd]
+ ldh a, [hPlayerXCoord]
dec a
.compareXCoords
cp b
diff --git a/engine/overworld/pokecenter.asm b/engine/overworld/pokecenter.asm
deleted file mode 100755
index cf0159f9..00000000
--- a/engine/overworld/pokecenter.asm
+++ /dev/null
@@ -1,149 +0,0 @@
-DisplayPokemonCenterDialogue_:
- ld a, [wCurMap]
- cp PEWTER_POKECENTER
- jr nz, .regularCenter
- call CheckPikachuFollowingPlayer
- jr z, .regularCenter
- ld hl, LooksContentText ; if pikachu is sleeping, don't heal
- call PrintText
- ret
-.regularCenter
- call SaveScreenTilesToBuffer1 ; save screen
- ld hl, PokemonCenterWelcomeText
- call PrintText
- ld hl, wd72e
- bit 2, [hl]
- set 1, [hl]
- set 2, [hl]
- jr nz, .skipShallWeHealYourPokemon
- ld hl, ShallWeHealYourPokemonText
- call PrintText
-.skipShallWeHealYourPokemon
- call YesNoChoicePokeCenter ; yes/no menu
- call UpdateSprites
- ld a, [wCurrentMenuItem]
- and a
- jp nz, .declinedHealing ; if the player chose No
- call SetLastBlackoutMap
- callab IsStarterPikachuInOurParty
- jr nc, .notHealingPlayerPikachu
- call CheckPikachuFollowingPlayer
- jr nz, .notHealingPlayerPikachu
- call LoadCurrentMapView
- call Delay3
- call UpdateSprites
- callab PikachuWalksToNurseJoy ; todo
-.notHealingPlayerPikachu
- ld hl, NeedYourPokemonText
- call PrintText
- ld c, 64
- call DelayFrames
- call CheckPikachuFollowingPlayer
- jr nz, .playerPikachuNotOnScreen
- call DisablePikachuOverworldSpriteDrawing
- callab IsStarterPikachuInOurParty
- call c, Func_6eaa
-.playerPikachuNotOnScreen
- lb bc, 1, 8
- call Func_6ebb
- ld c, 30
- call DelayFrames
- callba AnimateHealingMachine ; do the healing machine animation
- predef HealParty
- xor a
- ld [wAudioFadeOutControl], a
- ld a, [wAudioSavedROMBank]
- ld [wAudioROMBank], a
- ld a, [wMapMusicSoundID]
- ld [wLastMusicSoundID], a
- ld [wNewSoundID], a
- call PlaySound
- call CheckPikachuFollowingPlayer
- jr nz, .doNotReturnPikachu
- callab IsStarterPikachuInOurParty
- call c, Func_6eaa
- ld a, $5
- ld [wPikachuSpawnState], a
- call EnablePikachuOverworldSpriteDrawing
-.doNotReturnPikachu
- lb bc, 1, 0
- call Func_6ebb
- ld hl, PokemonFightingFitText
- call PrintText
- callab IsStarterPikachuInOurParty
- jr nc, .notInParty
- lb bc, 15, 0
- call Func_6ebb
-.notInParty
- call LoadCurrentMapView
- call Delay3
- call UpdateSprites
- callab ReloadWalkingTilePatterns
- ld a, $1
- ld [H_SPRITEINDEX], a
- ld a, $1
- ld [hSpriteImageIndex], a
- call SpriteFunc_34a1
- ld c, 40
- call DelayFrames
- call UpdateSprites
- call LoadFontTilePatterns
- jr .done
-.declinedHealing
- call LoadScreenTilesFromBuffer1 ; restore screen
-.done
- ld hl, PokemonCenterFarewellText
- call PrintText
- call UpdateSprites
- ret
-
-Func_6eaa:
- ld a, $1
- ld [H_SPRITEINDEX], a
- ld a, $4
- ld [hSpriteImageIndex], a
- call SpriteFunc_34a1
- ld c, 64
- call DelayFrames
- ret
-
-Func_6ebb:
- ld a, b
- ld [H_SPRITEINDEX], a
- ld a, c
- ld [hSpriteImageIndex], a
- push bc
- call SetSpriteFacingDirectionAndDelay
- pop bc
- ld a, b
- ld [H_SPRITEINDEX], a
- ld a, c
- ld [hSpriteImageIndex], a
- call SpriteFunc_34a1
- ret
-
-PokemonCenterWelcomeText:
- TX_FAR _PokemonCenterWelcomeText
- db "@"
-
-ShallWeHealYourPokemonText:
- TX_DELAY
- TX_FAR _ShallWeHealYourPokemonText
- db "@"
-
-NeedYourPokemonText:
- TX_FAR _NeedYourPokemonText
- db "@"
-
-PokemonFightingFitText:
- TX_FAR _PokemonFightingFitText
- db "@"
-
-PokemonCenterFarewellText:
- TX_DELAY
- TX_FAR _PokemonCenterFarewellText
- db "@"
-
-LooksContentText:
- TX_FAR _LooksContentText
- db "@"
diff --git a/engine/overworld/push_boulder.asm b/engine/overworld/push_boulder.asm
index 8a385345..09911ca3 100644
--- a/engine/overworld/push_boulder.asm
+++ b/engine/overworld/push_boulder.asm
@@ -1,4 +1,4 @@
-TryPushingBoulder:
+TryPushingBoulder::
ld a, [wd728]
bit 0, a ; using Strength?
ret z
@@ -8,15 +8,15 @@ Func_f0a7:
bit 1, a ; has boulder dust animation from previous push played yet?
ret nz
xor a
- ld [hSpriteIndexOrTextID], a
+ ldh [hSpriteIndexOrTextID], a
call IsSpriteInFrontOfPlayer
- ld a, [hSpriteIndexOrTextID]
+ ldh a, [hSpriteIndexOrTextID]
ld [wBoulderSpriteIndex], a
and a
jp z, ResetBoulderPushFlags
- ld hl, wSpriteStateData1 + 1
+ ld hl, wSpritePlayerStateData1MovementStatus
ld d, $0
- ld a, [hSpriteIndexOrTextID]
+ ldh a, [hSpriteIndexOrTextID]
swap a
ld e, a
add hl, de
@@ -29,16 +29,16 @@ Func_f0a7:
bit 6, [hl]
set 6, [hl] ; indicate that the player has tried pushing
ret z ; the player must try pushing twice before the boulder will move
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
and D_RIGHT | D_LEFT | D_UP | D_DOWN
ret z
predef CheckForCollisionWhenPushingBoulder
ld a, [wTileInFrontOfBoulderAndBoulderCollisionResult]
and a ; was there a collision?
jp nz, ResetBoulderPushFlags
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
ld b, a
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
cp SPRITE_FACING_UP
jr z, .pushBoulderUp
cp SPRITE_FACING_LEFT
@@ -73,28 +73,32 @@ Func_f0a7:
ret
PushBoulderUpMovementData:
- db NPC_MOVEMENT_UP,$FF
+ db NPC_MOVEMENT_UP
+ db -1 ; end
PushBoulderDownMovementData:
- db NPC_MOVEMENT_DOWN,$FF
+ db NPC_MOVEMENT_DOWN
+ db -1 ; end
PushBoulderLeftMovementData:
- db NPC_MOVEMENT_LEFT,$FF
+ db NPC_MOVEMENT_LEFT
+ db -1 ; end
PushBoulderRightMovementData:
- db NPC_MOVEMENT_RIGHT,$FF
+ db NPC_MOVEMENT_RIGHT
+ db -1 ; end
-DoBoulderDustAnimation:
+DoBoulderDustAnimation::
ld a, [wd730]
bit 0, a
ret nz
- callab AnimateBoulderDust
+ callfar AnimateBoulderDust
call DiscardButtonPresses
ld [wJoyIgnore], a
call ResetBoulderPushFlags
set 7, [hl]
ld a, [wBoulderSpriteIndex]
- ld [H_SPRITEINDEX], a
+ ldh [hSpriteIndex], a
call GetSpriteMovementByte2Pointer
ld [hl], $10
ld a, SFX_CUT
diff --git a/engine/overworld/saffron_guards.asm b/engine/overworld/saffron_guards.asm
deleted file mode 100755
index 3b26b6f8..00000000
--- a/engine/overworld/saffron_guards.asm
+++ /dev/null
@@ -1,16 +0,0 @@
-RemoveGuardDrink:
- ld hl, GuardDrinksList
-.drinkLoop
- ld a, [hli]
- ld [$ffdb], a
- and a
- ret z
- push hl
- ld b, a
- call IsItemInBag
- pop hl
- jr z, .drinkLoop
- jpba RemoveItemByID
-
-GuardDrinksList:
- db FRESH_WATER, SODA_POP, LEMONADE, $00
diff --git a/engine/overworld/set_blackout_map.asm b/engine/overworld/set_blackout_map.asm
deleted file mode 100644
index bac2f0ca..00000000
--- a/engine/overworld/set_blackout_map.asm
+++ /dev/null
@@ -1,29 +0,0 @@
-SetLastBlackoutMap:
-; Set the map to return to when
-; blacking out or using Teleport or Dig.
-; Safari rest houses don't count.
-
- push hl
- ld hl, SafariZoneRestHouses
- ld a, [wCurMap]
- ld b, a
-.loop
- ld a, [hli]
- cp -1
- jr z, .notresthouse
- cp b
- jr nz, .loop
- jr .done
-
-.notresthouse
- ld a, [wLastMap]
- ld [wLastBlackoutMap], a
-.done
- pop hl
- ret
-
-SafariZoneRestHouses:
- db SAFARI_ZONE_WEST_REST_HOUSE
- db SAFARI_ZONE_EAST_REST_HOUSE
- db SAFARI_ZONE_NORTH_REST_HOUSE
- db -1
diff --git a/engine/overworld/special_warps.asm b/engine/overworld/special_warps.asm
new file mode 100644
index 00000000..61356a03
--- /dev/null
+++ b/engine/overworld/special_warps.asm
@@ -0,0 +1,149 @@
+SpecialWarpIn::
+ call LoadSpecialWarpData
+ predef LoadTilesetHeader
+ ld hl, wd732
+ bit 2, [hl] ; dungeon warp or fly warp?
+ res 2, [hl]
+ jr z, .next
+; if dungeon warp or fly warp
+ ld a, [wDestinationMap]
+ jr .next2
+.next
+ bit 1, [hl]
+ jr z, .next3
+ call DebugStart
+.next3
+ ld a, 0
+.next2
+ ld b, a
+ ld a, [wd72d]
+ and a
+ jr nz, .next4
+ ld a, b
+.next4
+ ld hl, wd732
+ bit 4, [hl] ; dungeon warp?
+ ret nz
+; if not dungeon warp
+ ld [wLastMap], a
+ ret
+
+; gets the map ID, tile block map view pointer, tileset, and coordinates
+LoadSpecialWarpData:
+ ld a, [wd72d]
+ cp TRADE_CENTER
+ jr nz, .notTradeCenter
+ ld hl, TradeCenterSpec1
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right
+ jr z, .copyWarpData
+ ld hl, TradeCenterSpec2
+ jr .copyWarpData
+.notTradeCenter
+ cp COLOSSEUM
+ jr nz, .notColosseum
+ ld hl, ColosseumSpec1
+ ldh a, [hSerialConnectionStatus]
+ cp USING_INTERNAL_CLOCK
+ jr z, .copyWarpData
+ ld hl, ColosseumSpec2
+ jr .copyWarpData
+.notColosseum
+ ld a, [wd732]
+ bit 1, a
+ jr nz, .notFirstMap
+ bit 2, a
+ jr nz, .notFirstMap
+ ld hl, FirstMapSpec
+.copyWarpData
+ ld de, wCurMap
+ ld c, $7
+.copyWarpDataLoop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyWarpDataLoop
+ ld a, [hli]
+ ld [wCurMapTileset], a
+ xor a
+ jr .done
+.notFirstMap
+ ld a, [wLastMap] ; this value is overwritten before it's ever read
+ ld hl, wd732
+ bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
+ jr nz, .usedDunegonWarp
+ bit 6, [hl] ; return to last pokemon center (or player's house)?
+ res 6, [hl]
+ jr z, .otherDestination
+; return to last pokemon center or player's house
+ ld a, [wLastBlackoutMap]
+ jr .usedFlyWarp
+.usedDunegonWarp
+ ld hl, wd72d
+ res 4, [hl]
+ ld a, [wDungeonWarpDestinationMap]
+ ld b, a
+ ld [wCurMap], a
+ ld a, [wWhichDungeonWarp]
+ ld c, a
+ ld hl, DungeonWarpList
+ ld de, 0
+ ld a, 6
+ ld [wDungeonWarpDataEntrySize], a
+.dungeonWarpListLoop
+ ld a, [hli]
+ cp b
+ jr z, .matchedDungeonWarpDestinationMap
+ inc hl
+ jr .nextDungeonWarp
+.matchedDungeonWarpDestinationMap
+ ld a, [hli]
+ cp c
+ jr z, .matchedDungeonWarpID
+.nextDungeonWarp
+ ld a, [wDungeonWarpDataEntrySize]
+ add e
+ ld e, a
+ jr .dungeonWarpListLoop
+.matchedDungeonWarpID
+ ld hl, DungeonWarpData
+ add hl, de
+ jr .copyWarpData2
+.otherDestination
+ ld a, [wDestinationMap]
+.usedFlyWarp
+ ld b, a
+ ld [wCurMap], a
+ ld hl, FlyWarpDataPtr
+.flyWarpDataPtrLoop
+ ld a, [hli]
+ inc hl
+ cp b
+ jr z, .foundFlyWarpMatch
+ inc hl
+ inc hl
+ jr .flyWarpDataPtrLoop
+.foundFlyWarpMatch
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.copyWarpData2
+ ld de, wCurrentTileBlockMapViewPointer
+ ld c, $6
+.copyWarpDataLoop2
+ ld a, [hli]
+ ld [de], a
+ inc de
+ dec c
+ jr nz, .copyWarpDataLoop2
+ xor a ; OVERWORLD
+ ld [wCurMapTileset], a
+.done
+ ld [wYOffsetSinceLastSpecialWarp], a
+ ld [wXOffsetSinceLastSpecialWarp], a
+ ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps
+ ld [wDestinationWarpID], a
+ ret
+
+INCLUDE "data/maps/special_warps.asm"
diff --git a/engine/overworld/spinners.asm b/engine/overworld/spinners.asm
new file mode 100644
index 00000000..0ac6380d
--- /dev/null
+++ b/engine/overworld/spinners.asm
@@ -0,0 +1,65 @@
+LoadSpinnerArrowTiles::
+ ld a, [wSpritePlayerStateData1ImageIndex]
+ srl a
+ srl a
+ ld hl, SpinnerPlayerFacingDirections
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [hl]
+ ld [wSpritePlayerStateData1ImageIndex], a
+ ld a, [wCurMapTileset]
+ cp FACILITY
+ ld hl, FacilitySpinnerArrows
+ jr z, .asm_44ff6
+ ld hl, GymSpinnerArrows
+.asm_44ff6
+ ld a, [wSimulatedJoypadStatesIndex]
+ bit 0, a
+ jr nz, .asm_45001
+ ld de, $18
+ add hl, de
+.asm_45001
+ ld a, $4
+ ld bc, $0
+.asm_45006
+ push af
+ push hl
+ push bc
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call CopyVideoData
+ pop bc
+ ld a, $6
+ add c
+ ld c, a
+ pop hl
+ pop af
+ dec a
+ jr nz, .asm_45006
+ ret
+
+INCLUDE "data/tilesets/spinner_tiles.asm"
+
+SpinnerPlayerFacingDirections:
+; This isn't the order of the facing directions. Rather, it's a list of
+; the facing directions that come next. For example, when the player is
+; facing down (00), the next facing direction is left (08).
+ db $08 ; down -> left
+ db $0C ; up -> right
+ db $04 ; left -> up
+ db $00 ; right -> down
+
+; these tiles are the animation for the tiles that push the player in dungeons like Rocket HQ
+SpinnerArrowAnimTiles:
+ INCBIN "gfx/overworld/spinners.2bpp"
diff --git a/engine/overworld/sprite_collisions.asm b/engine/overworld/sprite_collisions.asm
new file mode 100644
index 00000000..db81977b
--- /dev/null
+++ b/engine/overworld/sprite_collisions.asm
@@ -0,0 +1,392 @@
+_UpdateSprites::
+ ld h, wSpriteStateData1 / $100
+ inc h
+ ld a, SPRITESTATEDATA2_IMAGEBASEOFFSET
+.spriteLoop
+ ld l, a
+ sub SPRITESTATEDATA2_IMAGEBASEOFFSET
+ ld c, a
+ ldh [hCurrentSpriteOffset], a
+ ld a, [hl]
+ and a
+ jr z, .skipSprite ; tests SPRITESTATEDATA2_IMAGEBASEOFFSET
+ push hl
+ push de
+ push bc
+ call .updateCurrentSprite
+ pop bc
+ pop de
+ pop hl
+.skipSprite
+ ld a, l
+ add $10 ; move to next sprite
+ cp SPRITESTATEDATA2_IMAGEBASEOFFSET ; test for overflow (back at beginning)
+ jr nz, .spriteLoop
+ ret
+.updateCurrentSprite
+ ldh a, [hCurrentSpriteOffset]
+ and a
+ jp z, UpdatePlayerSprite
+ cp $f0 ; pikachu
+ jp z, SpawnPikachu
+ ld a, [hl]
+
+UpdateNonPlayerSprite:
+ dec a
+ swap a
+ ldh [hTilePlayerStandingOn], a ; $10 * sprite#
+ ld a, [wNPCMovementScriptSpriteOffset] ; some sprite offset?
+ ld b, a
+ ldh a, [hCurrentSpriteOffset]
+ cp b
+ jr nz, .unequal
+ jp DoScriptedNPCMovement
+.unequal
+ jp UpdateNPCSprite
+
+; This detects if the current sprite (whose offset is at hCurrentSpriteOffset)
+; is going to collide with another sprite by looping over the other sprites.
+; The current sprite's offset will be labelled with i (e.g. i#SPRITESTATEDATA1_PICTUREID).
+; The loop sprite's offset will labelled with j (e.g. j#SPRITESTATEDATA1_PICTUREID).
+;
+; Note that the Y coordinate of the sprite (in [k#SPRITESTATEDATA1_YPIXELS])
+; is one of the following 9 values when the sprite is aligned with the grid:
+; $fc, $0c, $1c, $2c, ..., $7c.
+; The reason that 4 is added below to the coordinate is to make it align with a
+; multiple of $10 to make comparisons easier.
+DetectCollisionBetweenSprites:
+ ; nop
+
+ ld h, HIGH(wSpriteStateData1)
+ ldh a, [hCurrentSpriteOffset]
+ ld l, a
+
+ ld a, [hl] ; a = [i#SPRITESTATEDATA1_PICTUREID] (0 if slot is unused)
+ and a ; is this sprite slot slot used?
+ ret z ; return if not used
+
+ ld a, l
+ add 3
+ ld l, a
+
+ ld a, [hli] ; a = [i#SPRITESTATEDATA1_YSTEPVECTOR] (-1, 0, or 1)
+ call SetSpriteCollisionValues
+
+ ld a, [hli] ; a = [i#SPRITESTATEDATA1_YPIXELS]
+ add 4 ; align with multiple of $10
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving south or
+; subtract 7 from a if moving north.
+ add b
+ and $f0
+ or c
+
+ ldh [hFF90], a ; store Y coordinate adjusted for direction of movement
+
+ ld a, [hli] ; a = [i#SPRITESTATEDATA1_XSTEPVECTOR] (-1, 0, or 1)
+ call SetSpriteCollisionValues
+ ld a, [hl] ; a = [i#SPRITESTATEDATA1_XPIXELS]
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving east or
+; subtract 7 from a if moving west.
+ add b
+ and $f0
+ or c
+
+ ldh [hFF91], a ; store X coordinate adjusted for direction of movement
+
+ ld a, l
+ add 7
+ ld l, a
+
+ xor a
+ ld [hld], a ; zero [i#SPRITESTATEDATA1_0D] XXX what's this for?
+ ld [hld], a ; zero [i#SPRITESTATEDATA1_COLLISIONDATA]
+
+ ldh a, [hFF91]
+ ld [hld], a ; [i#SPRITESTATEDATA1_XADJUSTED]
+ ldh a, [hFF90]
+ ld [hl], a ; [i#SPRITESTATEDATA1_YADJUSTED]
+
+ xor a ; zero the loop counter
+
+.loop
+ ldh [hFF8F], a ; store loop counter
+ swap a
+ ld e, a
+ ldh a, [hCurrentSpriteOffset]
+ cp e ; does the loop sprite match the current sprite?
+ jp z, .next ; go to the next sprite if they match
+
+ ld d, h
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_PICTUREID] (0 if slot is unused)
+ and a ; is this sprite slot slot used?
+ jp z, .next ; go the next sprite if not used
+
+ inc e
+ inc e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_IMAGEINDEX] ($ff means the sprite is offscreen)
+ inc a
+ jp z, .next ; go the next sprite if offscreen
+
+ ldh a, [hCurrentSpriteOffset]
+ add 10
+ ld l, a
+
+ inc e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_YSTEPVECTOR]
+ call SetSpriteCollisionValues
+
+ inc e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_YPIXELS]
+ add 4 ; align with multiple of $10
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving south or
+; subtract 7 from a if moving north.
+ add b
+ and $f0
+ or c
+
+ sub [hl] ; subtract [i#SPRITESTATEDATA1_YADJUSTED] from [j#SPRITESTATEDATA1_YADJUSTED]
+
+; calculate the absolute value of the difference to get the distance
+ jr nc, .noCarry1
+ cpl
+ inc a
+.noCarry1
+ ldh [hFF90], a ; store the distance between the two sprites' adjusted Y values
+
+; Use the carry flag set by the above subtraction to determine which sprite's
+; Y coordinate is larger. This information is used later to set
+; [i#SPRITESTATEDATA1_COLLISIONDATA].
+; The following 5 lines set the lowest 2 bits of c, which are later shifted left by 2.
+; If sprite i's Y is larger, set lowest 2 bits of c to 10.
+; If sprite j's Y is larger or both are equal, set lowest 2 bits of c to 01.
+ push af
+ rl c
+ pop af
+ ccf
+ rl c
+
+; If sprite i's delta Y is 0, then b = 7, else b = 9.
+ ld b, 7
+ ld a, [hl] ; a = [i#SPRITESTATEDATA1_YADJUSTED]
+ and $f
+ jr z, .next1
+ ld b, 9
+
+.next1
+ ldh a, [hFF90] ; a = distance between adjusted Y coordinates
+ sub b
+ ldh [hFF92], a ; store distance adjusted using sprite i's direction
+ ld a, b
+ ldh [hFF90], a ; store 7 or 9 depending on sprite i's delta Y
+ jr c, .checkXDistance
+
+; If sprite j's delta Y is 0, then b = 7, else b = 9.
+ ld b, 7
+ dec e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_YSTEPVECTOR]
+ inc e
+ and a
+ jr z, .next2
+ ld b, 9
+
+.next2
+ ldh a, [hFF92] ; a = distance adjusted using sprite i's direction
+ sub b ; adjust distance using sprite j's direction
+ jr z, .checkXDistance
+ jr nc, .next ; go to next sprite if distance is still positive after both adjustments
+
+.checkXDistance
+ inc e
+ inc l
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_XSTEPVECTOR]
+
+ push bc
+
+ call SetSpriteCollisionValues
+ inc e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_XPIXELS]
+
+; The effect of the following 3 lines is to
+; add 7 to a if moving east or
+; subtract 7 from a if moving west.
+ add b
+ and $f0
+ or c
+
+ pop bc
+
+ sub [hl] ; subtract [i#SPRITESTATEDATA1_XADJUSTED] from [j#SPRITESTATEDATA1_XADJUSTED]
+
+; calculate the absolute value of the difference to get the distance
+ jr nc, .noCarry2
+ cpl
+ inc a
+.noCarry2
+ ldh [hFF91], a ; store the distance between the two sprites' adjusted X values
+
+; Use the carry flag set by the above subtraction to determine which sprite's
+; X coordinate is larger. This information is used later to set
+; [i#SPRITESTATEDATA1_COLLISIONDATA].
+; The following 5 lines set the lowest 2 bits of c.
+; If sprite i's X is larger, set lowest 2 bits of c to 10.
+; If sprite j's X is larger or both are equal, set lowest 2 bits of c to 01.
+ push af
+ rl c
+ pop af
+ ccf
+ rl c
+
+; If sprite i's delta X is 0, then b = 7, else b = 9.
+ ld b, 7
+ ld a, [hl] ; a = [i#SPRITESTATEDATA1_XADJUSTED]
+ and $f
+ jr z, .next3
+ ld b, 9
+
+.next3
+ ldh a, [hFF91] ; a = distance between adjusted X coordinates
+ sub b
+ ldh [hFF92], a ; store distance adjusted using sprite i's direction
+ ld a, b
+ ldh [hFF91], a ; store 7 or 9 depending on sprite i's delta X
+ jr c, .collision
+
+; If sprite j's delta X is 0, then b = 7, else b = 9.
+ ld b, 7
+ dec e
+ ld a, [de] ; a = [j#SPRITESTATEDATA1_XSTEPVECTOR]
+ inc e
+ and a
+ jr z, .next4
+ ld b, 9
+
+.next4
+ ldh a, [hFF92] ; a = distance adjusted using sprite i's direction
+ sub b ; adjust distance using sprite j's direction
+ jr z, .collision
+ jr nc, .next ; go to next sprite if distance is still positive after both adjustments
+
+.collision
+ ld a, l
+ and $f0 ; collision with pikachu?
+ jr nz, .asm_4cd9
+ xor a
+ ld [wd434], a
+ ldh a, [hFF8F]
+ cp $f
+ jr nz, .asm_4cd9
+ call Func_4d0a
+ jr .asm_4cef
+.asm_4cd9
+ ldh a, [hFF91] ; a = 7 or 9 depending on sprite i's delta X
+ ld b, a
+ ldh a, [hFF90] ; a = 7 or 9 depending on sprite i's delta Y
+ inc l
+
+; If delta X isn't 0 and delta Y is 0, then b = %0011, else b = %1100.
+; (note that normally if delta X isn't 0, then delta Y must be 0 and vice versa)
+ cp b
+ jr c, .next5
+ ld b, %1100
+ jr .next6
+.next5
+ ld b, %0011
+
+.next6
+ ld a, c ; c has 2 bits set (one of bits 0-1 is set for the X axis and one of bits 2-3 for the Y axis)
+ and b ; we select either the bit in bits 0-1 or bits 2-3 based on the calculation immediately above
+ or [hl] ; or with existing collision direction bits in [i#SPRITESTATEDATA1_COLLISIONDATA]
+ ld [hl], a ; store new value
+ ld a, c ; useless code because a is overwritten before being used again
+
+; set bit in [i#SPRITESTATEDATA1_0E] or [i#SPRITESTATEDATA1_0F]
+; to indicate which sprite the collision occurred with
+ inc l
+ inc l
+.asm_4cef
+ ldh a, [hFF8F] ; a = loop counter
+ ld de, SpriteCollisionBitTable
+ add a
+ add e
+ ld e, a
+ jr nc, .noCarry3
+ inc d
+.noCarry3
+ ld a, [de]
+ or [hl]
+ ld [hli], a
+ inc de
+ ld a, [de]
+ or [hl]
+ ld [hl], a
+
+.next
+ ldh a, [hFF8F] ; a = loop counter
+ inc a
+ cp $10
+ jp nz, .loop
+ ret
+
+; takes delta X or delta Y in a
+; b = delta X/Y
+; c = 0 if delta X/Y is 0
+; c = 7 if delta X/Y is 1
+; c = 9 if delta X/Y is -1
+Func_4d0a:
+ ldh a, [hFF91]
+ ld b, a
+ ldh a, [hFF90]
+ inc l
+ cp b
+ jr c, .asm_4d17
+ ld b, %1100
+ jr .asm_4d19
+.asm_4d17
+ ld b, %11
+.asm_4d19
+ ld a, c
+ and b
+ ld [wd434], a
+ ld a, c
+ inc l
+ inc l
+ ret
+
+SetSpriteCollisionValues:
+ and a
+ ld b, 0
+ ld c, 0
+ jr z, .done
+ ld c, 9
+ cp -1
+ jr z, .ok
+ ld c, 7
+ ld a, 0
+.ok
+ ld b, a
+.done
+ ret
+
+SpriteCollisionBitTable:
+ db %00000000,%00000001
+ db %00000000,%00000010
+ db %00000000,%00000100
+ db %00000000,%00001000
+ db %00000000,%00010000
+ db %00000000,%00100000
+ db %00000000,%01000000
+ db %00000000,%10000000
+ db %00000001,%00000000
+ db %00000010,%00000000
+ db %00000100,%00000000
+ db %00001000,%00000000
+ db %00010000,%00000000
+ db %00100000,%00000000
+ db %01000000,%00000000
+ db %10000000,%00000000
diff --git a/engine/overworld/ssanne.asm b/engine/overworld/ssanne.asm
deleted file mode 100755
index cf3b1284..00000000
--- a/engine/overworld/ssanne.asm
+++ /dev/null
@@ -1,95 +0,0 @@
-AnimateBoulderDust:
- ld a, $1
- ld [wWhichAnimationOffsets], a ; select the boulder dust offsets
- ld a, [wUpdateSpritesEnabled]
- push af
- ld a, $ff
- ld [wUpdateSpritesEnabled], a
- ld a, %11100100
- ld [rOBP1], a
- call UpdateGBCPal_OBP1
- call LoadSmokeTileFourTimes
- callba WriteCutOrBoulderDustAnimationOAMBlock
- ld c, 8 ; number of steps in animation
-.loop
- push bc
- call GetMoveBoulderDustFunctionPointer
- ld bc, .returnAddress
- push bc
- ld c, 4
- jp hl
-.returnAddress
- ld a, [rOBP1]
- xor %01100100
- ld [rOBP1], a
- call UpdateGBCPal_OBP1
- call Delay3
- pop bc
- dec c
- jr nz, .loop
- pop af
- ld [wUpdateSpritesEnabled], a
- jp LoadPlayerSpriteGraphics
-
-GetMoveBoulderDustFunctionPointer:
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
- ld hl, MoveBoulderDustFunctionPointerTable
- ld c, a
- ld b, $0
- add hl, bc
- ld a, [hli]
- ld [wCoordAdjustmentAmount], a
- ld a, [hli]
- ld e, a
- ld a, [hli]
- ld h, [hl]
- ld l, a
- push hl
- ld hl, wOAMBuffer + $90
- ld d, $0
- add hl, de
- ld e, l
- ld d, h
- pop hl
- ret
-
-MoveBoulderDustFunctionPointerTable:
-; facing down
- db $FF,$00
- dw AdjustOAMBlockYPos
-
-; facing up
- db $01,$00
- dw AdjustOAMBlockYPos
-
-; facing left
- db $01,$01
- dw AdjustOAMBlockXPos
-
-; facing right
- db $FF,$01
- dw AdjustOAMBlockXPos
-
-LoadSmokeTileFourTimes:
- ld hl, vChars1 + $7c0
- ld c, $4
-.loop
- push bc
- push hl
- call LoadSmokeTile
- pop hl
- ld bc, $10
- add hl, bc
- pop bc
- dec c
- jr nz, .loop
- ret
-
-LoadSmokeTile:
- ld de, SSAnneSmokePuffTile
- lb bc, BANK(SSAnneSmokePuffTile), (SSAnneSmokePuffTileEnd - SSAnneSmokePuffTile) / $10
- jp CopyVideoData
-
-SSAnneSmokePuffTile:
- INCBIN "gfx/ss_anne_smoke_puff.2bpp"
-SSAnneSmokePuffTileEnd:
diff --git a/engine/overworld/tileset_header.asm b/engine/overworld/tileset_header.asm
deleted file mode 100644
index 05061651..00000000
--- a/engine/overworld/tileset_header.asm
+++ /dev/null
@@ -1,51 +0,0 @@
-LoadTilesetHeader:
- call GetPredefRegisters
- push hl
- ld d, 0
- ld a, [wCurMapTileset]
- add a
- add a
- ld e, a
- ld hl, Tilesets
- add hl, de
- add hl, de
- add hl, de
- ld de, wTilesetBank
- ld bc, $b
- call CopyData
- ld a, [hl]
- ld [hTilesetType], a
- xor a
- ld [$ffd8], a
- pop hl
- ld a, [wCurMapTileset]
- push hl
- push de
- ld hl, DungeonTilesets
- ld de, $1
- call IsInArray
- pop de
- pop hl
- jr c, .notDungeonTileset
- ld a, [wCurMapTileset]
- ld b, a
- ld a, [hPreviousTileset]
- cp b
- jr z, .done
-.notDungeonTileset
- ld a, [wDestinationWarpID]
- cp $ff
- jr z, .done
- call LoadDestinationWarpPosition
- ld a, [wYCoord]
- and $1
- ld [wYBlockCoord], a
- ld a, [wXCoord]
- and $1
- ld [wXBlockCoord], a
-.done
- ret
-
-INCLUDE "data/dungeon_tilesets.asm"
-
-INCLUDE "data/tileset_headers.asm"
diff --git a/engine/overworld/tilesets.asm b/engine/overworld/tilesets.asm
new file mode 100644
index 00000000..686fa50c
--- /dev/null
+++ b/engine/overworld/tilesets.asm
@@ -0,0 +1,51 @@
+LoadTilesetHeader:
+ call GetPredefRegisters
+ push hl
+ ld d, 0
+ ld a, [wCurMapTileset]
+ add a
+ add a
+ ld e, a
+ ld hl, Tilesets
+ add hl, de
+ add hl, de
+ add hl, de
+ ld de, wTilesetBank
+ ld bc, $b
+ call CopyData
+ ld a, [hl]
+ ldh [hTilesetType], a
+ xor a
+ ldh [hMovingBGTilesCounter1], a
+ pop hl
+ ld a, [wCurMapTileset]
+ push hl
+ push de
+ ld hl, DungeonTilesets
+ ld de, $1
+ call IsInArray
+ pop de
+ pop hl
+ jr c, .notDungeonTileset
+ ld a, [wCurMapTileset]
+ ld b, a
+ ldh a, [hPreviousTileset]
+ cp b
+ jr z, .done
+.notDungeonTileset
+ ld a, [wDestinationWarpID]
+ cp $ff
+ jr z, .done
+ call LoadDestinationWarpPosition
+ ld a, [wYCoord]
+ and $1
+ ld [wYBlockCoord], a
+ ld a, [wXCoord]
+ and $1
+ ld [wXBlockCoord], a
+.done
+ ret
+
+INCLUDE "data/tilesets/dungeon_tilesets.asm"
+
+INCLUDE "data/tilesets/tileset_headers.asm"
diff --git a/engine/overworld/trainer_sight.asm b/engine/overworld/trainer_sight.asm
new file mode 100755
index 00000000..816dea7f
--- /dev/null
+++ b/engine/overworld/trainer_sight.asm
@@ -0,0 +1,349 @@
+_GetSpritePosition1::
+ ld hl, wSpriteStateData1
+ ld de, SPRITESTATEDATA1_YPIXELS
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ call GetSpriteDataPointer
+ ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
+ ldh [hSpriteScreenYCoord], a
+ inc hl
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
+ ldh [hSpriteScreenXCoord], a
+ ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
+ add hl, de
+ ld a, [hli] ; x#SPRITESTATEDATA2_MAPY
+ ldh [hSpriteMapYCoord], a
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
+ ldh [hSpriteMapXCoord], a
+ ret
+
+_GetSpritePosition2::
+ ld hl, wSpriteStateData1
+ ld de, SPRITESTATEDATA1_YPIXELS
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ call GetSpriteDataPointer
+ ld a, [hli] ; x#SPRITESTATEDATA1_YPIXELS
+ ld [wSavedSpriteScreenY], a
+ inc hl
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
+ ld [wSavedSpriteScreenX], a
+ ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
+ add hl, de
+ ld a, [hli] ; x#SPRITESTATEDATA2_MAPY
+ ld [wSavedSpriteMapY], a
+ ld a, [hl] ; x#SPRITESTATEDATA2_MAPX
+ ld [wSavedSpriteMapX], a
+ ret
+
+_SetSpritePosition1::
+ ld hl, wSpriteStateData1
+ ld de, SPRITESTATEDATA1_YPIXELS
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ call GetSpriteDataPointer
+ ldh a, [hSpriteScreenYCoord] ; x#SPRITESTATEDATA1_YPIXELS
+ ld [hli], a
+ inc hl
+ ldh a, [hSpriteScreenXCoord] ; x#SPRITESTATEDATA1_XPIXELS
+ ld [hl], a
+ ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
+ add hl, de
+ ldh a, [hSpriteMapYCoord] ; x#SPRITESTATEDATA2_MAPY
+ ld [hli], a
+ ldh a, [hSpriteMapXCoord] ; x#SPRITESTATEDATA2_MAPX
+ ld [hl], a
+ ret
+
+_SetSpritePosition2::
+ ld hl, wSpriteStateData1
+ ld de, SPRITESTATEDATA1_YPIXELS
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ call GetSpriteDataPointer
+ ld a, [wSavedSpriteScreenY]
+ ld [hli], a ; x#SPRITESTATEDATA1_YPIXELS
+ inc hl
+ ld a, [wSavedSpriteScreenX]
+ ld [hl], a ; x#SPRITESTATEDATA1_XPIXELS
+ ld de, wSpritePlayerStateData2MapY - wSpritePlayerStateData1XPixels
+ add hl, de
+ ld a, [wSavedSpriteMapY]
+ ld [hli], a ; x#SPRITESTATEDATA2_MAPY
+ ld a, [wSavedSpriteMapX]
+ ld [hl], a ; x#SPRITESTATEDATA2_MAPX
+ ret
+
+TrainerWalkUpToPlayer::
+ ld a, [wSpriteIndex]
+ swap a
+ ld [wTrainerSpriteOffset], a
+ call ReadTrainerScreenPosition
+ ld a, [wTrainerFacingDirection]
+ and a ; SPRITE_FACING_DOWN
+ jr z, .facingDown
+ cp SPRITE_FACING_UP
+ jr z, .facingUp
+ cp SPRITE_FACING_LEFT
+ jr z, .facingLeft
+ jr .facingRight
+.facingDown
+ ld a, [wTrainerScreenY]
+ ld b, a
+ ld a, $3c ; (fixed) player screen Y pos
+ call CalcDifference
+ cp $10 ; trainer is right above player
+ ret z
+ swap a
+ dec a
+ ld c, a ; bc = steps yet to go to reach player
+ xor a
+ ld b, a ; a = direction to go to
+ jr .writeWalkScript
+.facingUp
+ ld a, [wTrainerScreenY]
+ ld b, a
+ ld a, $3c ; (fixed) player screen Y pos
+ call CalcDifference
+ cp $10 ; trainer is right below player
+ ret z
+ swap a
+ dec a
+ ld c, a ; bc = steps yet to go to reach player
+ ld b, $0
+ ld a, $40 ; a = direction to go to
+ jr .writeWalkScript
+.facingRight
+ ld a, [wTrainerScreenX]
+ ld b, a
+ ld a, $40 ; (fixed) player screen X pos
+ call CalcDifference
+ cp $10 ; trainer is directly left of player
+ ret z
+ swap a
+ dec a
+ ld c, a ; bc = steps yet to go to reach player
+ ld b, $0
+ ld a, $c0 ; a = direction to go to
+ jr .writeWalkScript
+.facingLeft
+ ld a, [wTrainerScreenX]
+ ld b, a
+ ld a, $40 ; (fixed) player screen X pos
+ call CalcDifference
+ cp $10 ; trainer is directly right of player
+ ret z
+ swap a
+ dec a
+ ld c, a ; bc = steps yet to go to reach player
+ ld b, $0
+ ld a, $80 ; a = direction to go to
+.writeWalkScript
+ ld hl, wNPCMovementDirections2
+ ld de, wNPCMovementDirections2
+ call FillMemory ; write the necessary steps to reach player
+ ld [hl], $ff ; write end of list sentinel
+ ld a, [wSpriteIndex]
+ ldh [hSpriteIndex], a
+ jp MoveSprite_
+
+; input: de = offset within sprite entry
+; output: hl = pointer to sprite data
+GetSpriteDataPointer:
+ push de
+ add hl, de
+ ldh a, [hSpriteIndex]
+ swap a
+ ld d, $0
+ ld e, a
+ add hl, de
+ pop de
+ ret
+
+; tests if this trainer is in the right position to engage the player and do so if she is.
+TrainerEngage:
+ push hl
+ push de
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_IMAGEINDEX
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_IMAGEINDEX
+ sub $ff
+ jr nz, .spriteOnScreen ; test if sprite is on screen
+ jp .noEngage
+.spriteOnScreen
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_FACINGDIRECTION
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_FACINGDIRECTION
+ ld [wTrainerFacingDirection], a
+ call ReadTrainerScreenPosition
+ ld a, [wTrainerScreenY] ; sprite screen Y pos
+ ld b, a
+ ld a, $3c
+ cp b
+ jr z, .linedUpY
+ ld a, [wTrainerScreenX] ; sprite screen X pos
+ ld b, a
+ ld a, $40
+ cp b
+ jr z, .linedUpX
+ xor a
+ jp .noEngage
+.linedUpY
+ ld a, [wTrainerScreenX] ; sprite screen X pos
+ ld b, a
+ ld a, $40 ; (fixed) player X position
+ call CalcDifference ; calc distance
+ jr z, .noEngage ; exact same position as player
+ call CheckSpriteCanSeePlayer
+ jr c, .engage
+ xor a
+ jr .noEngage
+.linedUpX
+ ld a, [wTrainerScreenY] ; sprite screen Y pos
+ ld b, a
+ ld a, $3c ; (fixed) player Y position
+ call CalcDifference ; calc distance
+ jr z, .noEngage ; exact same position as player
+ call CheckSpriteCanSeePlayer
+ jr c, .engage
+ xor a
+ jp .noEngage
+.engage
+ call CheckPlayerIsInFrontOfSprite
+ ld a, [wTrainerSpriteOffset]
+ and a
+ jr z, .noEngage
+ ld hl, wFlags_0xcd60
+ set 0, [hl]
+ call EngageMapTrainer
+ ld a, $ff
+.noEngage
+ ld [wTrainerSpriteOffset], a
+ pop de
+ pop hl
+ ret
+
+; reads trainer's Y position to wTrainerScreenY and X position to wTrainerScreenX
+ReadTrainerScreenPosition:
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_YPIXELS
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_YPIXELS
+ ld [wTrainerScreenY], a
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_XPIXELS
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
+ ld [wTrainerScreenX], a
+ ret
+
+; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite
+; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back
+; a: distance player to sprite
+CheckSpriteCanSeePlayer:
+ ld b, a
+ ld a, [wTrainerEngageDistance] ; how far the trainer can see
+ cp b
+ jr nc, .checkIfLinedUp
+ jr .notInLine ; player too far away
+.checkIfLinedUp
+ ld a, [wTrainerFacingDirection] ; sprite facing direction
+ cp SPRITE_FACING_DOWN
+ jr z, .checkXCoord
+ cp SPRITE_FACING_UP
+ jr z, .checkXCoord
+ cp SPRITE_FACING_LEFT
+ jr z, .checkYCoord
+ cp SPRITE_FACING_RIGHT
+ jr z, .checkYCoord
+ jr .notInLine
+.checkXCoord
+ ld a, [wTrainerScreenX] ; sprite screen X position
+ ld b, a
+ cp $40
+ jr z, .inLine
+ jr .notInLine
+.checkYCoord
+ ld a, [wTrainerScreenY] ; sprite screen Y position
+ ld b, a
+ cp $3c
+ jr nz, .notInLine
+.inLine
+ scf
+ ret
+.notInLine
+ and a
+ ret
+
+; tests if the player is in front of the sprite (rather than behind it)
+CheckPlayerIsInFrontOfSprite:
+ ld a, [wCurMap]
+ cp POWER_PLANT
+ jp z, .engage ; bypass this for power plant to get voltorb fake items to work
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_YPIXELS
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_YPIXELS
+ cp $fc
+ jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block
+ ld a, $c
+.notOnTopmostTile
+ ld [wTrainerScreenY], a
+ ld a, [wTrainerSpriteOffset]
+ add SPRITESTATEDATA1_XPIXELS
+ ld d, $0
+ ld e, a
+ ld hl, wSpriteStateData1
+ add hl, de
+ ld a, [hl] ; x#SPRITESTATEDATA1_XPIXELS
+ ld [wTrainerScreenX], a
+ ld a, [wTrainerFacingDirection] ; facing direction
+ cp SPRITE_FACING_DOWN
+ jr nz, .notFacingDown
+ ld a, [wTrainerScreenY] ; sprite screen Y pos
+ cp $3c
+ jr c, .engage ; sprite above player
+ jr .noEngage ; sprite below player
+.notFacingDown
+ cp SPRITE_FACING_UP
+ jr nz, .notFacingUp
+ ld a, [wTrainerScreenY] ; sprite screen Y pos
+ cp $3c
+ jr nc, .engage ; sprite below player
+ jr .noEngage ; sprite above player
+.notFacingUp
+ cp SPRITE_FACING_LEFT
+ jr nz, .notFacingLeft
+ ld a, [wTrainerScreenX] ; sprite screen X pos
+ cp $40
+ jr nc, .engage ; sprite right of player
+ jr .noEngage ; sprite left of player
+.notFacingLeft
+ ld a, [wTrainerScreenX] ; sprite screen X pos
+ cp $40
+ jr nc, .noEngage ; sprite right of player
+.engage
+ ld a, $ff
+ jr .done
+.noEngage
+ xor a
+.done
+ ld [wTrainerSpriteOffset], a
+ ret
diff --git a/engine/overworld/trainers.asm b/engine/overworld/trainers.asm
deleted file mode 100755
index 655c6b2a..00000000
--- a/engine/overworld/trainers.asm
+++ /dev/null
@@ -1,349 +0,0 @@
-_GetSpritePosition1:
- ld hl, wSpriteStateData1
- ld de, $4
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- call GetSpriteDataPointer
- ld a, [hli] ; c1x4 (screen Y pos)
- ld [$ffeb], a
- inc hl
- ld a, [hl] ; c1x6 (screen X pos)
- ld [$ffec], a
- ld de, (wSpriteStateData2 + $4) - (wSpriteStateData1 + $6)
- add hl, de
- ld a, [hli] ; c2x4 (map Y pos)
- ld [$ffed], a
- ld a, [hl] ; c2x5 (map X pos)
- ld [$ffee], a
- ret
-
-_GetSpritePosition2:
- ld hl, wSpriteStateData1
- ld de, $4
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- call GetSpriteDataPointer
- ld a, [hli] ; c1x4 (screen Y pos)
- ld [wSavedSpriteScreenY], a
- inc hl
- ld a, [hl] ; c1x6 (screen X pos)
- ld [wSavedSpriteScreenX], a
- ld de, (wSpriteStateData2 + $4) - (wSpriteStateData1 + $6)
- add hl, de
- ld a, [hli] ; c2x4 (map Y pos)
- ld [wSavedSpriteMapY], a
- ld a, [hl] ; c2x5 (map X pos)
- ld [wSavedSpriteMapX], a
- ret
-
-_SetSpritePosition1:
- ld hl, wSpriteStateData1
- ld de, $4
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- call GetSpriteDataPointer
- ld a, [$ffeb] ; c1x4 (screen Y pos)
- ld [hli], a
- inc hl
- ld a, [$ffec] ; c1x6 (screen X pos)
- ld [hl], a
- ld de, (wSpriteStateData2 + $4) - (wSpriteStateData1 + $6)
- add hl, de
- ld a, [$ffed] ; c2x4 (map Y pos)
- ld [hli], a
- ld a, [$ffee] ; c2x5 (map X pos)
- ld [hl], a
- ret
-
-_SetSpritePosition2:
- ld hl, wSpriteStateData1
- ld de, 4
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- call GetSpriteDataPointer
- ld a, [wSavedSpriteScreenY]
- ld [hli], a ; c1x4 (screen Y pos)
- inc hl
- ld a, [wSavedSpriteScreenX]
- ld [hl], a ; c1x6 (screen X pos)
- ld de, (wSpriteStateData2 + $4) - (wSpriteStateData1 + $6)
- add hl, de
- ld a, [wSavedSpriteMapY]
- ld [hli], a ; c2x4 (map Y pos)
- ld a, [wSavedSpriteMapX]
- ld [hl], a ; c2x5 (map X pos)
- ret
-
-TrainerWalkUpToPlayer:
- ld a, [wSpriteIndex]
- swap a
- ld [wTrainerSpriteOffset], a
- call ReadTrainerScreenPosition
- ld a, [wTrainerFacingDirection]
- and a ; SPRITE_FACING_DOWN
- jr z, .facingDown
- cp SPRITE_FACING_UP
- jr z, .facingUp
- cp SPRITE_FACING_LEFT
- jr z, .facingLeft
- jr .facingRight
-.facingDown
- ld a, [wTrainerScreenY]
- ld b, a
- ld a, $3c ; (fixed) player screen Y pos
- call CalcDifference
- cp $10 ; trainer is right above player
- ret z
- swap a
- dec a
- ld c, a ; bc = steps yet to go to reach player
- xor a
- ld b, a ; a = direction to go to
- jr .writeWalkScript
-.facingUp
- ld a, [wTrainerScreenY]
- ld b, a
- ld a, $3c ; (fixed) player screen Y pos
- call CalcDifference
- cp $10 ; trainer is right below player
- ret z
- swap a
- dec a
- ld c, a ; bc = steps yet to go to reach player
- ld b, $0
- ld a, $40 ; a = direction to go to
- jr .writeWalkScript
-.facingRight
- ld a, [wTrainerScreenX]
- ld b, a
- ld a, $40 ; (fixed) player screen X pos
- call CalcDifference
- cp $10 ; trainer is directly left of player
- ret z
- swap a
- dec a
- ld c, a ; bc = steps yet to go to reach player
- ld b, $0
- ld a, $c0 ; a = direction to go to
- jr .writeWalkScript
-.facingLeft
- ld a, [wTrainerScreenX]
- ld b, a
- ld a, $40 ; (fixed) player screen X pos
- call CalcDifference
- cp $10 ; trainer is directly right of player
- ret z
- swap a
- dec a
- ld c, a ; bc = steps yet to go to reach player
- ld b, $0
- ld a, $80 ; a = direction to go to
-.writeWalkScript
- ld hl, wNPCMovementDirections2
- ld de, wNPCMovementDirections2
- call FillMemory ; write the necessary steps to reach player
- ld [hl], $ff ; write end of list sentinel
- ld a, [wSpriteIndex]
- ld [H_SPRITEINDEX], a
- jp MoveSprite_
-
-; input: de = offset within sprite entry
-; output: hl = pointer to sprite data
-GetSpriteDataPointer:
- push de
- add hl, de
- ld a, [H_SPRITEINDEX]
- swap a
- ld d, $0
- ld e, a
- add hl, de
- pop de
- ret
-
-; tests if this trainer is in the right position to engage the player and do so if she is.
-TrainerEngage:
- push hl
- push de
- ld a, [wTrainerSpriteOffset]
- add $2
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x2: sprite image index
- sub $ff
- jr nz, .spriteOnScreen ; test if sprite is on screen
- jp .noEngage
-.spriteOnScreen
- ld a, [wTrainerSpriteOffset]
- add $9
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x9: facing direction
- ld [wTrainerFacingDirection], a
- call ReadTrainerScreenPosition
- ld a, [wTrainerScreenY] ; sprite screen Y pos
- ld b, a
- ld a, $3c
- cp b
- jr z, .linedUpY
- ld a, [wTrainerScreenX] ; sprite screen X pos
- ld b, a
- ld a, $40
- cp b
- jr z, .linedUpX
- xor a
- jp .noEngage
-.linedUpY
- ld a, [wTrainerScreenX] ; sprite screen X pos
- ld b, a
- ld a, $40 ; (fixed) player X position
- call CalcDifference ; calc distance
- jr z, .noEngage ; exact same position as player
- call CheckSpriteCanSeePlayer
- jr c, .engage
- xor a
- jr .noEngage
-.linedUpX
- ld a, [wTrainerScreenY] ; sprite screen Y pos
- ld b, a
- ld a, $3c ; (fixed) player Y position
- call CalcDifference ; calc distance
- jr z, .noEngage ; exact same position as player
- call CheckSpriteCanSeePlayer
- jr c, .engage
- xor a
- jp .noEngage
-.engage
- call CheckPlayerIsInFrontOfSprite
- ld a, [wTrainerSpriteOffset]
- and a
- jr z, .noEngage
- ld hl, wFlags_0xcd60
- set 0, [hl]
- call EngageMapTrainer
- ld a, $ff
-.noEngage
- ld [wTrainerSpriteOffset], a
- pop de
- pop hl
- ret
-
-; reads trainer's Y position to wTrainerScreenY and X position to wTrainerScreenX
-ReadTrainerScreenPosition:
- ld a, [wTrainerSpriteOffset]
- add $4
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x4 (sprite Y pos)
- ld [wTrainerScreenY], a
- ld a, [wTrainerSpriteOffset]
- add $6
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x6 (sprite X pos)
- ld [wTrainerScreenX], a
- ret
-
-; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite
-; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back
-; a: distance player to sprite
-CheckSpriteCanSeePlayer:
- ld b, a
- ld a, [wTrainerEngageDistance] ; how far the trainer can see
- cp b
- jr nc, .checkIfLinedUp
- jr .notInLine ; player too far away
-.checkIfLinedUp
- ld a, [wTrainerFacingDirection] ; sprite facing direction
- cp SPRITE_FACING_DOWN
- jr z, .checkXCoord
- cp SPRITE_FACING_UP
- jr z, .checkXCoord
- cp SPRITE_FACING_LEFT
- jr z, .checkYCoord
- cp SPRITE_FACING_RIGHT
- jr z, .checkYCoord
- jr .notInLine
-.checkXCoord
- ld a, [wTrainerScreenX] ; sprite screen X position
- ld b, a
- cp $40
- jr z, .inLine
- jr .notInLine
-.checkYCoord
- ld a, [wTrainerScreenY] ; sprite screen Y position
- ld b, a
- cp $3c
- jr nz, .notInLine
-.inLine
- scf
- ret
-.notInLine
- and a
- ret
-
-; tests if the player is in front of the sprite (rather than behind it)
-CheckPlayerIsInFrontOfSprite:
- ld a, [wCurMap]
- cp POWER_PLANT
- jp z, .engage ; bypass this for power plant to get voltorb fake items to work
- ld a, [wTrainerSpriteOffset]
- add $4
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x4 (sprite screen Y pos)
- cp $fc
- jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block
- ld a, $c
-.notOnTopmostTile
- ld [wTrainerScreenY], a
- ld a, [wTrainerSpriteOffset]
- add $6
- ld d, $0
- ld e, a
- ld hl, wSpriteStateData1
- add hl, de
- ld a, [hl] ; c1x6 (sprite screen X pos)
- ld [wTrainerScreenX], a
- ld a, [wTrainerFacingDirection] ; facing direction
- cp SPRITE_FACING_DOWN
- jr nz, .notFacingDown
- ld a, [wTrainerScreenY] ; sprite screen Y pos
- cp $3c
- jr c, .engage ; sprite above player
- jr .noEngage ; sprite below player
-.notFacingDown
- cp SPRITE_FACING_UP
- jr nz, .notFacingUp
- ld a, [wTrainerScreenY] ; sprite screen Y pos
- cp $3c
- jr nc, .engage ; sprite below player
- jr .noEngage ; sprite above player
-.notFacingUp
- cp SPRITE_FACING_LEFT
- jr nz, .notFacingLeft
- ld a, [wTrainerScreenX] ; sprite screen X pos
- cp $40
- jr nc, .engage ; sprite right of player
- jr .noEngage ; sprite left of player
-.notFacingLeft
- ld a, [wTrainerScreenX] ; sprite screen X pos
- cp $40
- jr nc, .noEngage ; sprite right of player
-.engage
- ld a, $ff
- jr .done
-.noEngage
- xor a
-.done
- ld [wTrainerSpriteOffset], a
- ret
diff --git a/engine/overworld/update_map.asm b/engine/overworld/update_map.asm
index 8577b9e7..53a5592d 100644
--- a/engine/overworld/update_map.asm
+++ b/engine/overworld/update_map.asm
@@ -50,20 +50,20 @@ RedrawMapView:
ld a, [wIsInBattle]
inc a
ret z
- ld a, [H_AUTOBGTRANSFERENABLED]
+ ldh a, [hAutoBGTransferEnabled]
push af
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [hTilesetType], a ; no flower/water BG tile animations
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hTilesetType], a ; no flower/water BG tile animations
call LoadCurrentMapView
call RunDefaultPaletteCommand
ld hl, wMapViewVRAMPointer
ld a, [hli]
ld h, [hl]
ld l, a
- ld de, -2 * 32
+ ld de, -2 * BG_MAP_WIDTH
add hl, de
ld a, h
and $3
@@ -73,23 +73,23 @@ RedrawMapView:
ld a, h
ld [wBuffer + 1], a ; this copy of the address is not used
ld a, 2
- ld [$ffbe], a
- ld c, 9 ; number of rows of 2x2 tiles (this covers the whole screen)
+ ldh [hRedrawMapViewRowOffset], a
+ ld c, SCREEN_HEIGHT / 2 ; number of rows of 2x2 tiles (this covers the whole screen)
.redrawRowLoop
push bc
push hl
push hl
ld hl, wTileMap - 2 * SCREEN_WIDTH
ld de, SCREEN_WIDTH
- ld a, [$ffbe]
+ ldh a, [hRedrawMapViewRowOffset]
.calcWRAMAddrLoop
add hl, de
dec a
jr nz, .calcWRAMAddrLoop
call CopyToRedrawRowOrColumnSrcTiles
pop hl
- ld de, $20
- ld a, [$ffbe]
+ ld de, BG_MAP_WIDTH
+ ldh a, [hRedrawMapViewRowOffset]
ld c, a
.calcVRAMAddrLoop
add hl, de
@@ -98,13 +98,13 @@ RedrawMapView:
or $98
dec c
jr nz, .calcVRAMAddrLoop
- ld [hRedrawRowOrColumnDest + 1], a
+ ldh [hRedrawRowOrColumnDest + 1], a
ld a, l
- ld [hRedrawRowOrColumnDest], a
+ ldh [hRedrawRowOrColumnDest], a
ld a, REDRAW_ROW
- ld [hRedrawRowOrColumnMode], a
+ ldh [hRedrawRowOrColumnMode], a
call DelayFrame
- ld hl, $ffbe
+ ld hl, hRedrawMapViewRowOffset
inc [hl]
inc [hl]
pop hl
@@ -112,9 +112,9 @@ RedrawMapView:
dec c
jr nz, .redrawRowLoop
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
pop af
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
CompareHLWithBC:
diff --git a/engine/overworld/wild_mons.asm b/engine/overworld/wild_mons.asm
index dae57f23..2593e0ec 100644
--- a/engine/overworld/wild_mons.asm
+++ b/engine/overworld/wild_mons.asm
@@ -1,4 +1,4 @@
-LoadWildData:
+LoadWildData::
ld hl, WildDataPointers
ld a, [wCurMap]
@@ -16,10 +16,10 @@ LoadWildData:
jr z, .NoGrassData ; if no grass data, skip to surfing data
push hl
ld de, wGrassMons ; otherwise, load grass data
- ld bc, $0014
+ ld bc, $14
call CopyData
pop hl
- ld bc, $0014
+ ld bc, $14
add hl, bc
.NoGrassData
ld a, [hli]
@@ -27,7 +27,7 @@ LoadWildData:
and a
ret z ; if no water data, we're done
ld de, wWaterMons ; otherwise, load surfing data
- ld bc, $0014
+ ld bc, $14
jp CopyData
-INCLUDE "data/wild_mons.asm"
+INCLUDE "data/wild/grass_water.asm"
diff --git a/engine/palettes.asm b/engine/palettes.asm
deleted file mode 100755
index ec9816ab..00000000
--- a/engine/palettes.asm
+++ /dev/null
@@ -1,1116 +0,0 @@
-_RunPaletteCommand:
- call GetPredefRegisters
- ld a, b
- cp $ff
- jr nz, .next
- ld a, [wDefaultPaletteCommand] ; use default command if command ID is $ff
-.next
- cp UPDATE_PARTY_MENU_BLK_PACKET
- jp z, UpdatePartyMenuBlkPacket
- ld l, a
- ld h, 0
- add hl, hl
- ld de, SetPalFunctions
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, SendSGBPackets
- push de
- jp hl
-
-SetPal_Black:
- ld hl, PalPacket_Black
- ld de, BlkPacket_Battle
- ret
-
-; uses PalPacket_Empty to build a packet based on mon IDs and health color
-SetPal_Battle:
- ld hl, PalPacket_Empty
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- ;ld a, [wPlayerBattleStatus3]
- ld hl, wBattleMonSpecies
- ld a, [hl]
- and a
- jr z, .asm_71ef9
- ld hl, wPartyMon1
- ld a, [wPlayerMonNumber]
- ld bc, wPartyMon2 - wPartyMon1
- call AddNTimes
-.asm_71ef9
- call DeterminePaletteID
- ld b, a
- ;ld a, [wEnemyBattleStatus3]
- ld hl, wEnemyMonSpecies2
- call DeterminePaletteID
- ld c, a
- ld hl, wPalPacket + 1
- ld a, [wPlayerHPBarColor]
- add PAL_GREENBAR
- ld [hli], a
- inc hl
- ld a, [wEnemyHPBarColor]
- add PAL_GREENBAR
- ld [hli], a
- inc hl
- ld a, b
- ld [hli], a
- inc hl
- ld a, c
- ld [hl], a
- ld hl, wPalPacket
- ld de, BlkPacket_Battle
- ld a, SET_PAL_BATTLE
- ld [wDefaultPaletteCommand], a
- ret
-
-SetPal_TownMap:
- ld hl, PalPacket_TownMap
- ld de, BlkPacket_WholeScreen
- ret
-
-; uses PalPacket_Empty to build a packet based the mon ID
-SetPal_StatusScreen:
- ld hl, PalPacket_Empty
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- ld a, [wcf91]
- cp NUM_POKEMON_INDEXES + 1
- jr c, .pokemon
- ld a, $1 ; not pokemon
-.pokemon
- call DeterminePaletteIDOutOfBattle
- push af
- ld hl, wPalPacket + 1
- ld a, [wStatusScreenHPBarColor]
- add PAL_GREENBAR
- ld [hli], a
- inc hl
- pop af
- ld [hl], a
- ld hl, wPalPacket
- ld de, BlkPacket_StatusScreen
- ret
-
-SetPal_PartyMenu:
- ld hl, PalPacket_PartyMenu
- ld de, wPartyMenuBlkPacket
- ret
-
-SetPal_Pokedex:
- ld hl, PalPacket_Pokedex
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- ld a, [wcf91]
- call DeterminePaletteIDOutOfBattle
- ld hl, wPalPacket + 3
- ld [hl], a
- ld hl, wPalPacket
- ld de, BlkPacket_Pokedex
- ret
-
-SetPal_Slots:
- ld hl, PalPacket_Slots
- ld de, BlkPacket_Slots
- ret
-
-SetPal_Titlescreen:
- ld hl, PalPacket_Titlescreen
- ld de, BlkPacket_Titlescreen
- ret
-
-; used mostly for menus and the Oak intro
-SetPal_Generic:
- ld hl, PalPacket_Generic
- ld de, BlkPacket_WholeScreen
- ret
-
-SetPal_NidorinoIntro:
- ld hl, PalPacket_NidorinoIntro
- ld de, BlkPacket_NidorinoIntro
- ret
-
-SetPal_GameFreakIntro:
- ld hl, PalPacket_GameFreakIntro
- ld de, BlkPacket_GameFreakIntro
- ld a, SET_PAL_GENERIC
- ld [wDefaultPaletteCommand], a
- ret
-
-; uses PalPacket_Empty to build a packet based on the current map
-SetPal_Overworld:
- ld hl, PalPacket_Empty
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- ld a, [wCurMapTileset]
- cp CEMETERY
- jr z, .PokemonTowerOrAgatha
- cp CAVERN
- jr z, .caveOrBruno
- ld a, [wCurMap]
- cp REDS_HOUSE_1F
- jr c, .townOrRoute
- cp CERULEAN_CAVE_2F
- jr c, .normalDungeonOrBuilding
- cp NAME_RATERS_HOUSE
- jr c, .caveOrBruno
- cp LORELEIS_ROOM
- jr z, .Lorelei
- cp BRUNOS_ROOM
- jr z, .caveOrBruno
- cp TRADE_CENTER
- jr z, .trade_center_colosseum
- cp COLOSSEUM
- jr z, .trade_center_colosseum
-.normalDungeonOrBuilding
- ld a, [wLastMap] ; town or route that current dungeon or building is located
-.townOrRoute
- cp SAFFRON_CITY + 1
- jr c, .town
- ld a, PAL_ROUTE - 1
-.town
- inc a ; a town's palette ID is its map ID + 1
- ld hl, wPalPacket + 1
- ld [hld], a
- ld de, BlkPacket_WholeScreen
- ld a, SET_PAL_OVERWORLD
- ld [wDefaultPaletteCommand], a
- ret
-.PokemonTowerOrAgatha
- ld a, PAL_GREYMON - 1
- jr .town
-.caveOrBruno
- ld a, PAL_CAVE - 1
- jr .town
-.Lorelei
- xor a
- jr .town
-.trade_center_colosseum
- ld a, PAL_GREYMON - 1
- jr .town
-
-; used when a Pokemon is the only thing on the screen
-; such as evolution, trading and the Hall of Fame
-SetPal_PokemonWholeScreen:
- push bc
- ld hl, PalPacket_Empty
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- pop bc
- ld a, c
- and a
- ld a, PAL_BLACK
- jr nz, .next
- ld a, [wWholeScreenPaletteMonSpecies]
- call DeterminePaletteIDOutOfBattle
-.next
- ld [wPalPacket + 1], a
- ld hl, wPalPacket
- ld de, BlkPacket_WholeScreen
- ret
-
-SetPal_TrainerCard:
- ld hl, BlkPacket_TrainerCard
- ld de, wTrainerCardBlkPacket
- ld bc, $40
- call CopyData
- ld de, BadgeBlkDataLengths
- ld hl, wTrainerCardBlkPacket + 2
- ld a, [wObtainedBadges]
- ld c, 8
-.badgeLoop
- srl a
- push af
- jr c, .haveBadge
-; The player doens't have the badge, so zero the badge's blk data.
- push bc
- ld a, [de]
- ld c, a
- xor a
-.zeroBadgeDataLoop
- ld [hli], a
- dec c
- jr nz, .zeroBadgeDataLoop
- pop bc
- jr .nextBadge
-.haveBadge
-; The player does have the badge, so skip past the badge's blk data.
- ld a, [de]
-.skipBadgeDataLoop
- inc hl
- dec a
- jr nz, .skipBadgeDataLoop
-.nextBadge
- pop af
- inc de
- dec c
- jr nz, .badgeLoop
- ld hl, PalPacket_TrainerCard
- ld de, wTrainerCardBlkPacket
- ret
-
-SendUnknownPalPacket_7205d::
- ld hl, UnknownPalPacket_72811
- ld de, BlkPacket_WholeScreen
- ret
-
-SendUnknownPalPacket_72064::
- ld hl, UnknownPalPacket_72821
- ld de, UnknownPacket_72751
- ret
-
-SetPalFunctions:
- dw SetPal_Black
- dw SetPal_Battle
- dw SetPal_TownMap
- dw SetPal_StatusScreen
- dw SetPal_Pokedex
- dw SetPal_Slots
- dw SetPal_Titlescreen
- dw SetPal_NidorinoIntro
- dw SetPal_Generic
- dw SetPal_Overworld
- dw SetPal_PartyMenu
- dw SetPal_PokemonWholeScreen
- dw SetPal_GameFreakIntro
- dw SetPal_TrainerCard
- dw SendUnknownPalPacket_7205d
- dw SendUnknownPalPacket_72064
-
-; The length of the blk data of each badge on the Trainer Card.
-; The Rainbow Badge has 3 entries because of its many colors.
-BadgeBlkDataLengths:
- db 6 ; Boulder Badge
- db 6 ; Cascade Badge
- db 6 ; Thunder Badge
- db 6 * 3 ; Rainbow Badge
- db 6 ; Soul Badge
- db 6 ; Marsh Badge
- db 6 ; Volcano Badge
- db 6 ; Earth Badge
-
-DeterminePaletteID:
- ld a, [hl]
-DeterminePaletteIDOutOfBattle:
- ld [wd11e], a
- and a ; is the mon index 0?
- jr z, .skipDexNumConversion
- push bc
- predef IndexToPokedex
- pop bc
- ld a, [wd11e]
-.skipDexNumConversion
- ld e, a
- ld d, 0
- ld hl, MonsterPalettes ; not just for Pokemon, Trainers use it too
- add hl, de
- ld a, [hl]
- ret
-
-YellowIntroPaletteAction::
- ld a, e
- and a
- jr nz, .asm_720bd
- ld hl, PalPacket_Generic
- ld a, [hGBC]
- and a
- jp z, SendSGBPacket
- jp InitGBCPalettes
-
-.asm_720bd
- ld hl, UnknownPalPacket_72811
- ld a, [hGBC]
- and a
- jp z, SendSGBPacket
- call InitGBCPalettes
- ld hl, PalPacket_Generic
- inc hl
- ld a, [hli]
- call GetGBCBasePalAddress
- ld a, e
- ld [wGBCBasePalPointers + 2], a
- ld a, d
- ld [wGBCBasePalPointers + 2 + 1], a
- xor a ; CONVERT_BGP
- call DMGPalToGBCPal
- ld a, 1
- call TransferCurBGPData
- ret
-
-LoadOverworldPikachuFrontpicPalettes::
- ld hl, PalPacket_Empty
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- call GetPal_Pikachu
- ld hl, wPartyMenuBlkPacket
- ld [hl], a
- ld hl, wPartyMenuBlkPacket + 2
- ld a, $26
- ld [hl], a
- ld hl, wPalPacket
- ld a, [hGBC]
- and a
- jr nz, .cgb_1
- call SendSGBPacket
- jr .okay_1
-
-.cgb_1
- call InitGBCPalettes
-.okay_1
- ld hl, BlkPacket_WholeScreen
- ld de, wPalPacket
- ld bc, $10
- call CopyData
- ld hl, wPartyMenuBlkPacket + 2
- ld a, $5
- ld [hli], a
- ld a, $7
- ld [hli], a
- ld a, $6
- ld [hli], a
- ld a, $b
- ld [hli], a
- ld a, $a
- ld [hl], a
- ld hl, wPalPacket
- ld a, [hGBC]
- and a
- jr nz, .cgb_2
- call SendSGBPacket
- jr .okay_2
-
-.cgb_2
- call InitGBCPalettes
-.okay_2
- ret
-
-GetPal_Pikachu::
-; similar to SetPal_Overworld
- ld a, [wCurMapTileset]
- cp CEMETERY
- jr z, .PokemonTowerOrAgatha
- cp CAVERN
- jr z, .caveOrBruno
- ld a, [wCurMap]
- cp REDS_HOUSE_1F
- jr c, .townOrRoute
- cp CERULEAN_CAVE_2F
- jr c, .normalDungeonOrBuilding
- cp NAME_RATERS_HOUSE
- jr c, .caveOrBruno
- cp LORELEIS_ROOM
- jr z, .Lorelei
- cp BRUNOS_ROOM
- jr z, .caveOrBruno
- cp TRADE_CENTER
- jr z, .battleOrTradeCenter
- cp COLOSSEUM
- jr z, .battleOrTradeCenter
-.normalDungeonOrBuilding
- ld a, [wLastMap] ; town or route that current dungeon or building is located
-.townOrRoute
- cp SAFFRON_CITY + 1
- jr c, .town
- ld a, PAL_ROUTE - 1
-.town
- inc a ; a town's pallete ID is its map ID + 1
- ret
-
-.PokemonTowerOrAgatha
- ld a, PAL_GREYMON - 1
- jr .town
-
-.caveOrBruno
- ld a, PAL_CAVE - 1
- jr .town
-
-.Lorelei
- xor a ; PAL_PALLET - 1
- jr .town
-
-.battleOrTradeCenter
- ld a, PAL_GREYMON - 1
- jr .town
-
-InitPartyMenuBlkPacket:
- ld hl, BlkPacket_PartyMenu
- ld de, wPartyMenuBlkPacket
- ld bc, $30
- jp CopyData
-
-UpdatePartyMenuBlkPacket:
-; Update the blk packet with the palette of the HP bar that is
-; specified in [wWhichPartyMenuHPBar].
- ld hl, wPartyMenuHPBarColors
- ld a, [wWhichPartyMenuHPBar]
- ld e, a
- ld d, 0
- add hl, de
- ld e, l
- ld d, h
- ld a, [de]
- and a
- ld e, (1 << 2) | 1 ; green
- jr z, .next
- dec a
- ld e, (2 << 2) | 2 ; yellow
- jr z, .next
- ld e, (3 << 2) | 3 ; red
-.next
- push de
- ld hl, wPartyMenuBlkPacket + 8 + 1
- ld bc, 6
- ld a, [wWhichPartyMenuHPBar]
- call AddNTimes
- pop de
- ld [hl], e
- ret
-
-SendSGBPacket:
- ld a, 1
- ld [hDisableJoypadPolling], a ; don't poll joypad while sending packet
- call _SendSGBPacket
- xor a
- ld [hDisableJoypadPolling], a
- ret
-
-_SendSGBPacket:
-;check number of packets
- ld a, [hl]
- and $07
- ret z
-; store number of packets in B
- ld b, a
-.loop2
-; save B for later use
- push bc
-; send RESET signal (P14=LOW, P15=LOW)
- xor a
- ld [rJOYP], a
-; set P14=HIGH, P15=HIGH
- ld a, $30
- ld [rJOYP], a
-;load length of packets (16 bytes)
- ld b, $10
-.nextByte
-;set bit counter (8 bits per byte)
- ld e, $08
-; get next byte in the packet
- ld a, [hli]
- ld d, a
-.nextBit0
- bit 0, d
-; if 0th bit is not zero set P14=HIGH, P15=LOW (send bit 1)
- ld a, $10
- jr nz, .next0
-; else (if 0th bit is zero) set P14=LOW, P15=HIGH (send bit 0)
- ld a, $20
-.next0
- ld [rJOYP], a
-; must set P14=HIGH, P15=HIGH between each "pulse"
- ld a, $30
- ld [rJOYP], a
-; rotation will put next bit in 0th position (so we can always use command
-; "bit 0, d" to fetch the bit that has to be sent)
- rr d
-; decrease bit counter so we know when we have sent all 8 bits of current byte
- dec e
- jr nz, .nextBit0
- dec b
- jr nz, .nextByte
-; send bit 1 as a "stop bit" (end of parameter data)
- ld a, $20
- ld [rJOYP], a
-; set P14=HIGH, P15=HIGH
- ld a, $30
- ld [rJOYP], a
-; wait for about 70000 cycles
- call Wait7000
-; restore (previously pushed) number of packets
- pop bc
- dec b
-; return if there are no more packets
- ret z
-; else send 16 more bytes
- jr .loop2
-
-LoadSGB:
- xor a
- ld [wOnSGB], a
- call CheckSGB
- jr c, .onSGB
- ld a, [hGBC]
- and a
- jr z, .onDMG
- ld a, $1
- ld [wOnSGB], a
-.onDMG
- ret
-.onSGB
- ld a, $1
- ld [wOnSGB], a
- di
- call PrepareSuperNintendoVRAMTransfer
- ei
- ld a, 1
- ld [wCopyingSGBTileData], a
- ld de, ChrTrnPacket
- ld hl, SGBBorderGraphics
- call CopyGfxToSuperNintendoVRAM
- xor a
- ld [wCopyingSGBTileData], a
- ld de, PctTrnPacket
- ld hl, BorderPalettes
- call CopyGfxToSuperNintendoVRAM
- xor a
- ld [wCopyingSGBTileData], a
- ld de, PalTrnPacket
- ld hl, SuperPalettes
- call CopyGfxToSuperNintendoVRAM
- call ClearVram
- ld hl, MaskEnCancelPacket
- jp SendSGBPacket
-
-PrepareSuperNintendoVRAMTransfer:
- ld hl, .packetPointers
- ld c, 9
-.loop
- push bc
- ld a, [hli]
- push hl
- ld h, [hl]
- ld l, a
- call SendSGBPacket
- pop hl
- inc hl
- pop bc
- dec c
- jr nz, .loop
- ret
-
-.packetPointers
-; Only the first packet is needed.
- dw MaskEnFreezePacket
- dw DataSnd_728a1
- dw DataSnd_728b1
- dw DataSnd_728c1
- dw DataSnd_728d1
- dw DataSnd_728e1
- dw DataSnd_728f1
- dw DataSnd_72901
- dw DataSnd_72911
-
-CheckSGB:
-; Returns whether the game is running on an SGB in carry.
- ld hl, MltReq2Packet
- call SendSGBPacket
- call Wait7000
- ld a, [rJOYP]
- and $3
- cp $3
- jr nz, .isSGB
- ld a, $20
- ld [rJOYP], a
- ld a, [rJOYP]
- ld a, [rJOYP]
- call Wait7000
- call Wait7000
- ld a, $30
- ld [rJOYP], a
- call Wait7000
- call Wait7000
- ld a, $10
- ld [rJOYP], a
- ld a, [rJOYP]
- ld a, [rJOYP]
- ld a, [rJOYP]
- ld a, [rJOYP]
- ld a, [rJOYP]
- ld a, [rJOYP]
- call Wait7000
- call Wait7000
- ld a, $30
- ld [rJOYP], a
- ld a, [rJOYP]
- ld a, [rJOYP]
- ld a, [rJOYP]
- call Wait7000
- call Wait7000
- ld a, [rJOYP]
- and $3
- cp $3
- jr nz, .isSGB
- call SendMltReq1Packet
- and a
- ret
-.isSGB
- call SendMltReq1Packet
- scf
- ret
-
-SendMltReq1Packet:
- ld hl, MltReq1Packet
- call SendSGBPacket
- jp Wait7000
-
-CopyGfxToSuperNintendoVRAM:
- di
- push de
- call DisableLCD
- ld a, $e4
- ld [rBGP], a
- call _UpdateGBCPal_BGP_CheckDMG
- ld de, vChars1
- ld a, [wCopyingSGBTileData]
- and a
- jr z, .notCopyingTileData
- call CopySGBBorderTiles
- jr .next
-.notCopyingTileData
- ld bc, $1000
- call CopyData
-.next
- ld hl, vBGMap0
- ld de, $c
- ld a, $80
- ld c, $d
-.loop
- ld b, $14
-.innerLoop
- ld [hli], a
- inc a
- dec b
- jr nz, .innerLoop
- add hl, de
- dec c
- jr nz, .loop
- ld a, $e3
- ld [rLCDC], a
- pop hl
- call SendSGBPacket
- xor a
- ld [rBGP], a
- call _UpdateGBCPal_BGP_CheckDMG
- ei
- ret
-
-Wait7000:
-; Each loop takes 9 cycles so this routine actually waits 63000 cycles.
- ld de, 7000
-.loop
- nop
- nop
- nop
- dec de
- ld a, d
- or e
- jr nz, .loop
- ret
-
-SendSGBPackets:
- ld a, [hGBC]
- and a
- jr z, .notGBC
- push de
- call InitGBCPalettes
- pop hl
- call InitGBCPalettes
- ld a, [rLCDC]
- and rLCDC_ENABLE_MASK
- ret z
- call Delay3
- ret
-.notGBC
- push de
- call SendSGBPacket
- pop hl
- jp SendSGBPacket
-
-InitGBCPalettes:
- ld a, [hl]
- and $f8
- cp $20
- jp z, TranslatePalPacketToBGMapAttributes
-
- inc hl
-
-index = 0
-
- REPT NUM_ACTIVE_PALS
- IF index > 0
- pop hl
- ENDC
-
- ld a, [hli]
- inc hl
-
- IF index < (NUM_ACTIVE_PALS + -1)
- push hl
- ENDC
-
- call GetGBCBasePalAddress
- ld a, e
- ld [wGBCBasePalPointers + index * 2], a
- ld a, d
- ld [wGBCBasePalPointers + index * 2 + 1], a
-
- xor a ; CONVERT_BGP
- call DMGPalToGBCPal
- ld a, index
- call TransferCurBGPData
-
- ld a, CONVERT_OBP0
- call DMGPalToGBCPal
- ld a, index
- call TransferCurOBPData
-
- ld a, CONVERT_OBP1
- call DMGPalToGBCPal
- ld a, index + 4
- call TransferCurOBPData
-
-index = index + 1
- ENDR
-
- ret
-
-GetGBCBasePalAddress::
-; Input: a = palette ID
-; Output: de = palette address
- push hl
- ld l, a
- xor a
- ld h, a
- add hl, hl
- add hl, hl
- add hl, hl
- ld de, GBCBasePalettes
- add hl, de
- ld a, l
- ld e, a
- ld a, h
- ld d, a
- pop hl
- ret
-
-DMGPalToGBCPal::
-; Populate wGBCPal with colors from a base palette, selected using one of the
-; DMG palette registers.
-; Input:
-; a = which DMG palette register
-; de = address of GBC base palette
- and a
- jr nz, .notBGP
- ld a, [rBGP]
- ld [wLastBGP], a
- jr .convert
-.notBGP
- dec a
- jr nz, .notOBP0
- ld a, [rOBP0]
- ld [wLastOBP0], a
- jr .convert
-.notOBP0
- ld a, [rOBP1]
- ld [wLastOBP1], a
-.convert
-color_index = 0
- REPT NUM_COLORS
- ld b, a
- and %11
- call .GetColorAddress
- ld a, [hli]
- ld [wGBCPal + color_index * 2], a
- ld a, [hl]
- ld [wGBCPal + color_index * 2 + 1], a
-
- IF color_index < (NUM_COLORS + -1)
- ld a, b
- rrca
- rrca
- ENDC
-
-color_index = color_index + 1
- ENDR
- ret
-
-.GetColorAddress:
- add a
- ld l, a
- xor a
- ld h, a
- add hl, de
- ret
-
-TransferCurBGPData::
- push de
- add a
- add a
- add a
- or $80 ; auto-increment
- ld [rBGPI], a
- ld de, rBGPD
- ld hl, wGBCPal
- ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
- ld a, [rLCDC]
- and rLCDC_ENABLE_MASK
- jr nz, .lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDDisabled
- endr
- jr .done
-.lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDEnabled
- endr
-.done
- pop de
- ret
-
-BufferBGPPal::
-; Copy wGBCPal to palette a in wBGPPalsBuffer.
- push de
- add a
- add a
- add a
- ld l, a
- xor a
- ld h, a
- ld de, wBGPPalsBuffer
- add hl, de
- ld de, wGBCPal
- ld c, PAL_SIZE
-.loop
- ld a, [de]
- ld [hli], a
- inc de
- dec c
- jr nz, .loop
- pop de
- ret
-
-TransferBGPPals::
-; Transfer the buffered BG palettes.
- ld a, [rLCDC]
- and rLCDC_ENABLE_MASK
- jr z, .lcdDisabled
- di
-.waitLoop
- ld a, [rLY]
- cp 144
- jr c, .waitLoop
-.lcdDisabled
- call .DoTransfer
- ei
- ret
-
-.DoTransfer:
- xor a
- or $80 ; auto-increment
- ld [rBGPI], a
- ld de, rBGPD
- ld hl, wBGPPalsBuffer
- ld c, 4 * PAL_SIZE
-.loop
- ld a, [hli]
- ld [de], a
- dec c
- jr nz, .loop
- ret
-
-TransferCurOBPData:
- push de
- add a
- add a
- add a
- or $80 ; auto-increment
- ld [rOBPI], a
- ld de, rOBPD
- ld hl, wGBCPal
- ld b, %10 ; mask for non-V-blank/non-H-blank STAT mode
- ld a, [rLCDC]
- and rLCDC_ENABLE_MASK
- jr nz, .lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDDisabled
- endr
- jr .done
-.lcdEnabled
- rept NUM_COLORS
- call TransferPalColorLCDEnabled
- endr
-.done
- pop de
- ret
-
-TransferPalColorLCDEnabled:
-; Transfer a palette color while the LCD is enabled.
-
-; In case we're already in H-blank or V-blank, wait for it to end. This is a
-; precaution so that the transfer doesn't extend past the blanking period.
- ld a, [rSTAT]
- and b
- jr z, TransferPalColorLCDEnabled
-
-; Wait for H-blank or V-blank to begin.
-.notInBlankingPeriod
- ld a, [rSTAT]
- and b
- jr nz, .notInBlankingPeriod
-; fall through
-
-TransferPalColorLCDDisabled:
-; Transfer a palette color while the LCD is disabled.
- ld a, [hli]
- ld [de], a
- ld a, [hli]
- ld [de], a
- ret
-
-_UpdateGBCPal_BGP_CheckDMG::
- ld a, [hGBC]
- and a
- ret z
-; fall through
-
-_UpdateGBCPal_BGP::
-index = 0
-
- REPT NUM_ACTIVE_PALS
- ld a, [wGBCBasePalPointers + index * 2]
- ld e, a
- ld a, [wGBCBasePalPointers + index * 2 + 1]
- ld d, a
- xor a ; CONVERT_BGP
- call DMGPalToGBCPal
- ld a, index
- call BufferBGPPal
-
-index = index + 1
- ENDR
-
- call TransferBGPPals
- ret
-
-_UpdateGBCPal_OBP::
-index = 0
-
- REPT NUM_ACTIVE_PALS
- ld a, [wGBCBasePalPointers + index * 2]
- ld e, a
- ld a, [wGBCBasePalPointers + index * 2 + 1]
- ld d, a
- ld a, c
- call DMGPalToGBCPal
- ld a, c
- dec a
- rlca
- rlca
-
- IF index > 0
- IF index == 1
- inc a
- ELSE
- add index
- ENDC
- ENDC
-
- call TransferCurOBPData
-
-index = index + 1
- ENDR
-
- ret
-
-TranslatePalPacketToBGMapAttributes::
-; translate the SGB pal packets into something usable for the GBC
- push hl
- pop de
- ld hl, PalPacketPointers
- ld a, [hli]
- ld c, a
-.loop
- ld a, e
-.innerLoop
- cp [hl]
- jr z, .checkHighByte
- inc hl
- inc hl
- dec c
- jr nz, .innerLoop
- ret
-.checkHighByte
-; the low byte of pointer matched, so check the high byte
- inc hl
- ld a, d
- cp [hl]
- jr z, .foundMatchingPointer
- inc hl
- dec c
- jr nz, .loop
- ret
-.foundMatchingPointer
- callba LoadBGMapAttributes
- ret
-
-PalPacketPointers::
- db (palPacketPointersEnd - palPacketPointers) / 2
-palPacketPointers
- dw BlkPacket_WholeScreen
- dw BlkPacket_Battle
- dw BlkPacket_StatusScreen
- dw BlkPacket_Pokedex
- dw BlkPacket_Slots
- dw BlkPacket_Titlescreen
- dw BlkPacket_NidorinoIntro
- dw wPartyMenuBlkPacket
- dw wTrainerCardBlkPacket
- dw BlkPacket_GameFreakIntro
- dw wPalPacket
- dw UnknownPacket_72751
-palPacketPointersEnd
-
-CopySGBBorderTiles:
-; SGB tile data is stored in a 4BPP planar format.
-; Each tile is 32 bytes. The first 16 bytes contain bit planes 1 and 2, while
-; the second 16 bytes contain bit planes 3 and 4.
-; This function converts 2BPP planar data into this format by mapping
-; 2BPP colors 0-3 to 4BPP colors 0-3. 4BPP colors 4-15 are not used.
- ld b, 128
-.tileLoop
-; Copy bit planes 1 and 2 of the tile data.
- ld c, 16
-.copyLoop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyLoop
-
-; Zero bit planes 3 and 4.
- ld c, 16
- xor a
-.zeroLoop
- ld [de], a
- inc de
- dec c
- jr nz, .zeroLoop
-
- dec b
- jr nz, .tileLoop
- ret
-
-INCLUDE "data/sgb_packets.asm"
-
-INCLUDE "data/mon_palettes.asm"
-
-INCLUDE "data/super_palettes.asm"
-
-INCLUDE "data/sgb_border.asm"
diff --git a/engine/pathfinding.asm b/engine/pathfinding.asm
deleted file mode 100644
index f3d23b7c..00000000
--- a/engine/pathfinding.asm
+++ /dev/null
@@ -1,201 +0,0 @@
-FindPathToPlayer:
- xor a
- ld hl, hFindPathNumSteps
- ld [hli], a ; hFindPathNumSteps
- ld [hli], a ; hFindPathFlags
- ld [hli], a ; hFindPathYProgress
- ld [hl], a ; hFindPathXProgress
- ld hl, wNPCMovementDirections2
- ld de, $0
-.loop
- ld a, [hFindPathYProgress]
- ld b, a
- ld a, [hNPCPlayerYDistance] ; Y distance in steps
- call CalcDifference
- ld d, a
- and a
- jr nz, .asm_f76a
- ld a, [hFindPathFlags]
- set 0, a ; current end of path matches the player's Y coordinate
- ld [hFindPathFlags], a
-.asm_f76a
- ld a, [hFindPathXProgress]
- ld b, a
- ld a, [hNPCPlayerXDistance] ; X distance in steps
- call CalcDifference
- ld e, a
- and a
- jr nz, .asm_f77c
- ld a, [hFindPathFlags]
- set 1, a ; current end of path matches the player's X coordinate
- ld [hFindPathFlags], a
-.asm_f77c
- ld a, [hFindPathFlags]
- cp $3 ; has the end of the path reached the player's position?
- jr z, .done
-; Compare whether the X distance between the player and the current of the path
-; is greater or if the Y distance is. Then, try to reduce whichever is greater.
- ld a, e
- cp d
- jr c, .yDistanceGreater
-; x distance is greater
- ld a, [hNPCPlayerRelativePosFlags]
- bit 1, a
- jr nz, .playerIsLeftOfNPC
- ld d, NPC_MOVEMENT_RIGHT
- jr .next1
-.playerIsLeftOfNPC
- ld d, NPC_MOVEMENT_LEFT
-.next1
- ld a, [hFindPathXProgress]
- add 1
- ld [hFindPathXProgress], a
- jr .storeDirection
-.yDistanceGreater
- ld a, [hNPCPlayerRelativePosFlags]
- bit 0, a
- jr nz, .playerIsAboveNPC
- ld d, NPC_MOVEMENT_DOWN
- jr .next2
-.playerIsAboveNPC
- ld d, NPC_MOVEMENT_UP
-.next2
- ld a, [hFindPathYProgress]
- add 1
- ld [hFindPathYProgress], a
-.storeDirection
- ld a, d
- ld [hli], a
- ld a, [hFindPathNumSteps]
- inc a
- ld [hFindPathNumSteps], a
- jp .loop
-.done
- ld [hl], $ff
- ret
-
-CalcPositionOfPlayerRelativeToNPC:
- xor a
- ld [hNPCPlayerRelativePosFlags], a
- ld a, [wSpriteStateData1 + 4] ; player's sprite screen Y position in pixels
- ld d, a
- ld a, [wSpriteStateData1 + 6] ; player's sprite screen X position in pixels
- ld e, a
- ld hl, wSpriteStateData1
- ld a, [hNPCSpriteOffset]
- add l
- add $4
- ld l, a
- jr nc, .noCarry
- inc h
-.noCarry
- ld a, d
- ld b, a
- ld a, [hli] ; NPC sprite screen Y position in pixels
- call CalcDifference
- jr nc, .NPCSouthOfOrAlignedWithPlayer
-.NPCNorthOfPlayer
- push hl
- ld hl, hNPCPlayerRelativePosFlags
- bit 0, [hl]
- set 0, [hl]
- pop hl
- jr .divideYDistance
-.NPCSouthOfOrAlignedWithPlayer
- push hl
- ld hl, hNPCPlayerRelativePosFlags
- bit 0, [hl]
- res 0, [hl]
- pop hl
-.divideYDistance
- push hl
- ld hl, hDividend2
- ld [hli], a
- ld a, 16
- ld [hli], a
- call DivideBytes ; divide Y absolute distance by 16
- ld a, [hl] ; quotient
- ld [hNPCPlayerYDistance], a
- pop hl
- inc hl
- ld b, e
- ld a, [hl] ; NPC sprite screen X position in pixels
- call CalcDifference
- jr nc, .NPCEastOfOrAlignedWithPlayer
-.NPCWestOfPlayer
- push hl
- ld hl, hNPCPlayerRelativePosFlags
- bit 1, [hl]
- set 1, [hl]
- pop hl
- jr .divideXDistance
-.NPCEastOfOrAlignedWithPlayer
- push hl
- ld hl, hNPCPlayerRelativePosFlags
- bit 1, [hl]
- res 1, [hl]
- pop hl
-.divideXDistance
- ld [hDividend2], a
- ld a, 16
- ld [hDivisor2], a
- call DivideBytes ; divide X absolute distance by 16
- ld a, [hQuotient2]
- ld [hNPCPlayerXDistance], a
- ld a, [hNPCPlayerRelativePosPerspective]
- and a
- ret z
- ld a, [hNPCPlayerRelativePosFlags]
- cpl
- and $3
- ld [hNPCPlayerRelativePosFlags], a
- ret
-
-ConvertNPCMovementDirectionsToJoypadMasks:
- ld a, [hNPCMovementDirections2Index]
- ld [wNPCMovementDirections2Index], a
- dec a
- ld de, wSimulatedJoypadStatesEnd
- ld hl, wNPCMovementDirections2
- add l
- ld l, a
- jr nc, .loop
- inc h
-.loop
- ld a, [hld]
- call ConvertNPCMovementDirectionToJoypadMask
- ld [de], a
- inc de
- ld a, [hNPCMovementDirections2Index]
- dec a
- ld [hNPCMovementDirections2Index], a
- jr nz, .loop
- ret
-
-ConvertNPCMovementDirectionToJoypadMask:
- push hl
- ld b, a
- ld hl, NPCMovementDirectionsToJoypadMasksTable
-.loop
- ld a, [hli]
- cp $ff
- jr z, .done
- cp b
- jr z, .loadJoypadMask
- inc hl
- jr .loop
-.loadJoypadMask
- ld a, [hl]
-.done
- pop hl
- ret
-
-NPCMovementDirectionsToJoypadMasksTable:
- db NPC_MOVEMENT_UP, D_UP
- db NPC_MOVEMENT_DOWN, D_DOWN
- db NPC_MOVEMENT_LEFT, D_LEFT
- db NPC_MOVEMENT_RIGHT, D_RIGHT
- db $ff
-
-; unreferenced
- ret
diff --git a/engine/pikachu_emotions.asm b/engine/pikachu_emotions.asm
index 1518b28e..55262493 100755
--- a/engine/pikachu_emotions.asm
+++ b/engine/pikachu_emotions.asm
@@ -1,19 +1,19 @@
-IsPlayerTalkingToPikachu:
+IsPlayerTalkingToPikachu::
ld a, [wd436]
and a
ret z
- ld a, [hSpriteIndexOrTextID]
+ ldh a, [hSpriteIndexOrTextID]
cp $f
ret nz
call InitializePikachuTextID
xor a
- ld [hSpriteIndexOrTextID], a
+ ldh [hSpriteIndexOrTextID], a
ld [wd436], a
ret
-InitializePikachuTextID:
- ld a, $d4 ; display
- ld [hSpriteIndexOrTextID], a
+InitializePikachuTextID::
+ ld a, TEXT_PIKACHU_ANIM ; display
+ ldh [hSpriteIndexOrTextID], a
xor a
ld [wPlayerMovingDirection], a
ld a, $1
@@ -92,7 +92,7 @@ StarterPikachuEmotionCommand_pcm:
PlayPikachuSoundClip_:
cp $ff
ret z
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
ret
StarterPikachuEmotionCommand_emote:
@@ -190,7 +190,7 @@ PlaySpecificPikachuEmotion:
ld a, e
jr load_expression
-TalkToPikachu:
+TalkToPikachu::
call MapSpecificPikachuExpression
jr c, load_expression
call GetPikaPicAnimationScriptIndex
@@ -267,7 +267,7 @@ MapSpecificPikachuExpression:
jr .check_pikachu_status
.notPewterPokecenter
- callab Func_f24ae
+ callfar Func_f24ae
ld a, e
cp $ff
jr nz, .play_emotion
@@ -277,7 +277,7 @@ MapSpecificPikachuExpression:
call IsPlayerPikachuAsleepInParty
ldpikaemotion a, PikachuEmotion11
jr c, .play_emotion
- callab CheckPikachuFaintedOrStatused ; same bank
+ callfar CheckPikachuFaintedOrStatused ; same bank
ldpikaemotion a, PikachuEmotion28
jr c, .play_emotion
ld a, [wCurMap]
@@ -327,7 +327,7 @@ IsPlayerPikachuAsleepInParty:
jr z, .done
cp PIKACHU
jr nz, .curMonNotStarterPikachu
- callab IsThisPartymonStarterPikachu
+ callfar IsThisPartymonStarterPikachu
jr nc, .curMonNotStarterPikachu
ld a, [wWhichPokemon]
ld hl, wPartyMon1Status
@@ -358,7 +358,7 @@ INCLUDE "data/pikachu_emotions.asm"
PikachuWalksToNurseJoy:
ld a, $40
- ld [h_0xFFFC], a
+ ldh [hFFFC], a
call LoadPikachuSpriteIntoVRAM
call .GetMovementData
and a
@@ -366,7 +366,7 @@ PikachuWalksToNurseJoy:
call ApplyPikachuMovementData
.skip
xor a
- ld [h_0xFFFC], a
+ ldh [hFFFC], a
ret
.GetMovementData:
diff --git a/engine/pikachu_follow.asm b/engine/pikachu_follow.asm
index d9dc91df..fd2fbc47 100755
--- a/engine/pikachu_follow.asm
+++ b/engine/pikachu_follow.asm
@@ -457,7 +457,7 @@ Func_fc76a:
call Func_fc82e
jr c, .skip
push bc
- callab InitializeSpriteScreenPosition
+ callfar InitializeSpriteScreenPosition
pop bc
.skip
ld hl, wSpritePikachuStateData1MovementStatus - wSpritePikachuStateData1
@@ -472,7 +472,7 @@ Func_fc76a:
Func_fc793:
call RefreshPikachuFollow
push bc
- callab InitializeSpriteScreenPosition
+ callfar InitializeSpriteScreenPosition
pop bc
ld hl, wSpritePikachuStateData1ImageIndex - wSpritePikachuStateData1
add hl, bc
@@ -583,7 +583,7 @@ Func_fc842:
ld hl, $0
push af
call Random
- ld a, [hRandomAdd]
+ ldh a, [hRandomAdd]
and %11
ld e, a
ld d, $0
@@ -1107,7 +1107,7 @@ IsPikachuRightNextToPlayer:
xor a
ret
-GetPikachuFacingDirectionAndReturnToE:
+GetPikachuFacingDirectionAndReturnToE::
call GetPikachuFacingDirection
ld e, a
ret
@@ -1475,7 +1475,7 @@ AreThereAtLeastTwoStepsInPikachuFollowCommandBuffer:
WillPikachuSpawnOnTheScreen:
ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET] ; If we're here, this can only be $f0
+ ldh a, [hCurrentSpriteOffset] ; If we're here, this can only be $f0
add wSpritePikachuStateData2MapY - wSpritePikachuStateData2
ld l, a
ld b, [hl]
@@ -1516,7 +1516,7 @@ WillPikachuSpawnOnTheScreen:
jr c, .on_screen
.not_on_screen
ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add wSpritePikachuStateData1ImageIndex - wSpritePikachuStateData1
ld l, a
ld [hl], $ff
@@ -1525,7 +1525,7 @@ WillPikachuSpawnOnTheScreen:
.on_screen
ld h, wSpriteStateData2 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add wSpritePikachuStateData2GrassPriority - wSpritePikachuStateData2
ld l, a
ld a, [wGrassTile]
@@ -1541,7 +1541,7 @@ WillPikachuSpawnOnTheScreen:
.GetNPCCurrentTile:
ld h, wSpriteStateData1 / $100
- ld a, [H_CURRENTSPRITEOFFSET]
+ ldh a, [hCurrentSpriteOffset]
add wSpritePikachuStateData1YPixels - wSpritePikachuStateData1
ld l, a
ld a, [hli]
diff --git a/engine/pikachu_movement.asm b/engine/pikachu_movement.asm
index 938715a4..2d87e947 100755
--- a/engine/pikachu_movement.asm
+++ b/engine/pikachu_movement.asm
@@ -914,14 +914,14 @@ LoadPikachuShadowOAMData:
jr nz, .loop
ret
-LoadPikachuShadowIntoVRAM:
+LoadPikachuShadowIntoVRAM::
ld hl, vNPCSprites2 + $7f * $10
ld de, LedgeHoppingShadowGFX_3F
lb bc, BANK(LedgeHoppingShadowGFX_3F), (LedgeHoppingShadowGFX_3FEnd - LedgeHoppingShadowGFX_3F) / 8
jp CopyVideoDataDoubleAlternate
LedgeHoppingShadowGFX_3F:
-INCBIN "gfx/ledge_hopping_shadow.1bpp"
+INCBIN "gfx/overworld/shadow.1bpp"
LedgeHoppingShadowGFX_3FEnd:
LoadPikachuBallIconIntoVRAM:
@@ -958,7 +958,7 @@ LoadPikachuSpriteIntoVRAM:
call CopyVideoDataAlternate
ld de, PikachuSprite + $c * $10
ld hl, vNPCSprites2 + $c * $10
- ld a, [h_0xFFFC]
+ ldh a, [hFFFC]
and a
jr z, .load
ld de, PikachuSprite + $c * $10
@@ -1006,7 +1006,7 @@ Cosine_e: ; cosine?
Sine_e: ; sine?
ld a, e
-asm_fd908
+asm_fd908:
and $3f
cp $20
jr nc, .asm_fd913
diff --git a/engine/pikachu_pcm.asm b/engine/pikachu_pcm.asm
index 1e6f8dc2..bf1aa57f 100755
--- a/engine/pikachu_pcm.asm
+++ b/engine/pikachu_pcm.asm
@@ -23,12 +23,12 @@ PlayPikachuSoundClip::
push bc
push hl
ld a, $80
- ld [rNR52], a
+ ldh [rNR52], a
ld a, $77
- ld [rNR50], a
+ ldh [rNR50], a
xor a
- ld [rNR30], a
- ld hl, $ff30 ; wave data
+ ldh [rNR30], a
+ ld hl, rWave_0 ; wave data
ld de, wRedrawRowOrColumnSrcTiles
.saveWaveDataLoop
ld a, [hl]
@@ -40,18 +40,18 @@ PlayPikachuSoundClip::
cp $40 ; end of wave data
jr nz, .saveWaveDataLoop
ld a, $80
- ld [rNR30], a
- ld a, [rNR51]
+ ldh [rNR30], a
+ ldh a, [rNR51]
or $44
- ld [rNR51], a
+ ldh [rNR51], a
ld a, $ff
- ld [rNR31], a
+ ldh [rNR31], a
ld a, $20
- ld [rNR32], a
+ ldh [rNR32], a
ld a, $ff
- ld [rNR33], a
+ ldh [rNR33], a
ld a, $87
- ld [rNR34], a
+ ldh [rNR34], a
pop hl
pop bc
call PlayPikachuPCM
@@ -59,10 +59,10 @@ PlayPikachuSoundClip::
ld [wc0f3], a
ld [wc0f4], a
ld a, $80
- ld [rNR52], a
+ ldh [rNR52], a
xor a
- ld [rNR30], a
- ld hl, $ff30
+ ldh [rNR30], a
+ ld hl, rWave_0
ld de, wRedrawRowOrColumnSrcTiles
.reloadWaveDataLoop
ld a, [de]
@@ -72,20 +72,20 @@ PlayPikachuSoundClip::
cp $40 ; end of wave data
jr nz, .reloadWaveDataLoop
ld a, $80
- ld [rNR30], a
- ld a, [rNR51]
+ ldh [rNR30], a
+ ldh a, [rNR51]
and $bb
- ld [rNR51], a
+ ldh [rNR51], a
xor a
ld [wChannelSoundIDs + Ch5], a
ld [wChannelSoundIDs + Ch6], a
ld [wChannelSoundIDs + Ch7], a
ld [wChannelSoundIDs + Ch8], a
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
ei
ret
-PikachuCriesPointerTable:
+PikachuCriesPointerTable::
; format:
; db bank
; dw pointer to cry
diff --git a/engine/pikachu_pic_animation.asm b/engine/pikachu_pic_animation.asm
index c79d9add..7829c048 100755
--- a/engine/pikachu_pic_animation.asm
+++ b/engine/pikachu_pic_animation.asm
@@ -88,10 +88,10 @@ PikaPicAnimationScriptPointerLookupTable:
dpikapic PikaPicAnimScript20
StarterPikachuEmotionCommand_pikapic:
- ld a, [H_AUTOBGTRANSFERENABLED]
+ ldh a, [hAutoBGTransferEnabled]
push af
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, [de]
ld [wPikaPicAnimNumber], a
inc de
@@ -99,12 +99,12 @@ StarterPikachuEmotionCommand_pikapic:
call .RunPikapic
pop de
pop af
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
.RunPikapic:
call PlacePikapicTextBoxBorder
- callab LoadOverworldPikachuFrontpicPalettes
+ callfar LoadOverworldPikachuFrontpicPalettes
call ResetPikaPicAnimBuffer
call LoadCurrentPikaPicAnimScriptPointer
call ExecutePikaPicAnimScript
@@ -135,14 +135,14 @@ ResetPikaPicAnimBuffer:
PlacePikapicTextBoxBorder:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 6, 5
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 6, 5
lb bc, 5, 5
call TextBoxBorder
call Delay3
call UpdateSprites
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
ret
@@ -202,13 +202,13 @@ endm
ExecutePikaPicAnimScript:
.loop
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call RunPikaPicAnimSetupScript
call DummyFunction_fdad5
call AnimateCurrentPikaPicAnimFrame
call DummyFunction_fdad5
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PikaPicAnimTimerAndJoypad
and a
jr z, .loop
@@ -220,7 +220,7 @@ PikaPicAnimTimerAndJoypad:
and a
ret nz
call JoypadLowSensitivity
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and A_BUTTON | B_BUTTON
ret
@@ -460,7 +460,7 @@ LoadCurPikaPicObjectTilemap:
ld b, a
ld a, [wPikaPicPikaDrawStartY]
add b
- coord hl, 0, 0
+ hlcoord 0, 0
ld bc, SCREEN_WIDTH
call AddNTimes
ld a, [wCurPikaPicAnimObjectXOffset] ; X offset
@@ -611,14 +611,14 @@ PikaPicAnimCommand_loadgfx:
push af
ld a, $ff
ld [wUpdateSpritesEnabled], a
- ld a, [H_AUTOBGTRANSFERENABLED]
+ ldh a, [hAutoBGTransferEnabled]
push af
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld a, [hTilesetType]
+ ldh [hAutoBGTransferEnabled], a
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
call GetPikaPicAnimByte
ld [wPikaPicAnimCurGraphicID], a
ld a, [wPikaPicAnimCurGraphicID]
@@ -633,9 +633,9 @@ PikaPicAnimCommand_loadgfx:
call DecompressRequestPikaPicAnimGFX
.done
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
pop af
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
pop af
ld [wUpdateSpritesEnabled], a
ret
@@ -783,7 +783,7 @@ PikaPicAnimCommand_cry:
cp $ff
ret z
ld e, a
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
ret
PikaPicAnimCommand_thunderbolt:
@@ -843,7 +843,7 @@ PikaPicAnimCommand_thunderbolt:
.UpdatePal:
ld a, b
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
call DelayFrames
ret
diff --git a/engine/pokedex_rating.asm b/engine/pokedex_rating.asm
deleted file mode 100755
index 4dfb6b39..00000000
--- a/engine/pokedex_rating.asm
+++ /dev/null
@@ -1,154 +0,0 @@
-DisplayDexRating:
- ld hl, wPokedexSeen
- ld b, wPokedexSeenEnd - wPokedexSeen
- call CountSetBits
- ld a, [wNumSetBits]
- ld [hDexRatingNumMonsSeen], a
- ld hl, wPokedexOwned
- ld b, wPokedexOwnedEnd - wPokedexOwned
- call CountSetBits
- ld a, [wNumSetBits]
- ld [hDexRatingNumMonsOwned], a
- ld hl, DexRatingsTable
-.findRating
- ld a, [hli]
- ld b, a
- ld a, [hDexRatingNumMonsOwned]
- cp b
- jr c, .foundRating
- inc hl
- inc hl
- jr .findRating
-.foundRating
- ld a, [hli]
- ld h, [hl]
- ld l, a ; load text pointer into hl
- CheckAndResetEventA EVENT_HALL_OF_FAME_DEX_RATING
- jr nz, .hallOfFame
- push hl
- ld hl, DexCompletionText
- call PrintText
- pop hl
- call PrintText
- callba PlayPokedexRatingSfx
- jp WaitForTextScrollButtonPress
-.hallOfFame
- ld de, wDexRatingNumMonsSeen
- ld a, [hDexRatingNumMonsSeen]
- ld [de], a
- inc de
- ld a, [hDexRatingNumMonsOwned]
- ld [de], a
- inc de
-.copyRatingTextLoop
- ld a, [hli]
- cp "@"
- jr z, .doneCopying
- ld [de], a
- inc de
- jr .copyRatingTextLoop
-.doneCopying
- ld [de], a
- ret
-
-DexCompletionText:
- TX_FAR _DexCompletionText
- db "@"
-
-DexRatingsTable:
- db 10
- dw DexRatingText_Own0To9
- db 20
- dw DexRatingText_Own10To19
- db 30
- dw DexRatingText_Own20To29
- db 40
- dw DexRatingText_Own30To39
- db 50
- dw DexRatingText_Own40To49
- db 60
- dw DexRatingText_Own50To59
- db 70
- dw DexRatingText_Own60To69
- db 80
- dw DexRatingText_Own70To79
- db 90
- dw DexRatingText_Own80To89
- db 100
- dw DexRatingText_Own90To99
- db 110
- dw DexRatingText_Own100To109
- db 120
- dw DexRatingText_Own110To119
- db 130
- dw DexRatingText_Own120To129
- db 140
- dw DexRatingText_Own130To139
- db 150
- dw DexRatingText_Own140To149
- db NUM_POKEMON + 1
- dw DexRatingText_Own150To151
-
-DexRatingText_Own0To9:
- TX_FAR _DexRatingText_Own0To9
- db "@"
-
-DexRatingText_Own10To19:
- TX_FAR _DexRatingText_Own10To19
- db "@"
-
-DexRatingText_Own20To29:
- TX_FAR _DexRatingText_Own20To29
- db "@"
-
-DexRatingText_Own30To39:
- TX_FAR _DexRatingText_Own30To39
- db "@"
-
-DexRatingText_Own40To49:
- TX_FAR _DexRatingText_Own40To49
- db "@"
-
-DexRatingText_Own50To59:
- TX_FAR _DexRatingText_Own50To59
- db "@"
-
-DexRatingText_Own60To69:
- TX_FAR _DexRatingText_Own60To69
- db "@"
-
-DexRatingText_Own70To79:
- TX_FAR _DexRatingText_Own70To79
- db "@"
-
-DexRatingText_Own80To89:
- TX_FAR _DexRatingText_Own80To89
- db "@"
-
-DexRatingText_Own90To99:
- TX_FAR _DexRatingText_Own90To99
- db "@"
-
-DexRatingText_Own100To109:
- TX_FAR _DexRatingText_Own100To109
- db "@"
-
-DexRatingText_Own110To119:
- TX_FAR _DexRatingText_Own110To119
- db "@"
-
-DexRatingText_Own120To129:
- TX_FAR _DexRatingText_Own120To129
- db "@"
-
-DexRatingText_Own130To139:
- TX_FAR _DexRatingText_Own130To139
- db "@"
-
-DexRatingText_Own140To149:
- TX_FAR _DexRatingText_Own140To149
- db "@"
-
-DexRatingText_Own150To151:
- TX_FAR _DexRatingText_Own150To151
- db "@"
diff --git a/engine/add_mon.asm b/engine/pokemon/add_mon.asm
index 40b776d4..d3d08e99 100644
--- a/engine/add_mon.asm
+++ b/engine/pokemon/add_mon.asm
@@ -1,4 +1,4 @@
-_AddPartyMon:
+_AddPartyMon::
; Adds a new mon to the player's or enemy's party.
; [wMonDataLocation] is used in an unusual way in this function.
; If the lower nybble is 0, the mon is added to the player's party, else the enemy's.
@@ -15,7 +15,7 @@ _AddPartyMon:
ret nc ; return if the party is already full
ld [de], a
ld a, [de]
- ld [hNewPartyLength], a
+ ldh [hNewPartyLength], a
add e
ld e, a
jr nc, .noCarry
@@ -32,7 +32,7 @@ _AddPartyMon:
jr z, .next2
ld hl, wEnemyMonOT
.next2
- ld a, [hNewPartyLength]
+ ldh a, [hNewPartyLength]
dec a
call SkipFixedLengthTextEntries
ld d, h
@@ -44,7 +44,7 @@ _AddPartyMon:
and a
jr nz, .skipNaming
ld hl, wPartyMonNicks
- ld a, [hNewPartyLength]
+ ldh a, [hNewPartyLength]
dec a
call SkipFixedLengthTextEntries
ld a, NAME_MON_SCREEN
@@ -57,7 +57,7 @@ _AddPartyMon:
jr z, .next3
ld hl, wEnemyMons
.next3
- ld a, [hNewPartyLength]
+ ldh a, [hNewPartyLength]
dec a
ld bc, wPartyMon2 - wPartyMon1
call AddNTimes
@@ -75,8 +75,8 @@ _AddPartyMon:
push hl
ld a, [wMonDataLocation]
and $f
- ld a, $98 ; set enemy trainer mon IVs to fixed average values
- ld b, $88
+ ld a, ATKDEFDV_TRAINER ; set enemy trainer mon IVs to fixed average values
+ ld b, SPDSPCDV_TRAINER
jr nz, .next4
; If the mon is being added to the player's party, update the pokedex.
@@ -129,10 +129,10 @@ _AddPartyMon:
xor a
ld b, a
call CalcStat ; calc HP stat (set cur Hp to max HP)
- ld a, [H_MULTIPLICAND+1]
+ ldh a, [hMultiplicand+1]
ld [de], a
inc de
- ld a, [H_MULTIPLICAND+2]
+ ldh a, [hMultiplicand+2]
ld [de], a
inc de
xor a
@@ -207,16 +207,16 @@ _AddPartyMon:
push de
ld a, [wCurEnemyLVL]
ld d, a
- callab CalcExperience
+ callfar CalcExperience
pop de
inc de
- ld a, [hExperience] ; write experience
+ ldh a, [hExperience] ; write experience
ld [de], a
inc de
- ld a, [hExperience + 1]
+ ldh a, [hExperience + 1]
ld [de], a
inc de
- ld a, [hExperience + 2]
+ ldh a, [hExperience + 2]
ld [de], a
xor a
ld b, NUM_STATS * 2
@@ -283,7 +283,7 @@ AddPartyMon_WriteMovePP:
; adds enemy mon [wcf91] (at position [wWhichPokemon] in enemy list) to own party
; used in the cable club trade center
-_AddEnemyMonToPlayerParty:
+_AddEnemyMonToPlayerParty::
ld hl, wPartyCount
ld a, [hl]
cp PARTY_LENGTH
@@ -344,7 +344,7 @@ _AddEnemyMonToPlayerParty:
and a
ret ; return success
-_MoveMon:
+_MoveMon::
ld a, [wMoveMonType]
and a ; BOX_TO_PARTY
jr z, .checkPartyMonSlots
@@ -504,7 +504,7 @@ _MoveMon:
add $2
ld [wMonDataLocation], a
call LoadMonData
- callba CalcLevelFromExperience
+ farcall CalcLevelFromExperience
ld a, d
ld [wCurEnemyLVL], a
pop hl
diff --git a/engine/menu/bills_pc.asm b/engine/pokemon/bills_pc.asm
index 41626310..cc7864f2 100644
--- a/engine/menu/bills_pc.asm
+++ b/engine/pokemon/bills_pc.asm
@@ -1,6 +1,6 @@
DisplayPCMainMenu::
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call SaveScreenTilesToBuffer2
ld a, [wNumHoFTeams]
and a
@@ -10,15 +10,15 @@ DisplayPCMainMenu::
ld a, [wNumHoFTeams]
and a
jr nz, .leaguePCAvailable
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 8, 14
jr .next
.noOaksPC
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 6, 14
jr .next
.leaguePCAvailable
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 10, 14
.next
call TextBoxBorder
@@ -27,15 +27,15 @@ DisplayPCMainMenu::
ld [wMaxMenuItem], a
CheckEvent EVENT_MET_BILL
jr nz, .metBill
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, SomeonesPCText
jr .next2
.metBill
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, BillsPCText
.next2
call PlaceString
- coord hl, 2, 4
+ hlcoord 2, 4
ld de, wPlayerName
call PlaceString
ld l, c
@@ -44,7 +44,7 @@ DisplayPCMainMenu::
call PlaceString
CheckEvent EVENT_GOT_POKEDEX
jr z, .noOaksPC2
- coord hl, 2, 6
+ hlcoord 2, 6
ld de, OaksPCText
call PlaceString
ld a, [wNumHoFTeams]
@@ -52,20 +52,20 @@ DisplayPCMainMenu::
jr z, .noLeaguePC
ld a, 4
ld [wMaxMenuItem], a
- coord hl, 2, 8
+ hlcoord 2, 8
ld de, PKMNLeaguePCText
call PlaceString
- coord hl, 2, 10
+ hlcoord 2, 10
ld de, LogOffPCText
jr .next3
.noLeaguePC
- coord hl, 2, 8
+ hlcoord 2, 8
ld de, LogOffPCText
jr .next3
.noOaksPC2
ld a, $2
ld [wMaxMenuItem], a
- coord hl, 2, 6
+ hlcoord 2, 6
ld de, LogOffPCText
.next3
call PlaceString
@@ -79,14 +79,14 @@ DisplayPCMainMenu::
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], 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@"
+PKMNLeaguePCText: db "<PKMN>LEAGUE@"
LogOffPCText: db "LOG OFF@"
BillsPC_::
@@ -111,19 +111,19 @@ BillsPC_::
BillsPCMenu:
ld a, [wParentMenuItem]
ld [wCurrentMenuItem], a
- ld hl, vChars2 + $780
+ ld hl, vChars2 tile $78
ld de, PokeballTileGraphics
- lb bc, BANK(PokeballTileGraphics), $01
+ lb bc, BANK(PokeballTileGraphics), 1
call CopyVideoData
call LoadScreenTilesFromBuffer2DisableBGTransfer
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call TextBoxBorder
- coord hl, 0, 0
+ hlcoord 0, 0
lb bc, 12, 12
call TextBoxBorder
call UpdateSprites
- coord hl, 2, 2
+ hlcoord 2, 2
ld de, BillsPCMenuText
call PlaceString
ld hl, wTopMenuItemY
@@ -144,7 +144,7 @@ BillsPCMenu:
ld [hli], a ; wListScrollOffset
ld [hl], a ; wMenuWatchMovingOutOfBounds
ld [wPlayerMonNumber], a
- coord hl, 9, 14
+ hlcoord 9, 14
lb bc, 2, 9
call TextBoxBorder
ld a, [wCurrentBoxNum]
@@ -153,19 +153,19 @@ BillsPCMenu:
jr c, .singleDigitBoxNum
; two digit box num
sub 9
- coord hl, 17, 16
+ hlcoord 17, 16
ld [hl], "1"
add "0"
jr .next
.singleDigitBoxNum
add "1"
.next
- Coorda 18, 16
- coord hl, 10, 16
+ ldcoord_a 18, 16
+ hlcoord 10, 16
ld de, BoxNoPCText
call PlaceString
ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call HandleMenuInput
bit 1, a
@@ -204,7 +204,7 @@ ExitBillsPC:
ret
BillsPCPrintBox:
- callab PrintPCBox
+ callfar PrintPCBox
jp BillsPCMenu
BillsPCDeposit:
@@ -225,7 +225,7 @@ BillsPCDeposit:
ld hl, wPartyCount
call DisplayMonListMenu
jp c, BillsPCMenu
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .asm_215ad
call CheckPikachuFollowingPlayer
jr z, .asm_215ad
@@ -235,10 +235,10 @@ BillsPCDeposit:
.asm_215ad
call DisplayDepositWithdrawMenu
jp nc, BillsPCMenu
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .asm_215c9
ld e, $1b
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .asm_215cf
.asm_215c9
ld a, [wcf91]
@@ -272,8 +272,8 @@ BillsPCDeposit:
jp BillsPCMenu
SleepingPikachuText2:
- TX_FAR _SleepingPikachuText2
- db "@"
+ text_far _SleepingPikachuText2
+ text_end
BillsPCWithdraw:
ld a, [wNumInBox]
@@ -298,10 +298,10 @@ BillsPCWithdraw:
ld a, [wWhichPokemon]
ld hl, wBoxMonNicks
call GetPartyMonName
- callab IsThisPartymonStarterPikachu_Box
+ callfar IsThisPartymonStarterPikachu_Box
jr nc, .asm_21660
ld e, $22
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .asm_21666
.asm_21660
ld a, [wcf91]
@@ -329,7 +329,7 @@ BillsPCRelease:
ld hl, wNumInBox
call DisplayMonListMenu
jp c, BillsPCMenu
- callab IsThisPartymonStarterPikachu_Box
+ callfar IsThisPartymonStarterPikachu_Box
jr c, .asm_216cb
ld hl, OnceReleasedText
call PrintText
@@ -352,13 +352,13 @@ BillsPCRelease:
ld hl, wBoxMonNicks
call GetPartyMonName
ld e, $27
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
ld hl, PikachuUnhappyText
call PrintText
jp BillsPCMenu
BillsPCChangeBox:
- callba ChangeBox
+ farcall ChangeBox
jp BillsPCMenu
DisplayMonListMenu:
@@ -379,9 +379,9 @@ DisplayMonListMenu:
ret
BillsPCMenuText:
- db "WITHDRAW ", $4a
- next "DEPOSIT ", $4a
- next "RELEASE ", $4a
+ db "WITHDRAW <PKMN>"
+ next "DEPOSIT <PKMN>"
+ next "RELEASE <PKMN>"
next "CHANGE BOX"
next "PRINT BOX"
next "SEE YA!"
@@ -418,15 +418,10 @@ KnowsHMMove::
ret
HMMoveArray:
- db CUT
- db FLY
- db SURF
- db STRENGTH
- db FLASH
- db -1
+INCLUDE "data/moves/hm_moves.asm"
DisplayDepositWithdrawMenu:
- coord hl, 9, 10
+ hlcoord 9, 10
lb bc, 6, 9
call TextBoxBorder
ld a, [wParentMenuItem]
@@ -435,9 +430,9 @@ DisplayDepositWithdrawMenu:
jr nz, .next
ld de, WithdrawPCText
.next
- coord hl, 11, 12
+ hlcoord 11, 12
call PlaceString
- coord hl, 11, 14
+ hlcoord 11, 14
ld de, StatsCancelPCText
call PlaceString
ld hl, wTopMenuItemY
@@ -498,62 +493,62 @@ StatsCancelPCText:
next "CANCEL@"
SwitchOnText:
- TX_FAR _SwitchOnText
- db "@"
+ text_far _SwitchOnText
+ text_end
WhatText:
- TX_FAR _WhatText
- db "@"
+ text_far _WhatText
+ text_end
DepositWhichMonText:
- TX_FAR _DepositWhichMonText
- db "@"
+ text_far _DepositWhichMonText
+ text_end
MonWasStoredText:
- TX_FAR _MonWasStoredText
- db "@"
+ text_far _MonWasStoredText
+ text_end
CantDepositLastMonText:
- TX_FAR _CantDepositLastMonText
- db "@"
+ text_far _CantDepositLastMonText
+ text_end
BoxFullText:
- TX_FAR _BoxFullText
- db "@"
+ text_far _BoxFullText
+ text_end
MonIsTakenOutText:
- TX_FAR _MonIsTakenOutText
- db "@"
+ text_far _MonIsTakenOutText
+ text_end
NoMonText:
- TX_FAR _NoMonText
- db "@"
+ text_far _NoMonText
+ text_end
CantTakeMonText:
- TX_FAR _CantTakeMonText
- db "@"
+ text_far _CantTakeMonText
+ text_end
PikachuUnhappyText:
- TX_FAR _PikachuUnhappyText
- db "@"
+ text_far _PikachuUnhappyText
+ text_end
ReleaseWhichMonText:
- TX_FAR _ReleaseWhichMonText
- db "@"
+ text_far _ReleaseWhichMonText
+ text_end
OnceReleasedText:
- TX_FAR _OnceReleasedText
- db "@"
+ text_far _OnceReleasedText
+ text_end
MonWasReleasedText:
- TX_FAR _MonWasReleasedText
- db "@"
+ text_far _MonWasReleasedText
+ text_end
CableClubLeftGameboy::
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_EXTERNAL_CLOCK
ret z
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
cp SPRITE_FACING_RIGHT
ret nz
ld a, [wCurMap]
@@ -567,10 +562,10 @@ CableClubLeftGameboy::
tx_pre_jump JustAMomentText
CableClubRightGameboy::
- ld a, [hSerialConnectionStatus]
+ ldh a, [hSerialConnectionStatus]
cp USING_INTERNAL_CLOCK
ret z
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
cp SPRITE_FACING_LEFT
ret nz
ld a, [wCurMap]
@@ -584,15 +579,15 @@ CableClubRightGameboy::
tx_pre_jump JustAMomentText
JustAMomentText::
- TX_FAR _JustAMomentText
- db "@"
+ text_far _JustAMomentText
+ text_end
- ld a, [wSpritePlayerStateData1FacingDirection] ; player's sprite facing direction
+ ld a, [wSpritePlayerStateData1FacingDirection]
cp SPRITE_FACING_UP
ret nz
call EnableAutoTextBoxDrawing
tx_pre_jump OpenBillsPCText
OpenBillsPCText::
- TX_BILLS_PC
+ script_bills_pc
diff --git a/engine/pokemon/evos_moves.asm b/engine/pokemon/evos_moves.asm
new file mode 100755
index 00000000..4e48fe30
--- /dev/null
+++ b/engine/pokemon/evos_moves.asm
@@ -0,0 +1,668 @@
+; try to evolve the mon in [wWhichPokemon]
+TryEvolvingMon:
+EvolveTradeMon:
+ ld hl, wCanEvolveFlags
+ xor a
+ ld [hl], a
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, FLAG_SET
+ call Evolution_FlagAction
+
+; this is only called after battle
+; it is supposed to do level up evolutions, though there is a bug that allows item evolutions to occur
+EvolutionAfterBattle:
+ ldh a, [hTilesetType]
+ push af
+ xor a
+ ld [wEvolutionOccurred], a
+ dec a
+ ld [wWhichPokemon], a
+ push hl
+ push bc
+ push de
+ ld hl, wPartyCount
+ push hl
+
+Evolution_PartyMonLoop: ; loop over party mons
+ ld hl, wWhichPokemon
+ inc [hl]
+ pop hl
+ inc hl
+ ld a, [hl]
+ cp $ff ; have we reached the end of the party?
+ jp z, .done
+ ld [wEvoOldSpecies], a
+ push hl
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld hl, wCanEvolveFlags
+ ld b, FLAG_TEST
+ call Evolution_FlagAction
+ ld a, c
+ and a ; is the mon's bit set?
+ jp z, Evolution_PartyMonLoop ; if not, go to the next mon
+ ld a, [wEvoOldSpecies]
+ dec a
+ ld b, 0
+ ld hl, EvosMovesPointerTable
+ add a
+ rl b
+ ld c, a
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+ ld a, [wcf91]
+ push af
+ xor a ; PLAYER_PARTY_DATA
+ ld [wMonDataLocation], a
+ call LoadMonData
+ pop af
+ ld [wcf91], a
+ pop hl
+
+.evoEntryLoop ; loop over evolution entries
+ ld a, [hli]
+ and a ; have we reached the end of the evolution data?
+ jr z, Evolution_PartyMonLoop
+ ld b, a ; evolution type
+ cp EV_TRADE
+ jr z, .checkTradeEvo
+; not trade evolution
+ ld a, [wLinkState]
+ cp LINK_STATE_TRADING
+ jr z, Evolution_PartyMonLoop ; if trading, go the next mon
+ ld a, b
+ cp EV_ITEM
+ jr z, .checkItemEvo
+ ld a, [wForceEvolution]
+ and a
+ jr nz, Evolution_PartyMonLoop
+ ld a, b
+ cp EV_LEVEL
+ jr z, .checkLevel
+.checkTradeEvo
+ ld a, [wLinkState]
+ cp LINK_STATE_TRADING
+ jp nz, .nextEvoEntry1 ; if not trading, go to the next evolution entry
+ ld a, [hli] ; level requirement
+ ld b, a
+ ld a, [wLoadedMonLevel]
+ cp b ; is the mon's level greater than the evolution requirement?
+ jp c, Evolution_PartyMonLoop ; if so, go the next mon
+ jr .doEvolution
+.checkItemEvo
+ ld a, [wIsInBattle] ; are we in battle?
+ and a
+ ld a, [hli]
+ jp nz, .nextEvoEntry1 ; don't evolve if we're in a battle as wcf91 could be holding the last mon sent out
+
+ ld b, a ; evolution item
+ ld a, [wcf91] ; last item used
+ cp b ; was the evolution item in this entry used?
+ jp nz, .nextEvoEntry1 ; if not, go to the next evolution entry
+.checkLevel
+ ld a, [hli] ; level requirement
+ ld b, a
+ ld a, [wLoadedMonLevel]
+ cp b ; is the mon's level greater than the evolution requirement?
+ jp c, .nextEvoEntry2 ; if so, go the next evolution entry
+.doEvolution
+ ld [wCurEnemyLVL], a
+ ld a, 1
+ ld [wEvolutionOccurred], a
+ push hl
+ ld a, [hl]
+ ld [wEvoNewSpecies], a
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMonNicks
+ call GetPartyMonName
+ call CopyStringToCF4B
+ ld hl, IsEvolvingText
+ call PrintText
+ ld c, 50
+ call DelayFrames
+ xor a
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 0, 0
+ lb bc, 12, 20
+ call ClearScreenArea
+ ld a, $1
+ ldh [hAutoBGTransferEnabled], a
+ ld a, $ff
+ ld [wUpdateSpritesEnabled], a
+ call ClearSprites
+ callfar EvolveMon
+ jp c, CancelledEvolution
+ ld hl, EvolvedText
+ call PrintText
+ pop hl
+ ld a, [hl]
+ ld [wd0b5], a
+ ld [wLoadedMonSpecies], a
+ ld [wEvoNewSpecies], a
+ ld a, MONSTER_NAME
+ ld [wNameListType], a
+ ld a, BANK(MonsterNames) ; bank is not used for monster names
+ ld [wPredefBank], a
+ call GetName
+ push hl
+ ld hl, IntoText
+ call PrintText_NoCreatingTextBox
+ ld a, SFX_GET_ITEM_2
+ call PlaySoundWaitForCurrent
+ call WaitForSoundToFinish
+ ld c, 40
+ call DelayFrames
+ call ClearScreen
+ call RenameEvolvedMon
+ ld a, [wd11e]
+ push af
+ ld a, [wd0b5]
+ ld [wd11e], a
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld hl, BaseStats
+ ld bc, MonBaseStatsEnd - MonBaseStats
+ call AddNTimes
+ ld de, wMonHeader
+ call CopyData
+ ld a, [wd0b5]
+ ld [wMonHIndex], a
+ pop af
+ ld [wd11e], a
+ ld hl, wLoadedMonHPExp - 1
+ ld de, wLoadedMonStats
+ ld b, $1
+ call CalcStats
+ ld a, [wWhichPokemon]
+ ld hl, wPartyMon1
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+ ld e, l
+ ld d, h
+ push hl
+ push bc
+ ld bc, wPartyMon1MaxHP - wPartyMon1
+ add hl, bc
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, wLoadedMonMaxHP + 1
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a
+ ld hl, wLoadedMonHP + 1
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ dec hl
+ pop bc
+ call CopyData
+ ld a, [wd0b5]
+ ld [wd11e], a
+ xor a
+ ld [wMonDataLocation], a
+ call LearnMoveFromLevelUp
+ pop hl
+ predef SetPartyMonTypes
+ ld a, [wIsInBattle]
+ and a
+ call z, Evolution_ReloadTilesetTilePatterns
+ predef IndexToPokedex
+ ld a, [wd11e]
+ dec a
+ ld c, a
+ ld b, FLAG_SET
+ ld hl, wPokedexOwned
+ push bc
+ call Evolution_FlagAction
+ pop bc
+ ld hl, wPokedexSeen
+ call Evolution_FlagAction
+ pop de
+ pop hl
+ ld a, [wLoadedMonSpecies]
+ ld [hl], a
+ push hl
+ ld l, e
+ ld h, d
+ jr .nextEvoEntry2
+
+.nextEvoEntry1
+ inc hl
+
+.nextEvoEntry2
+ inc hl
+ jp .evoEntryLoop
+
+.done
+ pop de
+ pop bc
+ pop hl
+ pop af
+ ldh [hTilesetType], a
+ ld a, [wLinkState]
+ cp LINK_STATE_TRADING
+ ret z
+ ld a, [wIsInBattle]
+ and a
+ ret nz
+ ld a, [wEvolutionOccurred]
+ and a
+ call nz, PlayDefaultMusic
+ ret
+
+RenameEvolvedMon:
+; Renames the mon to its new, evolved form's standard name unless it had a
+; nickname, in which case the nickname is kept.
+ ld a, [wd0b5]
+ push af
+ ld a, [wMonHIndex]
+ ld [wd0b5], a
+ call GetName
+ pop af
+ ld [wd0b5], a
+ ld hl, wcd6d
+ ld de, wcf4b
+.compareNamesLoop
+ ld a, [de]
+ inc de
+ cp [hl]
+ inc hl
+ ret nz
+ cp "@"
+ jr nz, .compareNamesLoop
+ ld a, [wWhichPokemon]
+ ld bc, NAME_LENGTH
+ ld hl, wPartyMonNicks
+ call AddNTimes
+ push hl
+ call GetName
+ ld hl, wcd6d
+ pop de
+ jp CopyData
+
+CancelledEvolution:
+ ld hl, StoppedEvolvingText
+ call PrintText
+ call ClearScreen
+ pop hl
+ call Evolution_ReloadTilesetTilePatterns
+ jp Evolution_PartyMonLoop
+
+EvolvedText:
+ text_far _EvolvedText
+ text_end
+
+IntoText:
+ text_far _IntoText
+ text_end
+
+StoppedEvolvingText:
+ text_far _StoppedEvolvingText
+ text_end
+
+IsEvolvingText:
+ text_far _IsEvolvingText
+ text_end
+
+Evolution_ReloadTilesetTilePatterns:
+ ld a, [wLinkState]
+ cp LINK_STATE_TRADING
+ ret z
+ jp ReloadTilesetTilePatterns
+
+LearnMoveFromLevelUp:
+ ld a, [wd11e] ; species
+ ld [wcf91], a
+ call GetMonLearnset
+.learnSetLoop ; loop over the learn set until we reach a move that is learnt at the current level or the end of the list
+ ld a, [hli]
+ and a ; have we reached the end of the learn set?
+ jr z, .done ; if we've reached the end of the learn set, jump
+ ld b, a ; level the move is learnt at
+ ld a, [wCurEnemyLVL]
+ cp b ; is the move learnt at the mon's current level?
+ ld a, [hli] ; move ID
+ jr nz, .learnSetLoop
+ ld d, a ; ID of move to learn
+ ld a, [wMonDataLocation]
+ and a
+ jr nz, .next
+; If [wMonDataLocation] is 0 (PLAYER_PARTY_DATA), get the address of the mon's
+; current moves in party data. Every call to this function sets
+; [wMonDataLocation] to 0 because other data locations are not supported.
+; If it is not 0, this function will not work properly.
+ ld hl, wPartyMon1Moves
+ ld a, [wWhichPokemon]
+ ld bc, wPartyMon2 - wPartyMon1
+ call AddNTimes
+.next
+ ld b, NUM_MOVES
+.checkCurrentMovesLoop ; check if the move to learn is already known
+ ld a, [hli]
+ cp d
+ jr z, .done ; if already known, jump
+ dec b
+ jr nz, .checkCurrentMovesLoop
+ ld a, d
+ ld [wMoveNum], a
+ ld [wd11e], a
+ call GetMoveName
+ call CopyStringToCF4B
+ predef LearnMove
+ ld a, b
+ and a
+ jr z, .done
+ callfar IsThisPartymonStarterPikachu_Party
+ jr nc, .done
+ ld a, [wMoveNum]
+ cp THUNDERBOLT
+ jr z, .foundThunderOrThunderbolt
+ cp THUNDER
+ jr nz, .done
+.foundThunderOrThunderbolt
+ ld a, $5
+ ld [wd49c], a
+ ld a, $85
+ ld [wPikachuMood], a
+.done
+ ld a, [wcf91]
+ ld [wd11e], a
+ ret
+
+Func_3b079:
+ ld a, [wcf91]
+ push af
+ call Func_3b0a2
+ jr c, .asm_3b09c
+
+ call Func_3b10f
+ jr nc, .asm_3b096
+
+ call Func_3b0a2
+ jr c, .asm_3b09c
+
+ call Func_3b10f
+ jr nc, .asm_3b096
+
+ call Func_3b0a2
+ jr c, .asm_3b09c
+.asm_3b096
+ pop af
+ ld [wcf91], a
+ and a
+ ret
+.asm_3b09c
+ pop af
+ ld [wcf91], a
+ scf
+ ret
+
+Func_3b0a2:
+; XXX what is wcf91 entering this function?
+ ld a, [wd11e]
+ ld [wMoveNum], a
+ predef CanLearnTM
+ ld a, c
+ and a
+ jr nz, .asm_3b0ec
+ ld hl, Pointer_3b0ee
+ ld a, [wcf91]
+ ld de, $1
+ call IsInArray
+ jr c, .asm_3b0d2
+ ld a, $ff
+ ld [wMonHGrowthRate], a
+ ld a, [wd11e]
+ ld hl, wMonHMoves
+ ld de, $1
+ call IsInArray
+ jr c, .asm_3b0ec
+.asm_3b0d2
+ ld a, [wd11e]
+ ld d, a
+ call GetMonLearnset
+.loop
+ ld a, [hli]
+ and a
+ jr z, .asm_3b0ea
+ ld b, a
+ ld a, [wCurEnemyLVL]
+ cp b
+ jr c, .asm_3b0ea
+ ld a, [hli]
+ cp d
+ jr z, .asm_3b0ec
+ jr .loop
+.asm_3b0ea
+ and a
+ ret
+.asm_3b0ec
+ scf
+ ret
+
+Pointer_3b0ee:
+ db NIDOKING
+ db IVYSAUR
+ db EXEGGUTOR
+ db GENGAR
+ db NIDOQUEEN
+ db ARCANINE
+ db GYARADOS
+ db BLASTOISE
+ db GOLEM
+ db DRAGONITE
+ db NINETALES
+ db DRAGONAIR
+ db KABUTOPS
+ db OMASTAR
+ db JIGGLYPUFF
+ db FLAREON
+ db JOLTEON
+ db VAPOREON
+ db BEEDRILL
+ db BUTTERFREE
+ db MACHAMP
+ db CLOYSTER
+ db CLEFABLE
+ db ALAKAZAM
+ db STARMIE
+ db VENUSAUR
+ db TENTACRUEL
+ db CHARMELEON
+ db WARTORTLE
+ db CHARIZARD
+ db VILEPLUME
+ db VICTREEBEL
+ db $ff
+
+Func_3b10f:
+ ld c, $0
+.asm_3b111
+ ld hl, EvosMovesPointerTable
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.asm_3b11b
+ ld a, [hli]
+ and a
+ jr z, .asm_3b130
+ cp $2
+ jr nz, .asm_3b124
+ inc hl
+.asm_3b124
+ inc hl
+ ld a, [wcf91]
+ cp [hl]
+ jr z, .asm_3b138
+ inc hl
+ ld a, [hl]
+ and a
+ jr nz, .asm_3b11b
+.asm_3b130
+ inc c
+ ld a, c
+ cp VICTREEBEL
+ jr c, .asm_3b111
+ and a
+ ret
+.asm_3b138
+ inc c
+ ld a, c
+ ld [wcf91], a
+ scf
+ ret
+
+; writes the moves a mon has at level [wCurEnemyLVL] to [de]
+; move slots are being filled up sequentially and shifted if all slots are full
+WriteMonMoves:
+ call GetPredefRegisters
+ push hl
+ push de
+ push bc
+ call GetMonLearnset
+ jr .firstMove
+.nextMove
+ pop de
+.nextMove2
+ inc hl
+.firstMove
+ ld a, [hli] ; read level of next move in learnset
+ and a
+ jp z, .done ; end of list
+ ld b, a
+ ld a, [wCurEnemyLVL]
+ cp b
+ jp c, .done ; mon level < move level (assumption: learnset is sorted by level)
+ ld a, [wLearningMovesFromDayCare]
+ and a
+ jr z, .skipMinLevelCheck
+ ld a, [wDayCareStartLevel]
+ cp b
+ jr nc, .nextMove2 ; min level >= move level
+
+.skipMinLevelCheck
+
+; check if the move is already known
+ push de
+ ld c, NUM_MOVES
+.alreadyKnowsCheckLoop
+ ld a, [de]
+ inc de
+ cp [hl]
+ jr z, .nextMove
+ dec c
+ jr nz, .alreadyKnowsCheckLoop
+
+; try to find an empty move slot
+ pop de
+ push de
+ ld c, NUM_MOVES
+.findEmptySlotLoop
+ ld a, [de]
+ and a
+ jr z, .writeMoveToSlot2
+ inc de
+ dec c
+ jr nz, .findEmptySlotLoop
+
+; no empty move slots found
+ pop de
+ push de
+ push hl
+ ld h, d
+ ld l, e
+ call WriteMonMoves_ShiftMoveData ; shift all moves one up (deleting move 1)
+ ld a, [wLearningMovesFromDayCare]
+ and a
+ jr z, .writeMoveToSlot
+
+; shift PP as well if learning moves from day care
+ push de
+ ld bc, wPartyMon1PP - (wPartyMon1Moves + 3)
+ add hl, bc
+ ld d, h
+ ld e, l
+ call WriteMonMoves_ShiftMoveData ; shift all move PP data one up
+ pop de
+
+.writeMoveToSlot
+ pop hl
+.writeMoveToSlot2
+ ld a, [hl]
+ ld [de], a
+ ld a, [wLearningMovesFromDayCare]
+ and a
+ jr z, .nextMove
+
+; write move PP value if learning moves from day care
+ push hl
+ ld a, [hl]
+ ld hl, wPartyMon1PP - wPartyMon1Moves
+ add hl, de
+ push hl
+ dec a
+ ld hl, Moves
+ ld bc, MoveEnd - Moves
+ call AddNTimes
+ ld de, wBuffer
+ ld a, BANK(Moves)
+ call FarCopyData
+ ld a, [wBuffer + 5]
+ pop hl
+ ld [hl], a
+ pop hl
+ jr .nextMove
+
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+; shifts all move data one up (freeing 4th move slot)
+WriteMonMoves_ShiftMoveData:
+ ld c, NUM_MOVES - 1
+.loop
+ inc de
+ ld a, [de]
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+
+Evolution_FlagAction:
+ predef_jump FlagActionPredef
+
+GetMonLearnset:
+ ld hl, EvosMovesPointerTable
+ ld b, 0
+ ld a, [wcf91]
+ dec a
+ ld c, a
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+.skipEvolutionDataLoop ; loop to skip past the evolution data, which comes before the move data
+ ld a, [hli]
+ and a ; have we reached the end of the evolution data?
+ jr nz, .skipEvolutionDataLoop ; if not, jump back up
+ ret
+
+INCLUDE "data/pokemon/evos_moves.asm"
diff --git a/engine/pokemon/experience.asm b/engine/pokemon/experience.asm
new file mode 100755
index 00000000..427d2a7f
--- /dev/null
+++ b/engine/pokemon/experience.asm
@@ -0,0 +1,149 @@
+; calculates the level a mon should be based on its current exp
+CalcLevelFromExperience::
+ ld a, [wLoadedMonSpecies]
+ ld [wd0b5], a
+ call GetMonHeader
+ ld d, $1 ; init level to 1
+.loop
+ inc d ; increment level
+ call CalcExperience
+ push hl
+ ld hl, wLoadedMonExp + 2 ; current exp
+; compare exp needed for level d with current exp
+ ldh a, [hExperience + 2]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ldh a, [hExperience + 1]
+ ld c, a
+ ld a, [hld]
+ sbc c
+ ldh a, [hExperience]
+ ld c, a
+ ld a, [hl]
+ sbc c
+ pop hl
+ jr nc, .loop ; if exp needed for level d is not greater than exp, try the next level
+ dec d ; since the exp was too high on the last loop iteration, go back to the previous value and return
+ ret
+
+; calculates the amount of experience needed for level d
+CalcExperience::
+ ld a, [wMonHGrowthRate]
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, GrowthRateTable
+ add hl, bc
+ call CalcDSquared
+ ld a, d
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, [hl]
+ and $f0
+ swap a
+ ldh [hMultiplier], a
+ call Multiply
+ ld a, [hli]
+ and $f
+ ldh [hDivisor], a
+ ld b, $4
+ call Divide
+ ldh a, [hQuotient + 1]
+ push af
+ ldh a, [hQuotient + 2]
+ push af
+ ldh a, [hQuotient + 3]
+ push af
+ call CalcDSquared
+ ld a, [hl]
+ and $7f
+ ldh [hMultiplier], a
+ call Multiply
+ ldh a, [hProduct + 1]
+ push af
+ ldh a, [hProduct + 2]
+ push af
+ ldh a, [hProduct + 3]
+ push af
+ ld a, [hli]
+ push af
+ xor a
+ ldh [hMultiplicand], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+ ld b, [hl]
+ ldh a, [hProduct + 3]
+ sub b
+ ldh [hProduct + 3], a
+ ld b, $0
+ ldh a, [hProduct + 2]
+ sbc b
+ ldh [hProduct + 2], a
+ ldh a, [hProduct + 1]
+ sbc b
+ ldh [hProduct + 1], a
+; The difference of the linear term and the constant term consists of 3 bytes
+; starting at hProduct + 1. Below, hExperience (an alias of that address) will
+; be used instead for the further work of adding or subtracting the squared
+; term and adding the cubed term.
+ pop af
+ and $80
+ jr nz, .subtractSquaredTerm ; check sign
+ pop bc
+ ldh a, [hExperience + 2]
+ add b
+ ldh [hExperience + 2], a
+ pop bc
+ ldh a, [hExperience + 1]
+ adc b
+ ldh [hExperience + 1], a
+ pop bc
+ ldh a, [hExperience]
+ adc b
+ ldh [hExperience], a
+ jr .addCubedTerm
+.subtractSquaredTerm
+ pop bc
+ ldh a, [hExperience + 2]
+ sub b
+ ldh [hExperience + 2], a
+ pop bc
+ ldh a, [hExperience + 1]
+ sbc b
+ ldh [hExperience + 1], a
+ pop bc
+ ldh a, [hExperience]
+ sbc b
+ ldh [hExperience], a
+.addCubedTerm
+ pop bc
+ ldh a, [hExperience + 2]
+ add b
+ ldh [hExperience + 2], a
+ pop bc
+ ldh a, [hExperience + 1]
+ adc b
+ ldh [hExperience + 1], a
+ pop bc
+ ldh a, [hExperience]
+ adc b
+ ldh [hExperience], a
+ ret
+
+; calculates d*d
+CalcDSquared:
+ xor a
+ ldh [hMultiplicand], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ldh [hMultiplier], a
+ jp Multiply
+
+INCLUDE "data/growth_rates.asm"
diff --git a/engine/learn_move.asm b/engine/pokemon/learn_move.asm
index 021d0eeb..d365acd4 100755
--- a/engine/learn_move.asm
+++ b/engine/pokemon/learn_move.asm
@@ -76,7 +76,7 @@ DontAbandonLearning:
AbandonLearning:
ld hl, AbandonLearningText
call PrintText
- coord hl, 14, 7
+ hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -99,7 +99,7 @@ TryingToLearn:
push hl
ld hl, TryingToLearnText
call PrintText
- coord hl, 14, 7
+ hlcoord 14, 7
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
@@ -114,24 +114,24 @@ TryingToLearn:
ld de, wMoves
ld bc, NUM_MOVES
call CopyData
- callab FormatMovesString
+ callfar FormatMovesString
pop hl
.loop
push hl
ld hl, WhichMoveToForgetText
call PrintText
- coord hl, 4, 7
+ hlcoord 4, 7
lb bc, 4, 14
call TextBoxBorder
- coord hl, 6, 8
+ hlcoord 6, 8
ld de, wMovesString
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
set 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
call PlaceString
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
res 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
ld hl, wTopMenuItemY
ld a, 8
ld [hli], a ; wTopMenuItemY
@@ -145,10 +145,10 @@ TryingToLearn:
ld a, A_BUTTON | B_BUTTON
ld [hli], a ; wMenuWatchedKeys
ld [hl], 0 ; wLastMenuItem
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
set 1, [hl]
call HandleMenuInput
- ld hl, hFlags_0xFFFA
+ ld hl, hFlagsFFFA
res 1, [hl]
push af
call LoadScreenTilesFromBuffer1
@@ -183,33 +183,33 @@ TryingToLearn:
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 "@"
+ text_far _LearnedMove1Text
+ sound_get_item_1 ; plays SFX_GET_ITEM_1 in the party menu (rare candy) and plays SFX_LEVEL_UP in battle
+ text_promptbutton
+ text_end
WhichMoveToForgetText:
- TX_FAR _WhichMoveToForgetText
- db "@"
+ text_far _WhichMoveToForgetText
+ text_end
AbandonLearningText:
- TX_FAR _AbandonLearningText
- db "@"
+ text_far _AbandonLearningText
+ text_end
DidNotLearnText:
- TX_FAR _DidNotLearnText
- db "@"
+ text_far _DidNotLearnText
+ text_end
TryingToLearnText:
- TX_FAR _TryingToLearnText
- db "@"
+ text_far _TryingToLearnText
+ text_end
OneTwoAndText:
; bugfix: In Red/Blue, the SFX_SWAP sound was played in the wrong bank, which played an incorrect sound
; Yellow has fixed this by swapping to the correct bank
- TX_FAR _OneTwoAndText
- TX_DELAY
- TX_ASM
+ text_far _OneTwoAndText
+ text_pause
+ text_asm
push af
push bc
push de
@@ -239,12 +239,12 @@ OneTwoAndText:
ret
PoofText:
- TX_FAR _PoofText
- TX_DELAY
+ text_far _PoofText
+ text_pause
ForgotAndText:
- TX_FAR _ForgotAndText
- db "@"
+ text_far _ForgotAndText
+ text_end
HMCantDeleteText:
- TX_FAR _HMCantDeleteText
- db "@"
+ text_far _HMCantDeleteText
+ text_end
diff --git a/engine/load_mon_data.asm b/engine/pokemon/load_mon_data.asm
index e708113f..53840728 100644
--- a/engine/load_mon_data.asm
+++ b/engine/pokemon/load_mon_data.asm
@@ -1,4 +1,4 @@
-LoadMonData_:
+LoadMonData_::
; Load monster [wWhichPokemon] from list [wMonDataLocation]:
; 0: partymon
; 1: enemymon
diff --git a/engine/pokemon/remove_mon.asm b/engine/pokemon/remove_mon.asm
new file mode 100644
index 00000000..c85b96bf
--- /dev/null
+++ b/engine/pokemon/remove_mon.asm
@@ -0,0 +1,95 @@
+_RemovePokemon::
+ ld hl, wPartyCount
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .usePartyCount
+ ld hl, wNumInBox
+.usePartyCount
+ ld a, [hl]
+ dec a
+ ld [hli], a
+ ld a, [wWhichPokemon]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld e, l
+ ld d, h
+ inc de
+.shiftMonSpeciesLoop
+ ld a, [de]
+ inc de
+ ld [hli], a
+ inc a ; reached terminator?
+ jr nz, .shiftMonSpeciesLoop ; if not, continue shifting species
+ ld hl, wPartyMonOT
+ ld d, PARTY_LENGTH - 1 ; max number of pokemon to shift
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .usePartyMonOTs
+ ld hl, wBoxMonOT
+ ld d, MONS_PER_BOX - 1
+.usePartyMonOTs
+ ld a, [wWhichPokemon]
+ call SkipFixedLengthTextEntries
+ ld a, [wWhichPokemon]
+ cp d ; are we removing the last pokemon?
+ jr nz, .notRemovingLastMon ; if not, shift the pokemon below
+ ld [hl], $ff ; else, write the terminator and return
+ ret
+.notRemovingLastMon
+ ld d, h
+ ld e, l
+ ld bc, NAME_LENGTH
+ add hl, bc
+ ld bc, wPartyMonNicks
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .usePartyMonNicks
+ ld bc, wBoxMonNicks
+.usePartyMonNicks
+ call CopyDataUntil
+ ld hl, wPartyMons
+ ld bc, wPartyMon2 - wPartyMon1
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .usePartyMonStructs
+ ld hl, wBoxMons
+ ld bc, wBoxMon2 - wBoxMon1
+.usePartyMonStructs
+ ld a, [wWhichPokemon]
+ call AddNTimes ; get address of the pokemon removed
+ ld d, h ; store in de for CopyDataUntil
+ ld e, l
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .copyUntilPartyMonOTs
+ ld bc, wBoxMon2 - wBoxMon1
+ add hl, bc ; get address of pokemon after the pokemon removed
+ ld bc, wBoxMonOT ; address of when to stop copying
+ jr .continue
+.copyUntilPartyMonOTs
+ ld bc, wPartyMon2 - wPartyMon1
+ add hl, bc ; get address of pokemon after the pokemon removed
+ ld bc, wPartyMonOT ; address of when to stop copying
+.continue
+ call CopyDataUntil ; shift all pokemon data after the removed mon to the removed mon's location
+ ld hl, wPartyMonNicks
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .usePartyMonNicks2
+ ld hl, wBoxMonNicks
+.usePartyMonNicks2
+ ld bc, NAME_LENGTH
+ ld a, [wWhichPokemon]
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld bc, NAME_LENGTH
+ add hl, bc
+ ld bc, wPartyMonNicksEnd
+ ld a, [wRemoveMonFromBox]
+ and a
+ jr z, .copyUntilPartyMonNicksEnd
+ ld bc, wBoxMonNicksEnd
+.copyUntilPartyMonNicksEnd
+ jp CopyDataUntil
diff --git a/engine/predefs17_2.asm b/engine/pokemon/set_types.asm
index e9235f13..e9235f13 100755
--- a/engine/predefs17_2.asm
+++ b/engine/pokemon/set_types.asm
diff --git a/engine/status_ailments.asm b/engine/pokemon/status_ailments.asm
index 787533c4..3da1fc43 100755
--- a/engine/status_ailments.asm
+++ b/engine/pokemon/status_ailments.asm
@@ -1,4 +1,4 @@
-PrintStatusAilment:
+PrintStatusAilment::
ld a, [de]
bit PSN, a
jr nz, .psn
diff --git a/engine/menu/status_screen.asm b/engine/pokemon/status_screen.asm
index 1e2ba889..a2cfb595 100755
--- a/engine/menu/status_screen.asm
+++ b/engine/pokemon/status_screen.asm
@@ -40,7 +40,7 @@ DrawHP_:
push hl
call DrawHPBar
pop hl
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
bit 0, a
jr z, .printFractionBelowBar
ld bc, $9 ; right of bar
@@ -80,87 +80,87 @@ StatusScreen:
ld hl, wd72c
set 1, [hl]
ld a, $33
- ld [rNR50], a ; Reduce the volume
+ ldh [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
+ ld hl, vChars2 tile $6d ; dest
+ lb bc, BANK(BattleHudTiles1), 3
call CopyVideoDataDouble ; ·│ :L and halfarrow line end
ld de, BattleHudTiles2
- ld hl, vChars2 + $780
- lb bc, BANK(BattleHudTiles2), $01
+ ld hl, vChars2 tile $78
+ lb bc, BANK(BattleHudTiles2), 1
call CopyVideoDataDouble ; │
ld de, BattleHudTiles3
- ld hl, vChars2 + $760
- lb bc, BANK(BattleHudTiles3), $02
- call CopyVideoDataDouble ; ─┘
+ ld hl, vChars2 tile $76
+ lb bc, BANK(BattleHudTiles3), 2
+ 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]
+ ld hl, vChars2 tile $72
+ lb bc, BANK(PTile), 1
+ call CopyVideoDataDouble ; bold P (for PP)
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
- coord hl, 19, 1
+ ldh [hTilesetType], a
+ hlcoord 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)
+ ld [hl], "<DOT>"
dec hl
ld [hl], "№"
- coord hl, 19, 9
+ hlcoord 19, 9
lb bc, 8, 6
call DrawLineBox ; Draws the box around types, ID No. and OT
- coord hl, 10, 9
+ hlcoord 10, 9
ld de, Type1Text
call PlaceString ; "TYPE1/"
- coord hl, 11, 3
+ hlcoord 11, 3
predef DrawHP
ld hl, wStatusScreenHPBarColor
call GetHealthBarColor
ld b, SET_PAL_STATUS_SCREEN
call RunPaletteCommand
- coord hl, 16, 6
+ hlcoord 16, 6
ld de, wLoadedMonStatus
call PrintStatusCondition
jr nz, .StatusWritten
- coord hl, 16, 6
+ hlcoord 16, 6
ld de, OKText
call PlaceString ; "OK"
.StatusWritten
- coord hl, 9, 6
+ hlcoord 9, 6
ld de, StatusText
call PlaceString ; "STATUS/"
- coord hl, 14, 2
+ hlcoord 14, 2
call PrintLevel ; Pokémon level
ld a, [wMonHIndex]
ld [wd11e], a
ld [wd0b5], a
predef IndexToPokedex
- coord hl, 3, 7
+ hlcoord 3, 7
ld de, wd11e
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber ; Pokémon no.
- coord hl, 11, 10
+ hlcoord 11, 10
predef PrintMonType
ld hl, NamePointers2
call .GetStringPointer
ld d, h
ld e, l
- coord hl, 9, 1
+ hlcoord 9, 1
call PlaceString ; Pokémon name
ld hl, OTPointers
call .GetStringPointer
ld d, h
ld e, l
- coord hl, 12, 16
+ hlcoord 12, 16
call PlaceString ; OT
- coord hl, 12, 14
+ hlcoord 12, 14
ld de, wLoadedMonOTID
lb bc, LEADING_ZEROES | 2, 5
call PrintNumber ; ID Number
@@ -168,22 +168,22 @@ StatusScreen:
call PrintStatsBox
call Delay3
call GBPalNormal
- coord hl, 1, 0
+ hlcoord 1, 0
call LoadFlippedFrontSpriteByMonIndex ; draw Pokémon picture
ld a, [wMonDataLocation]
cp ENEMY_PARTY_DATA
jr z, .playRegularCry
cp BOX_DATA
jr z, .checkBoxData
- callab IsThisPartymonStarterPikachu_Party
+ callfar IsThisPartymonStarterPikachu_Party
jr nc, .playRegularCry
jr .playPikachuSoundClip
.checkBoxData
- callab IsThisPartymonStarterPikachu_Box
+ callfar IsThisPartymonStarterPikachu_Box
jr nc, .playRegularCry
.playPikachuSoundClip
ld e, 16
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
jr .continue
.playRegularCry
ld a, [wcf91]
@@ -191,7 +191,7 @@ StatusScreen:
.continue
call WaitForTextScrollButtonPress ; wait for button
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ret
.GetStringPointer
@@ -222,14 +222,17 @@ NamePointers2:
dw wDayCareMonName
Type1Text:
- db "TYPE1/", $4e
-
+ db "TYPE1/"
+ next ""
+ ; fallthrough
Type2Text:
- db "TYPE2/", $4e
-
+ db "TYPE2/"
+ next ""
+ ; fallthrough
IDNoText:
- db $73, "№/", $4e
-
+ db "<ID>№/"
+ next ""
+ ; fallthrough
OTText:
db "OT/"
next "@"
@@ -258,26 +261,24 @@ DrawLineBox:
ld [hl], $6f ; ← (halfarrow ending)
ret
-PTile: ; This is a single 1bpp "P" tile
- INCBIN "gfx/p_tile.1bpp"
-PTileEnd:
+PTile: INCBIN "gfx/font/P.1bpp"
PrintStatsBox:
ld a, d
and a ; a is 0 from the status screen
jr nz, .DifferentBox
- coord hl, 0, 8
+ hlcoord 0, 8
lb bc, 8, 8
call TextBoxBorder ; Draws the box
- coord hl, 1, 9 ; Start printing stats from here
- ld bc, $0019 ; Number offset
+ hlcoord 1, 9 ; Start printing stats from here
+ ld bc, $19 ; Number offset
jr .PrintStats
.DifferentBox
- coord hl, 9, 2
+ hlcoord 9, 2
lb bc, 8, 9
call TextBoxBorder
- coord hl, 11, 3
- ld bc, $0018
+ hlcoord 11, 3
+ ld bc, $18
.PrintStats
push bc
push hl
@@ -310,11 +311,11 @@ StatsText:
next "SPECIAL@"
StatusScreen2:
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hTilesetType], a
+ ldh [hAutoBGTransferEnabled], a
ld bc, NUM_MOVES + 1
ld hl, wMoves
call FillMemory
@@ -322,16 +323,16 @@ StatusScreen2:
ld de, wMoves
ld bc, NUM_MOVES
call CopyData
- callab FormatMovesString
- coord hl, 9, 2
+ callfar FormatMovesString
+ hlcoord 9, 2
lb bc, 5, 10
call ClearScreenArea ; Clear under name
- coord hl, 19, 3
+ hlcoord 19, 3
ld [hl], $78
- coord hl, 0, 8
+ hlcoord 0, 8
lb bc, 8, 18
call TextBoxBorder ; Draw move container
- coord hl, 2, 9
+ hlcoord 2, 9
ld de, wMovesString
call PlaceString ; Print moves
ld a, [wNumMovesMinusOne]
@@ -340,9 +341,9 @@ StatusScreen2:
ld a, $4
sub c
ld b, a ; Number of moves ?
- coord hl, 11, 10
+ hlcoord 11, 10
ld de, SCREEN_WIDTH * 2
- ld a, $72 ; special P tile id
+ ld a, "<BOLD_P>"
call StatusScreen_PrintPP ; Print "PP"
ld a, b
and a
@@ -352,7 +353,7 @@ StatusScreen2:
call StatusScreen_PrintPP ; Fill the rest with --
.InitPP
ld hl, wLoadedMonMoves
- coord de, 14, 10
+ decoord 14, 10
ld b, 0
.PrintPP
ld a, [hli]
@@ -367,7 +368,7 @@ StatusScreen2:
ld a, b
ld [hl], a
push hl
- callab GetMaxPP
+ callfar GetMaxPP
pop hl
pop af
ld [hl], a
@@ -402,7 +403,7 @@ StatusScreen2:
cp $4
jr nz, .PrintPP
.PPDone
- coord hl, 9, 3
+ hlcoord 9, 3
ld de, StatusScreenExpText
call PlaceString
ld a, [wLoadedMonLevel]
@@ -412,41 +413,41 @@ StatusScreen2:
inc a
ld [wLoadedMonLevel], a ; Increase temporarily if not 100
.Level100
- coord hl, 14, 6
- ld [hl], $70 ; 1-tile "to"
+ hlcoord 14, 6
+ ld [hl], "<to>"
inc hl
inc hl
call PrintLevel
pop af
ld [wLoadedMonLevel], a
ld de, wLoadedMonExp
- coord hl, 12, 4
+ hlcoord 12, 4
lb bc, 3, 7
call PrintNumber ; exp
call CalcExpToLevelUp
ld de, wLoadedMonExp
- coord hl, 7, 6
+ hlcoord 7, 6
lb bc, 3, 7
call PrintNumber ; exp needed to level up
- coord hl, 9, 0
+ hlcoord 9, 0
call StatusScreen_ClearName
- coord hl, 9, 1
+ hlcoord 9, 1
call StatusScreen_ClearName
ld a, [wMonHIndex]
ld [wd11e], a
call GetMonName
- coord hl, 9, 1
+ hlcoord 9, 1
call PlaceString
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call WaitForTextScrollButtonPress ; wait for button
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld hl, wd72c
res 1, [hl]
ld a, $77
- ld [rNR50], a
+ ldh [rNR50], a
call GBPalWhiteOut
jp ClearScreen
@@ -456,15 +457,15 @@ CalcExpToLevelUp:
jr z, .atMaxLevel
inc a
ld d, a
- callab CalcExperience
+ callfar CalcExperience
ld hl, wLoadedMonExp + 2
- ld a, [hExperience + 2]
+ ldh a, [hExperience + 2]
sub [hl]
ld [hld], a
- ld a, [hExperience + 1]
+ ldh a, [hExperience + 1]
sbc [hl]
ld [hld], a
- ld a, [hExperience]
+ ldh a, [hExperience]
sbc [hl]
ld [hld], a
ret
diff --git a/engine/predefs.asm b/engine/predefs.asm
index cc6af5ac..73f69d03 100755
--- a/engine/predefs.asm
+++ b/engine/predefs.asm
@@ -1,4 +1,4 @@
-GetPredefPointer:
+GetPredefPointer::
; Store the contents of the register
; pairs (hl, de, bc) at wPredefRegisters.
; Then put the bank and address of predef
@@ -49,113 +49,4 @@ GetPredefPointer:
ret
-PredefPointers::
- ; these are pointers to ASM routines.
- ; they appear to be used in overworld map scripts.
- const_def
- add_predef DrawPlayerHUDAndHPBar
- add_predef CopyUncompressedPicToTilemap
- add_predef AnimateSendingOutMon
- add_predef ScaleSpriteByTwo
- add_predef LoadMonBackPic
- add_predef CopyDownscaledMonTiles
- add_predef Func_f0a7
- add_predef HealParty
- add_predef MoveAnimation
- add_predef DivideBCDPredef
- add_predef DivideBCDPredef2
- add_predef AddBCDPredef
- add_predef SubBCDPredef
- add_predef DivideBCDPredef3
- add_predef DivideBCDPredef4
- add_predef InitPlayerData
- add_predef FlagActionPredef
- add_predef HideObject
- add_predef IsObjectHidden
- add_predef ApplyOutOfBattlePoisonDamage
- add_predef AnyPartyAlive
- add_predef ShowObject
- add_predef ShowObject2
- add_predef ReplaceTileBlock
- add_predef InitPlayerData2
- add_predef LoadTilesetHeader
- add_predef LearnMoveFromLevelUp
- add_predef LearnMove
- add_predef GetQuantityOfItemInBag
-
- predef_const CheckForHiddenObjectOrBookshelfOrCardKeyDoor
- predef_const GiveItem
- dbw $03, CheckForHiddenObjectOrBookshelfOrCardKeyDoor ; home bank
- dbw $03, GiveItem ; home bank
-
- add_predef ChangeBGPalColor0_4Frames
- add_predef FindPathToPlayer
- add_predef PredefShakeScreenVertically
- add_predef CalcPositionOfPlayerRelativeToNPC
- add_predef ConvertNPCMovementDirectionsToJoypadMasks
- add_predef PredefShakeScreenHorizontally
- add_predef UpdateHPBar
- add_predef HPBarLength
- add_predef Diploma_TextBoxBorder
- add_predef DoubleOrHalveSelectedStats
- add_predef ShowPokedexMenu
- add_predef EvolutionAfterBattle
- add_predef SaveSAVtoSRAM0
- add_predef InitOpponent
- add_predef CableClub_Run
- add_predef DrawBadges
- add_predef ExternalClockTradeAnim
- add_predef BattleTransition
- add_predef CopyTileIDsFromList
- add_predef PlayIntro
- add_predef GetMoveSoundB
- add_predef FlashScreen
- add_predef GetTileAndCoordsInFrontOfPlayer
- add_predef StatusScreen
- add_predef StatusScreen2
- add_predef InternalClockTradeAnim
- add_predef TrainerEngage
- add_predef IndexToPokedex
- add_predef DisplayPicCenteredOrUpperRight
- add_predef UsedCut
- add_predef ShowPokedexData
- add_predef WriteMonMoves
- add_predef SaveSAV
- add_predef LoadSGB
- add_predef MarkTownVisitedAndLoadMissableObjects
- add_predef SetPartyMonTypes
- add_predef CanLearnTM
- add_predef TMToMove
- add_predef _RunPaletteCommand
- add_predef StarterDex
- add_predef _AddPartyMon
- add_predef UpdateHPBar2
- add_predef DrawEnemyHUDAndHPBar
- add_predef LoadTownMap_Nest
- add_predef PrintMonType
- add_predef EmotionBubble
- add_predef EmptyFunc3 ; return immediately
- add_predef AskName
- add_predef PewterGuys
- add_predef SaveSAVtoSRAM2
- add_predef LoadSAV2
- add_predef LoadSAV
- add_predef SaveSAVtoSRAM1
- add_predef DoInGameTradeDialogue
- add_predef HallOfFamePC
- add_predef DisplayDexRating
-
- predef_const _LeaveMapAnim
- predef_const EnterMapAnim
- dbw $1E, _LeaveMapAnim ; wrong bank
- dbw $1E, EnterMapAnim ; wrong bank
- add_predef GetTileTwoStepsInFrontOfPlayer
- add_predef CheckForCollisionWhenPushingBoulder
- add_predef PrintStrengthTxt
- add_predef PickUpItem
- add_predef PrintMoveType
- add_predef LoadMovePPs
- add_predef DrawHP
- add_predef DrawHP2
- add_predef DisplayElevatorFloorMenu
- add_predef OaksAideScript
+INCLUDE "data/predef_pointers.asm"
diff --git a/engine/predefs17.asm b/engine/predefs17.asm
deleted file mode 100755
index 21289c6a..00000000
--- a/engine/predefs17.asm
+++ /dev/null
@@ -1,9 +0,0 @@
-; this function temporarily makes the starters (and Ivysaur) seen
-; so that the full Pokedex information gets displayed in Oak's lab
-StarterDex:
- ld a, %01001011 ; set starter flags
- ld [wPokedexOwned], a
- predef ShowPokedexData
- xor a ; unset starter flags
- ld [wPokedexOwned], a
- ret
diff --git a/engine/predefs7.asm b/engine/predefs7.asm
deleted file mode 100755
index bfa0ab57..00000000
--- a/engine/predefs7.asm
+++ /dev/null
@@ -1,54 +0,0 @@
-DisplayElevatorFloorMenu:
- ld hl, wd730
- ld a, [hl]
- push af
- set 6, [hl]
- ld hl, WhichFloorText
- call PrintText
- pop af
- ld [wd730], a
- ld hl, wItemList
- ld a, l
- ld [wListPointer], a
- ld a, h
- ld [wListPointer + 1], a
- ld a, [wListScrollOffset]
- push af
- xor a
- ld [wCurrentMenuItem], a
- ld [wListScrollOffset], a
- ld [wPrintItemPrices], a
- ld a, SPECIALLISTMENU
- ld [wListMenuID], a
- call DisplayListMenuID
- pop bc
- ld a, b
- ld [wListScrollOffset], a
- ret c
- ld hl, wCurrentMapScriptFlags
- set 7, [hl]
- ld hl, wElevatorWarpMaps
- ld a, [wWhichPokemon]
- add a
- ld d, 0
- ld e, a
- add hl, de
- ld a, [hli]
- ld b, a
- ld a, [hl]
- ld c, a
- ld hl, wWarpEntries
- call .UpdateWarp
-
-.UpdateWarp
- inc hl
- inc hl
- ld a, b
- ld [hli], a ; destination warp ID
- ld a, c
- ld [hli], a ; destination map ID
- ret
-
-WhichFloorText:
- TX_FAR _WhichFloorText
- db "@"
diff --git a/engine/predefsA.asm b/engine/predefsA.asm
deleted file mode 100644
index e25735c5..00000000
--- a/engine/predefsA.asm
+++ /dev/null
@@ -1,73 +0,0 @@
-; inverts the BGP for 4 (6 on CGB due to lag) frames
-ChangeBGPalColor0_4Frames:
- call GetPredefRegisters ; leftover of red/blue, has no use here
- ld a, [rBGP]
- xor $ff
- ld [rBGP], a
- call UpdateGBCPal_BGP
- ld c, 4
- call DelayFrames
- ld a, [rBGP]
- xor $ff
- ld [rBGP], a
- call UpdateGBCPal_BGP
- ret
-
-PredefShakeScreenVertically:
-; Moves the window down and then back in a sequence of progressively smaller
-; numbers of pixels, starting at b.
- call GetPredefRegisters
- ld a, 1
- ld [wDisableVBlankWYUpdate], a
- xor a
-.loop
- ld [$ff96], a
- call .MutateWY
- call .MutateWY
- dec b
- ld a, b
- jr nz, .loop
- xor a
- ld [wDisableVBlankWYUpdate], a
- ret
-
-.MutateWY
- ld a, [$ff96]
- xor b
- ld [$ff96], a
- ld [rWY], a
- ld c, 3
- jp DelayFrames
-
-PredefShakeScreenHorizontally:
-; Moves the window right and then back in a sequence of progressively smaller
-; numbers of pixels, starting at b.
- call GetPredefRegisters
- xor a
-.loop
- ld [$ff97], a
- call .MutateWX
- ld c, 1
- call DelayFrames
- call .MutateWX
- dec b
- ld a, b
- jr nz, .loop
-
-; restore normal WX
- ld a, 7
- ld [rWX], a
- ret
-
-.MutateWX
- ld a, [$ff97]
- xor b
- ld [$ff97], a
- bit 7, a
- jr z, .skipZeroing
- xor a ; zero a if it's negative
-.skipZeroing
- add 7
- ld [rWX], a
- ld c, 4
- jp DelayFrames
diff --git a/engine/printer.asm b/engine/printer.asm
index 5be5286c..f0b681af 100644
--- a/engine/printer.asm
+++ b/engine/printer.asm
@@ -16,16 +16,16 @@ PrintPokedexEntry:
push af
xor a
ld [wUpdateSpritesEnabled], a
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
call Printer_PlayPrinterMusic
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Printer_GetDexEntryRegisters
call Printer_StartTransmission
ld a, [wPrinterPokedexMonIsOwned]
@@ -40,10 +40,10 @@ PrintPokedexEntry:
ld [wcae2], a
call Printer_CopyTileMapToPrinterTileBuffer
call ClearScreen
- callab Pokedex_DrawInterface
- callab Pokedex_PlacePokemonList
+ callfar Pokedex_DrawInterface
+ callfar Pokedex_PlacePokemonList
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call .TryPrintPage
jr c, .finish_printing
ld a, [wPrinterPokedexMonIsOwned]
@@ -56,7 +56,7 @@ PrintPokedexEntry:
call DelayFrames
call SaveScreenTilesToBuffer1
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Printer_PrepareDexEntryForPrinting
ld a, $7
call Printer_StartTransmission
@@ -65,16 +65,16 @@ PrintPokedexEntry:
call Printer_CopyTileMapToPrinterTileBuffer
call LoadScreenTilesFromBuffer1
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call .TryPrintPage
.finish_printing
xor a
ld [wPrinterConnectionOpen], a
ld [wPrinterOpcode], a
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
call ReloadMapAfterPrinter
call Printer_PlayMapMusic
pop af
@@ -105,7 +105,7 @@ PrintPokedexEntry:
ret
Printer_GetDexEntryRegisters:
- callab DrawDexEntryOnScreen
+ callfar DrawDexEntryOnScreen
ld a, l
ld [wPrinterPokedexEntryTextPointer], a
ld a, h
@@ -125,20 +125,20 @@ Printer_GetDexEntryRegisters:
Printer_PrepareDexEntryForPrinting:
call ClearScreen
- callab Pokedex_PrepareDexEntryForPrinting
+ callfar Pokedex_PrepareDexEntryForPrinting
ret
PrintSurfingMinigameHighScore:
xor a
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
call Printer_PlayPrinterMusic
call Printer_PrepareSurfingMinigameHighScoreTileMap
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
call StartTransmission_Send9Rows
ld a, $13
ld [wcae2], a
@@ -163,24 +163,24 @@ PrintSurfingMinigameHighScore:
ld [wPrinterOpcode], a
call Printer_CopyTileMapFromPrinterTileBuffer
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
call ReloadMapAfterPrinter
call Printer_PlayMapMusic
ret
-PrintDiploma:
+PrintDiploma::
xor a
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
call Printer_PlayPrinterMusic
call _DisplayDiploma
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
call StartTransmission_Send9Rows
ld a, $10
ld [wcae2], a
@@ -194,7 +194,7 @@ PrintDiploma:
call DelayFrames
call SaveScreenTilesToBuffer1
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Func_e9ad3
call StartTransmission_Send9Rows
ld a, $3
@@ -208,9 +208,9 @@ PrintDiploma:
ld [wPrinterOpcode], a
call Printer_CopyTileMapFromPrinterTileBuffer
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
call ReloadMapAfterPrinter
call Printer_PlayMapMusic
ret
@@ -246,17 +246,17 @@ PrintPCBox::
push af
xor a
ld [wUpdateSpritesEnabled], a
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
call Printer_PlayPrinterMusic
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
call SaveScreenTilesToBuffer1
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PrintPCBox_DrawPage1
call StartTransmission_Send9Rows
ld a, $10
@@ -271,7 +271,7 @@ PrintPCBox::
ld c, 12
call DelayFrames
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PrintPCBox_DrawPage2
call StartTransmission_Send9Rows
ld a, $0
@@ -286,7 +286,7 @@ PrintPCBox::
ld c, 12
call DelayFrames
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PrintPCBox_DrawPage3
call StartTransmission_Send9Rows
ld a, $0
@@ -301,7 +301,7 @@ PrintPCBox::
ld c, 12
call DelayFrames
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call PrintPCBox_DrawPage4
call StartTransmission_Send9Rows
ld a, $3
@@ -314,9 +314,9 @@ PrintPCBox::
ld [wPrinterConnectionOpen], a
ld [wPrinterOpcode], a
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
call ReloadMapAfterPrinter
call Printer_PlayMapMusic
pop af
@@ -352,20 +352,20 @@ Func_e8dfb:
ret
String_e8e1f:
- TX_FAR _NoPokemonText
- db "@"
+ text_far _NoPokemonText
+ text_end
-PrintFanClubPortrait:
+PrintFanClubPortrait::
xor a
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
call Printer_PlayPrinterMusic
call Printer_GetMonStats
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
call StartTransmission_Send9Rows
ld a, $13
ld [wcae2], a
@@ -390,9 +390,9 @@ PrintFanClubPortrait:
ld [wPrinterOpcode], a
call Printer_CopyTileMapFromPrinterTileBuffer
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
call ReloadMapAfterPrinter
call Printer_PlayMapMusic
ret
@@ -403,17 +403,17 @@ PrinterDebug:
push de
push hl
call StopAllMusic
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $9
- ld [rIE], a
+ ldh [rIE], a
call StartTransmission_Send9Rows
ld a, $13
ld [wcae2], a
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Printer_CopyTileMapToPrinterTileBuffer
call PrinterDebug_LoadGFX
.loop
@@ -434,9 +434,9 @@ PrinterDebug:
xor a
call FillMemory
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
pop hl
pop de
pop bc
@@ -444,7 +444,7 @@ PrinterDebug:
ret
Printer_CheckPressingB:
- ld a, [hJoyHeld]
+ ldh a, [hJoyHeld]
and B_BUTTON
jr nz, .quit
and a
@@ -461,43 +461,43 @@ Printer_CheckPressingB:
ld a, $16
ld [wPrinterOpcode], a
ld a, $88
- ld [rSB], a
+ ldh [rSB], a
ld a, $1
- ld [rSC], a
+ ldh [rSC], a
ld a, $81
- ld [rSC], a
+ ldh [rSC], a
.wait_send_cancel
ld a, [wPrinterOpcode]
and a
jr nz, .wait_send_cancel
.already_done
ld a, $1
- ld [hCanceledPrinting], a
+ ldh [hCanceledPrinting], a
scf
ret
Printer_CopyTileMapToPrinterTileBuffer:
- coord hl, 0, 0
- coord de, 0, 0, wPrinterTileBuffer
+ hlcoord 0, 0
+ decoord 0, 0, wPrinterTileBuffer
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
call CopyData
ret
Printer_CopyTileMapFromPrinterTileBuffer:
- coord hl, 0, 0, wPrinterTileBuffer
- coord de, 0, 0
+ hlcoord 0, 0, wPrinterTileBuffer
+ decoord 0, 0
ld bc, SCREEN_HEIGHT * SCREEN_WIDTH
call CopyData
ret
Printer_ResetJoypadHRAM:
xor a
- ld [hJoyLast], a
- ld [hJoyReleased], a
- ld [hJoyPressed], a
- ld [hJoyHeld], a
- ld [hJoy5], a
- ld [hJoy6], a
+ ldh [hJoyLast], a
+ ldh [hJoyReleased], a
+ ldh [hJoyPressed], a
+ ldh [hJoyHeld], a
+ ldh [hJoy5], a
+ ldh [hJoy6], a
ret
Printer_PlayPrinterMusic:
@@ -568,8 +568,8 @@ GBPrinter_UpdateStatusMessage:
ret z
push af
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- coord hl, 0, 5
+ ldh [hAutoBGTransferEnabled], a
+ hlcoord 0, 5
lb bc, 10, 18
call TextBoxBorder
pop af
@@ -581,13 +581,13 @@ GBPrinter_UpdateStatusMessage:
ld e, [hl]
inc hl
ld d, [hl]
- coord hl, 1, 7
+ hlcoord 1, 7
call PlaceString
- coord hl, 2, 15
+ hlcoord 2, 15
ld de, .PressBToCancel
call PlaceString
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
xor a
ld [wPrinterStatusIndicator], a
ret
@@ -648,39 +648,39 @@ Printer_PrepareSurfingMinigameHighScoreTileMap:
ld hl, vChars2
lb bc, BANK(SurfingPikachu2Graphics), (SurfingPikachu2GraphicsEnd - SurfingPikachu2Graphics) / $10
call CopyVideoData
- coord hl, 0, 0
+ hlcoord 0, 0
call .PlaceRowAlternatingTiles
- coord hl, 0, 17
+ hlcoord 0, 17
call .PlaceRowAlternatingTiles
- coord hl, 0, 0
+ hlcoord 0, 0
call .PlaceColumnAlternatingTiles
- coord hl, 19, 0
+ hlcoord 19, 0
call .PlaceColumnAlternatingTiles
ld a, $4
- coord hl, 0, 0
+ hlcoord 0, 0
ld [hl], a
- coord hl, 0, 17
+ hlcoord 0, 17
ld [hl], a
- coord hl, 19, 0
+ hlcoord 19, 0
ld [hl], a
- coord hl, 19, 17
+ hlcoord 19, 17
ld [hl], a
ld de, .Tilemap1
- coord hl, 10, 8
+ hlcoord 10, 8
lb bc, 3, 8
call Diploma_Surfing_CopyBox
ld de, .Tilemap2
- coord hl, 2, 11
+ hlcoord 2, 11
lb bc, 6, 16
call Diploma_Surfing_CopyBox
ld de, .PikachusBeachString
- coord hl, 3, 2
+ hlcoord 3, 2
call PlaceString
ld de, .HiScoreString
- coord hl, 9, 4
+ hlcoord 9, 4
call PlaceString
ld de, .PointsString
- coord hl, 12, 6
+ hlcoord 12, 6
call PlaceString
ld de, wPlayerName
ld hl, wPlayerName
@@ -696,14 +696,14 @@ Printer_PrepareSurfingMinigameHighScoreTileMap:
xor a
.got_name_length
ld c, a
- coord hl, 2, 4
+ hlcoord 2, 4
add hl, bc
call PlaceString
call CopySurfingMinigameScore
ld b, 8
call RunPaletteCommand
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call GBPalNormal
ret
@@ -771,7 +771,7 @@ Diploma_Surfing_CopyBox:
CopySurfingMinigameScore:
ld de, wSurfingMinigameHiScore + 1
- coord hl, 7, 6
+ hlcoord 7, 6
ld a, [de]
call .BCDConvertScore
ld a, [de]
@@ -796,19 +796,19 @@ PrintPCBox_DrawPage1:
ld [wBoxNumString], a
call ClearScreen
call PrintPCBox_PlaceHorizontalLines
- coord hl, 0, 0
+ hlcoord 0, 0
ld bc, 11 * SCREEN_WIDTH
ld a, " "
call FillMemory
call PrintPCBox_DrawLeftAndRightBorders
call PrintPCBox_DrawTopBorder
- coord hl, 4, 4
+ hlcoord 4, 4
ld de, .PokemonListString
call PlaceString
- coord hl, 7, 6
+ hlcoord 7, 6
ld de, .BoxString
call PlaceString
- coord hl, 11, 6
+ hlcoord 11, 6
ld a, [wCurrentBoxNum]
and $7f
cp 9
@@ -823,7 +823,7 @@ PrintPCBox_DrawPage1:
add "1"
.placed_box_number
ld [hl], a
- coord hl, 4, 9
+ hlcoord 4, 9
ld de, wBoxSpecies
ld c, $3
call PrintPCBox_PlaceBoxMonInfo
@@ -839,7 +839,7 @@ PrintPCBox_DrawPage2:
ld a, [wBoxDataStart]
cp 4
ret c
- coord hl, 4, 0
+ hlcoord 4, 0
ld de, wBoxSpecies + 3
ld c, 6
call PrintPCBox_PlaceBoxMonInfo
@@ -852,7 +852,7 @@ PrintPCBox_DrawPage3:
ld a, [wBoxDataStart]
cp 10
ret c
- coord hl, 4, 0
+ hlcoord 4, 0
ld de, wBoxSpecies + 9
ld c, 6
call PrintPCBox_PlaceBoxMonInfo
@@ -862,16 +862,16 @@ PrintPCBox_DrawPage4:
call ClearScreen
call PrintPCBox_PlaceHorizontalLines
call PrintPCBox_DrawLeftAndRightBorders
- coord hl, 0, 15
+ hlcoord 0, 15
call PrintPCBox_DrawBottomBorderAtHL
- coord hl, 0, 16
+ hlcoord 0, 16
ld bc, 2 * SCREEN_WIDTH
ld a, " "
call FillMemory
ld a, [wBoxDataStart]
cp 16
ret c
- coord hl, 4, 0
+ hlcoord 4, 0
ld de, wBoxSpecies + 15
ld c, 5
call PrintPCBox_PlaceBoxMonInfo
@@ -933,7 +933,7 @@ PrintPCBox_PlaceBoxMonInfo:
ret
PrintPCBox_DrawTopBorder:
- coord hl, 0, 0
+ hlcoord 0, 0
ld a, $79
ld [hli], a
ld a, $7a
@@ -947,7 +947,7 @@ PrintPCBox_DrawTopBorder:
ret
PrintPCBox_DrawLeftAndRightBorders:
- coord hl, 0, 0
+ hlcoord 0, 0
ld de, SCREEN_WIDTH - 1
ld c, SCREEN_HEIGHT
.loop
@@ -961,7 +961,7 @@ PrintPCBox_DrawLeftAndRightBorders:
ret
PrintPCBox_DrawBottomBorder:
- coord hl, 0, 17
+ hlcoord 0, 17
PrintPCBox_DrawBottomBorderAtHL:
ld a, $7d
ld [hli], a
@@ -976,10 +976,10 @@ PrintPCBox_DrawBottomBorderAtHL:
ret
PrintPCBox_PlaceHorizontalLines:
- coord hl, 4, 0
+ hlcoord 4, 0
ld c, 6
call .PlaceHorizontalLine
- coord hl, 6, 1
+ hlcoord 6, 1
ld c, 6
.PlaceHorizontalLine:
.loop
diff --git a/engine/printer/serial.asm b/engine/printer/serial.asm
index fa83eb9d..97f655bb 100755
--- a/engine/printer/serial.asm
+++ b/engine/printer/serial.asm
@@ -7,8 +7,8 @@ Printer_StartTransmission:
xor a
call Printer_FillMemory
xor a
- ld [rSB], a
- ld [rSC], a
+ ldh [rSB], a
+ ldh [rSC], a
ld [wPrinterOpcode], a
ld hl, wPrinterConnectionOpen
set 0, [hl]
@@ -269,11 +269,11 @@ Printer_PrepareToSend:
ld a, $1
ld [wPrinterOpcode], a
ld a, $88
- ld [rSB], a
+ ldh [rSB], a
ld a, $1
- ld [rSC], a
+ ldh [rSC], a
ld a, $81
- ld [rSC], a
+ ldh [rSC], a
ret
CopyPrinterDataHeader:
@@ -438,7 +438,7 @@ PrinterDataPacket6: ; unused
db 15, 0, $00, 0
dw 15
-PrinterSerial_:
+PrinterSerial_::
ld a, [wPrinterOpcode]
ld e, a
ld d, 0
@@ -573,7 +573,7 @@ PrinterSerial_:
ret
.Receive1:
- ld a, [rSB]
+ ldh a, [rSB]
ld [wPrinterHandshake], a
ld a, $0
call .SendByte
@@ -581,7 +581,7 @@ PrinterSerial_:
ret
.Receive2:
- ld a, [rSB]
+ ldh a, [rSB]
ld [wPrinterStatusFlags], a
xor a
ld [wPrinterOpcode], a
@@ -606,15 +606,15 @@ PrinterSerial_:
ret
.SendByte:
- ld [rSB], a
+ ldh [rSB], a
ld a, $1
- ld [rSC], a
+ ldh [rSC], a
ld a, $81
- ld [rSC], a
+ ldh [rSC], a
ret
.Receive2_:
- ld a, [rSB]
+ ldh a, [rSB]
ld [wPrinterStatusFlags], a
xor a
ld [wPrinterOpcode], a
diff --git a/engine/random.asm b/engine/random.asm
deleted file mode 100755
index 2fc83f6f..00000000
--- a/engine/random.asm
+++ /dev/null
@@ -1,13 +0,0 @@
-Random_::
-; Generate a random 16-bit value.
- ld a, [rDIV]
- ld b, a
- ld a, [hRandomAdd]
- adc b
- ld [hRandomAdd], a
- ld a, [rDIV]
- ld b, a
- ld a, [hRandomSub]
- sbc b
- ld [hRandomSub], a
- ret
diff --git a/engine/remove_pokemon.asm b/engine/remove_pokemon.asm
deleted file mode 100644
index f29a428d..00000000
--- a/engine/remove_pokemon.asm
+++ /dev/null
@@ -1,95 +0,0 @@
-_RemovePokemon:
- ld hl, wPartyCount
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .usePartyCount
- ld hl, wNumInBox
-.usePartyCount
- ld a, [hl]
- dec a
- ld [hli], a
- ld a, [wWhichPokemon]
- ld c, a
- ld b, $0
- add hl, bc
- ld e, l
- ld d, h
- inc de
-.shiftMonSpeciesLoop
- ld a, [de]
- inc de
- ld [hli], a
- inc a ; reached terminator?
- jr nz, .shiftMonSpeciesLoop ; if not, continue shifting species
- ld hl, wPartyMonOT
- ld d, PARTY_LENGTH - 1 ; max number of pokemon to shift
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .usePartyMonOTs
- ld hl, wBoxMonOT
- ld d, MONS_PER_BOX - 1
-.usePartyMonOTs
- ld a, [wWhichPokemon]
- call SkipFixedLengthTextEntries
- ld a, [wWhichPokemon]
- cp d ; are we removing the last pokemon?
- jr nz, .notRemovingLastMon ; if not, shift the pokemon below
- ld [hl], $ff ; else, write the terminator and return
- ret
-.notRemovingLastMon
- ld d, h
- ld e, l
- ld bc, NAME_LENGTH
- add hl, bc
- ld bc, wPartyMonNicks
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .usePartyMonNicks
- ld bc, wBoxMonNicks
-.usePartyMonNicks
- call CopyDataUntil
- ld hl, wPartyMons
- ld bc, wPartyMon2 - wPartyMon1
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .usePartyMonStructs
- ld hl, wBoxMons
- ld bc, wBoxMon2 - wBoxMon1
-.usePartyMonStructs
- ld a, [wWhichPokemon]
- call AddNTimes ; get address of the pokemon removed
- ld d, h ; store in de for CopyDataUntil
- ld e, l
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .copyUntilPartyMonOTs
- ld bc, wBoxMon2 - wBoxMon1
- add hl, bc ; get address of pokemon after the pokemon removed
- ld bc, wBoxMonOT ; address of when to stop copying
- jr .continue
-.copyUntilPartyMonOTs
- ld bc, wPartyMon2 - wPartyMon1
- add hl, bc ; get address of pokemon after the pokemon removed
- ld bc, wPartyMonOT ; address of when to stop copying
-.continue
- call CopyDataUntil ; shift all pokemon data after the removed mon to the removed mon's location
- ld hl, wPartyMonNicks
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .usePartyMonNicks2
- ld hl, wBoxMonNicks
-.usePartyMonNicks2
- ld bc, NAME_LENGTH
- ld a, [wWhichPokemon]
- call AddNTimes
- ld d, h
- ld e, l
- ld bc, NAME_LENGTH
- add hl, bc
- ld bc, wPartyMonNicksEnd
- ld a, [wRemoveMonFromBox]
- and a
- jr z, .copyUntilPartyMonNicksEnd
- ld bc, wBoxMonNicksEnd
-.copyUntilPartyMonNicksEnd
- jp CopyDataUntil
diff --git a/engine/slots/game_corner_slots.asm b/engine/slots/game_corner_slots.asm
new file mode 100755
index 00000000..48321974
--- /dev/null
+++ b/engine/slots/game_corner_slots.asm
@@ -0,0 +1,54 @@
+StartSlotMachine:
+ ld a, [wHiddenObjectFunctionArgument]
+ cp SLOTS_OUTOFORDER
+ jr z, .printOutOfOrder
+ cp SLOTS_OUTTOLUNCH
+ jr z, .printOutToLunch
+ cp SLOTS_SOMEONESKEYS
+ jr z, .printSomeonesKeys
+ farcall AbleToPlaySlotsCheck
+ ld a, [wCanPlaySlots]
+ and a
+ ret z
+ ld a, [wLuckySlotHiddenObjectIndex]
+ ld b, a
+ ld a, [wHiddenObjectIndex]
+ inc a
+ cp b
+ jr z, .match
+ ld a, 253
+ jr .next
+.match
+ ld a, 250
+.next
+ ld [wSlotMachineSevenAndBarModeChance], a
+ ldh a, [hLoadedROMBank]
+ ld [wSlotMachineSavedROMBank], a
+ call PromptUserToPlaySlots
+ ret
+.printOutOfOrder
+ tx_pre_id GameCornerOutOfOrderText
+ jr .printText
+.printOutToLunch
+ tx_pre_id GameCornerOutToLunchText
+ jr .printText
+.printSomeonesKeys
+ tx_pre_id GameCornerSomeonesKeysText
+.printText
+ push af
+ call EnableAutoTextBoxDrawing
+ pop af
+ call PrintPredefTextID
+ ret
+
+GameCornerOutOfOrderText::
+ text_far _GameCornerOutOfOrderText
+ text_end
+
+GameCornerOutToLunchText::
+ text_far _GameCornerOutToLunchText
+ text_end
+
+GameCornerSomeonesKeysText::
+ text_far _GameCornerSomeonesKeysText
+ text_end
diff --git a/engine/slots/game_corner_slots2.asm b/engine/slots/game_corner_slots2.asm
new file mode 100755
index 00000000..a4ba4ec1
--- /dev/null
+++ b/engine/slots/game_corner_slots2.asm
@@ -0,0 +1,31 @@
+AbleToPlaySlotsCheck:
+ ld a, [wSpritePlayerStateData1ImageIndex]
+ and $8
+ jr z, .done ; not able
+ ld b, COIN_CASE
+ predef GetQuantityOfItemInBag
+ ld a, b
+ and a
+ ld b, (GameCornerCoinCaseText_id - TextPredefs) / 2 + 1
+ jr z, .printCoinCaseRequired
+ ld hl, wPlayerCoins
+ ld a, [hli]
+ or [hl]
+ jr nz, .done ; able to play
+ ld b, (GameCornerNoCoinsText_id - TextPredefs) / 2 + 1
+.printCoinCaseRequired
+ call EnableAutoTextBoxDrawing
+ ld a, b
+ call PrintPredefTextID
+ xor a
+.done
+ ld [wCanPlaySlots], a
+ ret
+
+GameCornerCoinCaseText::
+ text_far _GameCornerCoinCaseText
+ text_end
+
+GameCornerNoCoinsText::
+ text_far _GameCornerNoCoinsText
+ text_end
diff --git a/engine/slot_machine.asm b/engine/slots/slot_machine.asm
index b4514618..ba007d9d 100755
--- a/engine/slot_machine.asm
+++ b/engine/slots/slot_machine.asm
@@ -1,6 +1,6 @@
PromptUserToPlaySlots:
call SaveScreenTilesToBuffer2
- ld a, BANK(DisplayTextIDInit)
+ ld a, BANK(DisplayTextIDInit) ; TRUE
ld [wAutoTextBoxDrawingControl], a
ld b, a
ld hl, DisplayTextIDInit
@@ -26,14 +26,14 @@ PromptUserToPlaySlots:
call Delay3
call GBPalNormal
ld a, $e4
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
ld hl, wd730
set 6, [hl]
xor a
ld [wSlotMachineAllowMatchesCounter], a
ld hl, wStoppingWhichSlotMachineWheel
- ld bc, $0014
+ ld bc, $14
call FillMemory
call MainSlotMachineLoop
ld hl, wd730
@@ -55,8 +55,8 @@ PromptUserToPlaySlots:
jp CloseTextDisplay
PlaySlotMachineText:
- TX_FAR _PlaySlotMachineText
- db "@"
+ text_far _PlaySlotMachineText
+ text_end
MainSlotMachineLoop:
call SlotMachine_PrintCreditCoins
@@ -81,10 +81,10 @@ MainSlotMachineLoop:
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ld [wMenuWatchMovingOutOfBounds], a
- coord hl, 14, 11
+ hlcoord 14, 11
lb bc, 5, 4
call TextBoxBorder
- coord hl, 16, 12
+ hlcoord 16, 12
ld de, CoinMultiplierSlotMachineText
call PlaceString
call HandleMenuInput
@@ -134,7 +134,7 @@ MainSlotMachineLoop:
.skip2
ld hl, OneMoreGoSlotMachineText
call PrintText
- coord hl, 14, 12
+ hlcoord 14, 12
lb bc, 13, 15
xor a ; YES_NO_MENU
ld [wTwoOptionMenuID], a
@@ -153,24 +153,24 @@ CoinMultiplierSlotMachineText:
next "×1@"
OutOfCoinsSlotMachineText:
- TX_FAR _OutOfCoinsSlotMachineText
- db "@"
+ text_far _OutOfCoinsSlotMachineText
+ text_end
BetHowManySlotMachineText:
- TX_FAR _BetHowManySlotMachineText
- db "@"
+ text_far _BetHowManySlotMachineText
+ text_end
StartSlotMachineText:
- TX_FAR _StartSlotMachineText
- db "@"
+ text_far _StartSlotMachineText
+ text_end
NotEnoughCoinsSlotMachineText:
- TX_FAR _NotEnoughCoinsSlotMachineText
- db "@"
+ text_far _NotEnoughCoinsSlotMachineText
+ text_end
OneMoreGoSlotMachineText:
- TX_FAR _OneMoreGoSlotMachineText
- db "@"
+ text_far _OneMoreGoSlotMachineText
+ text_end
SlotMachine_SetFlags:
ld hl, wSlotMachineFlags
@@ -295,7 +295,7 @@ SlotMachine_StopWheel1Early:
; Stop early if the middle symbol is not a cherry.
inc hl
ld a, [hl]
- cp SLOTSCHERRY >> 8
+ cp HIGH(SLOTSCHERRY)
jr nz, .stopWheel
ret
; It looks like this was intended to make the wheel stop when a 7 symbol was
@@ -304,7 +304,7 @@ SlotMachine_StopWheel1Early:
ld c, $3
.loop
ld a, [hli]
- cp SLOTS7 >> 8
+ cp HIGH(SLOTS7)
jr c, .stopWheel ; condition never true
dec c
jr nz, .loop
@@ -331,7 +331,7 @@ SlotMachine_StopWheel2Early:
.sevenAndBarMode
call SlotMachine_FindWheel1Wheel2Matches
ld a, [de]
- cp (SLOTSBAR >> 8) + 1
+ cp HIGH(SLOTSBAR) + 1
ret nc
.stopWheel
xor a
@@ -428,7 +428,7 @@ SlotMachine_CheckForMatches:
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
+ cp HIGH(SLOTSBAR) + 1
jr c, .rollWheel3DownByOneSymbol
.acceptMatch
ld a, [hl]
@@ -455,9 +455,9 @@ SlotMachine_CheckForMatches:
jp hl
.flashScreenLoop
- ld a, [rBGP]
+ ldh a, [rBGP]
xor $40
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ld c, 5
call DelayFrames
@@ -474,12 +474,12 @@ SlotMachine_CheckForMatches:
call SlotMachine_PayCoinsToPlayer
call SlotMachine_PrintPayoutCoins
ld a, $e4
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
jp .done
SymbolLinedUpSlotMachineText:
- TX_ASM
+ text_asm
push bc
call SlotMachine_PrintWinningSymbol
ld hl, LinedUpText
@@ -491,8 +491,8 @@ SymbolLinedUpSlotMachineText:
ret
LinedUpText:
- TX_FAR _LinedUpText
- db "@"
+ text_far _LinedUpText
+ text_end
SlotRewardPointers:
dw SlotReward300Func
@@ -521,8 +521,8 @@ SlotReward15Text:
db "15@"
NotThisTimeText:
- TX_FAR _NotThisTimeText
- db "@"
+ text_far _NotThisTimeText
+ text_end
; compares the slot machine tiles at bc, de, and hl
SlotMachine_CheckForMatch:
@@ -612,13 +612,13 @@ SlotReward300Func:
ret
YeahText:
- TX_FAR _YeahText
- TX_DELAY
- db "@"
+ text_far _YeahText
+ text_pause
+ text_end
SlotMachine_PrintWinningSymbol:
; prints winning symbol and down arrow in text box
- coord hl, 2, 14
+ hlcoord 2, 14
ld a, [wSlotMachineWinningSymbol]
add $25
ld [hli], a
@@ -630,7 +630,7 @@ SlotMachine_PrintWinningSymbol:
ld [hli], a
inc a
ld [hl], a
- coord hl, 18, 16
+ hlcoord 18, 16
ld [hl], "▼"
ret
@@ -645,13 +645,13 @@ SlotMachine_SubtractBetFromPlayerCoins:
predef SubBCDPredef
SlotMachine_PrintCreditCoins:
- coord hl, 5, 1
+ hlcoord 5, 1
ld de, wPlayerCoins
ld c, $2
jp PrintBCDNumber
SlotMachine_PrintPayoutCoins:
- coord hl, 11, 1
+ hlcoord 11, 1
ld de, wPayoutCoins
lb bc, LEADING_ZEROES | 2, 4 ; 2 bytes, 4 digits
jp PrintNumber
@@ -698,15 +698,15 @@ SlotMachine_PayCoinsToPlayer:
ld a, [wAnimCounter]
dec a
jr nz, .skip1
- ld a, [rOBP0]
+ ldh a, [rOBP0]
xor $40 ; make the slot wheel symbols flash
- ld [rOBP0], a
+ ldh [rOBP0], a
call UpdateGBCPal_OBP0
ld a, 5
.skip1
ld [wAnimCounter], a
ld a, [wSlotMachineWinningSymbol]
- cp (SLOTSBAR >> 8) + 1
+ cp HIGH(SLOTSBAR) + 1
ld c, 8
jr nc, .skip2
srl c ; c = 4 (make the the coins transfer faster if the symbol was 7 or bar)
@@ -729,19 +729,19 @@ SlotMachine_LightBalls:
jr z, SlotMachine_UpdateTwoCoinBallTiles
SlotMachine_UpdateThreeCoinBallTiles:
- coord hl, 3, 2
+ hlcoord 3, 2
call SlotMachine_UpdateBallTiles
- coord hl, 3, 10
+ hlcoord 3, 10
call SlotMachine_UpdateBallTiles
SlotMachine_UpdateTwoCoinBallTiles:
- coord hl, 3, 4
+ hlcoord 3, 4
call SlotMachine_UpdateBallTiles
- coord hl, 3, 8
+ hlcoord 3, 8
call SlotMachine_UpdateBallTiles
SlotMachine_UpdateOneCoinBallTiles:
- coord hl, 3, 6
+ hlcoord 3, 6
SlotMachine_UpdateBallTiles:
ld a, [wNewSlotMachineBallTile]
@@ -829,7 +829,7 @@ SlotMachine_AnimWheel:
SlotMachine_HandleInputWhileWheelsSpin:
call DelayFrame
call JoypadLowSensitivity
- ld a, [hJoy5]
+ ldh a, [hJoy5]
and A_BUTTON
ret z
ld hl, wStoppingWhichSlotMachineWheel
@@ -854,21 +854,21 @@ LoadSlotMachineTiles:
call DisableLCD
ld hl, SlotMachineTiles2
ld de, vChars0
- ld bc, $1c0
+ ld bc, $1c tiles ; should be SlotMachineTiles2End - SlotMachineTiles2, or $18 tiles
ld a, BANK(SlotMachineTiles2)
call FarCopyData
ld hl, SlotMachineTiles1
ld de, vChars2
- ld bc, $250
+ ld bc, SlotMachineTiles1End - SlotMachineTiles1
ld a, BANK(SlotMachineTiles1)
call FarCopyData
ld hl, SlotMachineTiles2
- ld de, vChars2 + $250
- ld bc, $1c0
+ ld de, vChars2 tile $25
+ ld bc, $1c tiles ; should be SlotMachineTiles2End - SlotMachineTiles2, or $18 tiles
ld a, BANK(SlotMachineTiles2)
call FarCopyData
ld hl, SlotMachineMap
- coord de, 0, 0
+ decoord 0, 0
ld bc, SlotMachineMapEnd - SlotMachineMap
call CopyData
call EnableLCD
@@ -882,10 +882,11 @@ LoadSlotMachineTiles:
jp SlotMachine_AnimWheel3
SlotMachineMap:
- INCBIN "gfx/tilemaps/slotmachine.map"
+ INCBIN "gfx/slots/slots.tilemap"
SlotMachineMapEnd:
-INCLUDE "data/slot_machine_wheels.asm"
+INCLUDE "data/events/slot_machine_wheels.asm"
SlotMachineTiles1:
- INCBIN "gfx/slotmachine1.2bpp"
+ INCBIN "gfx/slots/slots_1.2bpp"
+SlotMachineTiles1End:
diff --git a/engine/special_warps.asm b/engine/special_warps.asm
deleted file mode 100644
index 3a8b8b86..00000000
--- a/engine/special_warps.asm
+++ /dev/null
@@ -1,149 +0,0 @@
-SpecialWarpIn:
- call LoadSpecialWarpData
- predef LoadTilesetHeader
- ld hl, wd732
- bit 2, [hl] ; dungeon warp or fly warp?
- res 2, [hl]
- jr z, .next
-; if dungeon warp or fly warp
- ld a, [wDestinationMap]
- jr .next2
-.next
- bit 1, [hl]
- jr z, .next3
- call EmptyFunc
-.next3
- ld a, 0
-.next2
- ld b, a
- ld a, [wd72d]
- and a
- jr nz, .next4
- ld a, b
-.next4
- ld hl, wd732
- bit 4, [hl] ; dungeon warp?
- ret nz
-; if not dungeon warp
- ld [wLastMap], a
- ret
-
-; gets the map ID, tile block map view pointer, tileset, and coordinates
-LoadSpecialWarpData:
- ld a, [wd72d]
- cp TRADE_CENTER
- jr nz, .notTradeCenter
- ld hl, TradeCenterSpec1
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right
- jr z, .copyWarpData
- ld hl, TradeCenterSpec2
- jr .copyWarpData
-.notTradeCenter
- cp COLOSSEUM
- jr nz, .notColosseum
- ld hl, ColosseumSpec1
- ld a, [hSerialConnectionStatus]
- cp USING_INTERNAL_CLOCK
- jr z, .copyWarpData
- ld hl, ColosseumSpec2
- jr .copyWarpData
-.notColosseum
- ld a, [wd732]
- bit 1, a
- jr nz, .notFirstMap
- bit 2, a
- jr nz, .notFirstMap
- ld hl, FirstMapSpec
-.copyWarpData
- ld de, wCurMap
- ld c, $7
-.copyWarpDataLoop
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyWarpDataLoop
- ld a, [hli]
- ld [wCurMapTileset], a
- xor a
- jr .done
-.notFirstMap
- ld a, [wLastMap] ; this value is overwritten before it's ever read
- ld hl, wd732
- bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)?
- jr nz, .usedDunegonWarp
- bit 6, [hl] ; return to last pokemon center (or player's house)?
- res 6, [hl]
- jr z, .otherDestination
-; return to last pokemon center or player's house
- ld a, [wLastBlackoutMap]
- jr .usedFlyWarp
-.usedDunegonWarp
- ld hl, wd72d
- res 4, [hl]
- ld a, [wDungeonWarpDestinationMap]
- ld b, a
- ld [wCurMap], a
- ld a, [wWhichDungeonWarp]
- ld c, a
- ld hl, DungeonWarpList
- ld de, 0
- ld a, 6
- ld [wDungeonWarpDataEntrySize], a
-.dungeonWarpListLoop
- ld a, [hli]
- cp b
- jr z, .matchedDungeonWarpDestinationMap
- inc hl
- jr .nextDungeonWarp
-.matchedDungeonWarpDestinationMap
- ld a, [hli]
- cp c
- jr z, .matchedDungeonWarpID
-.nextDungeonWarp
- ld a, [wDungeonWarpDataEntrySize]
- add e
- ld e, a
- jr .dungeonWarpListLoop
-.matchedDungeonWarpID
- ld hl, DungeonWarpData
- add hl, de
- jr .copyWarpData2
-.otherDestination
- ld a, [wDestinationMap]
-.usedFlyWarp
- ld b, a
- ld [wCurMap], a
- ld hl, FlyWarpDataPtr
-.flyWarpDataPtrLoop
- ld a, [hli]
- inc hl
- cp b
- jr z, .foundFlyWarpMatch
- inc hl
- inc hl
- jr .flyWarpDataPtrLoop
-.foundFlyWarpMatch
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.copyWarpData2
- ld de, wCurrentTileBlockMapViewPointer
- ld c, $6
-.copyWarpDataLoop2
- ld a, [hli]
- ld [de], a
- inc de
- dec c
- jr nz, .copyWarpDataLoop2
- xor a ; OVERWORLD
- ld [wCurMapTileset], a
-.done
- ld [wYOffsetSinceLastSpecialWarp], a
- ld [wXOffsetSinceLastSpecialWarp], a
- ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps
- ld [wDestinationWarpID], a
- ret
-
-INCLUDE "data/special_warps.asm"
diff --git a/engine/surfing_minigame.asm b/engine/surfing_minigame.asm
index b89d22dc..578e6b1e 100755
--- a/engine/surfing_minigame.asm
+++ b/engine/surfing_minigame.asm
@@ -3,52 +3,52 @@ SurfingPikachuMinigame:
call DelayFrame
call DelayFrame
call DelayFrame
- ld a, [hTilesetType]
+ ldh a, [hTilesetType]
push af
xor a
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ld a, [wUpdateSpritesEnabled]
push af
ld a, $ff
ld [wUpdateSpritesEnabled], a
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $f
- ld [rIE], a
+ ldh [rIE], a
ld a, $8
- ld [rSTAT], a
- ld a, [H_AUTOBGTRANSFERDEST + 1]
+ ldh [rSTAT], a
+ ldh a, [hAutoBGTransferDest + 1]
push af
ld a, $98
- ld [H_AUTOBGTRANSFERDEST + 1], a
+ ldh [hAutoBGTransferDest + 1], a
call SurfingPikachuMinigameIntro
call SurfingPikachuLoop
xor a
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
call ClearObjectAnimationBuffers
call ClearSprites
xor a
- ld [hLCDCPointer], a
- ld [hSCX], a
- ld [hSCY], a
+ ldh [hLCDCPointer], a
+ ldh [hSCX], a
+ ldh [hSCY], a
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
call DelayFrame
pop af
- ld [H_AUTOBGTRANSFERDEST + 1], a
+ ldh [hAutoBGTransferDest + 1], a
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
xor a
- ld [rSTAT], a
+ ldh [rSTAT], a
call RunDefaultPaletteCommand
call ReloadMapAfterSurfingMinigame
call PlayDefaultMusic
@@ -56,7 +56,7 @@ SurfingPikachuMinigame:
pop af
ld [wUpdateSpritesEnabled], a
pop af
- ld [hTilesetType], a
+ ldh [hTilesetType], a
ret
SurfingPikachuLoop:
@@ -88,12 +88,12 @@ SurfingPikachu_CheckPressedSelect:
ld hl, wd492
bit 1, [hl]
ret z
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and SELECT
ret
Func_f80b7:
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and START
ret z
ld hl, wc5e2
@@ -175,7 +175,7 @@ SurfingPikachuMinigame_LoadGFXAndLayout:
xor a
call FillMemory
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call ClearObjectAnimationBuffers
ld hl, SurfingPikachu1Graphics1
@@ -230,12 +230,12 @@ SurfingPikachuMinigame_LoadGFXAndLayout:
call SurfingMinigame_InitScanlineOverrides
xor a
- ld [hSCX], a
- ld [hSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
ld a, $7e
- ld [hWY], a
+ ldh [hWY], a
ld a, rSCY - $ff00
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld a, $40
ld [wSurfingMinigamePikachuSpeed], a
xor a
@@ -251,12 +251,12 @@ SurfingPikachuMinigame_LoadGFXAndLayout:
call Func_f81ff
call Func_f8256
ld a, $e3
- ld [rLCDC], a
+ ldh [rLCDC], a
call SurfingPikachuMinigame_SetBGPals
ld a, $e4
- ld [rOBP0], a
+ ldh [rOBP0], a
ld a, $e0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
ret
@@ -266,13 +266,13 @@ SurfingPikachuMinigame_SetBGPals:
and a
jr nz, .sgb
ld a, $d0
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ret
.sgb
ld a, $e4
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
ret
@@ -479,31 +479,31 @@ Func_f8324:
ld hl, wSurfingMinigameRoutineNumber
inc [hl]
ld a, $90
- ld [hSCX], a
+ ldh [hSCX], a
ld a, $72
ld [wSurfingMinigameWaveFunctionNumber], a
ld a, $4
ld [wc5d2], a
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld [wSurfingMinigameSCX], a
ld [wSurfingMinigameSCX + 1], a
ld [wSurfingMinigameSCX + 2], a
ret
Func_f835c:
- ld a, [hSCX]
+ ldh a, [hSCX]
and a
jr z, .asm_f837b
call SurfingMinigame_UpdateLYOverrides
call SurfingMinigame_SetPikachuHeight
call SurfingMinigame_ReadBGMapBuffer
- ld a, [hSCX]
+ ldh a, [hSCX]
dec a
dec a
dec a
dec a
- ld [hSCX], a
+ ldh [hSCX], a
ld a, $e0
ld [wSurfingMinigameXOffset], a
call SurfingMinigame_GenerateBGMap
@@ -599,7 +599,7 @@ SurfingMinigame_WaitLast:
SurfingMinigame_ExitOnPressA:
call SurfingMinigame_UpdateLYOverrides
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and A_BUTTON
ret z
ld hl, wSurfingMinigameRoutineNumber
@@ -620,7 +620,7 @@ SurfingMinigame_GameOver:
ret
.wait_press_a
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and A_BUTTON
ret z
ld hl, wSurfingMinigameRoutineNumber
@@ -662,7 +662,7 @@ SurfingMinigame_UpdatePikachuDistance:
dec [hl]
ret
-SurfingMinigameAnimatedObjectFn_Pikachu
+SurfingMinigameAnimatedObjectFn_Pikachu:
ld a, [wc5d2]
ld e, a
ld d, $0
@@ -1088,7 +1088,7 @@ SufingMinigame_ReduceSpeedBy128:
ret
Func_f871e:
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
cp $3
jr c, .asm_f8740
@@ -1110,7 +1110,7 @@ Func_f871e:
ret
Func_f8742:
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
cp $3
ret c
@@ -1209,7 +1209,7 @@ Func_f87b5:
ret
.GetYCoord:
- ld a, [hSCX]
+ ldh a, [hSCX]
and $8
jr nz, .get_height_plus_9
ld hl, wSurfingMinigameWaveHeight + 8
@@ -1229,7 +1229,7 @@ Func_f87b5:
ret
.six_or_twenty
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
ld e, a
ld a, [hl]
@@ -1237,7 +1237,7 @@ Func_f87b5:
ret
.seven
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
add [hl]
ret
@@ -1328,7 +1328,7 @@ SurfingMinigame_MoveClouds:
SurfingMinigame_ReadBGMapBuffer:
ld a, [wSurfingMinigameBGMapReadBuffer] ; ???
- ld a, [hSCX]
+ ldh a, [hSCX]
add $48
ld e, a
srl e
@@ -1358,19 +1358,19 @@ SurfingMinigame_ReadBGMapBuffer:
.copy
ld de, wSurfingMinigameBGMapReadBuffer
ld a, e
- ld [H_VBCOPYDEST], a
+ ldh [hVBlankCopyDest], a
ld a, d
- ld [H_VBCOPYDEST + 1], a
+ ldh [hVBlankCopyDest + 1], a
ld a, l
- ld [H_VBCOPYSRC], a
+ ldh [hVBlankCopySource], a
ld a, h
- ld [H_VBCOPYSRC + 1], a
+ ldh [hVBlankCopySource + 1], a
ld a, 16 / $10
- ld [H_VBCOPYSIZE], a
+ ldh [hVBlankCopySize], a
ret
SurfingMinigame_SetPikachuHeight:
- ld a, [hSCX]
+ ldh a, [hSCX]
and $8
jr nz, .asm_f88b9
ld hl, wSurfingMinigameWaveHeight + 7
@@ -1391,7 +1391,7 @@ SurfingMinigame_SetPikachuHeight:
ret
.asm_f88d0
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
ld e, a
ld a, [hl]
@@ -1400,7 +1400,7 @@ SurfingMinigame_SetPikachuHeight:
ret
.asm_f88db
- ld a, [hSCX]
+ ldh a, [hSCX]
and $7
add [hl]
ld [wSurfingMinigamePikachuObjectHeight], a
@@ -1457,7 +1457,7 @@ SurfingMinigame_DrawResultsScreen:
xor a
call FillMemory
ld hl, .BeachTilemap
- coord de, 0, 6
+ decoord 0, 6
ld bc, .BeachTilemapEnd - .BeachTilemap
call CopyData
call .PlaceTextbox
@@ -1466,7 +1466,7 @@ SurfingMinigame_DrawResultsScreen:
xor a
call FillMemory
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
.BeachTilemap:
@@ -1474,39 +1474,39 @@ INCBIN "gfx/unknown_f8946.map"
.BeachTilemapEnd:
.PlaceTextbox:
- coord hl, 1, 1
+ hlcoord 1, 1
lb de, $3b, $3c
ld a, $40
call .place_row
- coord hl, 1, 2
+ hlcoord 1, 2
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 3
+ hlcoord 1, 3
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 4
+ hlcoord 1, 4
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 5
+ hlcoord 1, 5
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 6
+ hlcoord 1, 6
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 7
+ hlcoord 1, 7
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 8
+ hlcoord 1, 8
lb de, $3f, $3f
ld a, $ff
call .place_row
- coord hl, 1, 9
+ hlcoord 1, 9
lb de, $3d, $3e
ld a, $40
call .place_row
@@ -1525,7 +1525,7 @@ INCBIN "gfx/unknown_f8946.map"
SurfingMinigame_PrintTextHiScore:
ld hl, .Hi_Score
- coord de, 6, 8
+ decoord 6, 8
ld bc, $9
call CopyData
ret
@@ -1535,7 +1535,7 @@ SurfingMinigame_PrintTextHiScore:
SurfingMinigame_WriteHPLeft:
ld hl, .HP_Left
- coord de, 2, 2
+ decoord 2, 2
ld bc, $7
call CopyData
call SurfingMinigame_BCDPrintHPLeft
@@ -1570,7 +1570,7 @@ SurfingMinigame_AddRemainingHPToTotal:
ret
SurfingMinigame_BCDPrintHPLeft:
- coord hl, 10, 2
+ hlcoord 10, 2
ld de, wSurfingMinigamePikachuHP + 1
ld a, [de]
call SurfingPikachu_PlaceBCDNumber
@@ -1588,7 +1588,7 @@ SurfingMinigame_BCDPrintHPLeft:
SurfingMinigame_WriteRadness:
ld hl, .Radness
- coord de, 2, 4
+ decoord 2, 4
ld bc, $7
call CopyData
call SurfingMinigame_BCDPrintRadness
@@ -1633,10 +1633,10 @@ SurfingMinigame_AddRadnessToTotal:
SurfingMinigame_BCDPrintRadness:
ld a, [wSurfingMinigameRadnessScore + 1]
- coord hl, 10, 4
+ hlcoord 10, 4
call SurfingPikachu_PlaceBCDNumber
ld a, [wSurfingMinigameRadnessScore]
- coord hl, 12, 4
+ hlcoord 12, 4
call SurfingPikachu_PlaceBCDNumber
inc hl
inc hl
@@ -1664,10 +1664,10 @@ SurfingMinigame_AddPointsToTotal:
SurfingMinigame_BCDPrintTotalScore:
ld a, [wSurfingMinigameTotalScore + 1]
- coord hl, 10, 6
+ hlcoord 10, 6
call SurfingPikachu_PlaceBCDNumber
ld a, [wSurfingMinigameTotalScore]
- coord hl, 12, 6
+ hlcoord 12, 6
call SurfingPikachu_PlaceBCDNumber
inc hl
inc hl
@@ -1680,7 +1680,7 @@ SurfingMinigame_BCDPrintTotalScore:
SurfingMinigame_WriteTotal:
ld hl, .Total
- coord de, 2, 6
+ decoord 2, 6
ld bc, $5
call CopyData
call SurfingMinigame_BCDPrintRadness
@@ -1723,10 +1723,10 @@ DidPlayerGetAHighScore:
SurfingMinigame_PlayPikaCryIfSurfingPikaInParty:
push de
- callab IsSurfingPikachuInThePlayersParty
+ callfar IsSurfingPikachuInThePlayersParty
pop de
ret nc
- callab PlayPikachuSoundClip
+ callfar PlayPikachuSoundClip
ret
SurfingMinigame_IncreaseRadnessMeter:
@@ -1853,7 +1853,7 @@ SurfingMinigame_AddRadness:
Func_f8c97:
ld a, $a0
ld [wSurfingMinigameXOffset], a
- ld a, [hSCX]
+ ldh a, [hSCX]
ld h, a
ld a, [wSurfingMinigameSCX]
ld l, a
@@ -1862,13 +1862,13 @@ Func_f8c97:
ld a, l
ld [wSurfingMinigameSCX], a
ld a, h
- ld [hSCX], a
+ ldh [hSCX], a
jr SurfingMinigame_GenerateBGMap
SurfingMinigame_ScrollAndGenerateBGMap:
ld a, $a0
ld [wSurfingMinigameXOffset], a
- ld a, [hSCX]
+ ldh a, [hSCX]
ld h, a
ld a, [wSurfingMinigameSCX]
ld l, a
@@ -1877,10 +1877,10 @@ SurfingMinigame_ScrollAndGenerateBGMap:
ld a, l
ld [wSurfingMinigameSCX], a
ld a, h
- ld [hSCX], a
+ ldh [hSCX], a
SurfingMinigame_GenerateBGMap:
ld hl, wSurfingMinigameSCX + 1
- ld a, [hSCX]
+ ldh a, [hSCX]
cp [hl]
ret z
ld [hl], a
@@ -1921,7 +1921,7 @@ SurfingMinigame_GenerateBGMap:
jr nz, .loop
ld a, [wSurfingMinigameXOffset]
ld e, a
- ld a, [hSCX]
+ ldh a, [hSCX]
add e
and $f0
srl a
@@ -1932,11 +1932,11 @@ SurfingMinigame_GenerateBGMap:
ld hl, vBGMap0
add hl, de
ld a, l
- ld [hRedrawRowOrColumnDest], a
+ ldh [hRedrawRowOrColumnDest], a
ld a, h
- ld [hRedrawRowOrColumnDest + 1], a
+ ldh [hRedrawRowOrColumnDest + 1], a
ld a, $1
- ld [hRedrawRowOrColumnMode], a
+ ldh [hRedrawRowOrColumnMode], a
ret
.CopyRedrawSrcTiles:
@@ -2330,7 +2330,7 @@ SurfingPikachuMinigameIntro:
call ClearSprites
call DisableLCD
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call ClearObjectAnimationBuffers
ld hl, SurfingPikachu1Graphics3
ld de, $8800
@@ -2358,24 +2358,24 @@ SurfingPikachuMinigameIntro:
call SpawnAnimatedObject
call DrawSurfingPikachuMinigameIntroBackground
xor a
- ld [hSCX], a
- ld [hSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
ld b, $f
call RunPaletteCommand
ld a, $e3
- ld [rLCDC], a
+ ldh [rLCDC], a
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call DelayFrame
call DelayFrame
call DelayFrame
call SurfingPikachuMinigame_SetBGPals
ld a, $e4
- ld [rOBP0], a
+ ldh [rOBP0], a
ld a, $e0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
call DelayFrame
@@ -2400,22 +2400,22 @@ DrawSurfingPikachuMinigameIntroBackground:
ld a, $ff
call FillMemory
ld hl, Tilemap_f90bc
- coord de, 0, 6
+ decoord 0, 6
ld bc, 12 * SCREEN_WIDTH
call CopyData
ld de, Tilemap_f91c8
- coord hl, 4, 0
+ hlcoord 4, 0
lb bc, 6, 12
call .CopyBox
- coord hl, 3, 7
+ hlcoord 3, 7
lb bc, 3, 15
call .FillBoxWithFF
ld hl, Tilemap_f91ac
- coord de, 3, 7
+ decoord 3, 7
ld bc, 15
call CopyData
ld hl, Tilemap_f91bb
- coord de, 4, 9
+ decoord 4, 9
ld bc, 13
call CopyData
ret
@@ -2499,25 +2499,25 @@ SurfingMinigame_InitScanlineOverrides:
SurfingPikachu_GetJoypad_3FrameBuffer:
call Joypad
- ld a, [H_FRAMECOUNTER]
+ ldh a, [hFrameCounter]
and a
jr nz, .delayed
- ld a, [hJoyHeld]
- ld [hJoy5], a
+ ldh a, [hJoyHeld]
+ ldh [hJoy5], a
ld a, $2
- ld [H_FRAMECOUNTER], a
+ ldh [hFrameCounter], a
ret
.delayed
xor a
- ld [hJoy5], a
+ ldh [hJoy5], a
ret
SurfingPikachuMinigame_BlankPals:
xor a
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -2525,10 +2525,10 @@ SurfingPikachuMinigame_BlankPals:
SurfingPikachuMinigame_NormalPals:
ld a, $e4
- ld [rBGP], a
- ld [rOBP0], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
ld a, $e0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
diff --git a/engine/test_battle.asm b/engine/test_battle.asm
deleted file mode 100644
index d9dcf1fa..00000000
--- a/engine/test_battle.asm
+++ /dev/null
@@ -1,45 +0,0 @@
-TestBattle:
- ret
-
-.loop
- call GBPalNormal
-
- ; Don't mess around
- ; with obedience.
- ld a, %10000000 ; EARTHBADGE
- ld [wObtainedBadges], a
-
- ld hl, wFlags_D733
- set BIT_TEST_BATTLE, [hl]
-
- ; Reset the party.
- ld hl, wPartyCount
- xor a
- ld [hli], a
- dec a
- ld [hl], a
-
- ; Give the player a
- ; level 20 Rhydon.
- ld a, RHYDON
- ld [wcf91], a
- ld a, 20
- ld [wCurEnemyLVL], a
- xor a
- ld [wMonDataLocation], a
- ld [wCurMap], a
- call AddPartyMon
-
- ; Fight against a
- ; level 20 Rhydon.
- ld a, RHYDON
- ld [wCurOpponent], a
-
- predef InitOpponent
-
- ; When the battle ends,
- ; do it all again.
- ld a, 1
- ld [wUpdateSpritesEnabled], a
- ld [H_AUTOBGTRANSFERENABLED], a
- jr .loop
diff --git a/engine/titlescreen.asm b/engine/titlescreen.asm
deleted file mode 100755
index d4dd0fd3..00000000
--- a/engine/titlescreen.asm
+++ /dev/null
@@ -1,370 +0,0 @@
-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
-; todo: fix hl pointers
- ld hl, NintendoCopyrightLogoGraphics
- ld de, vTitleLogo + $600
- ld bc, $50
- ld a, BANK(NintendoCopyrightLogoGraphics)
- call FarCopyData
- ld hl, NineTile
- ld de, vTitleLogo + $6e0
- ld bc, $10
- ld a, BANK(NineTile)
- call FarCopyData
- ld hl, GamefreakLogoGraphics
- ld de, vTitleLogo + 101 * $10
- ld bc, 9 * $10
- ld a, BANK(GamefreakLogoGraphics)
- call FarCopyData
- callab LoadYellowTitleScreenGFX
- ld hl, vBGMap0
- ld bc, (vBGMap1 + $400) - vBGMap0
- ld a, " "
- call FillMemory
- callab TitleScreen_PlacePokemonLogo
- call FillSpriteBuffer0WithAA
- call .WriteCopyrightTiles
- call SaveScreenTilesToBuffer2
- call LoadScreenTilesFromBuffer2
- call EnableLCD
- callab TitleScreen_PlacePikachu
- ld a, $9b
- 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, %11100000
- ld [rOBP0], a
- call UpdateGBCPal_OBP0
-
-; 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
-
-; place tiles for title screen copyright
-.WriteCopyrightTiles
- coord hl, 2, 17
- ld de, .tileScreenCopyrightTiles
-.titleScreenCopyrightTilesLoop
- ld a, [de]
- inc de
- cp $ff
- ret z
- ld [hli], a
- jr .titleScreenCopyrightTilesLoop
-
-.tileScreenCopyrightTiles
- db $e0,$e1,$e2,$e3,$e1,$e2,$ee,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ff ; ©1995-1999 GAME FREAK inc.
-
-.finishedBouncingPokemonLogo
- call LoadScreenTilesFromBuffer1
- ld c, 36
- call DelayFrames
- ld a, SFX_INTRO_WHOOSH
- call PlaySound
-
-; scroll game version in from the right
- callab TitleScreen_PlacePikaSpeechBubble
- ld a, SCREEN_HEIGHT_PIXELS
- ld [hWY], a
- call Delay3
- ld e, 0
- call TitleScreen_PlayPikachuPCM
- call WaitForSoundToFinish
- call StopAllMusic
- ld a, MUSIC_TITLE_SCREEN
- ld [wNewSoundID], a
- call PlaySound
-.loop
- xor a
- ld [wUnusedCC5B], a
- ld [wTitleScreenScene], a
- ld [wTitleScreenScene + 1], a
- ld [wTitleScreenScene + 2], a
- ld [wTitleScreenScene + 3], a
- ld a, $f
- ld [wTitleScreenScene + 4], a
-.titleScreenLoop
- call IncrementResetCounter
- jp c, .doTitlescreenReset
- call DelayFrame
- call JoypadLowSensitivity
- ld a, [hJoyHeld]
- cp D_UP | SELECT | B_BUTTON
- jr z, .go_to_main_menu
- and A_BUTTON | START
- jr nz, .go_to_main_menu
- call DoTitleScreenFunction
- jr .titleScreenLoop
-
-.go_to_main_menu
- ld e, $a
- call TitleScreen_PlayPikachuPCM
- 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
-
-.asm_42f0
-; unreferenced
- callab PrinterDebug
- jp .loop
-
-.asm_42fb
-; unreferenced
- ld a, [wTitleScreenScene + 4]
- inc a
- cp $2a
- jr c, .asm_4305
- ld a, $f
-.asm_4305
- ld [wTitleScreenScene + 4], a
- ld e, a
- callab PlayPikachuSoundClip
- xor a
- ld [wTitleScreenScene + 2], a
- ld [wTitleScreenScene + 3], a
- jp .titleScreenLoop
-
-.doTitlescreenReset
- ld [wAudioFadeOutControl], a
- call StopAllMusic
-.audioFadeLoop
- ld a, [wAudioFadeOutControl]
- and a
- jr nz, .audioFadeLoop
- jp Init
-
-.doClearSaveDialogue
- jpba DoClearSaveDialogue
-
-
-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), (TextBoxGraphics + $10 - NintendoCopyrightLogoGraphics) / $10 ; bug: overflows into text box graphics and copies the "A" tile
- call CopyVideoData
- coord hl, 2, 7
- ld de, CopyrightTextString
- jp PlaceString
-
-CopyrightTextString:
- db $60,$61,$62,$63,$61,$62,$7c,$7f,$65,$66,$67,$68,$69,$6a ; ©1995-1999 Nintendo
- next $60,$61,$62,$63,$61,$62,$7c,$7f,$6b,$6c,$6d,$6e,$6f,$70,$71,$72 ; ©1995-1999 Creatures inc.
- next $60,$61,$62,$63,$61,$62,$7c,$7f,$73,$74,$75,$76,$77,$78,$79,$7a,$7b ; ©1995-1999 GAME FREAK inc.
- db "@"
-
-TitleScreen_PlayPikachuPCM:
- callab PlayPikachuSoundClip
- ret
-
-DoTitleScreenFunction:
- call .CheckTimer
- ld a, [wTitleScreenScene]
- ld e, a
- ld d, 0
- ld hl, .Jumptable
- add hl, de
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- jp hl
-
-
-.Jumptable:
- dw .Nop
- dw .BlinkHalf
- dw .BlinkWait
- dw .BlinkWait
- dw .BlinkClosed
- dw .BlinkWait
- dw .BlinkWait
- dw .BlinkHalf
- dw .BlinkWait
- dw .BlinkWait
- dw .BlinkOpen
- dw .GoBackToStart
-
-.GoBackToStart:
- xor a
- ld [wTitleScreenScene], a
-.Nop
- ret
-
-.BlinkOpen:
- ld e, 0
- jr .LoadBlinkFrame
-
-.BlinkHalf:
- ld e, 4
- jr .LoadBlinkFrame
-
-.BlinkClosed:
- ld e, 8
-.LoadBlinkFrame:
- ld hl, wOAMBuffer + 2
- ld c, 8
-.loop
- ld a, [hl]
- and $f3
- or e
- ld [hli], a
- inc hl
- inc hl
- inc hl
- dec c
- jr nz, .loop
-.BlinkWait:
- ld hl, wTitleScreenScene
- inc [hl]
- ret
-
-.CheckTimer:
- ld hl, wTitleScreenTimer
- ld a, [hl]
- inc [hl]
- and a
- jr z, .restart
- cp $80
- jr z, .restart
- cp $90
- ret nz
-.restart
- ld a, $1
- ld [wTitleScreenScene], a
- ret
-
-; copy text of fixed length NAME_LENGTH (like player name, rival name, mon names, ...)
-CopyFixedLengthText:
- ld bc, NAME_LENGTH
- jp CopyData
-
-NintenText: db "NINTEN@"
-SonyText: db "SONY@"
-
-IncrementResetCounter:
- ld hl, wTitleScreenScene + 2
- ld e, [hl]
- inc hl
- ld d, [hl]
- inc de
- ld a, d
- cp $c
- jr z, .doReset
- ld [hl], d
- dec hl
- ld [hl], e
- and a
- ret
-
-.doReset
- scf
- ret
-
-FillSpriteBuffer0WithAA:
- xor a
- call SwitchSRAMBankAndLatchClockData
- ld hl, sSpriteBuffer0
- ld bc, $20
- ld a, $aa
- call FillMemory
- call PrepareRTCDataAndDisableSRAM
- ret
diff --git a/engine/titlescreen2.asm b/engine/titlescreen2.asm
deleted file mode 100755
index 8b4bc4de..00000000
--- a/engine/titlescreen2.asm
+++ /dev/null
@@ -1,122 +0,0 @@
-; Leftover of Red/Blue. Seemingly unused
-
-TitleScroll_WaitBall:
-; Wait around for the TitleBall animation to play out.
-; hi: speed
-; lo: duration
- db $05, $05, 0
-
-TitleScroll_In:
-; Scroll a TitleMon in from the right.
-; hi: speed
-; lo: duration
- db $a2, $94, $84, $63, $52, $31, $11, 0
-
-TitleScroll_Out:
-; Scroll a TitleMon out to the left.
-; hi: speed
-; lo: duration
- db $12, $22, $32, $42, $52, $62, $83, $93, 0
-
-TitleScroll:
- ld a, d
-
- ld bc, TitleScroll_In
- ld d, $88
- ld e, 0 ; don't animate titleball
-
- and a
- jr nz, .ok
-
- ld bc, TitleScroll_Out
- ld d, $00
- ld e, 0 ; don't animate titleball
-.ok
-
-_TitleScroll:
- ld a, [bc]
- and a
- ret z
-
- inc bc
- push bc
-
- ld b, a
- and $f
- ld c, a
- ld a, b
- and $f0
- swap a
- ld b, a
-
-.loop
- ld h, d
- ld l, $48
- call .ScrollBetween
-
- ld h, $00
- ld l, $88
- call .ScrollBetween
-
- ld a, d
- add b
- ld d, a
-
- call GetTitleBallY
- dec c
- jr nz, .loop
-
- pop bc
- jr _TitleScroll
-
-.ScrollBetween:
-.wait
- ld a, [rLY] ; rLY
- cp l
- jr nz, .wait
-
- ld a, h
- ld [rSCX], a
-
-.wait2
- ld a, [rLY] ; rLY
- cp h
- jr z, .wait2
- ret
-
-TitleBallYTable:
-; OBJ y-positions for the Poke Ball held by Red in the title screen.
-; This is really two 0-terminated lists. Initiated with an index of 1.
- db 0, $71, $6f, $6e, $6d, $6c, $6d, $6e, $6f, $71, $74, 0
-
-TitleScreenAnimateBallIfStarterOut:
-; Animate the TitleBall if a starter just got scrolled out.
- ld a, [wTitleScreenScene]
- cp STARTER1
- jr z, .ok
- cp STARTER2
- jr z, .ok
- cp STARTER3
- ret nz
-.ok
- ld e, 1 ; animate titleball
- ld bc, TitleScroll_WaitBall
- ld d, 0
- jp _TitleScroll
-
-GetTitleBallY:
-; Get position e from TitleBallYTable
- push de
- push hl
- xor a
- ld d, a
- ld hl, TitleBallYTable
- add hl, de
- ld a, [hl]
- pop hl
- pop de
- and a
- ret z
- ld [wOAMBuffer + $28], a
- inc e
- ret
diff --git a/engine/town_map.asm b/engine/town_map.asm
deleted file mode 100755
index 7d32b5fe..00000000
--- a/engine/town_map.asm
+++ /dev/null
@@ -1,628 +0,0 @@
-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
-
-.asm_70f87
- ld a,[hJoy5]
- and D_DOWN | D_UP
- ret z
- callab PlayPikachuSoundClip
- ret
-
-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
- ld a, $1
- ld [hJoy7], a
- call LoadPlayerSpriteGraphics
- call LoadFontTilePatterns
- ld de, BirdSprite
- ld b, BANK(BirdSprite)
- ld c, $c
- ld hl, vSprites + $40
- 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
- ld [hJoy7], 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
- lb bc, $12, $12
- call TextBoxBorder
- call DisableLCD
- ld hl, WorldMapTileGraphics
- ld de, vChars2 + $600
- ld bc, WorldMapTileGraphicsEnd - WorldMapTileGraphics
- ld a, BANK(WorldMapTileGraphics)
- call FarCopyData
- 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
- lb bc, 2, 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"
-
-INCLUDE "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/engine/trade.asm b/engine/trade.asm
deleted file mode 100755
index e4bc0768..00000000
--- a/engine/trade.asm
+++ /dev/null
@@ -1,857 +0,0 @@
-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
- and %110000 ; preserve speaker options
- ld [wOptions], a
- ld a, [hSCY]
- push af
- ld a, [hSCX]
- push af
- xor 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 FarCopyData
- ld hl, TradingAnimationGraphics2
- ld de, vSprites + $7c0
- ld bc, TradingAnimationGraphics2End - TradingAnimationGraphics2
- ld a, BANK(TradingAnimationGraphics2)
- call FarCopyData
- 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 UpdateGBCPal_OBP0
- 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
- call UpdateGBCPal_OBP1
- 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
- lb bc, 6, 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
- call UpdateGBCPal_OBP0
- 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
- lb bc, 6, 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
- call UpdateGBCPal_OBP0
- 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
- ld b, SET_PAL_GENERIC
- call RunPaletteCommand
- 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
- lb bc, 2, 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
- lb bc, 2, 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
- call UpdateGBCPal_BGP
- 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 ; SCREEN_WIDTH?
-.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/engine/unknown_ea3ea.asm b/engine/unknown_ea3ea.asm
index 1908809b..c10f1555 100755
--- a/engine/unknown_ea3ea.asm
+++ b/engine/unknown_ea3ea.asm
@@ -13,7 +13,7 @@ Printer_GetMonStats:
call CopyVideoDataDouble
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
xor a
ld [wWhichTradeMonSelectionMenu], a
call LoadMonData
@@ -22,22 +22,22 @@ Printer_GetMonStats:
lb bc, 16, 18
call TextBoxBorder
- coord hl, 0, 12
+ hlcoord 0, 12
lb bc, 4, 18
call TextBoxBorder
- coord hl, 3, 10
+ hlcoord 3, 10
call PrintLevelFull
- coord hl, 2, 10
+ hlcoord 2, 10
ld a, $6e
ld [hli], a
ld [hl], " "
- coord hl, 2, 11
- ld [hl], "′"
+ hlcoord 2, 11
+ ld [hl], "’"
- coord hl, 4, 11
+ hlcoord 4, 11
ld de, wLoadedMonMaxHP
lb bc, 2, 3
call PrintNumber
@@ -47,15 +47,15 @@ Printer_GetMonStats:
ld [wd0b5], a
ld hl, wPartyMonNicks
call .GetNamePointer
- coord hl, 8, 2
+ hlcoord 8, 2
call PlaceString
call GetMonName
- coord hl, 9, 3
+ hlcoord 9, 3
call PlaceString
predef IndexToPokedex
- coord hl, 2, 8
+ hlcoord 2, 8
ld [hl], "№"
inc hl
ld [hl], $f2
@@ -64,35 +64,35 @@ Printer_GetMonStats:
lb bc, $80 | 1, 3
call PrintNumber
- coord hl, 8, 4
+ hlcoord 8, 4
ld de, .OT
call PlaceString
ld hl, wPartyMonOT
call .GetNamePointer
- coord hl, 9, 5
+ hlcoord 9, 5
call PlaceString
- coord hl, 9, 6
+ hlcoord 9, 6
ld de, .IDNo
call PlaceString
- coord hl, 13, 6
+ hlcoord 13, 6
ld de, wLoadedMonOTID
lb bc, $80 | 2, 5
call PrintNumber
- coord hl, 9, 8
+ hlcoord 9, 8
ld de, .Stats
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
set 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
call PlaceString
- ld a, [hFlags_0xFFFA]
+ ldh a, [hFlagsFFFA]
res 2, a
- ld [hFlags_0xFFFA], a
+ ldh [hFlagsFFFA], a
- coord hl, 16, 8
+ hlcoord 16, 8
ld de, wLoadedMonAttack
ld a, 4
.loop
@@ -113,19 +113,19 @@ Printer_GetMonStats:
dec a
jr nz, .loop
- coord hl, 1, 13
+ hlcoord 1, 13
ld a, [wLoadedMonMoves]
call .PlaceMoveName
- coord hl, 1, 14
+ hlcoord 1, 14
ld a, [wLoadedMonMoves + 1]
call .PlaceMoveName
- coord hl, 1, 15
+ hlcoord 1, 15
ld a, [wLoadedMonMoves + 2]
call .PlaceMoveName
- coord hl, 1, 16
+ hlcoord 1, 16
ld a, [wLoadedMonMoves + 3]
call .PlaceMoveName
@@ -133,10 +133,10 @@ Printer_GetMonStats:
call RunPaletteCommand
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call Delay3
call GBPalNormal
- coord hl, 1, 1
+ hlcoord 1, 1
call LoadFlippedFrontSpriteByMonIndex
ret
@@ -468,11 +468,11 @@ Func_ea74c:
ld [wPrinterSendByteOffset], a
ld [wPrinterSendByteOffset + 1], a
ld a, $88
- ld [rSB], a
+ ldh [rSB], a
ld a, $1
- ld [rSC], a
+ ldh [rSC], a
ld a, $81
- ld [rSC], a
+ ldh [rSC], a
ret
Func_ea76b:
@@ -832,25 +832,25 @@ PrinterDebug_PrepOAMForPrinting:
dw .Pal3
.Pal0:
- ld a, [rOBP0]
+ ldh a, [rOBP0]
and $3
ret
.Pal2:
- ld a, [rOBP0]
+ ldh a, [rOBP0]
and $c
srl a
srl a
ret
.Pal1:
- ld a, [rOBP0]
+ ldh a, [rOBP0]
and $30
swap a
ret
.Pal3:
- ld a, [rOBP0]
+ ldh a, [rOBP0]
and $c0
rlca
rlca
diff --git a/engine/vermilion_gym_trash_cans.asm b/engine/vermilion_gym_trash_cans.asm
index 49dee50c..1bc0590b 100755
--- a/engine/vermilion_gym_trash_cans.asm
+++ b/engine/vermilion_gym_trash_cans.asm
@@ -54,7 +54,7 @@ Yellow_SampleSecondTrashCan:
call AddNTimes
call AddNTimes ; ????
ld a, [hli]
- ld [hGymTrashCanRandNumMask], a
+ ldh [hGymTrashCanRandNumMask], a
ld e, a
push hl
call TrashCanRandom
diff --git a/engine/yellow_intro.asm b/engine/yellow_intro.asm
index 9c9e26b3..324ba86d 100755
--- a/engine/yellow_intro.asm
+++ b/engine/yellow_intro.asm
@@ -1,12 +1,12 @@
PlayIntroScene:
- ld a, [rIE]
+ ldh a, [rIE]
push af
xor a
- ld [rIF], a
+ ldh [rIF], a
ld a, $f
- ld [rIE], a
+ ldh [rIE], a
ld a, $8
- ld [rSTAT], a
+ ldh [rSTAT], a
call InitYellowIntroGFXAndMusic
call DelayFrame
.loop
@@ -14,7 +14,7 @@ PlayIntroScene:
bit 7, a
jr nz, .go_to_title_screen
call JoypadLowSensitivity
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
and A_BUTTON | B_BUTTON | START
jr nz, .go_to_title_screen
call Func_f98fc
@@ -32,14 +32,14 @@ PlayIntroScene:
.go_to_title_screen
call YellowIntro_BlankPalettes
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
call DelayFrame
xor a
- ld [rIF], a
+ ldh [rIF], a
pop af
- ld [rIE], a
+ ldh [rIE], a
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
call ClearObjectAnimationBuffers
ld hl, wTileMap
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
@@ -47,12 +47,12 @@ PlayIntroScene:
call Bank3E_FillMemory
call YellowIntro_BlankOAMBuffer
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call DelayFrame
call DelayFrame
call DelayFrame
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ret
Func_f98a2:
@@ -127,20 +127,20 @@ YellowIntro_NextScene:
YellowIntroScene0:
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
lb de, $58, $58
ld a, $1
call YellowIntro_SpawnAnimatedObjectAndSavePointer
xor a
- ld [hSCX], a
- ld [hSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
ld a, $e4
- ld [rBGP], a
- ld [rOBP0], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
ld a, $c4
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -161,7 +161,7 @@ YellowIntroScene2:
ld c, $8
call UpdateMusicCTimes
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld hl, vBGMap0
ld bc, $400
xor a
@@ -196,7 +196,7 @@ YellowIntroScene2_PlaceGraphic:
add $10
dec b
jr nz, .row
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .dmg_sgb
; We can actually set palettes!
@@ -204,7 +204,7 @@ YellowIntroScene2_PlaceGraphic:
ld de, $20
ld b, $6
ld a, $1
- ld [rVBK], a
+ ldh [rVBK], a
.attr_row
ld c, $6
push hl
@@ -217,7 +217,7 @@ YellowIntroScene2_PlaceGraphic:
dec b
jr nz, .attr_row
xor a
- ld [rVBK], a
+ ldh [rVBK], a
.dmg_sgb
ret
@@ -260,11 +260,11 @@ YellowIntroFlyingSpeedBarData:
YellowIntroScene3:
call YellowIntro_CheckFrameTimerDecrement
jr c, .expired
- ld a, [hSCX]
+ ldh a, [hSCX]
cp $68
ret z
add $4
- ld [hSCX], a
+ ldh [hSCX], a
ret
.expired
@@ -276,7 +276,7 @@ YellowIntroScene4:
call YellowIntro_BlankPalsDelay2AndDisableLCD
ld c, $5
call UpdateMusicCTimes
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .dmg_sgb
; We can actually set palettes!
@@ -284,7 +284,7 @@ YellowIntroScene4:
ld de, $20
ld b, $6
ld a, $1
- ld [rVBK], a
+ ldh [rVBK], a
xor a
.attr_row
ld c, $6
@@ -298,10 +298,10 @@ YellowIntroScene4:
dec b
jr nz, .attr_row
xor a
- ld [rVBK], a
+ ldh [rVBK], a
.dmg_sgb
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
call Func_f9e5f
lb de, $58, $58
ld a, $2
@@ -324,7 +324,7 @@ YellowIntroScene6:
ld c, $5
call UpdateMusicCTimes
ld a, rSCY - $ff00
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
call YellowIntro_Copy8BitSineWave
ld hl, vBGMap0
ld bc, $60
@@ -385,7 +385,7 @@ YellowIntroScene8:
ld c, $5
call UpdateMusicCTimes
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
call Func_f9e5f
lb de, $58, $58
ld a, $3
@@ -408,7 +408,7 @@ YellowIntroScene10:
ld c, $5
call UpdateMusicCTimes
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld hl, vBGMap0
ld bc, $400
xor a
@@ -476,15 +476,15 @@ YellowIntroScene11:
ld hl, YellowIntroCloudGFX1
add hl, de
ld a, l
- ld [H_VBCOPYSRC], a
+ ldh [hVBlankCopySource], a
ld a, h
- ld [H_VBCOPYSRC + 1], a
+ ldh [hVBlankCopySource + 1], a
xor a
- ld [H_VBCOPYDEST], a
+ ldh [hVBlankCopyDest], a
ld a, $96
- ld [H_VBCOPYDEST + 1], a
+ ldh [hVBlankCopyDest + 1], a
ld a, $4
- ld [H_VBCOPYSIZE], a
+ ldh [hVBlankCopySize], a
ret
.expired
@@ -500,7 +500,7 @@ YellowIntroScene12:
ld c, $5
call UpdateMusicCTimes
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld hl, vBGMap0
ld bc, $80
ld a, $1
@@ -561,10 +561,10 @@ YellowIntroScene14:
ld de, YellowIntroPalSequence_f9dd6
call YellowIntro_LoadDMGPalAndIncrementCounter
jr c, .expired
- ld [rBGP], a
- ld [rOBP0], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
and $f0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -577,24 +577,24 @@ YellowIntroScene14:
ld bc, $50
ld a, $1
call Bank3E_FillMemory
- coord hl, 0, 4
+ hlcoord 0, 4
ld bc, CopyVideoDataAlternate
xor a
call Bank3E_FillMemory
- coord hl, 0, 14
+ hlcoord 0, 14
ld bc, $50
ld a, $1
call Bank3E_FillMemory
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call DelayFrame
call DelayFrame
call DelayFrame
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld a, $e4
- ld [rOBP0], a
- ld [rBGP], a
+ ldh [rOBP0], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
lb de, $58, $58
@@ -611,22 +611,22 @@ YellowIntroScene15:
ld a, [wYellowIntroSceneTimer]
and $3
ret nz
- ld a, [rOBP0]
+ ldh a, [rOBP0]
xor $ff
- ld [rOBP0], a
- ld a, [rBGP]
+ ldh [rOBP0], a
+ ldh a, [rBGP]
xor $3
- ld [rBGP], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
ret
.expired
xor a
- ld [hLCDCPointer], a
+ ldh [hLCDCPointer], a
ld a, $e4
- ld [rBGP], a
- ld [rOBP0], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call YellowIntro_NextScene
@@ -634,8 +634,8 @@ YellowIntroScene16:
ld de, YellowIntroPalSequence_f9e0a
call YellowIntro_LoadDMGPalAndIncrementCounter
jr c, .expired
- ld [rOBP0], a
- ld [rBGP], a
+ ldh [rOBP0], a
+ ldh [rBGP], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
ret
@@ -743,9 +743,9 @@ Func_f9e5f:
YellowIntro_BlankPalsDelay2AndDisableLCD:
xor a
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -756,19 +756,19 @@ YellowIntro_BlankPalsDelay2AndDisableLCD:
Func_f9e9a:
ld e, a
- callab YellowIntroPaletteAction
+ callfar YellowIntroPaletteAction
xor a
- ld [hSCX], a
- ld [hSCY], a
+ ldh [hSCX], a
+ ldh [hSCY], a
ld a, $90
- ld [hWY], a
+ ldh [hWY], a
ld a, $e3
- ld [rLCDC], a
+ ldh [rLCDC], a
ld a, $e4
- ld [rBGP], a
- ld [rOBP0], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
ld a, $e0
- ld [rOBP1], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
@@ -798,41 +798,41 @@ YellowIntro_Copy8BitSineWave:
Request7TileTransferFromC810ToC710:
ld a, $10
- ld [H_VBCOPYSRC], a
+ ldh [hVBlankCopySource], a
ld a, wLYOverridesBuffer / $100
- ld [H_VBCOPYSRC + 1], a
+ ldh [hVBlankCopySource + 1], a
ld a, $10
- ld [H_VBCOPYDEST], a
+ ldh [hVBlankCopyDest], a
ld a, wLYOverrides / $100
- ld [H_VBCOPYDEST + 1], a
+ ldh [hVBlankCopyDest + 1], a
ld a, $7
- ld [H_VBCOPYSIZE], a
+ ldh [hVBlankCopySize], a
ret
InitYellowIntroGFXAndMusic:
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld [hSCX], a
- ld [hSCY], a
- ld [H_AUTOBGTRANSFERDEST], a
+ ldh [hAutoBGTransferEnabled], a
+ ldh [hSCX], a
+ ldh [hSCY], a
+ ldh [hAutoBGTransferDest], a
ld a, $98
- ld [H_AUTOBGTRANSFERDEST + 1], a
+ ldh [hAutoBGTransferDest + 1], a
call YellowIntro_BlankTileMap
ld hl, wTileMap
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
ld a, $1
call Bank3E_FillMemory
- coord hl, 0, 4
+ hlcoord 0, 4
ld bc, CopyVideoDataAlternate
xor a
call Bank3E_FillMemory
ld a, $1
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
call DelayFrame
call DelayFrame
call DelayFrame
xor a
- ld [H_AUTOBGTRANSFERENABLED], a
+ ldh [hAutoBGTransferEnabled], a
ld de, $6b5a
ld hl, $8000
ld bc, $3eff
@@ -915,9 +915,9 @@ YellowIntro_BlankOAMBuffer:
YellowIntro_BlankPalettes:
xor a
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
+ ldh [rBGP], a
+ ldh [rOBP0], a
+ ldh [rOBP1], a
call UpdateGBCPal_BGP
call UpdateGBCPal_OBP0
call UpdateGBCPal_OBP1
diff --git a/engine/menu/start_menu.asm b/home/start_menu.asm
index 498d1467..bd1b24bf 100755
--- a/engine/menu/start_menu.asm
+++ b/home/start_menu.asm
@@ -6,9 +6,9 @@ DisplayStartMenu::
call PlaySound
RedisplayStartMenu::
- callba DrawStartMenu
-RedisplayStartMenu_DoNotDrawStartMenu:
- callba PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone
+ farcall DrawStartMenu
+RedisplayStartMenu_DoNotDrawStartMenu::
+ farcall PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone
call UpdateSprites
.loop
call HandleMenuInput
@@ -77,7 +77,7 @@ RedisplayStartMenu_DoNotDrawStartMenu:
; EXIT falls through to here
CloseStartMenu::
call Joypad
- ld a, [hJoyPressed]
+ ldh a, [hJoyPressed]
bit 0, a ; was A button newly pressed?
jr nz, CloseStartMenu
call LoadTextBoxTilePatterns