From 452a322140b675494a2ffa705afda2f8b77f5145 Mon Sep 17 00:00:00 2001 From: DrippingYellow <106562603+DrippingYellow@users.noreply.github.com> Date: Wed, 21 Jan 2026 17:43:18 -0600 Subject: [PATCH] Finish labelling bank $0f (#127) * Split bank $0f into engine/battle/core.asm and engine/overworld/wildmons.asm * Split wildmon probabilities into separate data/wild/probabilities.inc file for consistency --- constants/battle_constants.asm | 14 +- constants/collision_constants.asm | 16 +- constants/item_constants.asm | 1 + constants/pokemon_data_constants.asm | 10 +- constants/trainer_constants.asm | 2 + data/battle/held_stat_up.inc | 9 + data/predef_pointers.inc | 6 +- data/{wild.asm => wild/grassmons.inc} | 4 +- data/wild/probabilities.inc | 24 + engine/battle/core.asm | 6662 +++++++++++++++++++++++- engine/dumps/bank0d.asm | 172 +- engine/dumps/bank0e.asm | 16 +- engine/dumps/bank0f.asm | 6795 ------------------------- engine/dumps/bank14.asm | 6 +- engine/overworld/wildmons.asm | 264 + home/copy.asm | 2 + home/map.asm | 12 +- home/misc_32c8.asm | 2 +- home/tilemap.asm | 1 + home/unknown_388f.asm | 4 +- home/util.asm | 2 +- layout.link | 8 +- ram/wram.asm | 79 +- 23 files changed, 7147 insertions(+), 6964 deletions(-) create mode 100644 data/battle/held_stat_up.inc rename data/{wild.asm => wild/grassmons.inc} (99%) create mode 100644 data/wild/probabilities.inc delete mode 100644 engine/dumps/bank0f.asm create mode 100644 engine/overworld/wildmons.asm diff --git a/constants/battle_constants.asm b/constants/battle_constants.asm index 5af9138..a5700b7 100644 --- a/constants/battle_constants.asm +++ b/constants/battle_constants.asm @@ -234,13 +234,19 @@ DEF ALL_STATUS EQU (1 << PSN) | (1 << BRN) | (1 << FRZ) | (1 << PAR) | SLP const BATTLEACTION_SWITCH4 const BATTLEACTION_SWITCH5 const BATTLEACTION_SWITCH6 - const BATTLEACTION_A - const BATTLEACTION_B - const BATTLEACTION_C - const BATTLEACTION_D + const_skip + const_skip + const_skip + const BATTLEACTION_SKIPTURN const BATTLEACTION_STRUGGLE const BATTLEACTION_FORFEIT +; wBattlePlayerAction + const_def + const BATTLEPLAYERACTION_USEMOVE + const BATTLEPLAYERACTION_USEITEM + const BATTLEPLAYERACTION_SWITCH + ; wBattleEnded const_def const WIN diff --git a/constants/collision_constants.asm b/constants/collision_constants.asm index e4bdc94..1326cea 100644 --- a/constants/collision_constants.asm +++ b/constants/collision_constants.asm @@ -19,6 +19,8 @@ ; 6 - ??? E - unused ; 7 - Warps F - unused +; TODO: Replace all instances of COLLISION with COLL for consistency with pokegold. + DEF COLLISION_TYPE_MASK EQU $f0 DEF COLLISION_SUBTYPE_MASK EQU $07 DEF COLLISION_WATER_SUBTYPE_MASK EQU $03 @@ -42,7 +44,7 @@ DEF OLD_COLLISION_WATER2_S EQU $40 DEF OLD_COLLISION_ROCK EQU $51 -DEF OLD_COLLISION_CARPED EQU $60 +DEF OLD_COLLISION_CARPET EQU $60 DEF OLD_COLLISION_DOOR EQU $61 DEF OLD_COLLISION_SIGNPOST EQU $70 @@ -57,14 +59,17 @@ DEF OLD_COLLISION_GRASS EQU $82 DEF COLLISION_WALKABLE EQU $00 DEF COLLISION_SOLID EQU $07 +DEF COLLISION_08 EQU $08 ; triggers wild encounters DEF COLLISION_CUT_TREE EQU $12 DEF COLLISION_GRASS EQU $18 ; water collisions -DEF COLLISION_WATER EQU $21 +DEF COLLISION_WATER_21 EQU $21 DEF COLLISION_WATERFALL EQU $22 DEF COLLISION_WATER_SOLID EQU $27 +DEF COLLISION_WATER_28 EQU $28 ; triggers wild encounters +DEF COLLISION_WATER EQU $29 ; water collisions 2 DEF COLLISION_WATER2_E EQU $30 @@ -81,6 +86,13 @@ DEF COLLISION_LAND_N EQU $43 DEF COLLISION_LAND_S EQU $44 ; $45..$47 will behave like COLLISION_LAND_E +; All of these are listed in CheckGrassCollision. That's about all we know. +DEF COLLISION_48 EQU $48 +DEF COLLISION_49 EQU $49 +DEF COLLISION_4A EQU $4A +DEF COLLISION_4B EQU $4B +DEF COLLISION_4C EQU $4C + ; land collisions 2 DEF COLLISION_LAND2_E EQU $50 DEF COLLISION_LAND2_W EQU $51 diff --git a/constants/item_constants.asm b/constants/item_constants.asm index 305e9b4..c6b0dce 100644 --- a/constants/item_constants.asm +++ b/constants/item_constants.asm @@ -280,6 +280,7 @@ DEF ITEM_X_ATTACK_RED EQU $41 DEF ITEM_X_DEFEND_RED EQU $42 DEF ITEM_X_SPEED_RED EQU $43 DEF ITEM_X_SPECIAL_RED EQU $44 +DEF ITEM_EXP_ALL_RED EQU $4b DEF ITEM_ETHER_RED EQU $50 DEF ITEM_MAX_ETHER_RED EQU $51 DEF ITEM_ELIXER_RED EQU $52 diff --git a/constants/pokemon_data_constants.asm b/constants/pokemon_data_constants.asm index 33a811f..c820136 100644 --- a/constants/pokemon_data_constants.asm +++ b/constants/pokemon_data_constants.asm @@ -120,11 +120,13 @@ DEF NUM_HOF_TEAMS EQU 30 ; wild data -DEF NUM_GRASSMON EQU 6 ; data/wild/*_grass.asm table size -DEF NUM_WATERMON EQU 3 ; data/wild/*_water.asm table size +DEF NUM_GRASSMON EQU 18 ; data/wild/*_grass.asm table size + +DEF GRASS_WILDDATA_DAYBLOCK_START EQU 3 ; +DEF GRASS_WILDDATA_NITEBLOCK_START EQU 7 ; the slot in GrassMonProbTable to start at + +DEF GRASS_WILDDATA_LENGTH EQU (NUM_GRASSMON * 2) + 3 + 2 -DEF GRASS_WILDDATA_LENGTH EQU (NUM_GRASSMON * 2 + 1) * 3 + 2 -DEF WATER_WILDDATA_LENGTH EQU (NUM_WATERMON * 2 + 1) * 1 + 2 DEF BASE_HAPPINESS EQU 70 diff --git a/constants/trainer_constants.asm b/constants/trainer_constants.asm index 3b4737d..6ca7c16 100644 --- a/constants/trainer_constants.asm +++ b/constants/trainer_constants.asm @@ -146,3 +146,5 @@ ENDM trainerclass TRAINER_ELITE_FOUR_F ; 40 DEF NUM_TRAINER_CLASSES EQU __trainer_class__ + +DEF TRAINER_OPP_RIVAL3_RED EQU $2b diff --git a/data/battle/held_stat_up.inc b/data/battle/held_stat_up.inc new file mode 100644 index 0000000..aa3fee5 --- /dev/null +++ b/data/battle/held_stat_up.inc @@ -0,0 +1,9 @@ +HeldStatUpItems: + db HELD_ATTACK_UP, EFFECT_ATTACK_UP + db HELD_DEFENSE_UP, EFFECT_DEFENSE_UP + db HELD_SPEED_UP, EFFECT_SPEED_UP + db HELD_SP_ATTACK_UP, EFFECT_SP_ATK_UP + db HELD_SP_DEFENSE_UP, EFFECT_SP_DEF_UP + db HELD_ACCURACY_UP, EFFECT_ACCURACY_UP + db HELD_EVASION_UP, EFFECT_EVASION_UP + db -1 ; end diff --git a/data/predef_pointers.inc b/data/predef_pointers.inc index dea1a5e..c474f70 100644 --- a/data/predef_pointers.inc +++ b/data/predef_pointers.inc @@ -44,12 +44,12 @@ GiveItemPredef:: add_predef PrintMoveDescription add_predef UpdatePlayerHUD add_predef PlaceGraphic - add_predef Function3f068 ; 20 + add_predef Old_ScaleSpriteByTwo ; 20 add_predef LoadMonBackPic - add_predef AnyPartyAlive + add_predef CheckPlayerPartyForFitMon add_predef UpdateEnemyHUD add_predef DoubleOrHalveSelectedStats_Old - add_predef Function3ef19 + add_predef StartBattle add_predef CalcAndPlaceExpBar add_predef GetBattleMonBackpic add_predef GetEnemyMonFrontpic ; 28 diff --git a/data/wild.asm b/data/wild/grassmons.inc similarity index 99% rename from data/wild.asm rename to data/wild/grassmons.inc index 43af5b0..4db75c2 100644 --- a/data/wild.asm +++ b/data/wild/grassmons.inc @@ -1,6 +1,4 @@ -INCLUDE "constants.asm" - -SECTION "data/wild.asm", ROMX +; TODO: These aren't bespoke morning/day/night chunks. Find a way to indicate this. GrassWildMons:: diff --git a/data/wild/probabilities.inc b/data/wild/probabilities.inc new file mode 100644 index 0000000..a5f909e --- /dev/null +++ b/data/wild/probabilities.inc @@ -0,0 +1,24 @@ +MACRO mon_prob +; percent, index + db \1, \2 * 2 +ENDM + +GrassMonProbTable: + mon_prob 1, 0 ; start of morning block (#1) + mon_prob 4, 1 ; + mon_prob 5, 2 ; + mon_prob 1, 3 ; start of day block (#4) + mon_prob 4, 4 ; + mon_prob 15, 5 ; + mon_prob 20, 6 ; + mon_prob 5, 7 ; start of night block (#8) + mon_prob 10, 8 ; + mon_prob 20, 9 ; + mon_prob 15, 10 ; end of morning block (#11) + mon_prob 5, 11 ; + mon_prob 5, 12 ; end of day block (#13) + mon_prob 20, 13 ; + mon_prob 10, 14 ; + mon_prob 5, 15 ; + mon_prob 4, 16 ; + mon_prob 1, 17 ; end of night block (#18) \ No newline at end of file diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 4035bc3..bf62086 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -1,6 +1,5065 @@ INCLUDE "constants.asm" -SECTION "engine/battle/core.asm", ROMX +SECTION "engine/battle/core.asm@DoBattle", ROMX + +DoBattle: + xor a + ld [wBattleParticipantsNotFainted], a + ld [wBattleParticipantsIncludingFainted], a + ld [wBattlePlayerAction], a + + inc a + ld [wBattleHasJustStarted], a + + ld hl, wOTPartyMon1HP + ld bc, PARTYMON_STRUCT_LENGTH - 1 + ld d, BATTLEACTION_SWITCH1 - 1 +.loop + inc d + ld a, [hli] + or [hl] + jr nz, .alive + add hl, bc + jr .loop + +.alive + ld a, d + ld [wBattleAction], a + ld a, [wLinkMode] + and a + jr z, .not_linked + + ldh a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .player_2 + +.not_linked + ld a, [wBattleMode] + dec a + jr z, .wild + call EnemySwitch + call NewEnemyMonStatus + +.wild + ld c, 40 + call DelayFrames + +.player_2 + call BackUpTilesToBuffer +.check_any_alive + call CheckPlayerPartyForFitMon + ld a, d + and a + jp z, LostBattle + call ReloadTilesFromBuffer + ld a, [wBattleType] + and a + jp nz, .SafariZoneBattleTurn + xor a + ld [wCurPartyMon], a +.loop2 + call CheckIfCurPartyMonIsFitToFight + jr nz, .alive2 + ld hl, wCurPartyMon + inc [hl] + jr .loop2 + +.alive2 + ld a, [wCurPartyMon] + ld [wCurBattleMon], a + inc a + ld hl, wPartySpecies - 1 + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wCurPartySpecies], a + ld [wTempBattleMonSpecies], a + hlcoord 1, 5 + ld a, 9 + call SlideBattlePicOut + call BackUpTilesToBuffer + ld a, [wCurPartyMon] + ld c, a + ld b, SET_FLAG + push bc + ld hl, wBattleParticipantsNotFainted + predef SmallFarFlagAction + ld hl, wBattleParticipantsIncludingFainted + pop bc + predef SmallFarFlagAction + call LoadBattleMonFromParty + call ApplyStatMods + call SendOutMonText + call NewBattleMonStatus + call SendOutPlayerMon + call EmptyBattleTextbox + call BackUpTilesToBuffer + xor a + ldh [hBattleTurn], a + call SpikesDamage + ld a, [wLinkMode] + and a + jr z, .to_battle + ldh a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr nz, .to_battle + + call EnemySwitch + call NewEnemyMonStatus + ld a, 1 + ldh [hBattleTurn], a + call SpikesDamage +.to_battle + jp BattleTurn + +; Old Safari Zone code from Red & Green. +.SafariZoneBattleTurn + call BattleMenu + ret c + ld a, [wBattlePlayerAction] + and a ; if non-zero, this would have meant that the item was used successfully + jr z, .SafariZoneBattleTurn + ; There used to be code checking for Safari Balls here, but it was taken out. + call ReloadTilesFromBuffer + ld hl, Unused_OutOfSafariBallsText + jp PrintText + +; Unreferenced. +.not_out_of_safari_balls + call PrintSafariZoneBattleText + ld a, [wEnemyMonSpeed + 1] + add a + ld b, a + jp c, WildFled_EnemyFled_LinkBattleCanceled + ld a, [wUnused_SafariBaitFactor] + and a + jr z, .check_escape_factor + srl b + srl b +.check_escape_factor + ld a, [wUnused_SafariEscapeFactor] + and a + jr z, .compare_with_random_value + sla b + jr nc, .compare_with_random_value + ld b, $ff +.compare_with_random_value + call BattleRandom + cp b + jp nc, .check_any_alive + jr WildFled_EnemyFled_LinkBattleCanceled + +Unused_OutOfSafariBallsText: + text "アナウンス『ピンポーン!" + + para "サファリ ボールを" + line "ぜんぶ なげました!" + prompt + +WildFled_EnemyFled_LinkBattleCanceled: + call ReloadTilesFromBuffer + ld a, DRAW + ld [wBattleResult], a + + ld a, [wLinkMode] + and a + ld hl, WildPokemonFledText + jr z, .print_text + + xor a ; WIN + ld [wBattleResult], a + ld hl, EnemyPokemonFledText + +.print_text + call PrintText + ld de, SFX_RUN + call PlaySFX + xor a + ldh [hBattleTurn], a +; Was originally AnimationSlideEnemyMonOff in pokered. + jpfar Functioncc000 + +WildPokemonFledText: + text "やせいの@" + text_from_ram wEnemyMonNickname + text "は にげだした!" + prompt + +EnemyPokemonFledText: + text "てきの@" + text_from_ram wEnemyMonNickname + text "は にげだした!" + prompt + +BattleTurn: + call UpdateBattleMonInParty + ldh a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + jr z, .CheckEnemyFirst + + call CheckFaint_Player + jp z, HandlePlayerMonFaint + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + call HandlePerishSong + + call CheckFaint_Player + jp z, HandlePlayerMonFaint + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + jr .PerishSongDone + +.CheckEnemyFirst: + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + call CheckFaint_Player + jp z, HandlePlayerMonFaint + call HandlePerishSong + + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + call CheckFaint_Player + jp z, HandlePlayerMonFaint + +.PerishSongDone: + call HandleSafeguard + call HandleWeather + call HandleStatBoostingHeldItems + call HandleHealingItems + call UpdateBattleMonInParty + call BackUpTilesToBuffer + + call TryEnemyFlee + jp c, WildFled_EnemyFled_LinkBattleCanceled + + xor a + ld [wBattleHasJustStarted], a + ld a, [wPlayerSubStatus4] + and ((1 << SUBSTATUS_RECHARGE) | (1 << SUBSTATUS_RAGE)) + jp nz, .locked_in + + ld hl, wEnemySubStatus3 + res SUBSTATUS_FLINCHED, [hl] + ld hl, wPlayerSubStatus3 + res SUBSTATUS_FLINCHED, [hl] + + ld a, [hl] + and ((1 << SUBSTATUS_RAMPAGE) | (1 << SUBSTATUS_CHARGED)) + jp nz, .locked_in + + ld hl, wPlayerSubStatus1 + bit SUBSTATUS_ROLLOUT, [hl] + jp nz, .locked_in + +.loop1 + call BattleMenu + ret c + ld a, [wBattleEnded] + and a + ret nz + ld hl, wPlayerSubStatus5 + bit SUBSTATUS_ENCORED, [hl] + jr z, .not_encored + ld a, [wPlayerEncoreCount] + dec a + ld [wPlayerEncoreCount], a + jr nz, .encored + +.clear_encore + ld hl, wPlayerSubStatus5 + res SUBSTATUS_ENCORED, [hl] + xor a + ldh [hBattleTurn], a + ld hl, BattleText_TargetsEncoreEnded + call PrintText + jr .not_encored + +.encored +; If the player hasn't used a move (possible via sleep and freeze), Encore gets cleared. + ld a, [wLastPlayerCounterMove] + and a + jr z, .clear_encore + ld a, [wCurMoveNum] + ld c, a + ld b, 0 + ld hl, wBattleMonPP + add hl, bc + ld a, [hl] + and PP_MASK + jr z, .clear_encore + ld a, [wLastPlayerCounterMove] + ld [wCurPlayerMove], a + jr .encored2 + +.not_encored + ld a, [wPlayerSubStatus3] + and ((1 << SUBSTATUS_BIDE) | (1 << SUBSTATUS_USING_TRAPPING_MOVE)) + jr nz, .locked_in + ld a, [wBattlePlayerAction] + and a ; BATTLEPLAYERACTION_USEMOVE + jr nz, .locked_in + xor a + ld [wMoveSelectionMenuType], a + inc a ; MOVE_POUND + ld [wFXAnimID], a + call MoveSelectionScreen + push af + call ReloadTilesFromBuffer + call UpdateBattleHuds + pop af + jp nz, .loop1 + +.encored2 + xor a + ldh [hBattleTurn], a + callfar UpdateMoveData + ld a, [wPlayerMoveStructEffect] + cp EFFECT_FURY_CUTTER + jr z, .continue_fury_cutter + xor a + ld [wPlayerFuryCutterCount], a + jr .next + +.locked_in + xor a + ld [wPlayerFuryCutterCount], a +.continue_fury_cutter +.next + call ParseEnemyAction + ld a, [wLinkMode] + and a + jr z, .use_move + + ld a, [wOtherPlayerLinkAction] + cp BATTLEACTION_FORFEIT + jp z, WildFled_EnemyFled_LinkBattleCanceled + cp BATTLEACTION_STRUGGLE + jr z, .use_move + cp BATTLEACTION_SKIPTURN + jr z, .use_move + sub BATTLEACTION_SKIPTURN - BATTLEACTION_SWITCH6 + jr c, .use_move + + ld a, [wPlayerSubStatus3] + bit SUBSTATUS_USING_TRAPPING_MOVE, a + jr z, .dont_change_last_move + ld a, [wCurMoveNum] + ld hl, wBattleMonMoves + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + cp MOVE_METRONOME + jr nz, .dont_change_last_move + ld [wCurPlayerMove], a + +.dont_change_last_move + callfar AI_Switch + ld a, 1 + ldh [hBattleTurn], a + call SpikesDamage + jp Battle_EnemyFirst + +.use_move + ld a, [wCurPlayerMove] + call GetMoveEffect + cp EFFECT_PRIORITY_HIT + jr nz, .no_priority_player + ld a, [wCurEnemyMove] + call GetMoveEffect + cp EFFECT_PRIORITY_HIT + jr z, .equal_priority + jp Battle_PlayerFirst + +.no_priority_player + ld a, [wCurEnemyMove] + call GetMoveEffect + cp EFFECT_PRIORITY_HIT + jp z, Battle_EnemyFirst + ld a, [wCurPlayerMove] + call GetMoveEffect + cp EFFECT_COUNTER + jr nz, .no_counter_player + ld a, [wCurEnemyMove] + call GetMoveEffect + cp EFFECT_COUNTER + jr z, .equal_priority + jp Battle_EnemyFirst + +.no_counter_player + ld a, [wCurEnemyMove] + call GetMoveEffect + cp EFFECT_COUNTER + jp z, Battle_PlayerFirst + +.equal_priority + xor a + ldh [hBattleTurn], a + callfar GetUserItem + push bc + callfar GetOpponentItem + pop de + ld a, d + cp HELD_QUICK_CLAW + jr nz, .player_no_quick_claw + ld a, b + cp HELD_QUICK_CLAW + jr z, .both_have_quick_claw + call BattleRandom + cp e + jr nc, .speed_check + jp Battle_PlayerFirst + +.player_no_quick_claw + ld a, b + cp HELD_QUICK_CLAW + jr nz, .speed_check + call BattleRandom + cp c + jr nc, .speed_check + jp Battle_EnemyFirst + +.both_have_quick_claw + ldh a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .player_2b + call BattleRandom + cp c + jp c, Battle_EnemyFirst + call BattleRandom + cp e + jp c, Battle_PlayerFirst + jr .speed_check + +.player_2b + call BattleRandom + cp e + jp c, Battle_PlayerFirst + call BattleRandom + cp c + jp c, Battle_EnemyFirst + jr .speed_check + +.speed_check + ld de, wBattleMonSpeed + ld hl, wEnemyMonSpeed + ld c, 2 + call CompareBytes + jr z, .speed_tie + jp nc, Battle_PlayerFirst + jr Battle_EnemyFirst + +.speed_tie + ldh a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .player_2c + + call BattleRandom + cp 50 percent + 1 + jp c, Battle_PlayerFirst + jr Battle_EnemyFirst + +.player_2c + call BattleRandom + cp 50 percent + 1 + jr c, Battle_EnemyFirst + jp Battle_PlayerFirst + +TryEnemyFlee: + ld a, [wBattleMode] + dec a + jr nz, .stay + + ld a, [wDebugFlags] + bit DEBUG_BATTLE_F, a + jr nz, .stay + + ld a, [wEnemySubStatus5] + bit SUBSTATUS_CANT_RUN, a + jr nz, .stay + + call BattleRandom + cp 4 percent ; 10/256 chance for any Pokémon to run away + jr nc, .stay + scf + ret + +.stay + and a + ret + +GetMoveEffect: + dec a + ld hl, Moves + MOVE_EFFECT + ld bc, MOVE_LENGTH + call AddNTimes + ld a, BANK(Moves) + jp GetFarByte + +Battle_EnemyFirst: + ld a, 1 + ldh [hBattleTurn], a + callfar AI_SwitchOrTryItem + jr c, .switch_item + callfar DoEnemyTurn + call EndOpponentProtectEndureDestinyBond + ld a, [wBattleEnded] + and a + ret nz + call CheckFaint_Player + jp z, HandlePlayerMonFaint + +.switch_item + call ResidualDamage + jp z, HandleEnemyMonFaint + call UpdateBattleHuds + callfar DoPlayerTurn + call EndOpponentProtectEndureDestinyBond + ld a, [wBattleEnded] + and a + ret nz + + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + call ResidualDamage + jp z, HandlePlayerMonFaint + call UpdateBattleHuds + call CheckForEndOfTrappingMoves + xor a ; BATTLEPLAYERACTION_USEMOVE + ld [wBattlePlayerAction], a + jp BattleTurn + +Battle_PlayerFirst: + callfar DoPlayerTurn + call EndOpponentProtectEndureDestinyBond + ld a, [wBattleEnded] + and a + ret nz + call CheckFaint_Enemy + jp z, HandleEnemyMonFaint + call ResidualDamage + jp z, HandlePlayerMonFaint + call UpdateBattleHuds + ld a, 1 + ldh [hBattleTurn], a + callfar AI_SwitchOrTryItem + jr c, .switch_item + callfar DoEnemyTurn + call EndOpponentProtectEndureDestinyBond + ld a, [wBattleEnded] + and a + ret nz + call CheckFaint_Player + jp z, HandlePlayerMonFaint + +.switch_item + call ResidualDamage + jp z, HandleEnemyMonFaint + call UpdateBattleHuds + call CheckForEndOfTrappingMoves + xor a + ld [wFieldMoveSucceeded], a + jp BattleTurn + +EndOpponentProtectEndureDestinyBond: + ld hl, wEnemySubStatus5 + ld de, wEnemySubStatus1 + ldh a, [hBattleTurn] + and a + jr z, .ok + ld hl, wPlayerSubStatus5 + ld de, wPlayerSubStatus1 + +.ok + res SUBSTATUS_DESTINY_BOND, [hl] + ld a, [de] + res SUBSTATUS_PROTECT, a + res SUBSTATUS_ENDURE, a + ld [de], a + ret + +CheckFaint_Enemy: + ld hl, wEnemyMonHP + jr CheckIfHPIsZero + +CheckFaint_Player: + ld hl, wBattleMonHP +CheckIfHPIsZero: + ld a, [hli] + or [hl] + ret + +; Return z if the user fainted before +; or as a result of residual damage. +ResidualDamage: + ld hl, wBattleMonStatus + ldh a, [hBattleTurn] + and a + jr z, .ok + + ld hl, wEnemyMonStatus + +.ok + ld a, [hl] + and 1 << PSN | 1 << BRN + jr z, .did_psn_brn + + ld hl, HurtByPoisonText + ld de, ANIM_PSN + and 1 << BRN + jr z, .got_anim + ld hl, HurtByBurnText + ld de, ANIM_BRN + +.got_anim + push de + call PrintText + pop de + + xor a + ld [wNumHits], a + call Call_PlayBattleAnim + call GetEighthMaxHP + ld hl, wPlayerSubStatus5 + ld de, wPlayerToxicCount + ldh a, [hBattleTurn] + and a + jr z, .check_toxic + ld hl, wEnemySubStatus5 + ld de, wEnemyToxicCount + +.check_toxic + bit SUBSTATUS_TOXIC, [hl] + jr z, .did_toxic +; Multiplies the initial 1/8th health reduction by the toxic count + ld a, [de] + inc a + ld [de], a + ld hl, 0 + +.add + add hl, bc + dec a + jr nz, .add + ld b, h + ld c, l + +.did_toxic + call SubtractHPFromUser + +.did_psn_brn + ld hl, wPlayerSubStatus4 + ldh a, [hBattleTurn] + and a + jr z, .check_seed + ld hl, wEnemySubStatus4 + +.check_seed + bit SUBSTATUS_LEECH_SEED, [hl] + jr z, .not_seeded + + ldh a, [hBattleTurn] + push af + xor 1 + ldh [hBattleTurn], a + xor a + ld [wNumHits], a + ld de, ANIM_SAP + call Call_PlayBattleAnim + pop af + ldh [hBattleTurn], a + call GetEighthMaxHP + call SubtractHPFromUser + call RestoreHP + ld hl, LeechSeedSapsText + call PrintText + +.not_seeded + ld hl, wPlayerSubStatus1 + ldh a, [hBattleTurn] + and a + jr z, .check_nightmare + ld hl, wEnemySubStatus1 + +.check_nightmare + bit SUBSTATUS_NIGHTMARE, [hl] + jr z, .not_nightmare + xor a + ld [wNumHits], a + ld de, ANIM_IN_NIGHTMARE + call Call_PlayBattleAnim + call GetQuarterMaxHP + call SubtractHPFromUser + ld hl, HasANightmareText + call PrintText + +.not_nightmare + ld hl, wPlayerSubStatus1 + ldh a, [hBattleTurn] + and a + jr z, .check_curse + ld hl, wEnemySubStatus1 + +.check_curse + bit SUBSTATUS_CURSE, [hl] + jr z, .not_cursed + xor a + ld [wNumHits], a + ld de, ANIM_IN_NIGHTMARE + call Call_PlayBattleAnim + call GetQuarterMaxHP + call SubtractHPFromUser + ld hl, HurtByCurseText + call PrintText + +.not_cursed + ld hl, wPlayerScreens + ldh a, [hBattleTurn] + and a + jr z, .check_sandstorm + ld hl, wEnemyScreens + +.check_sandstorm + bit SCREENS_SANDSTORM, [hl] + jr z, .no_sandstorm + ldh a, [hBattleTurn] + push af + xor 1 + ldh [hBattleTurn], a + xor a + ld [wNumHits], a + ld de, ANIM_IN_SANDSTORM + call Call_PlayBattleAnim + pop af + ldh [hBattleTurn], a + call GetEighthMaxHP + call SubtractHPFromUser + ld hl, SandstormHitsText + call PrintText + +.no_sandstorm + ld hl, wBattleMonHP + ldh a, [hBattleTurn] + and a + jr z, .got_hp + ld hl, wEnemyMonHP + +.got_hp + ld a, [hli] + or [hl] + ret nz + call UpdateBattleHuds + ld c, 20 + call DelayFrames + xor a + ret + +HurtByPoisonText: + text "は" + line "どくの ダメージを うけている!" + prompt + +HurtByBurnText: + text "は" + line "やけどの ダメージを うけている!" + prompt + +LeechSeedSapsText: + text "やどりぎが の" + line "たいりょくを うばう!" + prompt + +HasANightmareText: + text "は" + line "あくむに うなされている!" + prompt + +HurtByCurseText: + text "は" + line "のろわれている!" + prompt + +SandstormHitsText: + text "すなあらしが を" + line "おそう!" + prompt + +HandlePerishSong: + ldh a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + jr z, .player1 + + xor a + ldh [hBattleTurn], a + call .do_it + ld a, 1 + ldh [hBattleTurn], a + call .do_it + ret + +.player1 + ld a, 1 + ldh [hBattleTurn], a + call .do_it + xor a + ldh [hBattleTurn], a + call .do_it + ret + +.do_it + ld hl, wPlayerSubStatus1 + ld de, wPlayerPerishCount + ldh a, [hBattleTurn] + and a + jr z, .got_count + ld hl, wEnemySubStatus1 + ld de, wEnemyPerishCount + +.got_count + bit SUBSTATUS_PERISH, [hl] + ret z + ld a, [de] + dec a + ld [de], a + ld [wTextDecimalByte], a + push af + push hl + ld hl, PerishCountText + call PrintText + pop hl + pop af + ret nz + res SUBSTATUS_PERISH, [hl] + ldh a, [hBattleTurn] + and a + jr nz, .kill_enemy + ld hl, wBattleMonHP + xor a + ld [hli], a + ld [hl], a + ld hl, wPartyMon1HP + ld a, [wCurBattleMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + xor a + ld [hli], a + ld [hl], a + ret + +.kill_enemy + ld hl, wEnemyMonHP + xor a + ld [hli], a + ld [hl], a + ld a, [wBattleMode] + dec a + ret z + ld hl, wOTPartyMon1HP + ld a, [wCurOTMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + xor a + ld [hli], a + ld [hl], a + ret + +PerishCountText: + text "の ほろびの" + line "カウントが @" + deciram wNumSetBits, 1, 1 + text "になった!" + prompt + +HandleSafeguard: + ld a, [wPlayerScreens] + bit SCREENS_SAFEGUARD, a + jr z, .check_enemy + ld hl, wPlayerSafeguardCount + dec [hl] + jr nz, .check_enemy + res SCREENS_SAFEGUARD, a + ld [wPlayerScreens], a + xor a + call .PrintSafeguardFadedText + +.check_enemy + ld a, [wEnemyScreens] + bit SCREENS_SAFEGUARD, a + ret z + ld hl, wEnemySafeguardCount + dec [hl] + ret nz + res SCREENS_SAFEGUARD, a + ld [wEnemyScreens], a + ld a, 1 + +.PrintSafeguardFadedText: + ldh [hBattleTurn], a + ld hl, BattleText_SafeguardFaded + jp PrintText + +BattleText_SafeguardFaded: + text "を つつんでいた" + line "しんぴの ベールが なくなった!" + prompt + +HandleWeather: + ld a, [wBattleWeather] + and a ; WEATHER_NONE + ret z + + dec a + ld c, a + ld hl, wWeatherCount + dec [hl] + ld hl, .WeatherMessages + jr nz, .PrintWeatherMessage + + xor a + ld [wBattleWeather], a + ld hl, .WeatherEndedMessages + +.PrintWeatherMessage: + ld b, 0 + add hl, bc + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + call PrintText + ret + +.WeatherMessages: + dw BattleText_RainContinuesToFall + dw BattleText_TheSunlightIsStrong + +.WeatherEndedMessages: + dw BattleText_TheRainStopped + dw BattleText_TheSunlightFaded + +BattleText_RainContinuesToFall: + text "あめが ふりつずいている" + prompt + +BattleText_TheSunlightIsStrong: + text "ひざしが つよい" + prompt + +BattleText_TheRainStopped: + text "あめが やんだ!" + prompt + +BattleText_TheSunlightFaded: + text "ひざしが よわくなった!" + prompt + +; Subtract c HP from mon +SubtractHPFromUser: + ld hl, wBattleMonHP + ldh a, [hBattleTurn] + and a + jr z, .got_mon_hp + ld hl, wEnemyMonHP + +.got_mon_hp + inc hl + 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, .end + + xor a + ld [hli], a + ld [hl], a + ld [wHPBarNewHP], a + ld [wHPBarNewHP + 1], a + +.end + call UpdateHPBarBattleHuds + ret + +; Output: bc +GetEighthMaxHP: + ld hl, wBattleMonMaxHP + ldh a, [hBattleTurn] + and a + jr z, .got_max_hp + ld hl, wEnemyMonMaxHP + +.got_max_hp + ld a, [hli] + ld [wHPBarMaxHP + 1], a + ld b, a + ld a, [hl] + ld [wHPBarMaxHP], a + ld c, a +; Quarter result. + srl b + rr c + srl b + rr c +; Assumes nothing can have 1024 or more HP. +; Halve result. + srl c + +; Make sure the amount is at least 1. + ld a, c + and a + jr nz, .end + inc c +.end + ret + +; Output: bc +GetQuarterMaxHP: + ld hl, wBattleMonMaxHP + ldh a, [hBattleTurn] + and a + jr z, .got_max_hp + ld hl, wEnemyMonMaxHP +.got_max_hp + ld a, [hli] + ld [wHPBarMaxHP + 1], a + ld b, a + ld a, [hl] + ld [wHPBarMaxHP], a + ld c, a + +; Quarter result + srl b + rr c + srl b + rr c + +; Assumes nothing can have 1024 or more hp. +; Make sure the amount is at least 1. + ld a, c + and a + jr nz, .end + inc c +.end + ret + +; Output: bc +GetHalfMaxHP: + ld hl, wBattleMonMaxHP + ldh a, [hBattleTurn] + and a + jr z, .got_max_hp + ld hl, wEnemyMonMaxHP +.got_max_hp + ld a, [hli] + ld [wHPBarMaxHP + 1], a + ld b, a + ld a, [hl] + ld [wHPBarMaxHP], a + ld c, a + +; Half result + srl b + rr c + +; MINOR BUG: If something has a multiple of 512 HP, then the HP amount will be increased by 1. +; This amount is achievable by using monsters with high base HP, e.g. Chansey. + + ld a, c + and a + jr nz, .end + inc c +.end + ret + +GetMaxHP: + ld hl, wBattleMonMaxHP + ldh a, [hBattleTurn] + and a + jr z, .got_max_hp + ld hl, wEnemyMonMaxHP +.got_max_hp + ld a, [hli] + ld [wHPBarMaxHP + 1], a + ld b, a + ld a, [hl] + ld [wHPBarMaxHP], a + ld c, a + ret + +RestoreHP: + ld hl, wEnemyMonMaxHP + ldh a, [hBattleTurn] + and a + jr z, .ok + ld hl, wBattleMonMaxHP + +.ok + ld a, [hli] + ld [wHPBarMaxHP + 1], a + ld a, [hld] + ld [wHPBarMaxHP], a + dec hl + ld a, [hl] + ld [wHPBarOldHP], a + add c + ld [hld], a + ld [wHPBarNewHP], a + ld a, [hl] + ld [wHPBarOldHP + 1], a + adc b + ld [hli], a + ld [wHPBarNewHP + 1], a + + ld a, [wHPBarMaxHP] + ld c, a + ld a, [hld] + sub c + ld a, [wHPBarMaxHP + 1] + ld b, a + ld a, [hl] + sbc b + jr c, .overflow + ld a, b + ld [hli], a + ld [wHPBarNewHP + 1], a + ld a, c + ld [hl], a + ld [wHPBarNewHP], a + +.overflow + ldh a, [hBattleTurn] + push af + xor 1 + ldh [hBattleTurn], a + call UpdateHPBarBattleHuds + pop af + ldh [hBattleTurn], a + ret + +UpdateHPBarBattleHuds: + hlcoord 10, 9 + ldh a, [hBattleTurn] + and a + ld a, 1 + jr z, .ok + hlcoord 2, 2 + xor a +.ok + push bc + ld [wWhichHPBar], a + predef UpdateHPBar + pop bc + ret + +; Clears SUBSTATUS_USING_TRAPPING_MOVE if a Pokémon's Rollout count is zero. +CheckForEndOfTrappingMoves: + ld a, [wPlayerRolloutCount] + and a + jr nz, .check_enemy + ld hl, wPlayerSubStatus3 + res SUBSTATUS_USING_TRAPPING_MOVE, [hl] + +.check_enemy + ld a, [wEnemyRolloutCount] + and a + ret nz + ld hl, wEnemySubStatus3 + res SUBSTATUS_USING_TRAPPING_MOVE, [hl] + ret + +HandleEnemyMonFaint: + xor a + ld [wWhichMonFaintedFirst], a + call UpdateBattleStateAndExperienceAfterEnemyFaint + call CheckPlayerPartyForFitMon + ld a, d + and a + jp z, LostBattle + + ld hl, wBattleMonHP + ld a, [hli] + or [hl] + call nz, UpdatePlayerHUD + + ld c, 60 + call DelayFrames + + ld a, [wBattleMode] + dec a + ret z + + call CheckEnemyTrainerDefeated + jp z, WinTrainerBattle + + ld hl, wBattleMonHP + ld a, [hli] + or [hl] + jr nz, .notfainted + + call AskUseNextPokemon + ret c + call ForcePlayerMonChoice + +.notfainted + ld a, 1 + ld [wBattlePlayerAction], a + call HandleEnemySwitch + jp z, WildFled_EnemyFled_LinkBattleCanceled + + xor a + ld [wFieldMoveSucceeded], a + jp BattleTurn + +UpdateBattleStateAndExperienceAfterEnemyFaint: + call UpdateBattleMonInParty + ld a, [wBattleMode] + dec a + jr z, .wild + + ld a, [wCurOTMon] + ld hl, wOTPartyMon1HP + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + xor a + ld [hli], a + ld [hl], a + +.wild + ld hl, wPlayerSubStatus3 + res SUBSTATUS_IN_LOOP, [hl] + xor a + ld hl, wPlayerDamageTaken + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld hl, wEnemySubStatus1 + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld [wEnemyDisableCount], a + ld [wEnemyDisabledMove], a + ld [wEnemyMinimized], a + ld hl, wLastPlayerCounterMove + ld [hli], a + ld [hl], a + + hlcoord 12, 5 + decoord 12, 6 + call MonFaintedAnimation + hlcoord 1, 0 + lb bc, 4, 10 + call ClearBox + + ld a, [wBattleMode] + dec a + jr z, .wild2 + + push de + ld de, SFX_KINESIS + call PlaySFX + call WaitSFX + pop de + push de + ld de, SFX_FAINT + call PlaySFX + call WaitSFX + pop de + jr .trainer + +.wild2 + call StopDangerSound + ld a, 0 + call PlayVictoryMusic + +.trainer + ld hl, wBattleMonHP + ld a, [hli] + or [hl] + jr nz, .player_mon_did_not_faint + ld a, [wWhichMonFaintedFirst] + and a + jr nz, .player_mon_did_not_faint + call UpdateFaintedPlayerMon + +.player_mon_did_not_faint + call CheckPlayerPartyForFitMon + ld a, d + and a + ret z + ld hl, EnemyMonFainted + call PrintText + call EmptyBattleTextbox + call BackUpTilesToBuffer + xor a + ld [wBattleResult], a + ld b, ITEM_EXP_ALL_RED + call Call_GetItemAmount + push af + jr z, .skip_exp + ld hl, wEnemyMonBaseStats + ld b, wEnemyMonEnd - wEnemyMonBaseStats + +.loop + srl [hl] + inc hl + dec b + jr nz, .loop + +.skip_exp + xor a ; FALSE + ld [wBoostExpByExpAll], a + call GiveExperiencePoints + pop af + ret z + + ld a, TRUE + ld [wBoostExpByExpAll], a + ld a, [wPartyCount] + ld b, 0 + +.gain_exp_loop + scf + rl b + dec a + jr nz, .gain_exp_loop + + ld a, b + ld [wBattleParticipantsNotFainted], a + jp GiveExperiencePoints + +EnemyMonFainted: + text "てきの @" + text_from_ram wEnemyMonNickname + text "は たおれた!" + prompt + +; TODO: Does it really stop the Danger Sound? wBattleLowHealthAlarm doesn't appear to be read anywhere else... +StopDangerSound: + inc a + ld [wBattleLowHealthAlarm], a + ret + +CheckEnemyTrainerDefeated: + ld a, [wOTPartyCount] + ld b, a + xor a + ld hl, wOTPartyMon1HP + ld de, PARTYMON_STRUCT_LENGTH + +.loop: + or [hl] + inc hl + or [hl] + dec hl + add hl, de + dec b + jr nz, .loop + + and a + ret + +HandleEnemySwitch: + ld hl, wEnemyHPPal + ld e, HP_BAR_LENGTH_PX + call UpdateHPPal + callfar EnemySwitch_TrainerHud + ld a, [wLinkMode] + and a + jr z, .not_linked + + call LinkBattleSendRecieveAction + ld a, [wOtherPlayerLinkAction] + cp BATTLEACTION_FORFEIT + ret z + + call ReloadTilesFromBuffer + +.not_linked + call EnemySwitch + call NewEnemyMonStatus + ld a, 1 + ldh [hBattleTurn], a + call SpikesDamage + xor a + ld [wEnemyMoveStruct], a + ld [wFieldMoveSucceeded], a + ld [wEnemyTurnsTaken], a + inc a + ret + +WinTrainerBattle: + call StopDangerSound + ld b, MUSIC_NONE + ld a, [wUnused_GymLeaderNo] + and a + jr nz, .gym_leader + ld b, MUSIC_VICTORY_TRAINER + +.gym_leader + ld a, [wTrainerClass] + cp TRAINER_OPP_RIVAL3_RED + jr nz, .notrival_red + ld b, MUSIC_NONE + ld hl, wDebugFlags ; wStatusFlags7 + set DEBUG_FIELD_F, [hl] ; BIT_NO_MAP_MUSIC + +.notrival_red + ld a, [wLinkMode] + and a + ld a, b + call z, PlayVictoryMusic + callfar Battle_GetTrainerName + ld hl, BattleText_EnemyWasDefeated + call PrintText + + ld a, [wLinkMode] + cp LINK_COLOSSEUM + ret z + + call BattleWinSlideInEnemyTrainerFrontpic + ld c, 40 + call DelayFrames + + ld a, [wOtherTrainerClass] + cp TRAINER_RIVAL + jr nz, .notrival + ld hl, RivalLossText + call PrintText + callfar HealParty + +.notrival +; No win/loss text implemented in this build, except for the rival's. + ld a, [wBattleMonItem] + ld b, a + callfar GetItemHeldEffect + ld a, b + cp HELD_AMULET_COIN + jr nz, .dont_double_reward + + ld hl, wBattleReward + 2 + sla [hl] + dec hl + rl [hl] + dec hl + rl [hl] + jr nc, .not_overflow + + ld a, $ff + ld [hli], a + ld [hli], a + ld [hl], a + +.dont_double_reward +.not_overflow + ld de, wMoney + 2 + ld hl, wBattleReward + 2 + ld c, 3 + and a +; Add battle money to account +.loop + ld a, [de] + adc [hl] + ld [de], a + dec de + dec hl + dec c + jr nz, .loop + ld hl, GotMoneyForWinningText + call PrintText + ret + +GotMoneyForWinningText: + text "は しょうきんとして" + line "@" + deciram wBattleReward, 3, 6 + text "円 てにいれた!" + prompt + +BattleText_EnemyWasDefeated: + text_from_ram wOTClassName + text "の @" + text_from_ram wStringBuffer1 + text_start + line "との しょうぶに かった!" + prompt + +RivalLossText: + text "『あれー?" + line "おまえの #に" + cont "すりゃあ よかったのかなあ?" + prompt + +PlayVictoryMusic: + push de + ld de, MUSIC_NONE + call PlayMusic + call DelayFrame + ld de, MUSIC_VICTORY_TRAINER + call PlayMusic + pop de + ret + +HandlePlayerMonFaint: + ld a, 1 + ld [wWhichMonFaintedFirst], a + call UpdateFaintedPlayerMon + call CheckPlayerPartyForFitMon + ld a, d + and a + jp z, LostBattle + ld hl, wEnemyMonHP + ld a, [hli] + or [hl] + jr nz, .notfainted + call UpdateBattleStateAndExperienceAfterEnemyFaint + ld a, [wBattleMode] + dec a + ret z + call CheckEnemyTrainerDefeated + jp z, WinTrainerBattle + +.notfainted + call AskUseNextPokemon + ret c + + call ForcePlayerMonChoice + jp nz, BattleTurn + ld a, BATTLEPLAYERACTION_USEITEM + ld [wBattlePlayerAction], a + + call HandleEnemySwitch + jp z, WildFled_EnemyFled_LinkBattleCanceled + + xor a + ld [wFieldMoveSucceeded], a + jp BattleTurn + +UpdateFaintedPlayerMon: + ld a, [wCurBattleMon] + ld c, a + ld hl, wBattleParticipantsNotFainted + ld b, RESET_FLAG + predef SmallFarFlagAction + ld hl, wEnemySubStatus3 + res SUBSTATUS_IN_LOOP, [hl] + ld a, [wLowHealthAlarmBuffer] + bit DANGER_ON_F, a + jr z, .no_low_health_alarm + + ld a, $ff + ld [wLowHealthAlarmBuffer], a + call WaitSFX + +.no_low_health_alarm + ld hl, wEnemyDamageTaken + ld [hli], a + ld [hl], a + ld [wBattleMonStatus], a + ld [wBattleMonStatus + 1], a + call UpdateBattleMonInParty + hlcoord 9, 7 + lb bc, 5, 11 + call ClearBox + hlcoord 1, 10 + decoord 1, 11 + call MonFaintedAnimation + ld a, LOSE + ld [wBattleResult], a + ld a, [wWhichMonFaintedFirst] + and a + ret z + + ld a, $f0 + ld [wCryTracks], a + ld a, [wBattleMonSpecies] + call PlayStereoCry + ld hl, FaintedText + jp PrintText + +FaintedText: + text_from_ram wBattleMonNickname + text "は たおれた!" + prompt + +AskUseNextPokemon: + call EmptyBattleTextbox + call BackUpTilesToBuffer +; We don't need to be here if we're in a Trainer battle, +; as that decision is made for us. + ld a, [wBattleMode] + and a + dec a + ret nz + ld hl, BattleText_UseNextMon + call PrintText + +.loop + lb bc, 1, 7 + call PlaceYesNoBox + ld a, [wMenuCursorY] + jr c, .pressed_b + and a + ret + +.pressed_b + ld a, [wMenuCursorY] + cp 1 ; YES + jr z, .loop + ld hl, wPartyMon1Speed + ld de, wEnemyMonSpeed + jp TryToRunAwayFromBattle + +BattleText_UseNextMon: + text "つぎの #をつかいますか?" + done + +ForcePlayerMonChoice: + call LoadStandardMenuHeader + ld a, PARTYMENUACTION_SWITCH + ld [wPartyMenuActionText], a + predef OpenPartyMenu_ClearGraphics + +.pick + jr nc, .picked +.not_fit_to_fight + predef OpenPartyMenu + jr .pick + +.picked + call CheckIfCurPartyMonIsFitToFight + jr z, .not_fit_to_fight + ld a, [wLinkMode] + cp LINK_COLOSSEUM + jr nz, .skip_link +; BUG TODO: Doesn't this result in invalid wBattlePlayerAction arguments? + inc a ; BATTLEPLAYERACTION_USEITEM + ld [wBattlePlayerAction], a + call LinkBattleSendRecieveAction + +.skip_link + xor a ; BATTLEPLAYERACTION_USEMOVE + ld [wBattlePlayerAction], a + call ClearSprites + ld a, [wCurPartyMon] + ld [wCurBattleMon], a + ld c, a + ld hl, wBattleParticipantsNotFainted + ld b, SET_FLAG + push bc + predef SmallFarFlagAction + pop bc + ld hl, wBattleParticipantsIncludingFainted + predef SmallFarFlagAction + call LoadBattleMonFromParty + call ApplyStatMods + + call ClearPalettes + call _LoadHPBar + call CloseWindow + call GetMemSGBLayout + call SetPalettes + + call SendOutMonText + call NewBattleMonStatus + call SendOutPlayerMon + call EmptyBattleTextbox + call BackUpTilesToBuffer + + xor a + ldh [hBattleTurn], a + call SpikesDamage + ld hl, wEnemyMonHP + ld a, [hli] + or [hl] + ret + +LostBattle: + ld a, [wLinkMode] + and a + jr nz, .link + + ld a, [wOtherTrainerClass] + cp TRAINER_RIVAL + jr nz, .not_rival + + ld hl, wTileMap + lb bc, 8, 21 + call ClearBox + call BattleWinSlideInEnemyTrainerFrontpic + + ld c, 40 + call DelayFrames + + ld hl, RivalWinText + call PrintText + callfar HealParty + ret + +.link +.not_rival +; Grayscale + ld b, SGB_BATTLE_GRAYSCALE + call GetSGBLayout + ld hl, OutOfUsableMonsText + + ld a, [wLinkMode] + cp LINK_COLOSSEUM + jr nz, .not_link + ld hl, LostAgainstText + +.not_link + call PrintText + call ClearTileMap + scf + ret + +RivalWinText: + text "『やった!" + line "いい# えらんだかも!" + prompt + +OutOfUsableMonsText: + text "の てもとには" + line "たたかえる #が いない!" + + para "は" + line "めのまえが まっくらに なった!" + prompt + +LostAgainstText: + text_from_ram wOTClassName + text "との" + line "しょうぶに まけた!" + prompt + +MonFaintedAnimation: + ld a, [wJoypadFlags] + push af + set 6, a ; JOYPAD_DISABLE_MON_FAINT_F + ld [wJoypadFlags], a + + ld b, 7 + +.OuterLoop: + push bc + push de + push hl + ld b, 6 + +.InnerLoop: + push bc + push hl + push de + ld bc, 7 + call CopyBytes + pop de + pop hl + ld bc, -SCREEN_WIDTH + add hl, bc + push hl + ld h, d + ld l, e + add hl, bc + ld d, h + ld e, l + pop hl + pop bc + dec b + jr nz, .InnerLoop + + ld bc, SCREEN_WIDTH + add hl, bc + ld de, .Spaces + call PlaceString + ld c, 2 + call DelayFrames + pop hl + pop de + pop bc + dec b + jr nz, .OuterLoop + pop af + ld [wJoypadFlags], a + ret + +.Spaces: + db "       @" + +SlideBattlePicOut: + ldh [hSpriteWidth], a + ld c, a + +.loop + push bc + push hl + ld b, 7 + +.loop2 + push hl + call .DoFrame + pop hl + ld de, SCREEN_WIDTH + add hl, de + dec b + jr nz, .loop2 + ld c, 2 + call DelayFrames + pop hl + pop bc + dec c + jr nz, .loop + ret + +.DoFrame: + ldh a, [hSpriteWidth] + ld c, a + cp 8 + jr nz, .back + +.forward + ld a, [hli] + ld [hld], a + dec hl + dec c + jr nz, .forward + ret + +.back + ld a, [hld] + ld [hli], a + inc hl + dec c + jr nz, .back + ret + +EnemySwitch: + ld hl, wBattleParticipantsNotFainted + xor a + ld [hl], a + + ld a, [wCurBattleMon] + ld c, a + ld b, SET_FLAG + push bc + predef SmallFarFlagAction + ld hl, wBattleParticipantsIncludingFainted + xor a + ld [hl], a + pop bc + predef SmallFarFlagAction + + xor a + ld hl, wLastPlayerCounterMove + ld [hli], a + ld [hl], a + dec a + ld [wEnemyItemState], a + ld hl, wPlayerSubStatus3 + res SUBSTATUS_USING_TRAPPING_MOVE, [hl] + + hlcoord 18, 0 + ld a, 8 + call SlideBattlePicOut + call EmptyBattleTextbox + call LoadStandardMenuHeader + + ld a, [wLinkMode] + and a + jr z, FindMonInOTPartyToSwitchIntoBattle + + ld a, [wOtherPlayerLinkAction] + sub BATTLEACTION_SWITCH1 + ld b, a + jp LoadEnemyMonToSwitchTo + +FindMonInOTPartyToSwitchIntoBattle: + ld a, [wBattleHasJustStarted] + and a + jp nz, GetRandomOTPartyMon + + ld b, -1 + ld a, 1 + ld [wEnemyEffectivenessVsPlayerMons], a + ld [wPlayerEffectivenessVsEnemyMons], a +.loop + ld hl, wEnemyEffectivenessVsPlayerMons + sla [hl] + inc hl + sla [hl] + inc b + ld a, [wOTPartyCount] + cp b + jp z, ScoreMonTypeMatchups + + ld a, [wCurOTMon] + cp b + jr z, .discourage + + ld hl, wOTPartyMon1HP + push bc + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, [hli] + ld c, a + ld a, [hl] + or c + pop bc + jr z, .discourage + call LookUpTheEffectivenessOfEveryMove + call IsThePlayerMonTypesEffectiveAgainstOTMon + jr .loop + +.discourage + ld hl, wPlayerEffectivenessVsEnemyMons + set 0, [hl] + jr .loop + +LookUpTheEffectivenessOfEveryMove: + push bc + ld hl, wOTPartyMon1Moves + ld a, b + ld bc, $30 + call AddNTimes + pop bc + ld e, 5 +.loop + dec e + jr z, .done + ld a, [hli] + and a + jr z, .done + push hl + push de + push bc + dec a + ld hl, Moves + ld bc, 7 + call AddNTimes + ld de, wEnemyMoveStruct + ld a, BANK(Moves) + call FarCopyBytes + ld a, 1 + ldh [hBattleTurn], a + callfar BattleCheckTypeMatchup + pop bc + pop de + pop hl + ld a, [wNumSetBits] + cp $b + jr c, .loop + ld hl, wEnemyEffectivenessVsPlayerMons + set 0, [hl] + ret +.done + ret + +IsThePlayerMonTypesEffectiveAgainstOTMon: + push bc + ld hl, wOTPartyCount + ld a, b + inc a + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + dec a + ld hl, BaseData + (wMonHTypes - wMonHeader) + ld bc, (wMonHeaderEnd - wMonHeader) + call AddNTimes + ld de, wEnemyMonType + ld bc, 2 + ld a, BANK(BaseData) + call FarCopyBytes + ld a, [wBattleMonType1] + ld [wPlayerMoveStructType], a + xor a + ldh [hBattleTurn], a + callfar BattleCheckTypeMatchup + ld a, [wNumSetBits] + cp $b + jr nc, .super_effective + ld a, [wBattleMonType2] + ld [wPlayerMoveStructType], a + callfar BattleCheckTypeMatchup + ld a, [wNumSetBits] + cp $b + jr nc, .super_effective + pop bc + ret + +.super_effective + pop bc + ld hl, wEnemyEffectivenessVsPlayerMons + bit 0, [hl] + jr nz, .reset + inc hl + set 0, [hl] + ret + +.reset + res 0, [hl] + ret + +ScoreMonTypeMatchups: +.loop1 + ld hl, wEnemyEffectivenessVsPlayerMons + sla [hl] + inc hl + sla [hl] + jr nc, .loop1 + ld a, [wOTPartyCount] + ld b, a + ld c, [hl] +.loop2 + sla c + jr nc, .okay + dec b + jr z, GetRandomOTPartyMon + jr .loop2 + +.okay + ld a, [wEnemyEffectivenessVsPlayerMons] + and a + jr z, .okay2 + ld b, -1 + ld c, a +.loop3 + inc b + sla c + jr nc, .loop3 + jr LoadEnemyMonToSwitchTo + +.okay2 + ld b, -1 + ld a, [wPlayerEffectivenessVsEnemyMons] + ld c, a +.loop4 + inc b + sla c + jr c, .loop4 + jr LoadEnemyMonToSwitchTo + +GetRandomOTPartyMon: +.loop + call BattleRandom + maskbits PARTY_LENGTH + cp PARTY_LENGTH + jr nc, .loop + + ld b, a + ld a, [wCurOTMon] + cp b + jr z, .loop + + ld hl, wOTPartyMon1HP + push bc + ld a, b + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + pop bc + + ld a, [hli] + ld c, a + ld a, [hl] + or c + jr z, .loop + +LoadEnemyMonToSwitchTo: + ; 'b' contains the PartyNr of the mon the AI will switch to + ld a, b + ld [wCurPartyMon], a + ld hl, wOTPartyMon1Level + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + + ld a, [hl] + ld [wCurPartyLevel], a + ld a, [wCurPartyMon] + inc a + ld hl, wOTPartySpecies - 1 + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + + ld [wTempEnemyMonSpecies], a + ld [wCurPartySpecies], a + call LoadEnemyMon + + ld hl, wEnemyMonHP + ld a, [hli] + ld [wEnemyHPAtTimeOfPlayerSwitch], a + ld a, [hl] + ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a + + ld a, 1 + ld [wMenuCursorY], a + ld a, [wBattleHasJustStarted] + dec a + jr z, EnemySendOutFirstMon + + ld a, [wPartyCount] + dec a + jr z, EnemySendOutFirstMon + + ld a, [wLinkMode] + and a + jr nz, EnemySendOutFirstMon + + ld a, [wOptions] + bit BATTLE_SHIFT_F, a + jr nz, EnemySendOutFirstMon + + callfar Battle_GetTrainerName + ld hl, TrainerAboutToUseText + call PrintText + + lb bc, 1, 7 + call PlaceYesNoBox + ld a, [wMenuCursorY] + dec a + jr nz, EnemySendOutFirstMon + + ld a, PARTYMENUACTION_SWITCH + ld [wPartyMenuActionText], a + predef OpenPartyMenu_ClearGraphics + +.pick + ld a, 1 + ld [wMenuCursorY], a + jr c, .canceled_switch + + ld hl, wCurBattleMon + ld a, [wCurPartyMon] + cp [hl] + jr nz, .notout + + ld hl, BattleText_MonIsAlreadyOut_0f + call PrintText + +.fainted + predef OpenPartyMenu + jr .pick + +.notout + call CheckIfCurPartyMonIsFitToFight + jr z, .fainted + xor a + ld [wMenuCursorY], a + +.canceled_switch + call ClearPalettes + call _LoadHPBar + +EnemySendOutFirstMon: + call CloseWindow + call ClearSprites + hlcoord 1, 0 + lb bc, 4, 10 + call ClearBox + + ld b, SGB_BATTLE_COLORS + call GetSGBLayout + call SetPalettes + callfar Battle_GetTrainerName + + ld hl, TrainerSentOutText + call PrintText + + ld a, [wTempEnemyMonSpecies] + ld [wCurPartySpecies], a + ld [wCurSpecies], a + call GetBaseData + + ld a, OTPARTYMON + ld [wMonType], a + predef CopyMonToTempMon + ld hl, wTempMonDVs + predef GetUnownLetter + ld de, vFrontPic + call LoadMonFrontSprite + xor a + ld [wNumHits], a + inc a + ldh [hBattleTurn], a + +; Play shiny animation for Sunflora and Pikachu + ld b, 1 + ld a, [wCurPartySpecies] + cp DEX_SUNNY + jr z, .apply_animation + cp DEX_PIKACHU + jr z, .apply_animation + +; Play scanline fade animation for Hoothoot + ld b, 2 + cp DEX_HOHO + jr z, .apply_animation + +; Play normal send out animation for everyone else + ld b, 0 + +.apply_animation + ld a, b + ld [wBattleAnimParam], a + ld de, ANIM_SEND_OUT_MON + call Call_PlayBattleAnim + +; mon on the right side + ld a, $f + ld [wCryTracks], a + ld a, [wTempEnemyMonSpecies] + call PlayStereoCry + call UpdateEnemyHUD + +; If battle has just started, go ahead and switch in your monster + ld a, [wMenuCursorY] + and a + ret nz + xor a + ld [wBattleParticipantsNotFainted], a + ld [wBattleParticipantsIncludingFainted], a + call BackUpTilesToBuffer + jp PlayerSwitch + +; BUG: They forgot to terminate the line immediately after StringBuffer1. +; This makes the game halt the script early and throw up an error handler, +; due to reading the start of the following 'text' line as a character. +TrainerAboutToUseText: + text_from_ram wOTClassName + text "の @" + text_from_ram wStringBuffer1 + text "は" + line + text_from_ram wEnemyMonNickname + text "を くりだそうと している" + + para "も #を" + line "とりかえますか?" + done + +TrainerSentOutText: + text_from_ram wOTClassName + text "の @" + text_from_ram wStringBuffer1 + text "は" + line "@" + text_from_ram wEnemyMonNickname + text "を くりだした!" + done + +NewEnemyMonStatus: + xor a + ld hl, wLastEnemyCounterMove + ld [hli], a + ld [hl], a + ld hl, wEnemySubStatus1 +rept 4 + ld [hli], a +endr + ld [hl], a + ld [wEnemyDisableCount], a + ld [wEnemyFuryCutterCount], a + ld [wEnemyDisabledMove], a + ld [wEnemyMinimized], a + ret + +CheckPlayerPartyForFitMon: +; Has the player any mon in his Party that can fight? + ld a, [wPartyCount] + ld e, a + xor a + ld hl, wPartyMon1HP + ld bc, PARTYMON_STRUCT_LENGTH - 1 +.loop + or [hl] + inc hl + or [hl] + add hl, bc + dec e + jr nz, .loop + ld d, a + ret + +CheckIfCurPartyMonIsFitToFight: + ld a, [wCurPartyMon] + ld hl, wPartyMon1HP + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, [hli] + or [hl] + ret nz + + ld a, [wBattleHasJustStarted] + and a + jr nz, .has_hp + ld hl, BattleText_TheresNoWillToBattle + call PrintText +.has_hp + xor a + ret + +BattleText_TheresNoWillToBattle: + text "たたかう きりょくが ない!" + prompt + +TryToRunAwayFromBattle: + ld a, [wBattleType] + cp BATTLETYPE_DEBUG + jp z, .can_escape + ld a, [wLinkMode] + and a + jp nz, .can_escape + ld a, [wBattleMode] + dec a + jp nz, .trainer_battle + ld a, [wPlayerSubStatus5] + bit SUBSTATUS_CANT_RUN, a + jp nz, .cannot_escape + + push hl + push de + ld a, [wBattleMonItem] + ld [wNamedObjectIndexBuffer], a + ld b, a + callfar GetItemHeldEffect + + ld a, b + cp HELD_ESCAPE + pop de + pop hl + jr nz, .no_flee_item + + call GetItemName + ld hl, BattleText_UserFledUsingAStringBuffer1 + call PrintText + jp .can_escape + +.no_flee_item + ld a, [wNumFleeAttempts] + inc a + ld [wNumFleeAttempts], a + ld a, [hli] + ldh [hMultiplicand + 1], a + ld a, [hl] + ldh [hMultiplicand + 2], a + ld a, [de] + inc de + ldh [hEnemyMonSpeed], a + ld a, [de] + ldh [hEnemyMonSpeed + 1], a + call ReloadTilesFromBuffer + ld de, hMultiplicand + 1 + ld hl, hEnemyMonSpeed + ld c, 2 + call CompareBytes + jr nc, .can_escape + + xor a + ldh [hMultiplicand], a + ld a, 32 + ldh [hMultiplier], a + call Multiply + ldh a, [hProduct + 2] + ldh [hDividend], a + ldh a, [hProduct + 3] + ldh [hDividend + 1], a + ldh a, [hEnemyMonSpeed] + ld b, a + ldh a, [hEnemyMonSpeed + 1] + srl b + rr a + srl b + rr a + and a + jr z, .can_escape + ldh [hDivisor], a + ld b, 2 + call Divide + ldh a, [hMultiplicand + 1] + and a + jr nz, .can_escape + ld a, [wNumFleeAttempts] + ld c, a +.loop + dec c + jr z, .cant_escape_2 + ld b, 30 + ldh a, [hMultiplicand + 2] + add b + ldh [hMultiplicand + 2], a + jr c, .can_escape + jr .loop + +.cant_escape_2 + call BattleRandom + ld b, a + ldh a, [hMultiplicand + 2] + cp b + jr nc, .can_escape + ld a, BATTLEPLAYERACTION_USEITEM + ld [wBattlePlayerAction], a +.cannot_escape + ld hl, BattleText_CantEscape + jr .print_text + +.trainer_battle + ld hl, BattleText_TheresNoEscapeFromTrainerBattle +.print_text + call PrintText + ld a, TRUE + ld [wFailedToFlee], a + call BackUpTilesToBuffer + and a + ret + +.can_escape + ld a, [wLinkMode] + and a + ld a, DRAW + jr z, .fled + call BackUpTilesToBuffer + xor a ; BATTLEPLAYERACTION_USEMOVE + ld [wBattlePlayerAction], a + ld a, BATTLEACTION_FORFEIT + ld [wCurMoveNum], a + call LinkBattleSendRecieveAction + call ReloadTilesFromBuffer + + ld a, [wOtherPlayerLinkAction] + cp BATTLEACTION_FORFEIT + ld a, DRAW + jr z, .fled + dec a +.fled + ld [wBattleResult], a + push de + ld de, SFX_RUN + call WaitPlaySFX + pop de + call WaitSFX + ld hl, BattleText_GotAwaySafely + call PrintText + call WaitSFX + call BackUpTilesToBuffer + scf + ret + +BattleText_CantEscape: + text "にげられない!" + prompt + +BattleText_TheresNoEscapeFromTrainerBattle: + text "ダメだ!" + line "しょうぶの さいちゅうに" + cont "あいてに せなかは みせられない!" + prompt + +BattleText_GotAwaySafely: + text "うまく にげきれた!" + prompt + +BattleText_UserFledUsingAStringBuffer1: + text "は そうびしていた" + line "@" + text_from_ram wStringBuffer1 + text "を つかって にげた" + prompt + +LoadBattleMonFromParty: + ld a, [wCurPartyMon] + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1 + call AddNTimes + ; Copy species, held item, and move + ld de, wBattleMon + ld bc, (wPartyMon1ID - wPartyMon1Species) ; 6 + call CopyBytes + ; Skip ID, experience, and stat experience + ld bc, (wPartyMon1DVs - wPartyMon1ID) ; 15 + add hl, bc + ; Copy DVs, PP, and happiness + ld de, wBattleMonDVs + ld bc, (wPartyMon1PokerusStatus - wPartyMon1DVs) ; 7 + call CopyBytes + ; Copy level, status, current and max HP, and stats + inc hl + inc hl + inc hl + ld de, wBattleMonLevel + ld bc, (wPartyMon1StatsEnd - wPartyMon1Level) ; 17 + call CopyBytes + ; Copy both types + ld a, [wTempBattleMonSpecies] + ld [wCurSpecies], a + call GetBaseData + + ld a, [wMonHType1] + ld [wBattleMonType1], a + ld a, [wMonHType2] + ld [wBattleMonType2], a + + ld hl, wPartyMonNicknames + ld a, [wCurBattleMon] + call SkipNames + + ld de, wBattleMonNickname + ld bc, MON_NAME_LENGTH + call CopyBytes + + ld hl, wBattleMonStats + ld de, wPlayerStats + ld bc, 2 * NUM_BATTLE_STATS + call CopyBytes + call ApplyStatusEffectOnPlayerStats + call BadgeStatBoosts + + xor a + ldh [hBattleTurn], a + callfar GetMonSGBPaletteFlags + ret + +ApplyStatMods: + ld a, 7 + ld b, 8 + ld hl, wPlayerStatLevels +.loop + ld [hli], a + dec b + jr nz, .loop + ret + +LoadEnemyMonFromParty: + ld a, [wCurPartyMon] + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wOTPartyMons + call AddNTimes + ; Copy species, held item, and move + ld de, wEnemyMon + ld bc, (wPartyMon1ID - wPartyMon1Species) ; 6 + call CopyBytes + ; Skip ID, experience, and stat experience + ld bc, (wPartyMon1DVs - wPartyMon1ID) ; 15 + add hl, bc + ; Copy DVs, PP, and happiness + ld de, wEnemyMonDVs + ld bc, (wPartyMon1PokerusStatus - wPartyMon1DVs) ; 7 + call CopyBytes + ; Copy level, status, current and max HP, and stats + inc hl + inc hl + inc hl + ld de, wEnemyMonLevel + ld bc, (wPartyMon1StatsEnd - wPartyMon1Level) ; 17 + call CopyBytes + + ld a, [wEnemyMonSpecies] + ld [wCurSpecies], a + call GetBaseData + + ld hl, wOTPartyMonNicknames + ld a, [wCurPartyMon] + call SkipNames + + ld de, wEnemyMonNickname + ld bc, MON_NAME_LENGTH + call CopyBytes + + ld hl, wEnemyMonStats + ld de, wEnemyStats + ld bc, 2 * NUM_BATTLE_STATS + call CopyBytes + + call ApplyStatusEffectOnEnemyStats + ld hl, wMonHType1 + ld de, wEnemyMonType1 + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + ld hl, wMonHBaseStats + ld de, wEnemyMonBaseStats + ld b, 5 +.base_stats_loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .base_stats_loop + ld a, 7 + ld b, 8 + ld hl, wEnemyStatLevels +.stat_mod_loop + ld [hli], a + dec b + jr nz, .stat_mod_loop + ld a, [wCurPartyMon] + ld [wCurOTMon], a + ret + +SendOutPlayerMon: + ld hl, wBattleMonDVs + predef GetUnownLetter + predef LoadMonBackPic + xor a + ldh [hGraphicStartTile], a + + ld hl, wBattleMenuCursorPosition + ld [hli], a + ld [hl], a + ld [wTypeModifier], a + ld [wPlayerMoveStruct + MOVE_ANIM], a + ld b, SGB_BATTLE_COLORS + call GetSGBLayout + + ld hl, wEnemySubStatus3 + res SUBSTATUS_USING_TRAPPING_MOVE, [hl] + xor a + ldh [hBattleTurn], a + ld [wNumHits], a + +; Play shiny animation for Sunflora and Pikachu + ld b, 1 + ld a, [wCurPartySpecies] + cp DEX_SUNNY + jr z, .apply_animation + cp DEX_PIKACHU + jr z, .apply_animation + +; Play scanline fade animation for Hoothoot + ld b, 2 + cp DEX_HOHO + jr z, .apply_animation + +; Play send out animation for everyone else + ld b, 0 + +.apply_animation + ld a, b + ld [wBattleAnimParam], a + ld de, ANIM_SEND_OUT_MON + call Call_PlayBattleAnim + +; mon on the left side + ld a, $f0 + ld [wCryTracks], a + ld a, [wCurPartySpecies] + call PlayStereoCry + call UpdatePlayerHUD + ret + +NewBattleMonStatus: + xor a + ld hl, wLastPlayerCounterMove + ld [hli], a + ld [hl], a + ld hl, wPlayerSubStatus1 +rept 4 + ld [hli], a +endr + ld [hl], a + ld [wPlayerDisableCount], a + ld [wPlayerFuryCutterCount], a + ld [wDisabledMove], a + ld [wPlayerMinimized], a + ret + +SpikesDamage: + ld hl, wPlayerScreens + ld de, wBattleMonType + ldh a, [hBattleTurn] + and a + jr z, .ok + ld hl, wEnemyScreens + ld de, wEnemyMonType + +.ok + bit SCREENS_SPIKES, [hl] + ret z + +; Flying-types aren't affected by Spikes. + ld a, [de] + cp TYPE_FLYING + ret z + inc de + ld a, [de] + cp TYPE_FLYING + ret z + + ld hl, BattleText_UserHurtBySpikes + call PrintText + + call GetEighthMaxHP + call SubtractHPFromUser + + ret + +BattleText_UserHurtBySpikes: + text "は まきびしの" + line "ダメージを うけた!" + prompt + +RecallPlayerMon: + ldh a, [hBattleTurn] + push af + xor a + ldh [hBattleTurn], a + ld [wNumHits], a + ld de, ANIM_RETURN_MON + call Call_PlayBattleAnim + pop af + ldh [hBattleTurn], a + ret + +; Update level, status, current HP +UpdateBattleMonInParty: + ld a, [wCurBattleMon] + ld hl, wPartyMon1Level + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + + ld d, h + ld e, l + ld hl, wBattleMonLevel + ld bc, (wBattleMonHP - wBattleMonLevel) + 2 + jp CopyBytes + +; Only handles HP-healing items at this point. +; Status-healing items aren't handled except at the moment when the target is afflicted. +HandleHealingItems: + ldh a, [hSerialConnectionStatus] + cp 1 + jr z, .player1 + call .DoPlayer + call .DoEnemy + ret + +.player1: + call .DoEnemy + call .DoPlayer + ret + +.DoPlayer: + xor a + ldh [hBattleTurn], a + call HandleHPHealingItem + ld a, 1 + ldh [hBattleTurn], a + call HandleHPHealingItem + ret + +.DoEnemy: + ld a, 1 + ldh [hBattleTurn], a + call HandleHPHealingItem + xor a + ldh [hBattleTurn], a + call HandleHPHealingItem + ret + +HandleHPHealingItem: + callfar GetOpponentItem + ld a, b + cp HELD_BERRY + ret nz + ld de, wEnemyMonHP + 1 + ld hl, wEnemyMonMaxHP + 1 + ldh a, [hBattleTurn] + and a + jr z, .go + ld de, wBattleMonHP + 1 + ld hl, wBattleMonMaxHP + 1 + +.go +; If, and only if, Pokemon's HP is less than half max, use the item. +; Store current HP in Buffer 3/4 + push bc + ld a, [de] + ld [wHPBuffer2], a + add a + ld c, a + dec de + ld a, [de] + inc de + ld [wHPBuffer2 + 1], a + adc a + ld b, a + ld a, c + cp [hl] + dec hl + ld a, b + sbc [hl] + pop bc + ret nc + + ; store max HP in wHPBuffer1 + ld a, [hli] + ld [wHPBuffer1 + 1], a + ld a, [hl] + ld [wHPBuffer1], a + ld a, [de] + add c + ld [wHPBuffer3], a + ld c, a + dec de + ld a, [de] + adc 0 + ld [wHPBuffer3 + 1], a + ld b, a + ld a, [hld] + cp c + ld a, [hl] + sbc b + jr nc, .okay + ld a, [hli] + ld [wHPBuffer3 + 1], a + ld a, [hl] + ld [wHPBuffer3], a + +.okay + ld a, [wHPBuffer3 + 1] + ld [de], a + inc de + ld a, [wHPBuffer3] + ld [de], a + call ItemRecoveryAnim + ldh a, [hBattleTurn] + ld [wWhichHPBar], a + and a + hlcoord 2, 2 + jr z, .got_hp_bar_coords + hlcoord 10, 9 + +.got_hp_bar_coords + ld [wWhichHPBar], a + predef UpdateHPBar + + call UpdateBattleHuds + callfar GetOpponentItem + ld a, [hl] + ld [wNamedObjectIndexBuffer], a + call GetItemName + callfar ConsumeHeldItem + ld hl, RecoveredUsingText + jp PrintText + +ItemRecoveryAnim: + ld a, MOVE_RECOVER + ld [wFXAnimID], a + ldh a, [hBattleTurn] + push af + xor 1 + ldh [hBattleTurn], a + xor a + ld [wNumHits], a + ld [wFXAnimID + 1], a + predef PlayBattleAnim + pop af + ldh [hBattleTurn], a + ret + +RecoveredUsingText: + text "は そうびしていた" + line "@" + text_from_ram wStringBuffer1 + text "で かいふくした!" + prompt + +HandleStatBoostingHeldItems: + ldh a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + jr z, .player1 + call .DoPlayer + call .DoEnemy + ret + +.player1 + call .DoEnemy + call .DoPlayer + ret + +.DoPlayer: + ld hl, wPartyMon1Item + ld a, [wCurBattleMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld bc, wBattleMonItem + ld de, wPlayerMoveStruct + ld a, 0 + call .HandleItem + ret + +.DoEnemy: + ld hl, wOTPartyMon1Item + ld a, [wCurOTMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld bc, wEnemyMonItem + ld de, wEnemyMoveStruct + ld a, 1 + call .HandleItem + ret + +.HandleItem: + ldh [hBattleTurn], a + push hl + push bc + ld a, [bc] + ld b, a + callfar GetItemHeldEffect + ld hl, HeldStatUpItems +.loop: + ld a, [hli] + cp -1 + jr z, .finish + inc hl + cp b + jr nz, .loop + pop bc + ld a, [bc] + ld [wNumSetBits], a + xor a + ld [bc], a + dec hl + ld b, [hl] + pop hl + ld [hl], 0 + push de + push bc + call GetItemName + ld hl, UseItemFailedText + call PrintText + pop bc + pop de +; Play the Growth animation when using the item. + ld a, [de] + push af + ld a, MOVE_GROWTH + ld [de], a + inc de + ld a, [de] + push af + push de + ld a, b + ld [de], a + callfar BattleCommand_StatUp + pop de + pop af + ld [de], a + pop af + dec de + ld [de], a + ret + +.finish + pop bc + pop hl + ret + +INCLUDE "data/battle/held_stat_up.inc" + +UseItemFailedText: + text "が そうびしていた" + line "@" + text_from_ram wStringBuffer1 + text "が さどうした!" + prompt + +UpdateBattleHuds:: + call UpdatePlayerHUD + jp UpdateEnemyHUD + +UpdatePlayerHUD: + xor a + ldh [hBGMapMode], a + hlcoord 9, 7 + lb bc, 5, 11 + call ClearBox + callfar DrawPlayerHUDBorder + + hlcoord 18, 9 + ld [hl], $73 + ld de, wBattleMonNickname + hlcoord 10, 8 + call CenterMonName + call PlaceString + + push bc + ld hl, wBattleMon + ld de, wTempMon + ld bc, (wBattleMonMovesEnd - wBattleMonSpecies) + call CopyBytes + + ld hl, wBattleMonLevel + ld de, wTempMonLevel + ld bc, (wBattleMonStatsEnd - wBattleMonLevel) + call CopyBytes + + ld a, [wTempMonSpecies] + ld [wCurSpecies], a + call GetBaseData + + pop hl + push hl + inc hl + ld de, wTempMonStatus + predef PlaceNonFaintStatus + pop hl + jr nz, .dont_print_level + call PrintLevel + +.dont_print_level + ld a, [wTempMonSpecies] + ld [wCurPartySpecies], a + hlcoord 10, 9 + ld b, 1 + predef DrawPlayerHP + + push de + ld a, [wCurBattleMon] + ld hl, wPartyMon1Exp + 2 + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + + ld d, h + ld e, l + hlcoord 10, 11 + ld a, [wTempMonLevel] + ld b, a + call CalcAndPlaceExpBar + + ld a, 1 + ldh [hBGMapMode], a + pop de + ld hl, wPlayerHPPal + call UpdateHPPal + + ld hl, wBattleMonHP + ld a, [hli] + or [hl] + jr z, .no_danger + ld a, [wBattleLowHealthAlarm] + and a + ret nz + ld a, [wPlayerHPPal] + cp HP_RED + jr z, .danger + +.no_danger + ld hl, wLowHealthAlarmBuffer + bit DANGER_ON_F, [hl] + ld [hl], 0 + ret z + ret + +.danger + ld hl, wLowHealthAlarmBuffer + set DANGER_ON_F, [hl] + ret + +UpdateEnemyHUD: + xor a + ldh [hBGMapMode], a + hlcoord 1, 0 + lb bc, 4, 11 + call ClearBox + callfar DrawEnemyHUDBorder + + ld de, wEnemyMonNickname + hlcoord 2, 1 + call CenterMonName + call PlaceString + + ld h, b + ld l, c + push hl + inc hl + ld de, wEnemyMonStatus + predef PlaceNonFaintStatus + + pop hl + jr nz, .dont_print_level + ld a, [wEnemyMonLevel] + ld [wTempMonLevel], a + call PrintLevel + +.dont_print_level + ld hl, wEnemyMonHP + ld a, [hli] + ldh [hMultiplicand + 1], a + ld a, [hld] + ldh [hMultiplicand + 2], a + or [hl] + jr nz, .hp_not_zero + + ld c, a + ld e, a + ld d, 6 + jp .draw_hp_bar + +.hp_not_zero + xor a + ldh [hMultiplicand], a + ld a, 48 + ldh [hMultiplier], a + call Multiply + + ld hl, wEnemyMonMaxHP + ld a, [hli] + ld b, a + ld a, [hl] + ldh [hDivisor], a + ld a, b + and a + jr z, .do_divide +; 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) + ldh a, [hDivisor] + srl b + rr a + srl b + rr a + ldh [hDivisor], a + ldh a, [hProduct + 2] + ld b, a + srl b + ldh a, [hProduct + 3] + rr a + srl b + rr a + ldh [hDividend + 3], a + ld a, b + ldh [hDividend + 2], a +.do_divide + ldh a, [hDividend + 2] + ldh [hDividend], a + ldh a, [hDividend + 3] + ldh [hDividend + 1], a + ld a, 2 + ld b, a + call Divide + ldh a, [hQuotient + 3] + ld e, a + ld a, 6 + ld d, a + ld c, a +.draw_hp_bar + xor a + ld [wWhichHPBar], a + hlcoord 2, 2 + ld b, 0 + call DrawBattleHPBar + ld a, 1 + ldh [hBGMapMode], a + ld hl, wEnemyHPPal + ; fallthrough + +UpdateHPPal: + ld b, [hl] + call SetHPPal + ld a, [hl] + cp b + ret z + ld b, SGB_BATTLE_COLORS + jp GetSGBLayout + +; center's mon's name on the battle screen +; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual +; (i.e. for names longer than 4 letters) +; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual +; (i.e. for names longer than 4 letters) +CenterMonName: +; Function is dummied out in the final game. See "Battle_DummyFunction" in pokegold. + push de + inc hl + inc hl + ld b, 2 +.loop: + inc de + ld a, [de] + cp '@' + jr z, .done + inc de + ld a, [de] + cp '@' + jr z, .done + dec hl + dec b + jr nz, .loop +.done: + pop de + ret + +BattleMenu: + call ReloadTilesFromBuffer + ld a, [wBattleType] + and a + jr nz, .ok + call UpdateBattleHuds + call EmptyBattleTextbox + call BackUpTilesToBuffer +.ok + +.loop + callfar LoadBattleMenu + jr c, .loop + ld a, [wStartmenuCursor] + cp 1 + jp z, BattleMenu_Fight + cp 2 + jp z, BattleMenu_Pack + cp 3 + jp z, BattleMenu_PKMN + cp 4 + jp z, BattleMenu_Run + jr .loop + +BattleMenu_Fight: + xor a + ld [wNumFleeAttempts], a + call ReloadTilesFromBuffer + and a + ret + +BattleMenu_Pack: + ld a, [wLinkMode] + and a + jp nz, .ItemsCantBeUsed + + call LoadStandardMenuHeader + + callfar GetPocket2Status + xor a + ld [wSelectedSwapPosition], a + call ClearPalettes + callfar DrawBackpack + +.item_menu_loop + xor a + ldh [hBGMapMode], a + call ClearSprites + hlcoord 2, 2 + ld b, 8 + ld c, 15 + call DrawTextBox + call Call_DebugBackpackLoop + jr c, .didnt_use_item + call BattleMenuPack_SelectItem + ld a, [wItemEffectSucceeded] + and a + jr z, .item_menu_loop + call Call_LoadBattleFontsHPBar + call ClearSprites + ld a, 1 + ld [wMenuCursorY], a + call StopUsingTrappingMove + ld a, [wWildMon] + and a + jr nz, .run + call CloseWindow + call BackUpTilesToBuffer + call UpdateBattleHuds + call WaitBGMap + call ClearWindowData + call SetPalettes + and a + ret + +.run + xor a + ld [wWildMon], a + ld a, DRAW + ld [wBattleResult], a + call ClearWindowData + call SetPalettes + scf + ret + +.didnt_use_item + call ClearPalettes + call DelayFrame + call Call_LoadBattleFontsHPBar + call CloseWindow + call BackUpTilesToBuffer + call SetPalettes + jp BattleMenu + +.ItemsCantBeUsed + ld hl, BattleText_ItemsCantBeUsedHere + call PrintText + jp BattleMenu + +BattleText_ItemsCantBeUsedHere: + text "ここでは どうぐを" + line "つかうことは できません" + prompt + +StopUsingTrappingMove: + ld a, [wPlayerSubStatus3] + bit SUBSTATUS_USING_TRAPPING_MOVE, a + jr z, .done + ld hl, wPlayerRolloutCount + dec [hl] + jr nz, .done + ld hl, wPlayerSubStatus3 + res SUBSTATUS_USING_TRAPPING_MOVE, [hl] +.done + ret + +Call_DebugBackpackLoop: + callfar DebugBackpackLoop + ret + +BattleMenuPack_SelectItem: + callfar ScrollingMenu_ClearLeftColumn + call PlaceHollowCursor + predef LoadItemData + callfar CheckItemContext + ld a, [wItemAttributeValue] + ld hl, .item_attribute_jump_table + call CallJumptable + ret + +.item_attribute_jump_table: + dw .cant_use ; ITEMMENU_NOUSE + dw .cant_use ; TM_HOLDER + dw .ball_holder ; BALL_HOLDER + dw .other_bags ; IMPORTANT_BAG/ITEM_BAG + dw .menu_close ; ITEMMENU_CURRENT + dw .normal_item_effect ; ITEMMENU_PARTY + dw .menu_close ; ITEMMENU_CLOSE + +.cant_use: + callfar PrintCantUseText + xor a + ld [wItemEffectSucceeded], a + ret + +.ball_holder: + callfar BallPocket + jr nc, .menu_close + xor a + ld [wItemEffectSucceeded], a + ret + +.other_bags: + callfar FlipPocket2Status + xor a + ld [wSelectedSwapPosition], a + ld [wItemEffectSucceeded], a + ret + +.normal_item_effect: + call DoItemEffect + call ClearPalettes + callfar DrawBackpack + ret + +.menu_close: + call DoItemEffect + ret + +BattleMenu_PKMN: + call LoadStandardMenuHeader + +.BattleMenuPKMN_ReturnFromStats: + call ExitMenu + call LoadStandardMenuHeader + xor a + ld [wPartyMenuActionText], a + predef OpenPartyMenu_ClearGraphics + jp c, .Cancel + jp .loop +.BattleMenuPKMN_Loop: + hlcoord 11, 11 + ld bc, $81 + ld a, ' ' + call ByteFill + xor a + ld [wPartyMenuActionText], a + predef OpenPartyMenu + jr c, .Cancel + +.loop + callfar FreezeMonIcons + callfar BattleMonMenu + jr c, .BattleMenuPKMN_Loop + call PlaceHollowCursor + ld a, [wMenuCursorY] + cp 1 ; SWITCH + jp z, .TryPlayerSwitch + cp 2 ; STATS + jr z, .Stats + cp 3 ; CANCEL + jr z, .Cancel + jr .loop + +.Stats: + call .Battle_StatsScreen + jp .BattleMenuPKMN_ReturnFromStats + +.Cancel: + call ClearSprites + call ClearPalettes + call _LoadHPBar + call CloseWindow + call BackUpTilesToBuffer + call GetMemSGBLayout + call SetPalettes + jp BattleMenu + +; TODO: Do the tile identifiers look right (are they not vFrontPic, vBackPic)?... +.Battle_StatsScreen: + call DisableLCD + + ld hl, vChars2 tile $31 + ld de, vChars0 + ld bc, $11 tiles + call CopyBytes + + ld hl, vChars2 + ld de, vChars0 tile $11 + ld bc, $31 tiles + call CopyBytes + + call EnableLCD + call ClearSprites + call LowVolume + xor a ; PARTYMON + ld [wMonType], a + ld hl, wPartyMon1Species + predef StatsScreenMain + call MaxVolume + + call DisableLCD + + ld hl, vChars0 + ld de, vChars2 tile $31 + ld bc, $11 tiles + call CopyBytes + + ld hl, vChars0 tile $11 + ld de, vChars2 + ld bc, $31 tiles + call CopyBytes + + call EnableLCD + ret + +.TryPlayerSwitch: + ld a, [wPlayerSubStatus5] + bit SUBSTATUS_CANT_RUN, a + jr z, .not_trapped + + ld hl, BattleText_MonCantBeRecalled + call PrintText + jp .BattleMenuPKMN_Loop + +.not_trapped + ld a, [wCurBattleMon] + ld d, a + ld a, [wCurPartyMon] + cp d + jr nz, .try_switch + ld hl, BattleText_MonIsAlreadyOut_0f + call PrintText + jp .BattleMenuPKMN_Loop + +.try_switch + call CheckIfCurPartyMonIsFitToFight + jp z, .BattleMenuPKMN_Loop + ld a, 1 + ld [wFieldMoveSucceeded], a + call ClearPalettes + call ClearSprites + call _LoadHPBar + call CloseWindow + call GetMemSGBLayout + call SetPalettes + +PlayerSwitch: + ld a, [wLinkMode] + and a + jr z, .not_linked + call LinkBattleSendRecieveAction + +.not_linked + call RetreatMon + ld c, 50 + call DelayFrames + call RecallPlayerMon + + hlcoord 9, 7 + lb bc, 5, 11 + call ClearBox + + ld a, [wCurPartyMon] + ld [wCurBattleMon], a + ld c, a + ld b, SET_FLAG + push bc + ld hl, wBattleParticipantsNotFainted + predef SmallFarFlagAction + + pop bc + ld hl, wBattleParticipantsIncludingFainted + predef SmallFarFlagAction + + call LoadBattleMonFromParty + call ApplyStatMods + call SendOutMonText + call NewBattleMonStatus + call SendOutPlayerMon + call EmptyBattleTextbox + call BackUpTilesToBuffer + xor a + ldh [hBattleTurn], a + call SpikesDamage + ld a, 2 + ld [wMenuCursorY], a + and a + ret + +PassedBattleMonEntrance: + ld c, 50 + call DelayFrames + + ld a, [wLinkMode] + and a + jr z, .not_link_battle + + call LinkBattleSendRecieveAction + +.not_link_battle + hlcoord 9, 7 + lb bc, 5, 11 + call ClearBox + + ld a, [wCurPartyMon] + ld [wCurBattleMon], a + ld c, a + ld b, SET_FLAG + push bc + ld hl, wBattleParticipantsNotFainted + predef SmallFarFlagAction + pop bc + ld hl, wBattleParticipantsIncludingFainted + predef SmallFarFlagAction + + call LoadBattleMonFromParty + xor a + ld [wApplyStatLevelMultipliersToEnemy], a + call ApplyStatLevelMultiplierOnAllStats + call SendOutPlayerMon + call EmptyBattleTextbox + call BackUpTilesToBuffer + xor a + ldh [hBattleTurn], a + call SpikesDamage + ret + +BattleText_MonIsAlreadyOut_0f: + text_from_ram wBattleMonNickname + text "はもうでています" + prompt + +BattleText_MonCantBeRecalled: + text_from_ram wBattleMonNickname + text "を もどすことが" + line "できない!" + prompt + +BattleMenu_Run: + call ReloadTilesFromBuffer + ld a, 3 + ld [wMenuCursorY], a + ld hl, wBattleMonSpeed + ld de, wEnemyMonSpeed + call TryToRunAwayFromBattle + ld a, FALSE + ld [wFailedToFlee], a + ret c + ld a, [wFieldMoveSucceeded] + and a + ret nz + jp BattleMenu + +MoveSelectionScreen:: + ld hl, wEnemyMonMoves + ld a, [wMoveSelectionMenuType] + dec a + jr z, .got_menu_type + dec a + jr z, .ether_elixer_menu + call .CheckPlayerHasUsableMoves + ret z + ld hl, wBattleMonMoves + jr .got_menu_type + +.ether_elixer_menu + ld a, [wCurPartyMon] + ld hl, wPartyMon1Moves + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + +.got_menu_type + ld de, wListMoves_MoveIndicesBuffer + ld bc, NUM_MOVES + call CopyBytes + xor a + ldh [hBGMapMode], a + hlcoord 0, 17 - (NUM_MOVES * 2) - 1 + ld b, 8 + ld c, 8 + ld a, [wMoveSelectionMenuType] + cp 2 + jr nz, .got_dims + hlcoord 10, 17 - (NUM_MOVES * 2) - 1 + ld b, 8 + ld c, 8 + +.got_dims + call DrawTextBox + hlcoord 2, 17 - (NUM_MOVES * 2) + 1 + ld a, [wMoveSelectionMenuType] + cp 2 + jr nz, .got_start_coord + hlcoord 12, 17 - (NUM_MOVES * 2) + 1 + +.got_start_coord + ld a, SCREEN_WIDTH * 2 + ld [wHPBarMaxHP], a + predef ListMoves + + ld b, 1 + ld a, [wMoveSelectionMenuType] + cp 2 + jr nz, .got_default_coord + ld b, 11 + +.got_default_coord + ld a, 17 - (NUM_MOVES * 2) + 1 + ld [w2DMenuCursorInitY], a + ld a, b + ld [w2DMenuCursorInitX], a + ld a, [wMoveSelectionMenuType] + cp 1 + jr z, .skip_inc + ld a, [wCurMoveNum] + inc a + +.skip_inc + ld [wMenuCursorY], a + ld a, 1 + ld [wMenuCursorX], a + ld a, [wNumMoves] + inc a + ld [w2DMenuNumRows], a + ld a, 1 + ld [w2DMenuNumCols], a + + ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP + ld a, [wMoveSelectionMenuType] + dec a + ld b, D_DOWN | D_UP | A_BUTTON + jr z, .okay + + dec a + ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON + jr z, .okay + + ld a, [wLinkMode] + cp LINK_COLOSSEUM + jr z, .okay + + ld a, [wDebugFlags] + bit DEBUG_BATTLE_F, a + ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON | SELECT + jr z, .okay + + ld b, D_DOWN | D_UP | D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON | START | SELECT + ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_SELECT | STATICMENU_DISABLE_B | STATICMENU_ENABLE_START | STATICMENU_WRAP + +.okay + ld a, b + ld [wMenuJoypadFilter], a + ld a, c + ld [w2DMenuFlags1], a + xor a + ld [w2DMenuFlags2], a + ld a, $20 + ld [w2DMenuCursorOffsets], a + +.menu_loop + ld a, [wMoveSelectionMenuType] + and a + jr z, .battle_player_moves + + dec a + jr nz, .interpret_joypad + hlcoord 11, 14 + ld de, .Unused_BattleText_MimicWhichMove + call PlaceString + jr .interpret_joypad + +.battle_player_moves + ld a, [wDebugFlags] + bit DEBUG_BATTLE_F, a + jr nz, .interpret_joypad + + call MoveInfoBox + ld a, [wSelectedSwapPosition] + and a + jr z, .interpret_joypad + hlcoord 1, 18 - (NUM_MOVES * 2) + dec a + ld bc, SCREEN_WIDTH * 2 + call AddNTimes + ld [hl], '▷' + +.interpret_joypad + call WaitBGMap + ld a, 1 + ldh [hBGMapMode], a + call ScrollingMenuJoypad + bit D_UP_F, a + jp nz, .pressed_up + bit D_DOWN_F, a + jp nz, .pressed_down + bit SELECT_F, a + jp nz, .pressed_select + bit START_F, a + jp nz, .pressed_start + bit D_RIGHT_F, a + jp nz, .pressed_right + bit D_LEFT_F, a + jp nz, .pressed_left + bit B_BUTTON_F, a + ; A button + push af + + xor a + ld [wSelectedSwapPosition], a + ld a, [wMenuCursorY] + dec a + ld [wMenuCursorY], a + ld b, a + ld a, [wMoveSelectionMenuType] + dec a + jr nz, .not_enemy_moves_process_b + pop af + ret + +.not_enemy_moves_process_b + dec a + ld a, b + ld [wCurMoveNum], a + jr nz, .use_move + + pop af + ret + +.use_move + pop af + ret nz + + ld hl, wBattleMonPP + ld a, [wMenuCursorY] + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + and PP_MASK + jr z, .no_pp_left + + ld a, [wPlayerDisableCount] + swap a + and $f + dec a + cp c + jr z, .move_disabled + + ld a, [wPlayerSubStatus5] + bit SUBSTATUS_TRANSFORMED, a + jr nz, .transformed + ; something was commented out here +.transformed + ld a, [wMenuCursorY] + ld hl, wBattleMonMoves + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wCurPlayerMove], a + xor a + ret + +.move_disabled + ld hl, .BattleText_TheMoveIsDisabled + jr .place_textbox_start_over + +.no_pp_left + ld hl, .BattleText_TheresNoPPLeftForThisMove + +.place_textbox_start_over + call PrintText + call ReloadTilesFromBuffer + jp MoveSelectionScreen + + + +.BattleText_TheresNoPPLeftForThisMove: + text "わざの のこりポイントが ない!" + prompt + +.BattleText_TheMoveIsDisabled: + text "わざを ふうじられている!" + prompt + +.Unused_BattleText_MimicWhichMove: + db "どのわざを" + next "ものまねする?@" + +.pressed_up + ld a, [wMenuCursorY] + and a + jp nz, .menu_loop + ld a, [wNumMoves] + inc a + ld [wMenuCursorY], a + jp .menu_loop + +.pressed_down + ld a, [wMenuCursorY] + ld b, a + ld a, [wNumMoves] + inc a + inc a + cp b + jp nz, .menu_loop + ld a, 1 + ld [wMenuCursorY], a + jp .menu_loop + +.DebugMovePreview: +.pressed_start + bit START_F, a + ld a, 0 + jr nz, .player_side + ld a, 1 + +.player_side + ldh [hBattleTurn], a + call ReloadTilesFromBuffer + call .DrawDebugMoveSelection + ld a, [wPlayerDebugSelectedMove] + and a + jp z, MoveSelectionScreen + ld [wFXAnimID], a + xor a + ld [wNumHits], a + ld [wFXAnimID + 1], a + predef PlayBattleAnim + jp MoveSelectionScreen + +.pressed_left + ld a, [wPlayerDebugSelectedMove] + dec a + jr .pressed_left_right_continue + +.pressed_right + ld a, [wPlayerDebugSelectedMove] + inc a + +.pressed_left_right_continue + ld [wPlayerDebugSelectedMove], a + call .DrawDebugMoveSelection + jp MoveSelectionScreen + +.DrawDebugMoveSelection: + hlcoord 10, 16 + lb bc, 2, 10 + call ClearBox + + hlcoord 10, 17 + ld de, wPlayerDebugSelectedMove + lb bc, PRINTNUM_LEADINGZEROS | 1, 3 + call PrintNumber + + ld a, [wPlayerDebugSelectedMove] + and a + ret z + cp NUM_ATTACKS + 1 + ret nc + + ld [wNamedObjectIndexBuffer], a + call GetMoveName + hlcoord 13, 17 + jp PlaceString + +.CheckPlayerHasUsableMoves: + ld a, MOVE_STRUGGLE + ld [wCurPlayerMove], a + ld a, [wPlayerDisableCount] + and a + ld hl, wBattleMonPP + jr nz, .disabled + + ld a, [hli] + or [hl] + inc hl + or [hl] + inc hl + or [hl] +; BUG: There should be "and PP_MASK" here + ret nz + jr .force_struggle + +.disabled + swap a + and $f + ld b, a + ld d, NUM_MOVES + 1 + xor a +.loop + dec d + jr z, .done + ld c, [hl] + inc hl + dec b + jr z, .loop + or c + jr .loop + +.done + ; BUG: This will result in a move with PP Up confusing the game. + and a ; should be "and PP_MASK" + ret nz + +.force_struggle + ld hl, .BattleText_MonHasNoMovesLeft + call PrintText + ld c, 60 + call DelayFrames + xor a + ret + +.BattleText_MonHasNoMovesLeft: + text_from_ram wBattleMonNickname + text "は だすことの できる" + line "わざが ない!" + done + +.pressed_select + ld a, [wDebugFlags] + bit DEBUG_BATTLE_F, a + jp nz, .DebugMovePreview + + ld a, [wSelectedSwapPosition] + and a + jr z, .start_swap + ld hl, wBattleMonMoves + call .swap_bytes + ld hl, wBattleMonPP + call .swap_bytes + ld hl, wPlayerDisableCount + ld a, [hl] + swap a + and $f + ld b, a + ld a, [wMenuCursorY] + cp b + jr nz, .not_swapping_disabled_move + ld a, [hl] + and $f + ld b, a + ld a, [wSelectedSwapPosition] + swap a + add b + ld [hl], a + jr .swap_moves_in_party_struct + +.not_swapping_disabled_move + ld a, [wSelectedSwapPosition] + cp b + jr nz, .swap_moves_in_party_struct + ld a, [hl] + and $f + ld b, a + ld a, [wMenuCursorY] + swap a + add b + ld [hl], a + +.swap_moves_in_party_struct +; BUG: COOLTRAINER glitch from Generation I still exists here. + ld hl, wPartyMon1Moves + ld a, [wCurBattleMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + push hl + call .swap_bytes + pop hl + ld bc, MON_PP - MON_MOVES + add hl, bc + call .swap_bytes + xor a + ld [wSelectedSwapPosition], a + jp MoveSelectionScreen + +.swap_bytes + push hl + ld a, [wSelectedSwapPosition] + dec a + ld c, a + ld b, 0 + add hl, bc + ld d, h + ld e, l + pop hl + ld a, [wMenuCursorY] + dec a + ld c, a + ld b, 0 + add hl, bc + ld a, [de] + ld b, [hl] + ld [hl], a + ld a, b + ld [de], a + ret + +.start_swap + ld a, [wMenuCursorY] + ld [wSelectedSwapPosition], a + jp MoveSelectionScreen + +MoveInfoBox: + xor a + ldh [hBGMapMode], a + + hlcoord 9, 12 + ld b, 4 + ld c, 9 + call DrawTextBox + + ld a, [wPlayerDisableCount] + and a + jr z, .not_disabled + + swap a + and $f + ld b, a + ld a, [wMenuCursorY] + cp b + jr nz, .not_disabled + + hlcoord 10, 15 + ld de, .Disabled + call PlaceString + jr .done + +.not_disabled + ld hl, wMenuCursorY + dec [hl] + xor a + ldh [hBattleTurn], a + ld hl, wBattleMonMoves + ld a, [wMenuCursorY] + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + ld [wCurPlayerMove], a + + ld a, [wCurBattleMon] + ld [wCurPartyMon], a + ld a, WILDMON + ld [wMonType], a + callfar GetMaxPPOfMove + + ld hl, wMenuCursorY + ld c, [hl] + inc [hl] + ld b, 0 + ld hl, wBattleMonPP + add hl, bc + ld a, [hl] + and PP_MASK + ld [wStringBuffer1], a + hlcoord 10, 15 + ld de, .Type + call PlaceString + + hlcoord 16, 13 + ld [hl], '/' + hlcoord 14, 16 + ld [hl], '/' + hlcoord 14, 13 + ld de, wStringBuffer1 + lb bc, 1, 2 + call PrintNumber + + hlcoord 17, 13 + ld de, wTempPP + lb bc, 1, 2 + call PrintNumber + + callfar UpdateMoveData + ld a, [wPlayerMoveStruct] + ld b, a + hlcoord 15, 16 + predef PrintMoveType + +.done + jp WaitBGMap + +.Disabled: + db "ふうじられている!@" +.Type: + db "わざタイプ@" + +ParseEnemyAction: + ld a, [wLinkMode] + and a + jr z, .not_linked + call BackUpTilesToBuffer + ld a, [wBattlePlayerAction] + and a + call z, LinkBattleSendRecieveAction + call ReloadTilesFromBuffer + + ld a, [wOtherPlayerLinkAction] + cp BATTLEACTION_STRUGGLE + jp z, .struggle + cp BATTLEACTION_SKIPTURN + jr z, .skip_turn + cp BATTLEACTION_SWITCH1 + jp nc, .locked_in + + ld [wCurEnemyMoveNum], a + ld c, a + ld hl, wEnemyMonMoves + ld b, 0 + add hl, bc + ld a, [hl] + jp .finish + +.not_linked + ld hl, wEnemySubStatus5 + bit SUBSTATUS_ENCORED, [hl] + jr z, .not_encored + ld a, [wEnemyEncoreCount] + dec a + ld [wEnemyEncoreCount], a + jr nz, .encored2 + +.clear_encore + ld hl, wEnemySubStatus5 + res SUBSTATUS_ENCORED, [hl] + ld a, 1 + ldh [hBattleTurn], a + ld hl, BattleText_TargetsEncoreEnded + call PrintText + jr .not_encored + +.encored2 + ld a, [wLastEnemyCounterMove] + and a + jr z, .clear_encore + + ld hl, wEnemyMonPP + ld a, [wCurEnemyMoveNum] + ld c, a + ld b, 0 + add hl, bc + ld a, [hl] + and PP_MASK + jr z, .clear_encore + + ld a, [wLastEnemyCounterMove] + jp .finish + +.not_encored + ld a, [wEnemySubStatus4] + and ((1 << SUBSTATUS_RECHARGE) | (1 << SUBSTATUS_RAGE)) + jp nz, .locked_in + + ld hl, wEnemySubStatus3 + ld a, [hl] + and ((1 << SUBSTATUS_RAMPAGE) | (1 << SUBSTATUS_CHARGED)) + jp nz, .locked_in + + ld hl, wEnemySubStatus1 + bit SUBSTATUS_ROLLOUT, [hl] + jp nz, .locked_in + + ld a, [wEnemySubStatus3] + and ((1 << SUBSTATUS_USING_TRAPPING_MOVE) | (1 << SUBSTATUS_BIDE)) + jp nz, .locked_in + + ld a, [wPlayerSubStatus3] + bit SUBSTATUS_USING_TRAPPING_MOVE, a + jr .continue + +.skip_turn + ld a, $ff + jr .finish + +.continue + ld hl, wEnemyMonPP + ld bc, 0 +.loop + inc b + ld a, b + cp NUM_MOVES + 1 + jr z, .finish_pp_check + ld a, [hli] + and PP_MASK + jr z, .loop + ld a, [wEnemyDisableCount] + swap a + and $f + cp b + jr z, .loop + inc c + jr .loop + +.finish_pp_check + ld a, c + and a + jr z, .struggle + + ld a, [wBattleMode] + dec a ; WILD_BATTLE + jr z, .wild_loop + +; Overwrites wTrainerClass in order to give trainers all the AI layers. + ld a, 1 + ld [wTrainerClass], a + callfar AIChooseMove + jr .skip_load + +.wild_loop + ld hl, wEnemyMonMoves + call BattleRandom + and 3 + ld c, a + ld b, 0 + add hl, bc + ld a, [wEnemyDisableCount] + swap a + and $f + dec a + cp c + jr z, .wild_loop + + ld a, [hl] + and a + jr z, .wild_loop + + ld hl, wEnemyMonPP + add hl, bc + ld b, a + ld a, [hl] + and a + jr z, .wild_loop + + ld a, c + ld [wCurEnemyMoveNum], a + ld a, b + +.finish + ld [wCurEnemyMove], a +.skip_load + ld a, 1 + ldh [hBattleTurn], a + callfar UpdateMoveData + ld a, [wEnemyMoveStructEffect] + cp EFFECT_FURY_CUTTER + ret z + xor a + ld [wEnemyFuryCutterCount], a + ret + +.struggle + ld a, MOVE_STRUGGLE + jr .finish + +.locked_in + xor a + ld [wEnemyFuryCutterCount], a + ret + +LinkBattleSendRecieveAction: + ld a, $ff + ld [wOtherPlayerLinkAction], a + ld a, [wBattlePlayerAction] + and a ; BATTLEPLAYERACTION_USEMOVE? + jr nz, .switch + + ld a, [wCurPlayerMove] + cp MOVE_STRUGGLE + ld b, BATTLEACTION_STRUGGLE + jr z, .struggle + + dec b + inc a + jr z, .struggle + ld a, [wCurMoveNum] + jr .use_move + +.switch + ld a, [wCurPartyMon] + add BATTLEACTION_SWITCH1 + ld b, a + +.struggle + ld a, b + +.use_move + ld [wPlayerLinkAction], a + callfar PlaceWaitingText + +.waiting + call LinkTransfer + call DelayFrame + ld a, [wOtherPlayerLinkAction] + inc a + jr z, .waiting + ld b, 10 + +.recieve + call DelayFrame + call LinkTransfer + dec b + jr nz, .recieve + ld b, 10 + +.acknowledge + call DelayFrame + call LinkDataReceived + dec b + jr nz, .acknowledge + ret + +BattleText_TargetsEncoreEnded: + text "の" + line "アンコールじょうたいが とけた!" + prompt + +; The Counter code from Generation I, completely unchanged. +Old_HandleCounterMove: + ldh a, [hBattleTurn] + and a + ld hl, wCurEnemyMove + ld de, wEnemyMoveStructPower + ld a, [wCurPlayerMove] + jr z, .next + ld hl, wCurPlayerMove + ld de, wPlayerMoveStructPower + ld a, [wCurEnemyMove] + +.next + cp MOVE_COUNTER + ret nz ; return if not using Counter + ld a, 1 + ld [wAttackMissed], a ; initialize the move missed variable to true (it is set to false below if the move hits) + ld a, [hl] + cp MOVE_COUNTER + ret z ; miss if the opponent's last selected move is Counter. + ld a, [de] + and a + ret z ; miss if the opponent's last selected move's Base Power is 0. + inc de + ld a, [de] + and a + jr z, .counterableType + cp TYPE_FIGHTING + jr z, .counterableType + xor a + ret + +.counterableType + ld hl, wCurDamage + ld a, [hli] + or [hl] + ret z ; If we made it here, Counter still misses if the last move used in battle did no damage to its target. + ; wDamage is shared by both players, so Counter may strike back damage dealt by the Counter user itself + ; if the conditions meet, even though 99% of the times damage will come from the target. +; if it did damage, double it + ld a, [hl] + add a + ld [hld], a + ld a, [hl] + adc a + ld [hl], a + jr nc, .noCarry + ld a, $ff + ld [hli], a + ld [hl], a + +.noCarry: + xor a + ld [wAttackMissed], a + callfar BattleCommand_CheckHit + xor a + ret + +; Initialize enemy monster parameters +; To do this we pull the species from wTempEnemyMonSpecies +LoadEnemyMon: +; Notes: +; BattleRandom is used to ensure sync between Game Boys + +; We don't need to be here if we're in a link battle + ld a, [wLinkMode] + and a + jp nz, LoadEnemyMonFromParty + +; Make sure everything knows what species we're working with + ld a, [wTempEnemyMonSpecies] + ld [wEnemyMonSpecies], a + ld [wCurSpecies], a + ld [wCurPartySpecies], a + +; Grab the BaseData for this species + call GetBaseData + +; Let's get the item: + +; Is the item predetermined? + ld a, [wBattleMode] + cp TRAINER_BATTLE + jr nz, .WildItem + +; If we're in a trainer battle, the item is in the party struct + ld a, [wCurPartyMon] + ld hl, wOTPartyMon1Item + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, [hl] + jr .UpdateItem + +.WildItem +; ~20% chance of getting an item. + call BattleRandom + cp 79 percent - 1 + ld a, 0 + jr c, .UpdateItem + ld a, [wMonHItems] + +.UpdateItem + ld [wEnemyMonItem], a + ld a, [wEnemySubStatus5] + bit SUBSTATUS_TRANSFORMED, a + ld hl, wEnemyBackupDVs + ld a, [hli] + ld b, [hl] + jr nz, .UpdateDVs + +; Load preset middle-class DVs for trainer battles. + ld a, [wBattleMode] + cp TRAINER_BATTLE + ln a, 9, 8 + ln b, 8, 8 + jr z, .UpdateDVs + +; Otherwise randomly generate DVs for wild encounters + call BattleRandom + ld b, a + call BattleRandom + +.UpdateDVs + ld hl, wEnemyMonDVs + ld [hli], a + ld [hl], b + + ld a, [wCurPartyLevel] + ld [wEnemyMonLevel], a + ld de, wEnemyMonMaxHP + ld b, 0 + ; This address doesn't seem to be referenced anywhere + ld hl, wEnemyMonDVs - (MON_DVS - MON_STAT_EXP + 1) + predef CalcMonStats + + ld a, [wBattleMode] + cp TRAINER_BATTLE + jr z, .OpponentParty + + ld a, [wEnemySubStatus5] + bit SUBSTATUS_TRANSFORMED, a + jr nz, .Moves + +; Zero out status when generating Pokémon + ld hl, wEnemyMonStatus + xor a + ld [hli], a + ld [hli], a + +; Set HP equal to max HP. + ld a, [wEnemyMonMaxHP] + ld [hli], a + ld a, [wEnemyMonMaxHP + 1] + ld [hli], a + jr .Moves + +.OpponentParty +; Get HP from the party struct + ld hl, wOTPartyMon1HP + 1 + ld a, [wCurPartyMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, [hld] + ld [wEnemyMonHP + 1], a + ld a, [hld] + ld [wEnemyMonHP], a + +; Make sure everything knows which monster the opponent is using + ld a, [wCurPartyMon] + ld [wCurOTMon], a + +; Get status from the party struct + dec hl + ld a, [hl] + ld [wEnemyMonStatus], a + +.Moves + ld hl, wMonHType1 + ld de, wEnemyMonType1 + ld a, [hli] + ld [de], a + inc de + ld a, [hl] + ld [de], a + + ld de, wEnemyMonMoves + ld a, [wBattleMode] + cp TRAINER_BATTLE + jr nz, .WildMoves + + ld hl, wOTPartyMon1Moves + ld a, [wCurPartyMon] + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld bc, NUM_MOVES + call CopyBytes + jr .PP + +.WildMoves + xor a + ld h, d + ld l, e + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld [wSkipMovesBeforeLevelUp], a + predef FillMoves + +.PP + ld hl, wEnemyMonMoves + ld de, wEnemyMonPP + predef FillPP + +.Finish + ld hl, wMonHBaseStats + ld de, wEnemyMonBaseStats + ld b, NUM_BATTLE_STATS + +.loop + ld a, [hli] + ld [de], a + inc de + dec b + jr nz, .loop + + ld a, [wMonHCatchRate] + ld [de], a + + inc de + ld a, [wMonHBaseEXP] + ld [de], a + + ld a, [wTempEnemyMonSpecies] + ld [wNamedObjectIndexBuffer], a + + call GetPokemonName + +; Update enemy nickname + ld hl, wStringBuffer1 + ld de, wEnemyMonNickname + ld bc, MON_NAME_LENGTH + call CopyBytes + +; Saw this mon + ld a, [wTempEnemyMonSpecies] + dec a + ld c, a + ld b, 1 + ld hl, wEndPokedexCaught + predef SmallFarFlagAction + ld hl, wEnemyMonStats + ld de, wEnemyStats + ld bc, NUM_BATTLE_STATS * 2 + call CopyBytes + + ld a, 7 + ld b, 8 + ld hl, wEnemyStatLevels + +.InitStatLevel + ld [hli], a + dec b + jr nz, .InitStatLevel + + ld a, 1 + ldh [hBattleTurn], a + callfar GetMonSGBPaletteFlags + ret + +; Leftover from Generation I. +Old_SwapPlayerAndEnemyLevels: + push bc + ld a, [wBattleMonLevel] + ld b, a + ld a, [wEnemyMonLevel] + ld [wBattleMonLevel], a + ld a, b + ld [wEnemyMonLevel], a + pop bc + ret + +; A leftover from Generation I, where it had no effect due to no stats actually being selected. +; BUG: Remarkably, this is STILL run from HealStatus despite the stat double/halve bitfields +; being overwritten with variables that are actually used as substatuses. +DoubleOrHalveSelectedStats_Old:: + call DoubleSelectedStats + jp HalveSelectedStats + +DoubleSelectedStats: + ldh a, [hBattleTurn] + and a + ld a, [wPlayerSubStatus1] ; wPlayerStatsToDouble + ld hl, wBattleMonAttack + 1 + jr z, .notEnemyTurn + ld a, [wEnemySubStatus1] ; wEnemyStatsToDouble + ld hl, wEnemyMonAttack + 1 + +.notEnemyTurn + ld c, 4 + ld b, a + +.loop + srl b + call c, .doubleStat + inc hl + inc hl + dec c + ret z + jr .loop + +.doubleStat + ld a, [hl] + add a + ld [hld], a + ld a, [hl] + rl a + ld [hli], a + ret + +HalveSelectedStats: + ldh a, [hBattleTurn] + and a + ld a, [wPlayerSubStatus2] ; wPlayerStatsToHalve + ld hl, wBattleMonAttack + jr z, .notEnemyTurn + ld a, [wEnemySubStatus2] ; wEnemyStatsToHalve + ld hl, wEnemyMonAttack +.notEnemyTurn + ld c, 4 + ld b, a +.loop + srl b + call c, .halveStat + inc hl + inc hl + dec c + ret z + jr .loop + +.halveStat + ld a, [hl] + srl a + ld [hli], a + ld d, a + ld a, [hl] + rr a + ld [hl], a + or d + jr nz, .nonzeroStat + ld a, 1 + ld [hl], a +.nonzeroStat + dec hl + ret + +BattleWinSlideInEnemyTrainerFrontpic: + xor a + ld [wTempEnemyMonSpecies], a + ld b, SGB_BATTLE_COLORS + call GetSGBLayout +; Should be a call instead + callfar GetTrainerPic + hlcoord 19, 0 + ld c, 0 + +.outer_loop + inc c + ld a, c + cp 7 + ret z + ld d, 0 + push bc + push hl + +.inner_loop + call .CopyColumn + inc hl + ld a, 7 + add d + ld d, a + dec c + jr nz, .inner_loop + ld c, 4 + call DelayFrames + pop hl + pop bc + dec hl + jr .outer_loop + +.CopyColumn: + push hl + push de + push bc + ld e, 7 + +.loop + ld [hl], d + ld bc, SCREEN_WIDTH + add hl, bc + inc d + dec e + jr nz, .loop + pop bc + pop de + pop hl + ret + +ApplyStatusEffectOnPlayerStats: + ld a, 1 + jr ApplyStatusEffectOnStats + +ApplyStatusEffectOnEnemyStats: + xor a + +ApplyStatusEffectOnStats: + ldh [hBattleTurn], a + call ApplyPrzEffectOnSpeed + jp ApplyBrnEffectOnAttack + +ApplyPrzEffectOnSpeed: + ldh a, [hBattleTurn] + and a + jr z, .enemy + ld a, [wBattleMonStatus] + and 1 << PAR + ret z + ld hl, wBattleMonSpeed + 1 + ld a, [hld] + ld b, a + ld a, [hl] + srl a + rr b + srl a + rr b + ld [hli], a + or b + jr nz, .player_ok + ld b, 1 + +.player_ok: + ld [hl], b + ret + +.enemy: + ld a, [wEnemyMonStatus] + and 1 << PAR + ret z + ld hl, wEnemyMonSpeed + 1 + ld a, [hld] + ld b, a + ld a, [hl] + srl a + rr b + srl a + rr b + ld [hli], a + or b + jr nz, .enemy_ok + ld b, 1 + +.enemy_ok: + ld [hl], b + ret + +ApplyBrnEffectOnAttack: + ldh a, [hBattleTurn] + and a + jr z, .enemy + ld a, [wBattleMonStatus] + and 1 << BRN + ret z + ld hl, wBattleMonAttack + 1 + ld a, [hld] + ld b, a + ld a, [hl] + srl a + rr b + ld [hli], a + or b + jr nz, .player_ok + ld b, 1 ; min attack + +.player_ok + ld [hl], b + ret + +.enemy + ld a, [wEnemyMonStatus] + and 1 << BRN + ret z + ld hl, wEnemyMonAttack + 1 + ld a, [hld] + ld b, a + ld a, [hl] + srl a + rr b + ld [hli], a + or b + jr nz, .enemy_ok + ld b, 1 ; min attack + +.enemy_ok + ld [hl], b + ret + +ApplyStatLevelMultiplierOnAllStats: + ld c, 0 + +.stat_loop + call ApplyStatLevelMultiplier + inc c + ld a, c + cp NUM_BATTLE_STATS + jr nz, .stat_loop + ret + +ApplyStatLevelMultiplier: + push bc + push bc + ld a, [wApplyStatLevelMultipliersToEnemy] + and a + ld a, c + + ld hl, wBattleMonStats + ld de, wPlayerStats + ld bc, wPlayerStatLevels + jr z, .got_pointers + + ld hl, wEnemyMonStats + ld de, wEnemyStats + ld bc, wEnemyStatLevels + +.got_pointers +; Adds a (battle stat index) to StatLevels, increase b if c overflows. + add c + ld c, a + jr nc, .okay + inc b + +.okay + ld a, [bc] + pop bc +; b = Stat Level + ld b, a + push bc +; c = Stat index * 2. Add to MonStats pointer. + sla c + ld b, 0 + add hl, bc + ld a, c +; Add stat index * 2 to wEnemyStats. + add e + ld e, a + jr nc, .okay2 + inc d + +.okay2 + pop bc + push hl + ld hl, StatLevelMultipliers_Applied +; Get index of stat level from StatLevelMultipliers_Applied. + dec b + sla b + ld c, b + ld b, 0 + add hl, bc +; Load enemy's original stat into Multiplicand. + xor a + ldh [hMultiplicand], a + ld a, [de] + ldh [hMultiplicand + 1], a + inc de + ld a, [de] + ldh [hMultiplicand + 2], a + +; Load multiplication value from StatLevelMultipliers_Applied. + ld a, [hli] + ldh [hMultiplier], a + call Multiply + +; Load division value from same table. + ld a, [hl] + ldh [hDivisor], a + ld b, 4 + call Divide + +; Cap at 999. + pop hl + ldh a, [hQuotient + 3] + sub LOW(MAX_STAT_VALUE) + ldh a, [hQuotient + 2] + sbc HIGH(MAX_STAT_VALUE) + jp c, .okay3 + + ld a, HIGH(MAX_STAT_VALUE) + ldh [hQuotient + 2], a + ld a, LOW(MAX_STAT_VALUE) + ldh [hQuotient + 3], a + +.okay3 +; Load output into MonStat. + ldh a, [hQuotient + 2] + ld [hli], a + ld b, a + ldh a, [hQuotient + 3] + ld [hl], a + or b +; Keep at minimum of 1 + jr nz, .okay4 + inc [hl] + +.okay4 + pop bc + ret + +StatLevelMultipliers_Applied: + INCLUDE "data/battle/stat_multipliers.inc" + +; Checks every odd-numbered badge, and triggers their corresponding boosts. +; Stat boosts are identical to Gen 1, with Special Attack replacing Special. +BadgeStatBoosts:: + ld a, [wLinkMode] + cp LINK_COLOSSEUM + ret z + + ld a, [wBadges] + ld b, a + ld hl, wBattleMonAttack + ld c, 4 + +.CheckBadge + srl b + call c, BoostStat + inc hl + inc hl +; Check every other badge. + srl b + dec c + jr nz, .CheckBadge + ret + +; Raise stat at hl by 1/8. +BoostStat: + ld a, [hli] + ld d, a + ld e, [hl] + srl d + rr e + srl d + rr e + srl d + rr e + ld a, [hl] + add e + ld [hld], a + ld a, [hl] + adc d + ld [hli], a + +; Cap at 999. + ld a, [hld] + sub LOW(MAX_STAT_VALUE) + ld a, [hl] + sbc HIGH(MAX_STAT_VALUE) + ret c + ld a, HIGH(MAX_STAT_VALUE) + ld [hli], a + ld a, LOW(MAX_STAT_VALUE) + ld [hld], a + ret + +Call_LoadBattleFontsHPBar: + jpfar LoadBattleFontsHPBar + +_LoadHPBar: + jpfar LoadHPBar + + ld de, HpExpBarParts0GFX + ld hl, vChars2 tile $6c + lb bc, BANK(HpExpBarParts0GFX), 04 + call Get1bpp + + ld de, HpExpBarParts1GFX + ld hl, vChars2 tile $73 + lb bc, BANK(HpExpBarParts1GFX), 06 + call Get1bpp + + ld de, ExpBarGFX + ld hl, vChars2 tile $55 + lb bc, BANK(ExpBarGFX), 08 + jp Get2bpp + +EmptyBattleTextbox: + ld hl, .empty + jp PrintText + +.empty: + text_end + _BattleRandom: ; If the normal RNG is used in a link battle it'll desync. ; To circumvent this a shared PRNG is used instead. @@ -61,9 +5120,1608 @@ _BattleRandom: jr nz, .loop ; This has the side effect of pulling the last value first, -; then wrapping around. As a result +; then wrapping around. As a result, when we check to see if +; we've reached the end, we check the one before it. pop af pop bc pop hl ret + +Call_PlayBattleAnim: + ld a, e + ld [wFXAnimID], a + ld a, d + ld [wFXAnimID + 1], a + call WaitBGMap + predef_jump PlayBattleAnim + +; Give experience. +; Don't give experience if linked. +GiveExperiencePoints: + ld a, [wLinkMode] + and a + ret nz + + call .EvenlyDivideExpAmongParticipants + xor a + ld [wCurPartyMon], a + ld bc, wPartyMon1Species + +.loop: + ld hl, MON_HP + add hl, bc + ld a, [hli] + or [hl] + jp z, .next_mon ; fainted + + push bc + ld hl, wBattleParticipantsNotFainted + ld a, [wCurPartyMon] + ld c, a + + ld b, CHECK_FLAG + ld d, 0 + predef SmallFarFlagAction + ld a, c + and a + pop bc + jp z, .next_mon + +; give stat exp + ld hl, MON_STAT_EXP + 1 + add hl, bc + ld d, h + ld e, l + ld hl, wEnemyMonBaseStats + push bc + ld c, NUM_EXP_STATS +.stat_exp_loop + ld a, [hli] + ld b, a + ld a, [de] + add b + ld [de], a + jr nc, .no_carry_stat_exp + dec de + ld a, [de] + inc a + jr z, .stat_exp_maxed_out + ld [de], a + inc de + jr .no_carry_stat_exp + +.stat_exp_maxed_out + ld a, $ff + ld [de], a + inc de + ld [de], a + +.no_carry_stat_exp + dec c + jr z, .stat_exp_awarded + inc de + inc de + jr .stat_exp_loop + +.stat_exp_awarded + xor a + ldh [hMultiplicand], a + ldh [hMultiplicand + 1], a + ld a, [wEnemyMonBaseExp] + ldh [hMultiplicand + 2], a + ld a, [wEnemyMonLevel] + ldh [hMultiplier], a + call Multiply + ld a, 7 + ldh [hDivisor], a + ld b, 4 + call Divide +; Boost Experience for traded Pokemon + pop bc + ld hl, MON_ID + add hl, bc + ld a, [wPlayerID] + cp [hl] + jr nz, .boosted + inc hl + ld a, [wPlayerID + 1] + cp [hl] + ld a, 0 + jr z, .no_boost + +.boosted + call BoostExp + ld a, 1 + +.no_boost +; Boost experience for a Trainer Battle + ld [wStringBuffer2 + 2], a + ld a, [wBattleMode] + dec a + call nz, BoostExp + + ld hl, MON_EXP + 2 + add hl, bc + ld d, [hl] + + + ldh a, [hQuotient + 3] + ld [wStringBuffer2 + 1], a + add d + ld [hld], a + ld d, [hl] + ldh a, [hQuotient + 2] + ld [wStringBuffer2], a + adc d + ld [hl], a + jr nc, .no_exp_overflow + dec hl + inc [hl] + +.no_exp_overflow + ld a, [wCurPartyMon] + ld e, a + ld d, 0 + ld hl, wPartySpecies + add hl, de + ld a, [hl] + ld [wCurSpecies], a + call GetBaseData + push bc + ld d, MAX_LEVEL + callfar CalcExpAtLevel + pop bc + ld hl, MON_EXP + 2 + add hl, bc + push bc + ldh a, [hQuotient + 1] + ld b, a + ldh a, [hQuotient + 2] + ld c, a + ldh a, [hQuotient + 3] + ld d, a + ld a, [hld] + sub d + ld a, [hld] + sbc c + ld a, [hl] + sbc b + jr c, .not_max_exp + ld a, b + ld [hli], a + ld a, c + ld [hli], a + ld a, d + ld [hld], a + +.not_max_exp +; grew to level ##! + ld a, [wCurPartyMon] + ld hl, wPartyMonNicknames + call GetNick + ld hl, BoostedExpPointsText + call PrintText +; Check if the mon leveled up + xor a + ld [wMonType], a + predef CopyMonToTempMon + farcall CalcLevel + pop bc + ld hl, MON_LEVEL + add hl, bc + ld a, [hl] + cp d + jp z, .next_mon + + ld a, [wCurPartyLevel] + push af + ld a, d + ld [wCurPartyLevel], a + ld [hl], a + ld hl, 0 + add hl, bc + ld a, [hl] + ld [wCurSpecies], a + ld [wTempSpecies], a ; unused? + call GetBaseData + ld hl, MON_MAXHP + 1 + add hl, bc + ld a, [hld] + ld e, a + ld d, [hl] + push de + ld hl, MON_MAXHP + add hl, bc + ld d, h + ld e, l + ld hl, MON_STAT_EXP - 1 + add hl, bc + push bc + ld b, TRUE + predef CalcMonStats + pop bc + pop de + ld hl, MON_MAXHP + 1 + add hl, bc + ld a, [hld] + sub e + ld e, a + ld a, [hl] + sbc d + ld d, a + dec hl + ld a, [hl] + add e + ld [hld], a + ld a, [hl] + adc d + ld [hl], a + ld a, [wCurBattleMon] + ld d, a + ld a, [wCurPartyMon] + cp d + jr nz, .skip_active_mon_update + ld de, wBattleMonHP + ld a, [hli] + ld [de], a + inc de + ld a, [hli] + ld [de], a + ld de, wBattleMonMaxHP + push bc + ld bc, PARTYMON_STRUCT_LENGTH - MON_MAXHP + call CopyBytes + pop bc + ld hl, MON_LEVEL + add hl, bc + ld a, [hl] + ld [wBattleMonLevel], a + ld a, [wPlayerSubStatus5] + bit SUBSTATUS_TRANSFORMED, a + jr nz, .transformed + ld hl, MON_ATK + add hl, bc + ld de, wPlayerStats + ld bc, PARTYMON_STRUCT_LENGTH - MON_ATK + call CopyBytes + +.transformed + xor a ; FALSE + ld [wApplyStatLevelMultipliersToEnemy], a + call ApplyStatLevelMultiplierOnAllStats +; these three calls should be regular calls + callfar ApplyStatusEffectOnPlayerStats + callfar BadgeStatBoosts + callfar UpdatePlayerHUD + call EmptyBattleTextbox + call BackUpTilesToBuffer + +.skip_active_mon_update + ld hl, GrewToLevelText + call PrintText + xor a + ld [wMonType], a + predef CopyMonToTempMon + ld d, 1 + callfar PrintTempMonStats + call TextboxWaitPressAorB_BlinkCursor + call ReloadTilesFromBuffer + xor a ; PARTYMON + ld [wMonType], a + ld a, [wCurSpecies] + ld [wTempSpecies], a ; unused? + predef LearnLevelMoves + ld hl, wEvolvableFlags + ld a, [wCurPartyMon] + ld c, a + ld b, SET_FLAG + predef SmallFarFlagAction + pop af + ld [wCurPartyLevel], a + +.next_mon + ld a, [wPartyCount] + ld b, a + ld a, [wCurPartyMon] + inc a + cp b + jr z, .done + ld [wCurPartyMon], a + ld bc, PARTYMON_STRUCT_LENGTH + ld hl, wPartyMon1Species + call AddNTimes + ld b, h + ld c, l + jp .loop + +.done + ld hl, wBattleParticipantsNotFainted + xor a + ld [hl], a + ld a, [wCurBattleMon] + ld c, a + ld b, SET_FLAG + push bc + predef SmallFarFlagAction + ld hl, wBattleParticipantsIncludingFainted + xor a + ld [hl], a + pop bc + predef_jump SmallFarFlagAction + +; Divide enemy base stats, catch rate, and base exp by the number of mons gaining exp. +.EvenlyDivideExpAmongParticipants: +; count number of battle participants + ld a, [wBattleParticipantsNotFainted] + ld b, a + xor a + ld c, 8 + ld d, 0 + +.count_loop + xor a + srl b + adc d + ld d, a + dec c + jr nz, .count_loop + cp 2 + ret c + + ld [wTempByteValue], a + ld hl, wEnemyMonBaseStats + ld c, wEnemyMonEnd - wEnemyMonBaseStats + +.base_stat_division_loop + xor a + ldh [hDividend], a + ld a, [hl] + ldh [hDividend + 1], a + ld a, [wNumSetBits] + ldh [hDivisor], a + ld b, 2 + call Divide + ldh a, [hQuotient + 3] + ld [hli], a + dec c + jr nz, .base_stat_division_loop + ret + +; Multiply experience by 1.5x +BoostExp: + push bc +; load experience value + ldh a, [hProduct + 2] + ld b, a + ldh a, [hProduct + 3] + ld c, a +; halve it + srl b + rr c +; add it back to the whole exp value + add c + ldh [hProduct + 3], a + ldh a, [hProduct + 2] + adc b + ldh [hProduct + 2], a + pop bc + ret + +BoostedExpPointsText: + text_from_ram wStringBuffer1 + text "は@" + start_asm + ld a, [wBoostExpByExpAll] + ld hl, .WithExpAllText + and a + ret nz + ld hl, .ExpPointsText + ld a, [wGainBoostedExp] + and a + ret z + ld hl, .BoostedExpPointsText + ret + +.WithExpAllText: + text " がくしゅうそうちで@" + start_asm + ld hl, .ExpPointsText + ret + +.BoostedExpPointsText: + text " おおめに@" +.ExpPointsText: + text_start + line "@" + deciram wStringBuffer2, 2, 4 + text " けいけんちを もらった!" + prompt + +GrewToLevelText: + text_from_ram wStringBuffer1 + text "は" + line "レベル@" + deciram wCurPartyLevel, 1, 3 + text " に あがった!@" + sound_dex_fanfare_50_79 + text_end + +SendOutMonText: + ld a, [wLinkMode] + and a + jr z, .not_linked + +; If we're in a LinkBattle print just "Go " +; unless DoBattle already set [wBattleHasJustStarted] + ld hl, GoMonText + ld a, [wBattleHasJustStarted] + and a + jr nz, .skip_to_textbox + +; Depending on the HP of the enemy mon, the game prints a different text +.not_linked + ld hl, wEnemyMonHP + ld a, [hli] + or [hl] + ld hl, GoMonText + jr z, .skip_to_textbox + + ; compute enemy health remaining as a percentage + xor a + ldh [hMultiplicand], a + ld hl, wEnemyMonHP + ld a, [hli] + ld [wEnemyHPAtTimeOfPlayerSwitch], a + ldh [hMultiplicand + 1], a + ld a, [hl] + ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a + ldh [hMultiplicand + 2], a + ld a, 25 + ldh [hPrintNumDivisor], a + call Multiply + ld hl, wEnemyMonMaxHP + ld a, [hli] + ld b, [hl] + srl a + rr b + srl a + rr b + ld a, b + ld b, 4 + ldh [hDivisor], a + call Divide + +; (enemy's current HP * 25) / (enemy's max HP / 4) +; approximates current % of max HP + ldh a, [hQuotient + 3] +; >= 70% + ld hl, GoMonText + cp 70 + jr nc, .skip_to_textbox +; 40% <= HP <= 69% + ld hl, DoItMonText + cp 40 + jr nc, .skip_to_textbox +; 10% <= HP <= 39% + ld hl, GoForItMonText + cp 10 + jr nc, .skip_to_textbox +; < 10% + ld hl, YourFoesWeakGetmMonText +.skip_to_textbox + jp PrintText + +GoMonText: + text "ゆけっ! @" + start_asm + jr PrintPlayerMon1Text + +DoItMonText: + text "いってこい! @" + start_asm + jr PrintPlayerMon1Text + +GoForItMonText: + text "がんばれ! @" + start_asm + jr PrintPlayerMon1Text + +YourFoesWeakGetmMonText: + text "あいてが よわっている!" + line "チャンスだ! @" + start_asm + +PrintPlayerMon1Text: + ld hl, .Text + ret +.Text: + text_from_ram wBattleMonNickname + text "!" + done + +RetreatMon: + ld hl, PlayerMon2Text + jp PrintText + +PlayerMon2Text: + text_from_ram wBattleMonNickname + text " @" + start_asm + push de + push bc + ld hl, wEnemyMonHP + 1 + ld de, wEnemyHPAtTimeOfPlayerSwitch + 1 + ld b, [hl] + dec hl + ld a, [de] + sub b + ldh [hMultiplicand + 2], a + dec de + ld b, [hl] + ld a, [de] + sbc b + ldh [hMultiplicand + 1], a + ld a, 25 + ldh [hMultiplier], a + call Multiply + ld hl, wEnemyMonMaxHP + ld a, [hli] + ld b, [hl] + srl a + rr b + srl a + rr b + ld a, b + ld b, 4 + ldh [hDivisor], a + call Divide + pop bc + pop de + ldh a, [hQuotient + 3] +; HP stays the same + ld hl, EnoughText + and a + ret z +; HP went down 1% - 29% + ld hl, ComeBackText + cp 30 + ret c +; HP went down 30% - 69% + ld hl, OKExclamationText + cp 70 + ret c +; HP went down 70% or more + ld hl, GoodText + ret + +EnoughText: + text "もういい!@" + start_asm + jr PrintComeBackText + +OKExclamationText: + text "いいぞ!@" + start_asm + jr PrintComeBackText + +GoodText: + text "よくやった!@" + start_asm + jr PrintComeBackText + +PrintComeBackText: + ld hl, ComeBackText + ret + +ComeBackText: + text_start + line "もどれ!" + done + +PrintSafariZoneBattleText: + ld hl, wUnused_SafariBaitFactor + ld a, [hl] + and a + jr z, .no_bait + dec [hl] + ld hl, Unused_SafariZoneEatingText + jr .done + +.no_bait + dec hl + ld a, [hl] + and a + ret z + dec [hl] + ld hl, Unused_SafariZoneAngryText + jr nz, .done + push hl + ld a, [wEnemyMonSpecies] + ld [wCurSpecies], a + call GetBaseData + ld a, [wMonHCatchRate] + ld [wEnemyMonCatchRate], a + pop hl + +.done + push hl + call ReloadTilesFromBuffer + pop hl + jp PrintText + +Unused_SafariZoneEatingText: + text "やせいの@" + text_from_ram wEnemyMonNickname + text "は" + line "エサを たべてる!" + prompt + +Unused_SafariZoneAngryText: + text "やせいの@" + text_from_ram wEnemyMonNickname + text "は" + line "おこってる!" + prompt + +; Calculate the percent exp between this level and the next +; Level in b, then place the exp bar. Split in the final game. +CalcAndPlaceExpBar: + push hl + push de + ld d, b + push de + callfar CalcExpAtLevel + pop de +; exp at current level gets pushed to the stack + ld hl, hMultiplicand + ld a, [hli] + push af + ld a, [hli] + push af + ld a, [hl] + push af +; next level + inc d + callfar CalcExpAtLevel +; back up the next level exp, and subtract the two levels + ld hl, hMultiplicand + 2 + ld a, [hl] + ldh [hMathBuffer + 2], a + pop bc + sub b + ld [hld], a + ld a, [hl] + ldh [hMathBuffer + 1], a + pop bc + sbc b + ld [hld], a + ld a, [hl] + ldh [hMathBuffer], a + pop bc + sbc b + ld [hl], a + pop de + + ld hl, hMultiplicand + 1 + ld a, [hli] + push af + ld a, [hl] + push af +; get the amount of exp remaining to the next level + ld a, [de] + dec de + ld c, a + ldh a, [hMathBuffer + 2] + sub c + ld [hld], a + ld a, [de] + dec de + ld b, a + ldh a, [hMathBuffer + 1] + sbc b + ld [hld], a + ld a, [de] + ld c, a + ldh a, [hMathBuffer] + sbc c + ld [hld], a + xor a + ld [hl], a + ld a, 64 + ldh [hMultiplier], a + call Multiply + pop af + ld c, a + pop af + ld b, a +.loop + ld a, b + and a + jr z, .done + srl b + rr c + ld hl, hProduct + srl [hl] + inc hl + rr [hl] + inc hl + rr [hl] + inc hl + rr [hl] + jr .loop +.done + ld a, c + ldh [hDivisor], a + ld b, 4 + call Divide + pop hl + ld bc, 7 + add hl, bc + ldh a, [hQuotient + 3] + ld b, a + ld a, $40 + sub b + ld b, a + +; Separated into PlaceExpBar in the final game + ld c, 8 +.loop2 + ld a, b + sub 8 + jr c, .next + ld b, a + ld a, $6a ; full bar + ld [hld], a + dec c + jr z, .finish + jr .loop2 + +.next + add 8 + jr z, .loop3 + add $54 ; tile to the left of small exp bar tile + jr .skip + +.loop3 + ld a, $62 ; empty bar + +.skip + ld [hld], a + ld a, $62 ; empty bar + dec c + jr nz, .loop3 +.finish + ret + +GetBattleMonBackpic: + ld a, [wPlayerSubStatus4] + bit SUBSTATUS_SUBSTITUTE, a + ld hl, BattleAnimCmd_RaiseSub + jr nz, GetBattleMonBackpic_DoAnim + +DropPlayerSub: + ld a, [wPlayerMinimized] + and a + ld hl, BattleAnimCmd_MinimizeOpp + jr nz, GetBattleMonBackpic_DoAnim + ld a, [wCurPartySpecies] + push af + ld a, [wBattleMonSpecies] + ld [wCurSpecies], a + ld [wCurPartySpecies], a + call GetBaseData + ld hl, wMonHBackSprite - wMonHeader + call UncompressMonSprite + ld hl, vBackPic + predef GetMonBackpic + pop af + ld [wCurPartySpecies], a + ret + +GetBattleMonBackpic_DoAnim: + ldh a, [hBattleTurn] + push af + xor a + ldh [hBattleTurn], a + ld a, BANK(BattleAnimCmd_RaiseSub) + call FarCall_hl + pop af + ldh [hBattleTurn], a + ret + +GetEnemyMonFrontpic: + ld a, [wEnemySubStatus4] + bit SUBSTATUS_SUBSTITUTE, a + ld hl, BattleAnimCmd_RaiseSub + jr nz, GetEnemyMonFrontpic_DoAnim + +DropEnemySub: + ld a, [wEnemyMinimized] + and a + ld hl, BattleAnimCmd_MinimizeOpp + jr nz, GetEnemyMonFrontpic_DoAnim + ld a, [wCurPartySpecies] + push af + ld a, [wEnemyMonSpecies] + ld [wCurSpecies], a + ld [wCurPartySpecies], a + call GetBaseData + ld hl, wEnemyMonDVs + predef GetUnownLetter + ld de, vFrontPic + call LoadMonFrontSprite + pop af + ld [wCurPartySpecies], a + ret + +GetEnemyMonFrontpic_DoAnim: + ldh a, [hBattleTurn] + push af + ld a, 1 + ldh [hBattleTurn], a + ld a, BANK(BattleAnimCmd_RaiseSub) + call FarCall_hl + pop af + ldh [hBattleTurn], a + ret + +SECTION "engine/battle/core.asm@StartBattle", ROMX + +StartBattle:: + ld a, [wOtherTrainerClass] + and a + jr nz, .battle_intro + + ld a, [wTempWildMonSpecies] + and a + jr z, .battle_intro + + ld [wCurPartySpecies], a + ld [wTempEnemyMonSpecies], a + +.battle_intro + ld a, [wTimeOfDayPal] + push af + ld hl, wTextboxFlags + ld a, [hl] + push af + res TEXT_DELAY_F, [hl] + ldh a, [hMapAnims] + ld [wMapAnimsBackup], a + call PlayBattleMusic + call ShowLinkBattleParticipants + call ClearBattleRAM + ld a, [wOtherTrainerClass] + and a + jr nz, .trainer + + call InitEnemyWildmon + jr .back_up_bgmap2 +.trainer + call InitEnemyTrainer + +.back_up_bgmap2 + ld b, 0 + call GetSGBLayout + ld hl, wStateFlags + res SPRITE_UPDATES_DISABLED_F, [hl] + call InitBattleDisplay + call BattleStartMessage + xor a + ldh [hBGMapMode], a + call EmptyBattleTextbox + hlcoord 9, 7 + lb bc, 5, 10 + call ClearBox + hlcoord 1, 0 + lb bc, 4, 10 + call ClearBox + call ClearSprites + ld a, [wBattleMode] + cp WILD_BATTLE + call z, UpdateEnemyHUD + call DoBattle + call ExitBattle + pop af + ld [wTextboxFlags], a + pop af + ld [wTimeOfDayPal], a + ld a, [wMapAnimsBackup] + ldh [hMapAnims], a + scf + ret + +InitEnemyTrainer: + ld [wTrainerClass], a + callfar GetTrainerAttributes + callfar ReadTrainerParty + + ; RIVAL's first mon has no held item + ld a, [wTrainerClass] + cp TRAINER_RIVAL + jr nz, .ok + xor a + ld [wOTPartyMon1Item], a + +.ok + call GetTrainerPic + xor a + ld [wTempEnemyMonSpecies], a + ldh [hGraphicStartTile], a + dec a + ld [wEnemyItemState], a + hlcoord 12, 0 + lb bc, 7, 7 + predef PlaceGraphic + ld a, -1 + ld [wCurOTMon], a + ld a, TRAINER_BATTLE + ld [wBattleMode], a + ret + +InitEnemyWildmon: + ld a, 1 + ld [wBattleMode], a + call LoadEnemyMon + ld hl, wEnemyMonDVs + predef GetUnownLetter + ld de, vFrontPic + call LoadMonFrontSprite + xor a + ld [wTrainerClass], a + ldh [hGraphicStartTile], a + hlcoord 12, 0 + lb bc, 7, 7 + predef PlaceGraphic + ret + +GetTrainerPic: + ld a, [wEnemyTrainerGraphicsPointer] + ld e, a + ld a, [wEnemyTrainerGraphicsPointer + 1] + ld d, a + ld a, BANK("gfx.asm@Trainer Battle Sprites") + call UncompressSpriteFromDE + ld de, vFrontPic + ln a, 7, 7 + ld c, a + jp LoadUncompressedSpriteData + +; Fill wBoxAlignment-aligned box width b height c +; with iterating tile starting from hGraphicStartTile at hl. +PlaceGraphic: + ld de, SCREEN_WIDTH + + ld a, [wSpriteFlipped] + and a + jr nz, .right + + ldh a, [hGraphicStartTile] + +.x1 + push bc + push hl + +.y1 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .y1 + + pop hl + inc hl + pop bc + dec b + jr nz, .x1 + ret + +.right + push bc + ld b, 0 + dec c + add hl, bc + pop bc + + ldh a, [hGraphicStartTile] +.x2 + push bc + push hl + +.y2 + ld [hl], a + add hl, de + inc a + dec c + jr nz, .y2 + + pop hl + dec hl + pop bc + dec b + jr nz, .x2 + ret + +LoadMonBackPic: + ld a, [wTempBattleMonSpecies] + ld [wCurPartySpecies], a + hlcoord 1, 5 + ld b, 7 + ld c, 8 + call ClearBox + ld hl, wMonHBackSprite - wMonHeader + call UncompressMonSprite + ld hl, vBackPic + predef_jump GetMonBackpic + +; Old back sprite scaling code from Red & Green. +Old_ScaleSpriteByTwo: + ld de, sSpriteBuffer1 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped + ld hl, sSpriteBuffer0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer + call ScaleLastSpriteColumnByTwo ; last tile column is special case + call ScaleFirstThreeSpriteColumnsByTwo ; scale first 3 tile columns + ld de, sSpriteBuffer2 + (4*4*8) - 5 ; last byte of input data, last 4 rows already skipped + ld hl, sSpriteBuffer1 + SPRITEBUFFERSIZE - 1 ; end of destination buffer + call ScaleLastSpriteColumnByTwo ; last tile column is special case + +ScaleFirstThreeSpriteColumnsByTwo: + ld b, $3 ; 3 tile columns +.columnLoop + ld c, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows +.columnInnerLoop + push bc + ld a, [de] + ld bc, -(7*8)+1 ; -$37, scale lower nybble and seek to previous output column + call ScalePixelsByTwo + ld a, [de] + dec de + swap a + ld bc, 7*8+1-2 ; $37, scale upper nybble and seek back to current output column and to the next 2 rows + call ScalePixelsByTwo + pop bc + dec c + jr nz, .columnInnerLoop + dec de + dec de + dec de + dec de + ld a, b + 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 + jr nz, .columnLoop + ret + +ScaleLastSpriteColumnByTwo: + ld a, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows + ldh [hSpriteInterlaceCounter], a + ld bc, -1 +.columnInnerLoop + ld a, [de] + dec de + swap a ; only high nybble contains information + call ScalePixelsByTwo + ldh a, [hSpriteInterlaceCounter] + dec a + ldh [hSpriteInterlaceCounter], a + jr nz, .columnInnerLoop + dec de ; skip last 4 rows of new column + dec de + dec de + dec de + ret + +; scales the given 4 bits in a (4x1 pixels) to 2 output bytes (8x2 pixels) +; hl: destination pointer +; bc: destination pointer offset (added after the two bytes have been written) +ScalePixelsByTwo: + push hl + and $f + ld hl, DuplicateBitsTable + add l + ld l, a + jr nc, .noCarry + inc h +.noCarry + ld a, [hl] + pop hl + ld [hld], a ; write output byte twice to make it 2 pixels high + ld [hl], a + add hl, bc ; add offset + ret + +DuplicateBitsTable: +FOR n, 16 + db (n & 1) * 3 + (n & 2) * 6 + (n & 4) * 12 + (n & 8) * 24 +ENDR + +ClearBattleRAM: + xor a + ld [wBattlePlayerAction], a + ld [wBattleResult], a + + ld hl, wPartyMenuCursor + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + + ld [wMenuScrollPosition], a + ld [wCriticalHit], a + ld [wBattleMonSpecies], a + ld [wBattleParticipantsNotFainted], a + ld [wCurBattleMon], a + ld [wBattleEnded], a + ld [wTimeOfDayPal], a + ld [wEnemyTurnsTaken], a + + ld hl, wPlayerHPPal + ld [hli], a + ld [hl], a + + ld hl, wBattleMonDVs + ld [hli], a + ld [hl], a + + ld hl, wEnemyMonDVs + ld [hli], a + ld [hl], a + +; Clear the entire BattleMons area + ld hl, wEnemyMoveStruct + ld bc, wBattleEnd - wBattle + xor a + call ByteFill + + call ClearWindowData + + ld hl, hBGMapAddress + xor a + ld [hli], a + ld [hl], HIGH(vBGMap0) + ld a, (LCDC_DEFAULT & ~(1 << rLCDC_WINDOW_TILEMAP)) + ldh [rLCDC], a + ld a, [wMapId] + cp $d9 ; SAFARI_ZONE_EAST + jr c, .return + cp $dd ; SAFARI_ZONE_CENTER_REST_HOUSE + jr nc, .return + ld a, 2 + ld [wBattleType], a +.return + ret + +ExitBattle: + call IsLinkBattle + jr nz, .HandleEndOfBattle + call ShowLinkBattleParticipantsAfterEnd + jr .CheckEvolution + +.HandleEndOfBattle + ld a, [wBattleResult] + and a + jr nz, .CleanUpBattleRAM + ; WIN + call CheckPayDay + +.CheckEvolution + xor a + ld [wForceEvolution], a + predef EvolveAfterBattle + +.CleanUpBattleRAM: + xor a + ld [wLowHealthAlarmBuffer], a + ld [wBattleMode], a + ld [wBattleType], a + ld [wAttackMissed], a + ld [wTempWildMonSpecies], a + ld [wOtherTrainerClass], a + ld [wFailedToFlee], a + ld [wNumFleeAttempts], a + ld [wBattleEnded], a + ld hl, wPartyMenuCursor + ld [hli], a + ld [hli], a + ld [hli], a + ld [hl], a + ld [wMenuScrollPosition], a + ld hl, wPlayerSubStatus1 + ld b, wEnemyFuryCutterCount - wPlayerSubStatus1 +.loop + ld [hli], a + dec b + jr nz, .loop + ld hl, wd4a7 + set 0, [hl] + call WaitSFX + + ld a, $e3 + ldh [rLCDC], a + ld hl, wd14f + res 7, [hl] + call ClearPalettes + ret + +CheckPayDay: + ld hl, wPayDayMoney + ld a, [hli] + or [hl] + inc hl + or [hl] + ret z + + ld a, [wBattleMonItem] + ld b, a + callfar GetItemHeldEffect + ld a, b + cp HELD_AMULET_COIN + jr nz, AddBattleMoneyToAccount + + ld hl, wPayDayMoney + 2 + sla [hl] + dec hl + rl [hl] + dec hl + rl [hl] + jr nc, AddBattleMoneyToAccount + + ld a, $ff + ld [hli], a + ld [hli], a + ld [hl], a + +AddBattleMoneyToAccount: + ld hl, wPayDayMoney + 2 + ld de, wMoney + 2 + ld c, 3 + and a +.loop + ld a, [de] + adc [hl] + ld [de], a + dec de + dec hl + dec c + jr nz, .loop + ld hl, BattleText_PlayerPickedUpPayDayMoney + call PrintText + ret + +BattleText_PlayerPickedUpPayDayMoney: + text "は @" + deciram wPayDayMoney, 3, 6 + text "円" + line "ひろった!" + prompt + +ShowLinkBattleParticipantsAfterEnd: + ld a, [wCurOTMon] + ld hl, wOTPartyMon1Status + ld bc, PARTYMON_STRUCT_LENGTH + call AddNTimes + ld a, [wEnemyMonStatus] + ld [hl], a + call ClearTileMap + call _ShowLinkBattleParticipants + ld a, [wBattleResult] + cp LOSE + ld de, .YouWin + jr c, .store_result + ld de, .YouLose + jr z, .store_result + ld de, .Draw + +.store_result + hlcoord 6, 8 + call PlaceString + ld c, 200 + call DelayFrames + ret + +.YouWin: + db "あなたの かち@" + +.YouLose: + db "あなたの まけ@" + +.Draw: + db "  ひきわけ@" + +PlayBattleMusic: + push hl + push de + push bc + xor a + ld [wMusicFade], a + ld de, 0 + call PlayMusic + call DelayFrame + call MaxVolume +; plays vs. gym leader music regardless of the battle type + ld de, MUSIC_LEADER_BATTLE + call PlayMusic + pop bc + pop de + pop hl + ret + +InitBattleDisplay: + call GetTrainerBackpic + hlcoord 0, 12 + ld b, 4 + ld c, 18 + call DrawTextBox + hlcoord 1, 5 + lb bc, 3, 7 + call ClearBox + call DisableLCD + call LoadFont + call Call_LoadBattleFontsHPBar + ld hl, vBGMap0 + lb bc, 4, 0 + ld a, ' ' + call ByteFill + call LoadMapTimeOfDay.PushAttrMap + call EnableLCD + xor a + ldh [hMapAnims], a + ldh [hSCY], a + ld a, SCREEN_HEIGHT_PX + ldh [hWY], a + ldh [rWY], a + call WaitBGMap + xor a + ldh [hBGMapMode], a + call BattleIntroSlidingPics + ld a, 1 + ldh [hBGMapMode], a + ld a, $31 + ldh [hGraphicStartTile], a + hlcoord 2, 6 + lb bc, 6, 6 + predef PlaceGraphic + xor a + ldh [hWY], a + ldh [rWY], a + call WaitBGMap + ld b, SGB_BATTLE_COLORS + call GetSGBLayout + call HideSprites + ld a, SCREEN_HEIGHT_PX + ldh [hWY], a + xor a + ldh [hSCX], a + ret + + +BattleIntroSlidingPics: + ld b, $70 + ld c, $90 + ld a, c + ldh [hSCX], a + call DelayFrame + ld a, %11100100 + ldh [rBGP], a + ldh [rOBP0], a + ldh [rOBP1], a +.loop1 + push bc + ld h, b + ld l, $40 + call .subfunction2 + ld h, 0 + ld l, $60 + call .subfunction2 + call .subfunction1 + pop bc + ld a, c + ldh [hSCX], a + inc b + inc b + dec c + dec c + jr nz, .loop1 + ret + +.subfunction1: + push bc + ld hl, wShadowOAMSprite00XCoord + ld c, $12 + ld de, SPRITEOAMSTRUCT_LENGTH +.loop2 + dec [hl] + dec [hl] + add hl, de + dec c + jr nz, .loop2 + pop bc + ret + +.subfunction2: +.loop3 + ldh a, [rLY] + cp l + jr nz, .loop3 + ld a, h + ldh [rSCX], a +.loop4 + ldh a, [rLY] + cp h + jr z, .loop4 + ret + +GetTrainerBackpic: + ld de, PlayerBacksprite + ld a, BANK(PlayerBacksprite) + call UncompressSpriteFromDE + ld hl, vChars2 tile $31 + predef GetMonBackpic + ld a, BANK(sSpriteBuffer1) + call OpenSRAM + ld hl, vSprites + ld de, sSpriteBuffer1 + ldh a, [hROMBank] + ld b, a + ld c, 7 * 7 + call Request2bpp + call CloseSRAM + call .LoadTrainerBackpicAsOAM + + ld a, $31 + ldh [hGraphicStartTile], a + hlcoord 2, 6 + lb bc, 6, 6 + predef PlaceGraphic + ret + +.LoadTrainerBackpicAsOAM: + ld hl, wShadowOAMSprite00 + xor a + ldh [hMapObjectIndex], a + ld b, 6 + ld e, (SCREEN_WIDTH + 1) * TILE_WIDTH + +.outer_loop + ld c, 3 + ld d, 8 * TILE_WIDTH + +.inner_loop + ld [hl], d + inc hl + ld [hl], e + inc hl + ldh a, [hMapObjectIndex] + ld [hli], a + inc a + ldh [hMapObjectIndex], a + inc hl + ld a, d + add 1 * TILE_WIDTH + ld d, a + dec c + jr nz, .inner_loop + ldh a, [hMapObjectIndex] + add 3 + ldh [hMapObjectIndex], a + ld a, e + add 1 * TILE_WIDTH + ld e, a + dec b + jr nz, .outer_loop + ret + +PlayerBacksprite: +INCBIN "gfx/trainer/protagonist_back.pic" + +Unused_OldManBacksprite: +INCBIN "gfx/trainer/oldman_back.pic" + +BattleStartMessage: + ld a, [wBattleMode] + dec a + jr z, .wild + + ld de, SFX_SHINE + call PlaySFX + call WaitSFX + + ld c, 20 + call DelayFrames + + callfar Battle_GetTrainerName + + ld hl, WantsToBattleText + jr .PrintBattleStartText + +.wild + ld a, $f + ld [wCryTracks], a + ld a, [wTempEnemyMonSpecies] + call PlayStereoCry + ld hl, WildPokemonAppearedText + ld a, [wAttackMissed] + and a + jr z, .PrintBattleStartText + ld hl, HookedPokemonAttackedText + +.PrintBattleStartText: + push hl + callfar BattleStart_TrainerHuds + pop hl + call PrintText + ret + +WildPokemonAppearedText: + text "あ! やせいの" + line "@" + text_from_ram wEnemyMonNickname + text "が とびだしてきた!" + prompt + +HookedPokemonAttackedText: + text "つりあげた @" + text_from_ram wEnemyMonNickname + text "が" + line "とびかかってきた!" + prompt + +WantsToBattleText: + text_from_ram wOTClassName + text "の @" + text_from_ram wStringBuffer1 + text "が" + line "しょうぶを しかけてきた!" + prompt + +ShowLinkBattleParticipants: + call IsLinkBattle + jr nz, .ok + call _ShowLinkBattleParticipants + call ClearTileMap +.ok + call DelayFrame + predef DoBattleTransition + call Call_LoadBattleFontsHPBar + ld a, 1 + ldh [hBGMapMode], a + call ClearSprites + call ClearTileMap + xor a + ldh [hBGMapMode], a + ldh [hWY], a + ldh [rWY], a + ldh [hMapAnims], a + ret + +_ShowLinkBattleParticipants: + call LoadFontExtra + hlcoord 3, 4 + ld b, 7 + ld c, 12 + call DrawTextBox + hlcoord 4, 6 + ld de, wPlayerName + call PlaceString + hlcoord 4, 10 + ld de, wOTPlayerName + call PlaceString + hlcoord 9, 8 + ld a, 'V' + ld [hli], a + ld [hl], 'S' + callfar LinkBattle_TrainerHuds + ld c, 150 + jp DelayFrames + +IsLinkBattle: + push bc + push af + ld a, [wLinkMode] + cp LINK_COLOSSEUM + pop bc + ld a, b + pop bc + ret diff --git a/engine/dumps/bank0d.asm b/engine/dumps/bank0d.asm index 754a128..6599933 100644 --- a/engine/dumps/bank0d.asm +++ b/engine/dumps/bank0d.asm @@ -238,9 +238,9 @@ BattleCommand_CheckTurn: ; Repurposed as hardcoded turn handling. Useless as a command. ldh a, [hBattleTurn] and a - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] jr z, .go - ld a, [wCurEnemySelectedMove] + ld a, [wCurEnemyMove] .go inc a @@ -289,14 +289,14 @@ BattleCommand_CheckTurn: call PrintText ; Snore and Sleep Talk bypass sleep. - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] cp MOVE_SNORE jr z, .not_asleep cp MOVE_SLEEP_TALK jr z, .not_asleep xor a - ld [wCurPlayerMove], a + ld [wLastPlayerCounterMove], a jp EndTurn .not_asleep @@ -305,7 +305,7 @@ BattleCommand_CheckTurn: jr z, .not_frozen ; Flame Wheel and Sacred Fire thaw the user. - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] cp MOVE_FLAME_WHEEL jr z, .not_frozen cp MOVE_SACRED_FIRE @@ -314,7 +314,7 @@ BattleCommand_CheckTurn: ld hl, FrozenSolidText call PrintText xor a - ld [wCurPlayerMove], a + ld [wLastPlayerCounterMove], a jp EndTurn .not_frozen @@ -323,7 +323,7 @@ BattleCommand_CheckTurn: jp z, .not_trapped ; Rapid Spin breaks the player free of trapping moves - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] cp MOVE_RAPID_SPIN jp z, .not_trapped ld hl, CantMoveText @@ -428,7 +428,7 @@ BattleCommand_CheckTurn: and a jr z, .no_disabled_move - ld hl, wCurPlayerSelectedMove + ld hl, wCurPlayerMove cp [hl] jr nz, .no_disabled_move @@ -504,14 +504,14 @@ CheckEnemyTurn: .fast_asleep ; Snore and Sleep Talk bypass sleep. - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] cp MOVE_SNORE jr z, .not_asleep cp MOVE_SLEEP_TALK jr z, .not_asleep xor a - ld [wCurEnemyMove], a + ld [wLastEnemyCounterMove], a jp EndTurn .not_asleep @@ -520,7 +520,7 @@ CheckEnemyTurn: jr z, .not_frozen ; Flame Wheel and Sacred Fire thaw the user. - ld a, [wCurEnemySelectedMove] + ld a, [wCurEnemyMove] cp MOVE_FLAME_WHEEL jr z, .not_frozen cp MOVE_SACRED_FIRE @@ -529,7 +529,7 @@ CheckEnemyTurn: ld hl, FrozenSolidText call PrintText xor a - ld [wCurEnemyMove], a + ld [wLastEnemyCounterMove], a jp EndTurn .not_frozen @@ -538,7 +538,7 @@ CheckEnemyTurn: jp z, .not_trapped ; Rapid Spin breaks the player free of trapping moves - ld a, [wCurEnemySelectedMove] + ld a, [wCurEnemyMove] cp MOVE_RAPID_SPIN jp z, .not_trapped ld hl, CantMoveText @@ -657,7 +657,7 @@ CheckEnemyTurn: and a jr z, .no_disabled_move - ld hl, wCurEnemySelectedMove + ld hl, wCurEnemyMove cp [hl] jr nz, .no_disabled_move @@ -800,12 +800,12 @@ InfatuationText: prompt MoveDisabled: - ld hl, wCurPlayerSelectedMove + ld hl, wCurPlayerMove ld de, wPlayerSubStatus3 ldh a, [hBattleTurn] and a jr z, .ok - inc hl ; wCurEnemySelectedMove + inc hl ; wCurEnemyMove ld de, wEnemySubStatus3 .ok @@ -1084,7 +1084,7 @@ BattleCommand_CheckObedience: ld hl, wBattleMonMoves add hl, bc ld a, [hl] - ld [wCurPlayerSelectedMove], a + ld [wCurPlayerMove], a call UpdateMoveData .EndDisobedience @@ -1125,10 +1125,10 @@ UsedMoveText: ldh a, [hBattleTurn] and a ld a, [wPlayerMoveStruct] - ld hl, wCurPlayerMove + ld hl, wLastPlayerCounterMove jr z, .playerTurn ld a, [wEnemyMoveStruct] - ld hl, wCurEnemyMove + ld hl, wLastEnemyCounterMove .playerTurn: ld [hl], a @@ -1343,12 +1343,12 @@ MoveGrammar: BattleCommand_DoTurn: ldh a, [hBattleTurn] and a - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] ld hl, wBattleMonPP ld de, wPlayerSubStatus3 jr z, .proceed - ld a, [wCurEnemySelectedMove] + ld a, [wCurEnemyMove] ld hl, wEnemyMonPP ld de, wEnemySubStatus3 @@ -2003,12 +2003,12 @@ BattleCommand_CheckHit: bit SUBSTATUS_INVULNERABLE, [hl] jp z, .EnemyMonMist - ld hl, wCurEnemyMove + ld hl, wLastEnemyCounterMove ld de, wPlayerMoveStruct ldh a, [hBattleTurn] and a jr z, .fly_moves - ld hl, wCurPlayerMove + ld hl, wLastPlayerCounterMove ld de, wEnemyMoveStruct .fly_moves: @@ -2553,7 +2553,7 @@ Unreferenced_Gen1HealEffect: .updateHPBar: ld [wWhichHPBar], a predef UpdateHPBar - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, Unused_RegainedHealthText jp PrintText @@ -3146,7 +3146,7 @@ GetEnemyMonStat: push de push bc ld a, [wLinkMode] - cp 3 ; LINK_COLOSSEUM + cp LINK_COLOSSEUM jr nz, .notLinkBattle ld hl, wOTPartyMon1MaxHP @@ -3563,10 +3563,10 @@ INCLUDE "data/moves/flail_reversal_power.inc" BattleCommand_Counter: ldh a, [hBattleTurn] and a - ld hl, wCurEnemySelectedMove + ld hl, wCurEnemyMove ld de, wEnemyMoveStructPower jr z, .got_enemy_move - ld hl, wCurPlayerSelectedMove + ld hl, wCurPlayerMove ld de, wPlayerMoveStructPower .got_enemy_move @@ -3611,11 +3611,11 @@ BattleCommand_Encore: and a ld hl, wEnemySubStatus5 ld de, wEnemyEncoreCount - ld a, [wCurEnemyMove] + ld a, [wLastEnemyCounterMove] jr z, .ok ld hl, wPlayerSubStatus5 ld de, wPlayerEncoreCount - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] .ok ; Struggle, Mirror Move, and Encore itself can be encored, unlike the final game. @@ -3857,7 +3857,7 @@ TookAimText: BattleCommand_Sketch: ld a, [wLinkMode] - cp 3 ; LINK_COLOSSEUM + cp LINK_COLOSSEUM jr z, .failed call CheckSubstituteOpp @@ -3870,7 +3870,7 @@ BattleCommand_Sketch: ld c, a ld b, 0 add hl, bc - ld a, [wCurEnemyMove] + ld a, [wLastEnemyCounterMove] ld [hl], a ld hl, wPartyMon1Moves @@ -3928,12 +3928,12 @@ BattleCommand_SleepTalk: ldh a, [hBattleTurn] and a ld hl, wBattleMonMoves + 1 - ld de, wCurPlayerSelectedMove + ld de, wCurPlayerMove ld bc, wPlayerMoveStruct ld a, [wBattleMonStatus] jr z, .go ld hl, wEnemyMonMoves + 1 - ld de, wCurEnemySelectedMove + ld de, wCurEnemyMove ld bc, wEnemyMoveStruct ld a, [wEnemyMonStatus] @@ -4019,11 +4019,11 @@ BattleCommand_Spite: and a ld hl, wEnemyMonMoves ld de, wOTPartyMon1PP - ld a, [wCurEnemyMove] + ld a, [wLastEnemyCounterMove] jr z, .got_moves ld hl, wBattleMonMoves ld de, wPartyMon1PP - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] .got_moves and a @@ -4241,7 +4241,7 @@ DoEnemyDamage: ld [wWhichHPBar], a predef UpdateHPBar .did_no_damage: - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F DoPlayerDamage: @@ -4296,7 +4296,7 @@ DoPlayerDamage: predef UpdateHPBar .did_no_damage: - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F DoSubstituteDamage: @@ -4352,7 +4352,7 @@ DoSubstituteDamage: .got_move_effect: xor a ld [hl], a - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F SubTookDamageText: @@ -4372,18 +4372,18 @@ UpdateMoveData: ld hl, wEnemySubStatus5 ld de, wEnemyMoveStruct - ld bc, wCurEnemyMove + ld bc, wLastEnemyCounterMove push bc - ld a, [wCurEnemySelectedMove] + ld a, [wCurEnemyMove] ld b, a jr .get_move_data .player: ld hl, wPlayerSubStatus5 ld de, wPlayerMoveStruct - ld bc, wCurPlayerMove + ld bc, wLastPlayerCounterMove push bc - ld a, [wCurPlayerSelectedMove] + ld a, [wCurPlayerMove] ld b, a ld a, [wPlayerDebugSelectedMove] and a @@ -4463,7 +4463,7 @@ Unreferenced_OldSleepTarget: ld [de], a call PlayDamageAnim push de - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, FellAsleepText @@ -4487,9 +4487,9 @@ Unreferenced_OldSleepTarget: and ~SLP ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F FellAsleepText: @@ -4558,7 +4558,7 @@ BattleCommand_SleepTarget: ld [de], a call PlayDamageAnim push de - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, FellAsleepText @@ -4580,9 +4580,9 @@ BattleCommand_SleepTarget: and ~SLP ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F .fail: @@ -4630,7 +4630,7 @@ BattleCommand_PoisonTarget: push de ld de, ANIM_PSN call PlayOpponentBattleAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, WasPoisonedText call PrintText @@ -4651,9 +4651,9 @@ BattleCommand_PoisonTarget: res PSN, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F WasPoisonedText: @@ -4724,7 +4724,7 @@ BattleCommand_Poison: xor a ld [de], a call PlayDamageAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, BadlyPoisonedText @@ -4747,9 +4747,9 @@ BattleCommand_Poison: res PSN, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F call .check_toxic ret nz @@ -4937,7 +4937,7 @@ BattleCommand_BurnTarget: call CallFromBank0F ld de, ANIM_BRN call PlayOpponentBattleAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, WasBurnedText call PrintText @@ -4958,9 +4958,9 @@ BattleCommand_BurnTarget: res BRN, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F WasBurnedText: @@ -5032,7 +5032,7 @@ BattleCommand_FreezeTarget: ld de, ANIM_FRZ call PlayOpponentBattleAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, WasFrozenText call PrintText @@ -5053,9 +5053,9 @@ BattleCommand_FreezeTarget: res FRZ, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F WasFrozenText: @@ -5100,7 +5100,7 @@ BattleCommand_ParalyzeTarget: call CallFromBank0F ld de, ANIM_PAR call PlayOpponentBattleAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F call PrintParalyze @@ -5120,9 +5120,9 @@ BattleCommand_ParalyzeTarget: res PAR, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F BattleCommand_StatUp: @@ -5347,7 +5347,7 @@ BattleCommand_StatDown: ld hl, wPlayerStatLevels ld de, wEnemyMoveStructEffect ld a, [wLinkMode] - cp 3 ; LINK_COLOSSEUM + cp LINK_COLOSSEUM jr z, .got_stat_levels ; 25% chance for enemy monsters' stat-lowering moves to fail call BattleRandom @@ -6557,7 +6557,7 @@ BattleCommand_Paralyze: ld c, 30 call DelayFrames call LoadMoveAnim - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F call PrintParalyze @@ -6577,9 +6577,9 @@ BattleCommand_Paralyze: res PAR, a ld [de], a ld a, [hl] - call PrintRecoveredUsingItem + call PrintUsersItemActivated call ConsumeHeldItem - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F .paralyzed @@ -6650,7 +6650,7 @@ BattleCommand_Substitute: .played_anim ld hl, MadeSubstituteText call PrintText - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds jp CallFromBank0F .already_has_sub @@ -6719,12 +6719,12 @@ BattleCommand_Mimic: jr nz, .fail ld hl, wBattleMonMoves - ld de, wCurEnemyMove + ld de, wLastEnemyCounterMove ldh a, [hBattleTurn] and a jr z, .player_turn ld hl, wEnemyMonMoves - ld de, wCurPlayerMove + ld de, wLastPlayerCounterMove .player_turn ; BUG: No checks for Struggle, so it can be mimicked. @@ -6814,13 +6814,13 @@ BattleCommand_Disable: ld de, wEnemyDisableCount ld hl, wEnemyMonMoves - ld bc, wCurEnemyMove + ld bc, wLastEnemyCounterMove ldh a, [hBattleTurn] and a jr z, .got_moves ld de, wPlayerDisableCount ld hl, wBattleMonMoves - ld bc, wCurPlayerMove + ld bc, wLastPlayerCounterMove .got_moves ld a, [de] @@ -6965,7 +6965,7 @@ BattleCommand_ResetStats: call .CopyStats ld hl, wEnemyMonStatus - ld de, wCurEnemySelectedMove + ld de, wCurEnemyMove ldh a, [hBattleTurn] and a jr z, .cure_status @@ -7110,7 +7110,7 @@ BattleCommand_Heal: callfar RestoreHP pop af ldh [hBattleTurn], a - ld hl, DrawHUDsAndHPBars + ld hl, UpdateBattleHuds call CallFromBank0F ld hl, RegainedHealthText jp PrintText @@ -7456,13 +7456,13 @@ BattleCommand_Selfdestruct: BattleCommand_MirrorMove: ldh a, [hBattleTurn] and a - ld a, [wCurEnemyMove] - ld hl, wCurPlayerSelectedMove + ld a, [wLastEnemyCounterMove] + ld hl, wCurPlayerMove ld de, wPlayerMoveStruct jr z, .got_moves - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] ld de, wEnemyMoveStruct - ld hl, wCurEnemySelectedMove + ld hl, wCurEnemyMove .got_moves cp MOVE_MIRROR_MOVE @@ -7508,12 +7508,12 @@ MirrorMoveFailedText: BattleCommand_Metronome: call LoadMoveAnim ld de, wPlayerMoveStructEffect - ld hl, wCurPlayerSelectedMove + ld hl, wCurPlayerMove ldh a, [hBattleTurn] and a jr z, .GetMove ld de, wEnemyMoveStructEffect - ld hl, wCurEnemySelectedMove + ld hl, wCurEnemyMove .GetMove call BattleRandom @@ -8450,7 +8450,7 @@ BattleCommand_BatonPass: cp [hl] jr nz, .picked_mon - ld hl, BattleText_MonIsAlreadyOut + ld hl, BattleText_MonIsAlreadyOut_0d call PrintText .pressed_b @@ -8458,7 +8458,7 @@ BattleCommand_BatonPass: jr .player_loop .picked_mon - callfar HasMonFainted + callfar CheckIfCurPartyMonIsFitToFight jr z, .pressed_b call ClearPalettes @@ -8543,7 +8543,7 @@ BattleCommand_BatonPass: call BattleCommand_MoveDelay jp PrintButItFailed -BattleText_MonIsAlreadyOut: +BattleText_MonIsAlreadyOut_0d: text_from_ram wBattleMonNickname text "はもうでています" prompt @@ -8943,20 +8943,20 @@ ConsumeHeldItem: INCLUDE "data/battle/held_consumables.inc" -PrintRecoveredUsingItem: +PrintUsersItemActivated: push hl push de push bc ld [wNamedObjectIndexBuffer], a call GetItemName - ld hl, RecoveredUsingText + ld hl, BattleText_UsersStringBuffer1Activated call PrintText pop bc pop de pop hl ret -RecoveredUsingText: +BattleText_UsersStringBuffer1Activated: text "そうびしていた" line "@" text_from_ram wStringBuffer1 diff --git a/engine/dumps/bank0e.asm b/engine/dumps/bank0e.asm index a47ee2c..2293928 100644 --- a/engine/dumps/bank0e.asm +++ b/engine/dumps/bank0e.asm @@ -906,7 +906,7 @@ AIChooseMove:: and a jr z, .ChooseMove - ld [wCurEnemySelectedMove], a + ld [wCurEnemyMove], a ld a, c ld [wCurEnemyMoveNum], a ret @@ -1278,7 +1278,7 @@ AI_Smart_DreamEater: AI_Smart_MirrorMove: ; If the player did not use any move last turn... - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] and a jr nz, .usedmove @@ -1466,7 +1466,7 @@ AI_Smart_Substitute: ; that would not be effective against itself. ; Consequently, the Smart AI might still use Mimic even if no move has actually been used yet. AI_Smart_Mimic: - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] and a ret z @@ -1485,7 +1485,7 @@ AI_Smart_Mimic: dec [hl] .skip_encourage - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] and a ret z ; Pointless repeat of an earlier check... @@ -1551,7 +1551,7 @@ AI_Smart_Counter: cp 3 jr nc, .encourage - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] and a jr z, .done @@ -1584,7 +1584,7 @@ AI_Smart_Encore: jr nz, .discourage push hl - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] ld hl, EncoreMoves ld de, 1 call FindItemInTable @@ -1664,7 +1664,7 @@ AI_Smart_DefrostOpponent: ; less than four moves encourages the AI to use Spite against them. AI_Smart_Spite: push hl - ld a, [wCurPlayerMove] + ld a, [wLastPlayerCounterMove] ld b, a ld c, NUM_MOVES ld hl, wBattleMonMoves @@ -2590,7 +2590,7 @@ ReadTrainerParty:: .skip_name ld a, [hli] - cp "@" + cp '@' jr nz, .skip_name ld a, [hli] diff --git a/engine/dumps/bank0f.asm b/engine/dumps/bank0f.asm deleted file mode 100644 index 88f3ab2..0000000 --- a/engine/dumps/bank0f.asm +++ /dev/null @@ -1,6795 +0,0 @@ -INCLUDE "constants.asm" - -SECTION "engine/dumps/bank0f.asm@StartBattle", ROMX -StartBattle: - xor a - ld [wBattleParticipantsNotFainted], a - ld [wBattleParticipantsIncludingFainted], a - ld [wFieldMoveSucceeded], a - inc a - ld [wBattleHasJustStarted], a - ld hl, wOTPartyMon1HP - ld bc, $2f - ld d, 3 -.find_first_enemy_alive_loop - inc d - ld a, [hli] - or [hl] - jr nz, .found_first_enemy_alive - add hl, bc - jr .find_first_enemy_alive_loop -.found_first_enemy_alive - ld a, d - ld [wOtherPlayerLinkAction], a - ld a, [wLinkMode] - and a - jr z, .asm_3c02e - ldh a, [hSerialConnectionStatus] - cp 2 - jr z, .asm_3c03f -.asm_3c02e - ld a, [wBattleMode] - dec a - jr z, .asm_3c03a - call EnemySwitch - call sub_3d071 -.asm_3c03a - ld c, 40 - call DelayFrames -.asm_3c03f - call BackUpTilesToBuffer -.check_any_alive - call AnyPartyAlive - ld a, d - and a - jp z, asm_3cc56 - call ReloadTilesFromBuffer - ld a, [wBattleType] - and a - jp nz, .asm_3c0d2 - xor a - ld [wCurPartyMon], a -.find_first_alive_loop - call HasMonFainted - jr nz, .found_first_alive - ld hl, wCurPartyMon - inc [hl] - jr .find_first_alive_loop -.found_first_alive - ld a, [wCurPartyMon] - ld [wCurBattleMon], a - inc a - ld hl, wPartyCount - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - ld [wCurPartySpecies], a - ld [wTempBattleMonSpecies], a - ld hl, $c305 - ld a, 9 - call SlideBattlePicOut - call BackUpTilesToBuffer - ld a, [wCurPartyMon] - ld c, a - ld b, 1 - push bc - ld hl, wBattleParticipantsNotFainted - predef SmallFarFlagAction - ld hl, wBattleParticipantsIncludingFainted - pop bc - predef SmallFarFlagAction - call LoadBattleMonFromParty - call ApplyStatMods - call PrintSendOutMonMessage - call sub_3d387 - call SendOutPlayerMon - call PrintEmptyString - call BackUpTilesToBuffer - xor a - ldh [hBattleTurn], a - call SpikesDamage - ld a, [wLinkMode] - and a - jr z, .to_battle - ldh a, [hSerialConnectionStatus] - cp 2 - jr nz, .to_battle - call EnemySwitch - call sub_3d071 - ld a, 1 - ldh [hBattleTurn], a - call SpikesDamage -.to_battle - jp asm_3c183 - -.asm_3c0d2 - call DisplayBattleMenu - ret c - ld a, [wFieldMoveSucceeded] - and a - jr z, .asm_3c0d2 - call ReloadTilesFromBuffer - ld hl, SafariZonePAText - jp PrintText - - call sub_3e81b - ld a, [wEnemyMonSpeed + 1] - add a - ld b, a - jp c, asm_3c132 - ld a, [wcace] - and a - jr z, .asm_3c0fa - srl b - srl b -.asm_3c0fa - ld a, [wcacd] - and a - jr z, .asm_3c106 - sla b - jr nc, .asm_3c106 - ld b, $ff -.asm_3c106 - call BattleRandom - cp b - jp nc, .check_any_alive - jr asm_3c132 - -SafariZonePAText: - text "アナウンス『ピンポーン!" - - para "サファリ ボールを" - line "ぜんぶ なげました!" - prompt - - -asm_3c132: - call ReloadTilesFromBuffer - ld a, 2 - ld [wBattleResult], a - ld a, [wLinkMode] - and a - ld hl, WildPokemonFledText - jr z, asm_3c14a - xor a - ld [wBattleResult], a - ld hl, EnemyPokemonFledText - -asm_3c14a: - call PrintText - ld de, SFX_RUN - call PlaySFX - xor a - ldh [hBattleTurn], a - jpfar Functioncc000 - -WildPokemonFledText: - text "やせいの@" - text_from_ram wEnemyMonNickname - text "は にげだした!" - prompt - -EnemyPokemonFledText: - text "てきの@" - text_from_ram wEnemyMonNickname - text "は にげだした!" - prompt - -asm_3c183: - call UpdateBattleMonInParty - ldh a, [hSerialConnectionStatus] - cp 1 - jr z, asm_3c1a9 - call sub_3c492 - jp z, asm_3caf3 - call sub_3c48d - jp z, asm_3c883 - call sub_3c61e - call sub_3c492 - jp z, asm_3caf3 - call sub_3c48d - jp z, asm_3c883 - jr asm_3c1c4 - -asm_3c1a9: - call sub_3c48d - jp z, asm_3c883 - call sub_3c492 - jp z, asm_3caf3 - call sub_3c61e - call sub_3c48d - jp z, asm_3c883 - call sub_3c492 - jp z, asm_3caf3 - -asm_3c1c4: - call sub_3c6b8 - call sub_3c704 - call sub_3d50b - call sub_3d40b - call UpdateBattleMonInParty - call BackUpTilesToBuffer - call sub_3c399 - jp c, asm_3c132 - xor a - ld [wBattleHasJustStarted], a - ld a, [wPlayerSubStatus4] - and $60 - jp nz, asm_3c281 - ld hl, wEnemySubStatus3 - res 3, [hl] - ld hl, wPlayerSubStatus3 - res 3, [hl] - ld a, [hl] - and $12 - jp nz, asm_3c281 - ld hl, wPlayerSubStatus1 - bit 6, [hl] - jp nz, asm_3c281 - -asm_3c200: - call DisplayBattleMenu - ret c - ld a, [wBattleEnded] - and a - ret nz - ld hl, wPlayerSubStatus5 - bit 4, [hl] - jr z, asm_3c246 - ld a, [wPlayerEncoreCount] - dec a - ld [wPlayerEncoreCount], a - jr nz, asm_3c229 - -asm_3c219: - ld hl, wPlayerSubStatus5 - res 4, [hl] - xor a - ldh [hBattleTurn], a - ld hl, BattleText_TargetsEncoreEnded - call PrintText - jr asm_3c246 - -asm_3c229: - ld a, [wCurPlayerMove] - and a - jr z, asm_3c219 - ld a, [wCurMoveNum] - ld c, a - ld b, 0 - ld hl, wBattleMonPP - add hl, bc - ld a, [hl] - and PP_MASK - jr z, asm_3c219 - ld a, [wCurPlayerMove] - ld [wCurPlayerSelectedMove], a - jr asm_3c269 - -asm_3c246: - ld a, [wPlayerSubStatus3] - and $21 - jr nz, asm_3c281 - ld a, [wFieldMoveSucceeded] - and a - jr nz, asm_3c281 - xor a - ld [wMoveSelectionMenuType], a - inc a - ld [wFXAnimID], a - call MoveSelectionScreen - push af - call ReloadTilesFromBuffer - call DrawHUDsAndHPBars - pop af - jp nz, asm_3c200 - -asm_3c269: - xor a - ldh [hBattleTurn], a - callfar UpdateMoveData - ld a, [wPlayerMoveStructEffect] - cp $77 - jr z, asm_3c285 - xor a - ld [wPlayerFuryCutterCount], a - jr asm_3c285 - -asm_3c281: - xor a - ld [wPlayerFuryCutterCount], a - -asm_3c285: - call sub_3de6e - ld a, [wLinkMode] - and a - jr z, asm_3c2cd - ld a, [wOtherPlayerLinkAction] - cp $f - jp z, asm_3c132 - cp $e - jr z, asm_3c2cd - cp $d - jr z, asm_3c2cd - sub 4 - jr c, asm_3c2cd - ld a, [wPlayerSubStatus3] - bit 5, a - jr z, asm_3c2bb - ld a, [wCurMoveNum] - ld hl, wBattleMonMoves - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - cp $76 - jr nz, asm_3c2bb - ld [wCurPlayerSelectedMove], a - -asm_3c2bb: - callfar AI_Switch - ld a, 1 - ldh [hBattleTurn], a - call SpikesDamage - jp asm_3c3c7 - -asm_3c2cd: - ld a, [wCurPlayerSelectedMove] - call sub_3c3b8 - cp $67 - jr nz, asm_3c2e4 - ld a, [wCurEnemySelectedMove] - call sub_3c3b8 - cp $67 - jr z, asm_3c311 - jp asm_3c41d - -asm_3c2e4: - ld a, [wCurEnemySelectedMove] - call sub_3c3b8 - cp $67 - jp z, asm_3c3c7 - ld a, [wCurPlayerSelectedMove] - call sub_3c3b8 - cp $59 - jr nz, asm_3c306 - ld a, [wCurEnemySelectedMove] - call sub_3c3b8 - cp $59 - jr z, asm_3c311 - jp asm_3c3c7 - -asm_3c306: - ld a, [wCurEnemySelectedMove] - call sub_3c3b8 - cp $59 - jp z, asm_3c41d - -asm_3c311: - xor a - ldh [hBattleTurn], a - callfar GetUserItem - push bc - callfar GetOpponentItem - pop de - ld a, d - cp $4a - jr nz, asm_3c339 - ld a, b - cp $4a - jr z, asm_3c347 - call BattleRandom - cp e - jr nc, asm_3c36d - jp asm_3c41d - -asm_3c339: - ld a, b - cp $4a - jr nz, asm_3c36d - call BattleRandom - cp c - jr nc, asm_3c36d - jp asm_3c3c7 - -asm_3c347: - ldh a, [hSerialConnectionStatus] - cp 2 - jr z, asm_3c35d - call BattleRandom - cp c - jp c, asm_3c3c7 - call BattleRandom - cp e - jp c, asm_3c41d - jr asm_3c36d - -asm_3c35d: - call BattleRandom - cp e - jp c, asm_3c41d - call BattleRandom - cp c - jp c, asm_3c3c7 - jr asm_3c36d - -asm_3c36d: - ld de, wBattleMonSpeed - ld hl, wEnemyMonSpeed - ld c, 2 - call memcmp - jr z, asm_3c37f - jp nc, asm_3c41d - jr asm_3c3c7 - -asm_3c37f: - ldh a, [hSerialConnectionStatus] - cp 2 - jr z, asm_3c38f - call BattleRandom - cp $80 - jp c, asm_3c41d - jr asm_3c3c7 - -asm_3c38f: - call BattleRandom - cp $80 - jr c, asm_3c3c7 - jp asm_3c41d - -sub_3c399: - ld a, [wBattleMode] - dec a - jr nz, asm_3c3b6 - ld a, [wDebugFlags] - bit DEBUG_BATTLE_F, a - jr nz, asm_3c3b6 - ld a, [wEnemySubStatus5] - bit 7, a - jr nz, asm_3c3b6 - call BattleRandom - cp $a - jr nc, asm_3c3b6 - scf - ret - -asm_3c3b6: - and a - ret - -sub_3c3b8: - dec a - ld hl, Moves + 1 - ld bc, 7 - call AddNTimes - ld a, BANK(Moves) - jp GetFarByte - -asm_3c3c7: - ld a, 1 - ldh [hBattleTurn], a - callfar AI_SwitchOrTryItem - jr c, asm_3c3eb - callfar DoEnemyTurn - call sub_3c473 - ld a, [wBattleEnded] - and a - ret nz - call sub_3c492 - jp z, asm_3caf3 - -asm_3c3eb: - call sub_3c498 - jp z, asm_3c883 - call DrawHUDsAndHPBars - callfar DoPlayerTurn - call sub_3c473 - ld a, [wBattleEnded] - and a - ret nz - call sub_3c48d - jp z, asm_3c883 - call sub_3c498 - jp z, asm_3caf3 - call DrawHUDsAndHPBars - call sub_3c86d - xor a - ld [wFieldMoveSucceeded], a - jp asm_3c183 - -asm_3c41d: - callfar DoPlayerTurn - call sub_3c473 - ld a, [wBattleEnded] - and a - ret nz - call sub_3c48d - jp z, asm_3c883 - call sub_3c498 - jp z, asm_3caf3 - call DrawHUDsAndHPBars - ld a, 1 - ldh [hBattleTurn], a - callfar AI_SwitchOrTryItem - jr c, asm_3c460 - callfar DoEnemyTurn - call sub_3c473 - ld a, [wBattleEnded] - and a - ret nz - call sub_3c492 - jp z, asm_3caf3 - -asm_3c460: - call sub_3c498 - jp z, asm_3c883 - call DrawHUDsAndHPBars - call sub_3c86d - xor a - ld [wFieldMoveSucceeded], a - jp asm_3c183 - -sub_3c473: - ld hl, wEnemySubStatus5 - ld de, wEnemySubStatus1 - ldh a, [hBattleTurn] - and a - jr z, asm_3c484 - ld hl, wPlayerSubStatus5 - ld de, wPlayerSubStatus1 - -asm_3c484: - res 6, [hl] - ld a, [de] - res 2, a - res 5, a - ld [de], a - ret - -sub_3c48d: - ld hl, wEnemyMonHP - jr asm_3c495 - -sub_3c492: - ld hl, wBattleMonHP - -asm_3c495: - ld a, [hli] - or [hl] - ret - -sub_3c498: - ld hl, wBattleMonStatus - ldh a, [hBattleTurn] - and a - jr z, asm_3c4a3 - ld hl, wEnemyMonStatus - -asm_3c4a3: - ld a, [hl] - and $18 - jr z, asm_3c4eb - ld hl, HurtByPoisonText - ld de, ANIM_PSN - and $10 - jr z, asm_3c4b8 - ld hl, HurtByBurnText - ld de, ANIM_BRN - -asm_3c4b8: - push de - call PrintText - pop de - xor a - ld [wNumHits], a - call PlayMoveAnimation - call GetEighthMaxHP - ld hl, wPlayerSubStatus5 - ld de, wPlayerToxicCount - ldh a, [hBattleTurn] - and a - jr z, asm_3c4d8 - ld hl, wEnemySubStatus5 - ld de, wEnemyToxicCount - -asm_3c4d8: - bit 0, [hl] - jr z, asm_3c4e8 - ld a, [de] - inc a - ld [de], a - ld hl, 0 - -asm_3c4e2: - add hl, bc - dec a - jr nz, asm_3c4e2 - ld b, h - ld c, l - -asm_3c4e8: - call SubtractHPFromUser - -asm_3c4eb: - ld hl, wPlayerSubStatus4 - ldh a, [hBattleTurn] - and a - jr z, asm_3c4f6 - ld hl, wEnemySubStatus4 - -asm_3c4f6: - bit 7, [hl] - jr z, asm_3c51d - ldh a, [hBattleTurn] - push af - xor 1 - ldh [hBattleTurn], a - xor a - ld [wNumHits], a - ld de, ANIM_SAP - call PlayMoveAnimation - pop af - ldh [hBattleTurn], a - call GetEighthMaxHP - call SubtractHPFromUser - call RestoreHP - ld hl, LeechSeedSapsText - call PrintText - -asm_3c51d: - ld hl, wPlayerSubStatus1 - ldh a, [hBattleTurn] - and a - jr z, asm_3c528 - ld hl, wEnemySubStatus1 - -asm_3c528: - bit 0, [hl] - jr z, asm_3c542 - xor a - ld [wNumHits], a - ld de, ANIM_IN_NIGHTMARE - call PlayMoveAnimation - call GetQuarterMaxHP - call SubtractHPFromUser - ld hl, HasANightmareText - call PrintText - -asm_3c542: - ld hl, wPlayerSubStatus1 - ldh a, [hBattleTurn] - and a - jr z, asm_3c54d - ld hl, wEnemySubStatus1 - -asm_3c54d: - bit 1, [hl] - jr z, asm_3c567 - xor a - ld [wNumHits], a - ld de, ANIM_IN_NIGHTMARE - call PlayMoveAnimation - call GetQuarterMaxHP - call SubtractHPFromUser - ld hl, HurtByCurseText - call PrintText - -asm_3c567: - ld hl, wPlayerScreens - ldh a, [hBattleTurn] - and a - jr z, asm_3c572 - ld hl, wEnemyScreens - -asm_3c572: - bit SCREENS_SANDSTORM, [hl] - jr z, asm_3c596 - ldh a, [hBattleTurn] - push af - xor 1 - ldh [hBattleTurn], a - xor a - ld [wNumHits], a - ld de, ANIM_IN_SANDSTORM - call PlayMoveAnimation - pop af - ldh [hBattleTurn], a - call GetEighthMaxHP - call SubtractHPFromUser - ld hl, SandstormHitsText - call PrintText - -asm_3c596: - ld hl, wBattleMonHP - ldh a, [hBattleTurn] - and a - jr z, asm_3c5a1 - ld hl, wEnemyMonHP - -asm_3c5a1: - ld a, [hli] - or [hl] - ret nz - call DrawHUDsAndHPBars - ld c, 20 - call DelayFrames - xor a - ret - -HurtByPoisonText: - text "は" - line "どくの ダメージを うけている!" - prompt - -HurtByBurnText: - text "は" - line "やけどの ダメージを うけている!" - prompt - -LeechSeedSapsText: - text "やどりぎが の" - line "たいりょくを うばう!" - prompt - -HasANightmareText: - text "は" - line "あくむに うなされている!" - prompt - -HurtByCurseText: - text "は" - line "のろわれている!" - prompt - -SandstormHitsText: - text "すなあらしが を" - line "おそう!" - prompt - -sub_3c61e: - ldh a, [hSerialConnectionStatus] - cp 1 - jr z, asm_3c632 - xor a - ldh [hBattleTurn], a - call sub_3c640 - ld a, 1 - ldh [hBattleTurn], a - call sub_3c640 - ret - -asm_3c632: - ld a, 1 - ldh [hBattleTurn], a - call sub_3c640 - xor a - ldh [hBattleTurn], a - call sub_3c640 - ret - -sub_3c640: - ld hl, wPlayerSubStatus1 - ld de, wPlayerPerishCount - ldh a, [hBattleTurn] - and a - jr z, asm_3c651 - ld hl, wEnemySubStatus1 - ld de, wEnemyPerishCount - -asm_3c651: - bit 4, [hl] - ret z - ld a, [de] - dec a - ld [de], a - ld [wNumSetBits], a - push af - push hl - ld hl, PerishCountText - call PrintText - pop hl - pop af - ret nz - res 4, [hl] - ldh a, [hBattleTurn] - and a - jr nz, asm_3c682 - ld hl, wBattleMonHP - xor a - ld [hli], a - ld [hl], a - ld hl, wPartyMon1HP - ld a, [wCurBattleMon] - ld bc, $30 - call AddNTimes - xor a - ld [hli], a - ld [hl], a - ret - -asm_3c682: - ld hl, wEnemyMonHP - xor a - ld [hli], a - ld [hl], a - ld a, [wBattleMode] - dec a - ret z - ld hl, wOTPartyMon1HP - ld a, [wCurOTMon] - ld bc, $30 - call AddNTimes - xor a - ld [hli], a - ld [hl], a - ret - -PerishCountText: - text "の ほろびの" - line "カウントが @" - deciram wNumSetBits, 1, 1 - text "になった!" - prompt - -sub_3c6b8: - ld a, [wcadd] - bit 2, a - jr z, asm_3c6ce - ld hl, wPlayerSafeguardCount - dec [hl] - jr nz, asm_3c6ce - res 2, a - ld [wcadd], a - xor a - call sub_3c6e0 - -asm_3c6ce: - ld a, [wcade] - bit 2, a - ret z - ld hl, wEnemySafeguardCount - dec [hl] - ret nz - res 2, a - ld [wcade], a - ld a, 1 - -sub_3c6e0: - ldh [hBattleTurn], a - ld hl, EndPsychicVeilText - jp PrintText - -EndPsychicVeilText: - text "を つつんでいた" - line "しんぴの ベールが なくなった!" - prompt - -sub_3c704: - ld a, [wBattleWeather] - and a - ret z - dec a - ld c, a - ld hl, wWeatherCount - dec [hl] - ld hl, TextPointers3c726 - jr nz, asm_3c71b - xor a - ld [wBattleWeather], a - ld hl, TextPointers3c72a - -asm_3c71b: - ld b, 0 - add hl, bc - add hl, bc - ld a, [hli] - ld h, [hl] - ld l, a - call PrintText - ret - -TextPointers3c726: - dw RainingText - dw SunlightIsStrongText - -TextPointers3c72a: - dw RainStoppedText - dw SunlightFadedText - -RainingText: - text "あめが ふりつずいている" - prompt - -SunlightIsStrongText: - text "ひざしが つよい" - prompt - -RainStoppedText: - text "あめが やんだ!" - prompt - -SunlightFadedText: - text "ひざしが よわくなった!" - prompt - -; Subtract c HP from mon -SubtractHPFromUser: - ld hl, wBattleMonHP - ldh a, [hBattleTurn] - and a - jr z, .got_mon_hp - ld hl, wEnemyMonHP - -.got_mon_hp - inc hl - 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, .end - - xor a - ld [hli], a - ld [hl], a - ld [wHPBarNewHP], a - ld [wHPBarNewHP + 1], a - -.end - call UpdateHPBarBattleHuds - ret - -; Output: bc -GetEighthMaxHP: - ld hl, wBattleMonMaxHP - ldh a, [hBattleTurn] - and a - jr z, .got_max_hp - ld hl, wEnemyMonMaxHP - -.got_max_hp - ld a, [hli] - ld [wHPBarMaxHP + 1], a - ld b, a - ld a, [hl] - ld [wHPBarMaxHP], a - ld c, a -; Quarter result. - srl b - rr c - srl b - rr c -; Assumes nothing can have 1024 or more HP. -; Halve result. - srl c - -; Make sure the amount is at least 1. - ld a, c - and a - jr nz, .end - inc c -.end - ret - -; Output: bc -GetQuarterMaxHP: - ld hl, wBattleMonMaxHP - ldh a, [hBattleTurn] - and a - jr z, .got_max_hp - ld hl, wEnemyMonMaxHP -.got_max_hp - ld a, [hli] - ld [wHPBarMaxHP + 1], a - ld b, a - ld a, [hl] - ld [wHPBarMaxHP], a - ld c, a - -; Quarter result - srl b - rr c - srl b - rr c - -; Assumes nothing can have 1024 or more hp. -; Make sure the amount is at least 1. - ld a, c - and a - jr nz, .end - inc c -.end - ret - -; Output: bc -GetHalfMaxHP: - ld hl, wBattleMonMaxHP - ldh a, [hBattleTurn] - and a - jr z, .got_max_hp - ld hl, wEnemyMonMaxHP -.got_max_hp - ld a, [hli] - ld [wHPBarMaxHP + 1], a - ld b, a - ld a, [hl] - ld [wHPBarMaxHP], a - ld c, a - -; Half result - srl b - rr c - -; MINOR BUG: If something has a multiple of 512 HP, then the HP amount will be increased by 1. -; This amount is achievable by using monsters with high base HP, e.g. Chansey. - - ld a, c - and a - jr nz, .end - inc c -.end - ret - -GetMaxHP: - ld hl, wBattleMonMaxHP - ldh a, [hBattleTurn] - and a - jr z, .got_max_hp - ld hl, wEnemyMonMaxHP -.got_max_hp - ld a, [hli] - ld [wHPBarMaxHP + 1], a - ld b, a - ld a, [hl] - ld [wHPBarMaxHP], a - ld c, a - ret - -RestoreHP: - ld hl, wEnemyMonMaxHP - ldh a, [hBattleTurn] - and a - jr z, .ok - ld hl, wBattleMonMaxHP - -.ok - ld a, [hli] - ld [wHPBarMaxHP + 1], a - ld a, [hld] - ld [wHPBarMaxHP], a - dec hl - ld a, [hl] - ld [wHPBarOldHP], a - add c - ld [hld], a - ld [wHPBarNewHP], a - ld a, [hl] - ld [wHPBarOldHP + 1], a - adc b - ld [hli], a - ld [wHPBarNewHP + 1], a - - ld a, [wHPBarMaxHP] - ld c, a - ld a, [hld] - sub c - ld a, [wHPBarMaxHP + 1] - ld b, a - ld a, [hl] - sbc b - jr c, .overflow - ld a, b - ld [hli], a - ld [wHPBarNewHP + 1], a - ld a, c - ld [hl], a - ld [wHPBarNewHP], a - -.overflow - ldh a, [hBattleTurn] - push af - xor 1 - ldh [hBattleTurn], a - call UpdateHPBarBattleHuds - pop af - ldh [hBattleTurn], a - ret - -UpdateHPBarBattleHuds: - hlcoord 10, 9 - ldh a, [hBattleTurn] - and a - ld a, 1 - jr z, .ok - hlcoord 2, 2 - xor a -.ok - push bc - ld [wWhichHPBar], a - predef UpdateHPBar - pop bc - ret - -sub_3c86d: - ld a, [wPlayerRolloutCount] - and a - jr nz, asm_3c878 - ld hl, wPlayerSubStatus3 - res 5, [hl] - -asm_3c878: - ld a, [wEnemyRolloutCount] - and a - ret nz - ld hl, wEnemySubStatus3 - res 5, [hl] - ret - -asm_3c883: - xor a - ld [wcad5], a - call sub_3c8ca - call AnyPartyAlive - ld a, d - and a - jp z, asm_3cc56 - ld hl, wBattleMonHP - ld a, [hli] - or [hl] - call nz, UpdatePlayerHUD - ld c, $3c - call DelayFrames - ld a, [wBattleMode] - dec a - ret z - call sub_3c9ad - jp z, asm_3c9fd - ld hl, wBattleMonHP - ld a, [hli] - or [hl] - jr nz, asm_3c8b8 - call sub_3cb9d - ret c - call sub_3cbdb - -asm_3c8b8: - ld a, 1 - ld [wFieldMoveSucceeded], a - call sub_3c9c2 - jp z, asm_3c132 - xor a - ld [wFieldMoveSucceeded], a - jp asm_3c183 - -sub_3c8ca: - call UpdateBattleMonInParty - ld a, [wBattleMode] - dec a - jr z, asm_3c8e2 - ld a, [wCurOTMon] - ld hl, wOTPartyMon1HP - ld bc, $30 - call AddNTimes - xor a - ld [hli], a - ld [hl], a - -asm_3c8e2: - ld hl, wPlayerSubStatus3 - res 2, [hl] - xor a - ld hl, wPlayerDamageTaken - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld hl, wEnemySubStatus1 - ld [hli], a - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wEnemyDisableCount], a - ld [wEnemyDisabledMove], a - ld [wEnemyMinimized], a - ld hl, wCurPlayerMove - ld [hli], a - ld [hl], a - ld hl, $c310 - ld de, $c324 - call sub_3ccef - ld hl, $c2a1 - ld bc, $040a - call ClearBox - ld a, [wBattleMode] - dec a - jr z, asm_3c935 - push de - ld de, SFX_KINESIS - call PlaySFX - call WaitSFX - pop de - push de - ld de, SFX_FAINT - call PlaySFX - call WaitSFX - pop de - jr asm_3c93d - -asm_3c935: - call sub_3c9a8 - ld a, 0 - call sub_3cae1 - -asm_3c93d: - ld hl, wBattleMonHP - ld a, [hli] - or [hl] - jr nz, asm_3c94d - ld a, [wcad5] - and a - jr nz, asm_3c94d - call sub_3cb34 - -asm_3c94d: - call AnyPartyAlive - ld a, d - and a - ret z - ld hl, EnemyMonFainted - call PrintText - call PrintEmptyString - call BackUpTilesToBuffer - xor a - ld [wBattleResult], a - ld b, $4b - call Function32c8 - push af - jr z, asm_3c976 - ld hl, wEnemyMonBaseStats - ld b, 7 - -asm_3c970: - srl [hl] - inc hl - dec b - jr nz, asm_3c970 - -asm_3c976: - xor a - ld [wHPBarMaxHP], a - call sub_3e421 - pop af - ret z - ld a, 1 - ld [wHPBarMaxHP], a - ld a, [wPartyCount] - ld b, 0 - -asm_3c989: - scf - rl b - dec a - jr nz, asm_3c989 - ld a, b - ld [wBattleParticipantsNotFainted], a - jp sub_3e421 - -EnemyMonFainted: - text "てきの @" - text_from_ram wEnemyMonNickname - text "は たおれた!" - prompt - -sub_3c9a8: - inc a - ld [wBattleLowHealthAlarm], a - ret - -sub_3c9ad: - ld a, [wOTPartyCount] - ld b, a - xor a - ld hl, wOTPartyMon1HP - ld de, $30 - -asm_3c9b8: - or [hl] - inc hl - or [hl] - dec hl - add hl, de - dec b - jr nz, asm_3c9b8 - and a - ret - -sub_3c9c2: - ld hl, wEnemyHPPal - ld e, $30 - call UpdateHPPal - callfar EnemySwitch_TrainerHud - ld a, [wLinkMode] - and a - jr z, asm_3c9e4 - call LinkBattleSendRecieveAction - ld a, [wOtherPlayerLinkAction] - cp $f - ret z - call ReloadTilesFromBuffer - -asm_3c9e4: - call EnemySwitch - call sub_3d071 - ld a, 1 - ldh [hBattleTurn], a - call SpikesDamage - xor a - ld [wEnemyMoveStruct], a - ld [wFieldMoveSucceeded], a - ld [wEnemyTurnsTaken], a - inc a - ret - -asm_3c9fd: - call sub_3c9a8 - ld b, 0 - ld a, [wce04] - and a - jr nz, asm_3ca0a - ld b, $b - -asm_3ca0a: - ld a, [wTrainerClass] - cp $2b - jr nz, asm_3ca18 - ld b, 0 - ld hl, wDebugFlags - set DEBUG_FIELD_F, [hl] - -asm_3ca18: - ld a, [wLinkMode] - and a - ld a, b - call z, sub_3cae1 - callfar Battle_GetTrainerName - ld hl, BattleText_EnemyWasDefeated - call PrintText - ld a, [wLinkMode] - cp 3 - ret z - call sub_3e201 - ld c, 40 - call DelayFrames - ld a, [wOtherTrainerClass] - cp 9 - jr nz, asm_3ca51 - ld hl, RivalLossText - call PrintText - callfar HealParty - -asm_3ca51: - ld a, [wBattleMonItem] - ld b, a - callfar GetItemHeldEffect - ld a, b - cp HELD_AMULET_COIN - jr nz, asm_3ca74 - ld hl, wBattleReward + 2 - sla [hl] - dec hl - rl [hl] - dec hl - rl [hl] - jr nc, asm_3ca74 - ld a, $ff - ld [hli], a - ld [hli], a - ld [hl], a - -asm_3ca74: - ld de, wMoney + 2 - ld hl, wBattleReward + 2 - ld c, 3 - and a - -asm_3ca7d: - ld a, [de] - adc [hl] - ld [de], a - dec de - dec hl - dec c - jr nz, asm_3ca7d - ld hl, GotMoneyForWinningText - call PrintText - ret - -GotMoneyForWinningText: - text "は しょうきんとして" - line "@" - deciram wBattleReward, 3, 6 - text "円 てにいれた!" - prompt - -BattleText_EnemyWasDefeated: - text_from_ram wOTClassName - text "の @" - text_from_ram wStringBuffer1 - text_start - line "との しょうぶに かった!" - prompt - -RivalLossText: - text "『あれー?" - line "おまえの #に" - cont "すりゃあ よかったのかなあ?" - prompt - -sub_3cae1: - push de - ld de, MUSIC_NONE - call PlayMusic - call DelayFrame - ld de, MUSIC_VICTORY_TRAINER - call PlayMusic - pop de - ret - -asm_3caf3: - ld a, 1 - ld [wcad5], a - call sub_3cb34 - call AnyPartyAlive - ld a, d - and a - jp z, asm_3cc56 - ld hl, wEnemyMonHP - ld a, [hli] - or [hl] - jr nz, asm_3cb18 - call sub_3c8ca - ld a, [wBattleMode] - dec a - ret z - call sub_3c9ad - jp z, asm_3c9fd - -asm_3cb18: - call sub_3cb9d - ret c - call sub_3cbdb - jp nz, asm_3c183 - ld a, 1 - ld [wFieldMoveSucceeded], a - call sub_3c9c2 - jp z, asm_3c132 - xor a - ld [wFieldMoveSucceeded], a - jp asm_3c183 - -sub_3cb34: - ld a, [wCurBattleMon] - ld c, a - ld hl, wBattleParticipantsNotFainted - ld b, 0 - predef SmallFarFlagAction - ld hl, wEnemySubStatus3 - res SUBSTATUS_IN_LOOP, [hl] - ld a, [wLowHealthAlarmBuffer] - bit 7, a - jr z, asm_3cb56 - ld a, $ff - ld [wLowHealthAlarmBuffer], a - call WaitSFX - -asm_3cb56: - ld hl, wEnemyDamageTaken - ld [hli], a - ld [hl], a - ld [wBattleMonStatus], a - ld [wBattleMonStatus + 1], a - call UpdateBattleMonInParty - ld hl, $c335 - ld bc, $050b - call ClearBox - ld hl, $c369 - ld de, $c37d - call sub_3ccef - ld a, 1 - ld [wBattleResult], a - ld a, [wcad5] - and a - ret z - ld a, $f0 - ld [wCryTracks], a - ld a, [wBattleMonSpecies] - call PlayStereoCry - ld hl, FaintedText - jp PrintText - -FaintedText: - text_from_ram wBattleMonNickname - text "は たおれた!" - prompt - -sub_3cb9d: - call PrintEmptyString - call BackUpTilesToBuffer - ld a, [wBattleMode] - and a - dec a - ret nz - ld hl, UseNextMonText - call PrintText - -asm_3cbaf: - ld bc, $0107 - call PlaceYesNoBox - ld a, [wMenuCursorY] - jr c, asm_3cbbc - and a - ret - -asm_3cbbc: - ld a, [wMenuCursorY] - cp 1 - jr z, asm_3cbaf - ld hl, wPartyMon1Speed - ld de, wEnemyMonSpeed - jp TryRunningFromBattle - -UseNextMonText: - text "つぎの #をつかいますか?" - done - -sub_3cbdb: - call LoadStandardMenuHeader - ld a, PARTYMENUACTION_SWITCH - ld [wPartyMenuActionText], a - predef OpenPartyMenu_ClearGraphics - -asm_3cbe8: - jr nc, asm_3cbf1 - -asm_3cbea: - predef OpenPartyMenu - jr asm_3cbe8 - -asm_3cbf1: - call HasMonFainted - jr z, asm_3cbea - ld a, [wLinkMode] - cp 3 - jr nz, asm_3cc04 - inc a - ld [wFieldMoveSucceeded], a - call LinkBattleSendRecieveAction - -asm_3cc04: - xor a - ld [wFieldMoveSucceeded], a - call ClearSprites - ld a, [wCurPartyMon] - ld [wCurBattleMon], a - ld c, a - ld hl, wBattleParticipantsNotFainted - ld b, 1 - push bc - predef SmallFarFlagAction - pop bc - ld hl, wBattleParticipantsIncludingFainted - predef SmallFarFlagAction - call LoadBattleMonFromParty - call ApplyStatMods - call ClearPalettes - call _LoadHPBar - call CloseWindow - call GetMemSGBLayout - call SetPalettes - call PrintSendOutMonMessage - call sub_3d387 - call SendOutPlayerMon - call PrintEmptyString - call BackUpTilesToBuffer - xor a - ldh [hBattleTurn], a - call SpikesDamage - ld hl, wEnemyMonHP - ld a, [hli] - or [hl] - ret - -asm_3cc56: - ld a, [wLinkMode] - and a - jr nz, asm_3cc83 - ld a, [wOtherTrainerClass] - cp 9 - jr nz, asm_3cc83 - ld hl, wTileMap - ld bc, $0815 - call ClearBox - call sub_3e201 - ld c, 40 - call DelayFrames - ld hl, RivalWinText - call PrintText - callfar HealParty - ret - -asm_3cc83: - ld b, 0 - call GetSGBLayout - ld hl, OutOfUsableMonsText - ld a, [wLinkMode] - cp 3 - jr nz, asm_3cc95 - ld hl, Data3ccdd - -asm_3cc95: - call PrintText - call ClearTileMap - scf - ret - -RivalWinText: - text "『やった!" - line "いい# えらんだかも!" - prompt - -OutOfUsableMonsText: - text "の てもとには" - line "たたかえる #が いない!" - - para "は" - line "めのまえが まっくらに なった!" - prompt - -Data3ccdd: - text_from_ram wOTClassName - text "との" - line "しょうぶに まけた!" - prompt - -sub_3ccef: - ld a, [wJoypadFlags] - push af - set 6, a - ld [wJoypadFlags], a - ld b, 7 - -asm_3ccfa: - push bc - push de - push hl - ld b, 6 - -asm_3ccff: - push bc - push hl - push de - ld bc, 7 - call CopyBytes - pop de - pop hl - ld bc, hFFEC - add hl, bc - push hl - ld h, d - ld l, e - add hl, bc - ld d, h - ld e, l - pop hl - pop bc - dec b - jr nz, asm_3ccff - ld bc, $14 - add hl, bc - ld de, SevenBlankSpacesString - call PlaceString - ld c, 2 - call DelayFrames - pop hl - pop de - pop bc - dec b - jr nz, asm_3ccfa - pop af - ld [wJoypadFlags], a - ret - -SevenBlankSpacesString: - db "       @" - -SlideBattlePicOut: - ldh [hSpriteWidth], a - ld c, a - -.loop - push bc - push hl - ld b, 7 - -.loop2 - push hl - call .DoFrame - pop hl - ld de, SCREEN_WIDTH - add hl, de - dec b - jr nz, .loop2 - ld c, 2 - call DelayFrames - pop hl - pop bc - dec c - jr nz, .loop - ret - -.DoFrame: - ldh a, [hTextBoxCursorBlinkInterval] - ld c, a - cp 8 - jr nz, .back - -.forward - ld a, [hli] - ld [hld], a - dec hl - dec c - jr nz, .forward - ret - -.back - ld a, [hld] - ld [hli], a - inc hl - dec c - jr nz, .back - ret - -EnemySwitch: - ld hl, wBattleParticipantsNotFainted - xor a - ld [hl], a - - ld a, [wCurBattleMon] - ld c, a - ld b, SET_FLAG - push bc - predef SmallFarFlagAction - ld hl, wBattleParticipantsIncludingFainted - xor a - ld [hl], a - pop bc - predef SmallFarFlagAction - - xor a - ld hl, wCurPlayerMove - ld [hli], a - ld [hl], a - dec a - ld [wEnemyItemState], a - ld hl, wPlayerSubStatus3 - res SUBSTATUS_USING_TRAPPING_MOVE, [hl] - - hlcoord 18, 0 - ld a, 8 - call SlideBattlePicOut - call PrintEmptyString - call LoadStandardMenuHeader - - ld a, [wLinkMode] - and a - jr z, FindMonInOTPartyToSwitchIntoBattle - - ld a, [wOtherPlayerLinkAction] - sub BATTLEACTION_SWITCH1 - ld b, a - jp LoadEnemyMonToSwitchTo - -FindMonInOTPartyToSwitchIntoBattle: - ld a, [wBattleHasJustStarted] - and a - jp nz, GetRandomOTPartyMon - - ld b, -1 - ld a, 1 - ld [wEnemyEffectivenessVsPlayerMons], a - ld [wPlayerEffectivenessVsEnemyMons], a -.loop - ld hl, wEnemyEffectivenessVsPlayerMons - sla [hl] - inc hl - sla [hl] - inc b - ld a, [wOTPartyCount] - cp b - jp z, ScoreMonTypeMatchups - - ld a, [wCurOTMon] - cp b - jr z, .discourage - - ld hl, wOTPartyMon1HP - push bc - ld a, b - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld a, [hli] - ld c, a - ld a, [hl] - or c - pop bc - jr z, .discourage - call LookUpTheEffectivenessOfEveryMove - call IsThePlayerMonTypesEffectiveAgainstOTMon - jr .loop - -.discourage - ld hl, wPlayerEffectivenessVsEnemyMons - set 0, [hl] - jr .loop - -LookUpTheEffectivenessOfEveryMove: - push bc - ld hl, wOTPartyMon1Moves - ld a, b - ld bc, $30 - call AddNTimes - pop bc - ld e, 5 -.loop - dec e - jr z, .done - ld a, [hli] - and a - jr z, .done - push hl - push de - push bc - dec a - ld hl, Moves - ld bc, 7 - call AddNTimes - ld de, wEnemyMoveStruct - ld a, BANK(Moves) - call FarCopyBytes - ld a, 1 - ldh [hBattleTurn], a - callfar BattleCheckTypeMatchup - pop bc - pop de - pop hl - ld a, [wNumSetBits] - cp $b - jr c, .loop - ld hl, wEnemyEffectivenessVsPlayerMons - set 0, [hl] - ret -.done - ret - -IsThePlayerMonTypesEffectiveAgainstOTMon: - push bc - ld hl, wOTPartyCount - ld a, b - inc a - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - dec a - ld hl, BaseData + (wMonHTypes - wMonHeader) - ld bc, (wMonHeaderEnd - wMonHeader) - call AddNTimes - ld de, wEnemyMonType - ld bc, 2 - ld a, BANK(BaseData) - call FarCopyBytes - ld a, [wBattleMonType1] - ld [wPlayerMoveStructType], a - xor a - ldh [hBattleTurn], a - callfar BattleCheckTypeMatchup - ld a, [wNumSetBits] - cp $b - jr nc, .super_effective - ld a, [wBattleMonType2] - ld [wPlayerMoveStructType], a - callfar BattleCheckTypeMatchup - ld a, [wNumSetBits] - cp $b - jr nc, .super_effective - pop bc - ret - -.super_effective - pop bc - ld hl, wEnemyEffectivenessVsPlayerMons - bit 0, [hl] - jr nz, .reset - inc hl - set 0, [hl] - ret - -.reset - res 0, [hl] - ret - -ScoreMonTypeMatchups: -.loop1 - ld hl, wEnemyEffectivenessVsPlayerMons - sla [hl] - inc hl - sla [hl] - jr nc, .loop1 - ld a, [wOTPartyCount] - ld b, a - ld c, [hl] -.loop2 - sla c - jr nc, .okay - dec b - jr z, GetRandomOTPartyMon - jr .loop2 - -.okay - ld a, [wEnemyEffectivenessVsPlayerMons] - and a - jr z, .okay2 - ld b, -1 - ld c, a -.loop3 - inc b - sla c - jr nc, .loop3 - jr LoadEnemyMonToSwitchTo - -.okay2 - ld b, -1 - ld a, [wPlayerEffectivenessVsEnemyMons] - ld c, a -.loop4 - inc b - sla c - jr c, .loop4 - jr LoadEnemyMonToSwitchTo - -GetRandomOTPartyMon: -.loop - call BattleRandom - maskbits PARTY_LENGTH - cp PARTY_LENGTH - jr nc, .loop - - ld b, a - ld a, [wCurOTMon] - cp b - jr z, .loop - - ld hl, wOTPartyMon1HP - push bc - ld a, b - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - pop bc - - ld a, [hli] - ld c, a - ld a, [hl] - or c - jr z, .loop - -LoadEnemyMonToSwitchTo: - ; 'b' contains the PartyNr of the mon the AI will switch to - ld a, b - ld [wCurPartyMon], a - ld hl, wOTPartyMon1Level - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - - ld a, [hl] - ld [wCurPartyLevel], a - ld a, [wCurPartyMon] - inc a - ld hl, wOTPartySpecies - 1 - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - - ld [wTempEnemyMonSpecies], a - ld [wCurPartySpecies], a - call LoadEnemyMon - - ld hl, wEnemyMonHP - ld a, [hli] - ld [wEnemyHPAtTimeOfPlayerSwitch], a - ld a, [hl] - ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a - - ld a, 1 - ld [wMenuCursorY], a - ld a, [wBattleHasJustStarted] - dec a - jr z, EnemySendOutFirstMon - - ld a, [wPartyCount] - dec a - jr z, EnemySendOutFirstMon - - ld a, [wLinkMode] - and a - jr nz, EnemySendOutFirstMon - - ld a, [wOptions] - bit BATTLE_SHIFT_F, a - jr nz, EnemySendOutFirstMon - - callfar Battle_GetTrainerName - ld hl, TrainerAboutToUseText - call PrintText - - lb bc, 1, 7 - call PlaceYesNoBox - ld a, [wMenuCursorY] - dec a - jr nz, EnemySendOutFirstMon - - ld a, PARTYMENUACTION_SWITCH - ld [wPartyMenuActionText], a - predef OpenPartyMenu_ClearGraphics - -.pick - ld a, 1 - ld [wMenuCursorY], a - jr c, .canceled_switch - - ld hl, wCurBattleMon - ld a, [wCurPartyMon] - cp [hl] - jr nz, .notout - - ld hl, IsAlreadyOutText - call PrintText - -.fainted - predef OpenPartyMenu - jr .pick - -.notout - call HasMonFainted - jr z, .fainted - xor a - ld [wMenuCursorY], a - -.canceled_switch - call ClearPalettes - call _LoadHPBar - -EnemySendOutFirstMon: - call CloseWindow - call ClearSprites - hlcoord 1, 0 - lb bc, 4, 10 - call ClearBox - - ld b, SGB_BATTLE_COLORS - call GetSGBLayout - call SetPalettes - callfar Battle_GetTrainerName - - ld hl, TrainerSentOutText - call PrintText - - ld a, [wTempEnemyMonSpecies] - ld [wCurPartySpecies], a - ld [wCurSpecies], a - call GetBaseData - - ld a, OTPARTYMON - ld [wMonType], a - predef CopyMonToTempMon - ld hl, wTempMonDVs - predef GetUnownLetter - ld de, vFrontPic - call LoadMonFrontSprite - xor a - ld [wNumHits], a - inc a - ldh [hBattleTurn], a - -; Play shiny animation for Sunflora and Pikachu - ld b, 1 - ld a, [wCurPartySpecies] - cp DEX_SUNNY - jr z, .apply_animation - cp DEX_PIKACHU - jr z, .apply_animation - -; Play scanline fade animation for Hoothoot - ld b, 2 - cp DEX_HOHO - jr z, .apply_animation - -; Play normal send out animation for everyone else - ld b, 0 - -.apply_animation - ld a, b - ld [wBattleAnimParam], a - ld de, ANIM_SEND_OUT_MON - call PlayMoveAnimation - -; mon on the right side - ld a, $f - ld [wCryTracks], a - ld a, [wTempEnemyMonSpecies] - call PlayStereoCry - call UpdateEnemyHUD - -; If battle has just started, go ahead and switch in your monster - ld a, [wMenuCursorY] - and a - ret nz - xor a - ld [wBattleParticipantsNotFainted], a - ld [wBattleParticipantsIncludingFainted], a - call BackUpTilesToBuffer - jp SwitchPlayerMon - -; BUG: They forgot to terminate the line immediately after StringBuffer1. -; This makes the game halt the script early and throw up an error handler, -; due to reading the start of the following 'text' line as a character. -TrainerAboutToUseText: - text_from_ram wOTClassName - text "の @" - text_from_ram wStringBuffer1 - text "は" - line "" - text_from_ram wEnemyMonNickname - text "を くりだそうと している" - - para "も #を" - line "とりかえますか?" - done - -TrainerSentOutText: - text_from_ram wOTClassName - text "の @" - text_from_ram wStringBuffer1 - text "は" - line "@" - text_from_ram wEnemyMonNickname - text "を くりだした!" - done - -sub_3d071: - xor a - ld hl, wCurEnemyMove - ld [hli], a - ld [hl], a - ld hl, wEnemySubStatus1 - ld [hli], a - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wEnemyDisableCount], a - ld [wEnemyFuryCutterCount], a - ld [wEnemyDisabledMove], a - ld [wEnemyMinimized], a - ret - -AnyPartyAlive: - ld a, [wPartyCount] - ld e, a - xor a - ld hl, wPartyMon1HP - ld bc, $2f -.loop - or [hl] - inc hl - or [hl] - add hl, bc - dec e - jr nz, .loop - ld d, a - ret - -HasMonFainted: - ld a, [wCurPartyMon] - ld hl, wPartyMon1HP - ld bc, (wPartyMon2 - wPartyMon1) - call AddNTimes - ld a, [hli] - or [hl] - ret nz - ld a, [wBattleHasJustStarted] - and a - jr nz, .has_hp - ld hl, BattleText_TheresNoWillToBattle - call PrintText -.has_hp - xor a - ret - -BattleText_TheresNoWillToBattle: - text "たたかう きりょくが ない!" - prompt - -TryRunningFromBattle: - ld a, [wBattleType] - cp 2 - jp z, .can_escape - ld a, [wLinkMode] - and a - jp nz, .can_escape - ld a, [wBattleMode] - dec a - jp nz, .trainer_battle - ld a, [wPlayerSubStatus5] - bit SUBSTATUS_CANT_RUN, a - jp nz, .cannot_escape - - push hl - push de - ld a, [wBattleMonItem] - ld [wNamedObjectIndexBuffer], a - ld b, a - callfar GetItemHeldEffect - - ld a, b - cp HELD_ESCAPE - pop de - pop hl - jr nz, .no_flee_item - - call GetItemName - ld hl, EscapedUsingItemText - call PrintText - jp .can_escape - -.no_flee_item - ld a, [wNumFleeAttempts] - inc a - ld [wNumFleeAttempts], a - ld a, [hli] - ldh [hMultiplicand + 1], a - ld a, [hl] - ldh [hMultiplicand + 2], a - ld a, [de] - inc de - ldh [hEnemyMonSpeed], a - ld a, [de] - ldh [hEnemyMonSpeed + 1], a - call ReloadTilesFromBuffer - ld de, hMultiplicand + 1 - ld hl, hEnemyMonSpeed - ld c, 2 - call memcmp - jr nc, .can_escape - - xor a - ldh [hMultiplicand], a - ld a, $20 - ldh [hMultiplier], a - call Multiply - ldh a, [hProduct + 2] - ldh [hDividend], a - ldh a, [hProduct + 3] - ldh [hDividend + 1], a - ldh a, [hEnemyMonSpeed] - ld b, a - ldh a, [hEnemyMonSpeed + 1] - srl b - rr a - srl b - rr a - and a - jr z, .can_escape - ldh [hDivisor], a - ld b, 2 - call Divide - ldh a, [hMultiplicand + 1] - and a - jr nz, .can_escape - ld a, [wce39] - ld c, a -.asm_3d165 - dec c - jr z, .asm_3d173 - ld b, $1e - ldh a, [hMultiplicand + 2] - add b - ldh [hMultiplicand + 2], a - jr c, .can_escape - jr .asm_3d165 - -.asm_3d173 - call BattleRandom - ld b, a - ldh a, [hMultiplicand + 2] - cp b - jr nc, .can_escape - ld a, 1 - ld [wFieldMoveSucceeded], a -.cannot_escape - ld hl, CantEscapeText - jr .print_text - -.trainer_battle - ld hl, NoRunningText -.print_text - call PrintText - ld a, 1 - ld [wce38], a - call BackUpTilesToBuffer - and a - ret - -.can_escape - ld a, [wLinkMode] - and a - ld a, 2 - jr z, .play_sound - call BackUpTilesToBuffer - xor a - ld [wFieldMoveSucceeded], a - ld a, $f - ld [wCurMoveNum], a - call LinkBattleSendRecieveAction - call ReloadTilesFromBuffer - ld a, [wOtherPlayerLinkAction] - cp $f - ld a, 2 - jr z, .play_sound - dec a -.play_sound - ld [wBattleResult], a - push de - ld de, SFX_RUN - call WaitPlaySFX - pop de - call WaitSFX - ld hl, GotAwayText - call PrintText - call WaitSFX - call BackUpTilesToBuffer - scf - ret - -CantEscapeText: - text "にげられない!" - prompt - -NoRunningText: - text "ダメだ!" - line "しょうぶの さいちゅうに" - cont "あいてに せなかは みせられない!" - prompt - -GotAwayText: - text "うまく にげきれた!" - prompt - -EscapedUsingItemText: - text "は そうびしていた" - line "@" - text_from_ram wStringBuffer1 - text "を つかって にげた" - prompt - -LoadBattleMonFromParty: - ld a, [wCurPartyMon] - ld bc, PARTYMON_STRUCT_LENGTH - ld hl, wPartyMon1 - call AddNTimes - ; Copy species, held item, and move - ld de, wBattleMon - ld bc, (wPartyMon1ID - wPartyMon1Species) ; 6 - call CopyBytes - ; Skip ID, experience, and stat experience - ld bc, (wPartyMon1DVs - wPartyMon1ID) ; 15 - add hl, bc - ; Copy DVs, PP, and happiness - ld de, wBattleMonDVs - ld bc, (wPartyMon1PokerusStatus - wPartyMon1DVs) ; 7 - call CopyBytes - ; Copy level, status, current and max HP, and stats - inc hl - inc hl - inc hl - ld de, wBattleMonLevel - ld bc, (wPartyMon1StatsEnd - wPartyMon1Level) ; 17 - call CopyBytes - ; Copy both types - ld a, [wTempBattleMonSpecies] - ld [wCurSpecies], a - call GetBaseData - - ld a, [wMonHType1] - ld [wBattleMonType1], a - ld a, [wMonHType2] - ld [wBattleMonType2], a - - ld hl, wPartyMonNicknames - ld a, [wCurBattleMon] - call SkipNames - - ld de, wBattleMonNickname - ld bc, MON_NAME_LENGTH - call CopyBytes - - ld hl, wBattleMonStats - ld de, wPlayerStats - ld bc, 2 * NUM_BATTLE_STATS - call CopyBytes - call ApplyStatusEffectOnPlayerStats - call BadgeStatBoosts - - xor a - ldh [hBattleTurn], a - callfar GetMonSGBPaletteFlags - ret - -ApplyStatMods: - ld a, 7 - ld b, 8 - ld hl, wPlayerStatLevels -.loop - ld [hli], a - dec b - jr nz, .loop - ret - -LoadEnemyMonFromParty: - ld a, [wCurPartyMon] - ld bc, PARTYMON_STRUCT_LENGTH - ld hl, wOTPartyMons - call AddNTimes - ; Copy species, held item, and move - ld de, wEnemyMon - ld bc, (wPartyMon1ID - wPartyMon1Species) ; 6 - call CopyBytes - ; Skip ID, experience, and stat experience - ld bc, (wPartyMon1DVs - wPartyMon1ID) ; 15 - add hl, bc - ; Copy DVs, PP, and happiness - ld de, wEnemyMonDVs - ld bc, (wPartyMon1PokerusStatus - wPartyMon1DVs) ; 7 - call CopyBytes - ; Copy level, status, current and max HP, and stats - inc hl - inc hl - inc hl - ld de, wEnemyMonLevel - ld bc, (wPartyMon1StatsEnd - wPartyMon1Level) ; 17 - call CopyBytes - - ld a, [wEnemyMonSpecies] - ld [wCurSpecies], a - call GetBaseData - - ld hl, wOTPartyMonNicknames - ld a, [wCurPartyMon] - call SkipNames - - ld de, wEnemyMonNickname - ld bc, MON_NAME_LENGTH - call CopyBytes - - ld hl, wEnemyMonStats - ld de, wEnemyStats - ld bc, 2 * NUM_BATTLE_STATS - call CopyBytes - - call ApplyStatusEffectOnEnemyStats - ld hl, wMonHType1 - ld de, wEnemyMonType1 - ld a, [hli] - ld [de], a - inc de - ld a, [hl] - ld [de], a - ld hl, wMonHBaseStats - ld de, wEnemyMonBaseStats - ld b, 5 -.base_stats_loop - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, .base_stats_loop - ld a, 7 - ld b, 8 - ld hl, wEnemyStatLevels -.stat_mod_loop - ld [hli], a - dec b - jr nz, .stat_mod_loop - ld a, [wCurPartyMon] - ld [wCurOTMon], a - ret - -SendOutPlayerMon: - ld hl, wBattleMonDVs - predef GetUnownLetter - predef LoadMonBackPic - xor a - ldh [hGraphicStartTile], a - - ld hl, wBattleMenuCursorPosition - ld [hli], a - ld [hl], a - ld [wTypeModifier], a - ld [wPlayerMoveStruct + MOVE_ANIM], a - ld b, SGB_BATTLE_COLORS - call GetSGBLayout - - ld hl, wEnemySubStatus3 - res SUBSTATUS_USING_TRAPPING_MOVE, [hl] - xor a - ldh [hBattleTurn], a - ld [wNumHits], a - -; Play shiny animation for Sunflora and Pikachu - ld b, 1 - ld a, [wCurPartySpecies] - cp DEX_SUNNY - jr z, .apply_animation - cp DEX_PIKACHU - jr z, .apply_animation - -; Play scanline fade animation for Hoothoot - ld b, 2 - cp DEX_HOHO - jr z, .apply_animation - -; Play send out animation for everyone else - ld b, 0 - -.apply_animation - ld a, b - ld [wBattleAnimParam], a - ld de, ANIM_SEND_OUT_MON - call PlayMoveAnimation - -; mon on the left side - ld a, $f0 - ld [wCryTracks], a - ld a, [wCurPartySpecies] - call PlayStereoCry - call UpdatePlayerHUD - ret - -sub_3d387: - xor a - ld hl, wCurPlayerMove - ld [hli], a - ld [hl], a - ld hl, wPlayerSubStatus1 - ld [hli], a - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wPlayerDisableCount], a - ld [wPlayerFuryCutterCount], a - ld [wDisabledMove], a - ld [wPlayerMinimized], a - ret - -SpikesDamage: - ld hl, wPlayerScreens - ld de, wBattleMonType - ldh a, [hBattleTurn] - and a - jr z, .ok - ld hl, wEnemyScreens - ld de, wEnemyMonType - -.ok - bit SCREENS_SPIKES, [hl] - ret z - -; Flying-types aren't affected by Spikes. - ld a, [de] - cp TYPE_FLYING - ret z - inc de - ld a, [de] - cp TYPE_FLYING - ret z - - ld hl, BattleText_UserHurtBySpikes - call PrintText - - call GetEighthMaxHP - call SubtractHPFromUser - - ret - -BattleText_UserHurtBySpikes: - text "は まきびしの" - line "ダメージを うけた!" - prompt - -RecallPlayerMon: - ldh a, [hBattleTurn] - push af - xor a - ldh [hBattleTurn], a - ld [wNumHits], a - ld de, ANIM_RETURN_MON - call PlayMoveAnimation - pop af - ldh [hBattleTurn], a - ret - -; Update level, status, current HP -UpdateBattleMonInParty: - ld a, [wCurBattleMon] - ld hl, wPartyMon1Level - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - - ld d, h - ld e, l - ld hl, wBattleMonLevel - ld bc, (wBattleMonHP - wBattleMonLevel) + 2 - jp CopyBytes - -sub_3d40b: - ldh a, [hSerialConnectionStatus] - cp 1 - jr z, asm_3d418 - call sub_3d41f - call sub_3d42d - ret - -asm_3d418: - call sub_3d42d - call sub_3d41f - ret - -sub_3d41f: - xor a - ldh [hBattleTurn], a - call sub_3d43b - ld a, 1 - ldh [hBattleTurn], a - call sub_3d43b - ret - -sub_3d42d: - ld a, 1 - ldh [hBattleTurn], a - call sub_3d43b - xor a - ldh [hBattleTurn], a - call sub_3d43b - ret - -sub_3d43b: - callfar GetOpponentItem - ld a, b - cp 1 - ret nz - ld de, wEnemyMonHP + 1 - ld hl, wEnemyMonMaxHP + 1 - ldh a, [hBattleTurn] - and a - jr z, asm_3d458 - ld de, wBattleMonHP + 1 - ld hl, wBattleMonMaxHP + 1 - -asm_3d458: - push bc - ld a, [de] - ld [wHPBarOldHP], a - add a - ld c, a - dec de - ld a, [de] - inc de - ld [wReplacementBlock], a - adc a - ld b, a - ld a, c - cp [hl] - dec hl - ld a, b - sbc [hl] - pop bc - ret nc - ld a, [hli] - ld [wMapBlocksAddress], a - ld a, [hl] - ld [wHPBarMaxHP], a - ld a, [de] - add c - ld [wHPBarNewHP], a - ld c, a - dec de - ld a, [de] - adc 0 - ld [wcdc8], a - ld b, a - ld a, [hld] - cp c - ld a, [hl] - sbc b - jr nc, asm_3d492 - ld a, [hli] - ld [wcdc8], a - ld a, [hl] - ld [wHPBarNewHP], a - -asm_3d492: - ld a, [wcdc8] - ld [de], a - inc de - ld a, [wHPBarNewHP] - ld [de], a - call sub_3d4d4 - ldh a, [hBattleTurn] - ld [wWhichHPBar], a - and a - ld hl, $c2ca - jr z, asm_3d4ac - ld hl, $c35e - -asm_3d4ac: - ld [wWhichHPBar], a - predef UpdateHPBar - call DrawHUDsAndHPBars - callfar GetOpponentItem - ld a, [hl] - ld [wNumSetBits], a - call GetItemName - callfar ConsumeHeldItem - ld hl, RecoveredWithItemText - jp PrintText - -sub_3d4d4: - ld a, $69 - ld [wFXAnimID], a - ldh a, [hBattleTurn] - push af - xor 1 - ldh [hBattleTurn], a - xor a - ld [wNumHits], a - ld [wFXAnimID + 1], a - predef PlayBattleAnim - pop af - ldh [hBattleTurn], a - ret - -RecoveredWithItemText: - text "は そうびしていた" - line "@" - text_from_ram wStringBuffer1 - text "で かいふくした!" - prompt - -sub_3d50b: - ldh a, [hSerialConnectionStatus] - cp 1 - jr z, asm_3d518 - call sub_3d51f - call sub_3d537 - ret - -asm_3d518: - call sub_3d537 - call sub_3d51f - ret - -sub_3d51f: - ld hl, wPartyMon1Item - ld a, [wCurBattleMon] - ld bc, $30 - call AddNTimes - ld bc, wBattleMonItem - ld de, wPlayerMoveStruct - ld a, 0 - call sub_3d54f - ret - -sub_3d537: - ld hl, wOTPartyMon1Item - ld a, [wCurOTMon] - ld bc, $30 - call AddNTimes - ld bc, wEnemyMonItem - ld de, wEnemyMoveStruct - ld a, 1 - call sub_3d54f - ret - -sub_3d54f: - ldh [hBattleTurn], a - push hl - push bc - ld a, [bc] - ld b, a - callfar GetItemHeldEffect - ld hl, Data3d59f - -asm_3d560: - ld a, [hli] - cp $ff - jr z, asm_3d59c - inc hl - cp b - jr nz, asm_3d560 - pop bc - ld a, [bc] - ld [wNumSetBits], a - xor a - ld [bc], a - dec hl - ld b, [hl] - pop hl - ld [hl], 0 - push de - push bc - call GetItemName - ld hl, UseItemFailedText - call PrintText - pop bc - pop de - ld a, [de] - push af - ld a, $4a - ld [de], a - inc de - ld a, [de] - push af - push de - ld a, b - ld [de], a - callfar BattleCommand_StatUp - pop de - pop af - ld [de], a - pop af - dec de - ld [de], a - ret - -asm_3d59c: - pop bc - pop hl - ret - -Data3d59f: - db $1f, $a - db $20, $b - db $21, $c - db $22, $d - db $23, $e - db $24, $f - db $25, $10 - db -1 - -UseItemFailedText: - text "が そうびしていた" - line "@" - text_from_ram wStringBuffer1 - text "が さどうした!" - prompt - -DrawHUDsAndHPBars: - call UpdatePlayerHUD - jp UpdateEnemyHUD - -UpdatePlayerHUD: - xor a - ldh [hBGMapMode], a - hlcoord 9, 7 - lb bc, 5, 11 - call ClearBox - callfar DrawPlayerHUDBorder - - hlcoord 18, 9 - ld [hl], $73 - ld de, wBattleMonNickname - hlcoord 10, 8 - call CenterMonName - call PlaceString - - push bc - ld hl, wBattleMon - ld de, wTempMon - ld bc, (wBattleMonMovesEnd - wBattleMonSpecies) - call CopyBytes - - ld hl, wBattleMonLevel - ld de, wTempMonLevel - ld bc, (wBattleMonStatsEnd - wBattleMonLevel) - call CopyBytes - - ld a, [wTempMonSpecies] - ld [wCurSpecies], a - call GetBaseData - - pop hl - push hl - inc hl - ld de, wTempMonStatus - predef PlaceNonFaintStatus - pop hl - jr nz, .dont_print_level - call PrintLevel - -.dont_print_level - ld a, [wTempMonSpecies] - ld [wCurPartySpecies], a - hlcoord 10, 9 - ld b, 1 - predef DrawPlayerHP - - push de - ld a, [wCurBattleMon] - ld hl, wPartyMon1Exp + 2 - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - - ld d, h - ld e, l - hlcoord 10, 11 - ld a, [wTempMonLevel] - ld b, a - call CalcAndPlaceExpBar - - ld a, 1 - ldh [hBGMapMode], a - pop de - ld hl, wPlayerHPPal - call UpdateHPPal - - ld hl, wBattleMonHP - ld a, [hli] - or [hl] - jr z, .no_danger - ld a, [wBattleLowHealthAlarm] - and a - ret nz - ld a, [wPlayerHPPal] - cp HP_RED - jr z, .danger - -.no_danger - ld hl, wLowHealthAlarmBuffer - bit DANGER_ON_F, [hl] - ld [hl], 0 - ret z - ret - -.danger - ld hl, wLowHealthAlarmBuffer - set DANGER_ON_F, [hl] - ret - -UpdateEnemyHUD: - xor a - ldh [hBGMapMode], a - hlcoord 1, 0 - lb bc, 4, 11 - call ClearBox - callfar DrawEnemyHUDBorder - - ld de, wEnemyMonNickname - hlcoord 2, 1 - call CenterMonName - call PlaceString - - ld h, b - ld l, c - push hl - inc hl - ld de, wEnemyMonStatus - predef PlaceNonFaintStatus - - pop hl - jr nz, .dont_print_level - ld a, [wEnemyMonLevel] - ld [wTempMonLevel], a - call PrintLevel - -.dont_print_level - ld hl, wEnemyMonHP - ld a, [hli] - ldh [hMultiplicand + 1], a - ld a, [hld] - ldh [hMultiplicand + 2], a - or [hl] - jr nz, .hp_not_zero - - ld c, a - ld e, a - ld d, 6 - jp .draw_hp_bar - -.hp_not_zero - xor a - ldh [hMultiplicand], a - ld a, 48 - ldh [hMultiplier], a - call Multiply - - ld hl, wEnemyMonMaxHP - ld a, [hli] - ld b, a - ld a, [hl] - ldh [hDivisor], a - ld a, b - and a - jr z, .do_divide -; 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) - ldh a, [hDivisor] - srl b - rr a - srl b - rr a - ldh [hDivisor], a - ldh a, [hProduct + 2] - ld b, a - srl b - ldh a, [hProduct + 3] - rr a - srl b - rr a - ldh [hDividend + 3], a - ld a, b - ldh [hDividend + 2], a -.do_divide - ldh a, [hDividend + 2] - ldh [hDividend], a - ldh a, [hDividend + 3] - ldh [hDividend + 1], a - ld a, 2 - ld b, a - call Divide - ldh a, [hQuotient + 3] - ld e, a - ld a, 6 - ld d, a - ld c, a -.draw_hp_bar - xor a - ld [wWhichHPBar], a - hlcoord 2, 2 - ld b, 0 - call DrawBattleHPBar - ld a, 1 - ldh [hBGMapMode], a - ld hl, wEnemyHPPal - ; fallthrough - -UpdateHPPal: - ld b, [hl] - call SetHPPal - ld a, [hl] - cp b - ret z - ld b, SGB_BATTLE_COLORS - jp GetSGBLayout - -; center's mon's name on the battle screen -; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual -; (i.e. for names longer than 4 letters) -; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual -; (i.e. for names longer than 4 letters) -CenterMonName: -; Function is dummied out in the final game. See "Battle_DummyFunction" in pokegold. - push de - inc hl - inc hl - ld b, 2 -.loop: - inc de - ld a, [de] - cp '@' - jr z, .done - inc de - ld a, [de] - cp '@' - jr z, .done - dec hl - dec b - jr nz, .loop -.done: - pop de - ret - -DisplayBattleMenu: - call ReloadTilesFromBuffer - ld a, [wBattleType] - and a - jr nz, .menu_loop - call DrawHUDsAndHPBars - call PrintEmptyString - call BackUpTilesToBuffer - -.menu_loop: - callfar LoadBattleMenu - jr c, .menu_loop - ld a, [wStartmenuCursor] - cp 1 - jp z, BattleMenu_Fight - cp 2 - jp z, BattleMenu_Pack - cp 3 - jp z, BattleMenu_PKMN - cp 4 - jp z, BattleMenu_Run - jr .menu_loop - -BattleMenu_Fight: - xor a - ld [wNumFleeAttempts], a - call ReloadTilesFromBuffer - and a - ret - -BattleMenu_Pack: - ld a, [wLinkMode] - and a - jp nz, .ItemsCantBeUsed - call LoadStandardMenuHeader - callfar GetPocket2Status - xor a - ld [wSelectedSwapPosition], a - call ClearPalettes - callfar DrawBackpack - -.item_menu_loop - xor a - ldh [hBGMapMode], a - call ClearSprites - hlcoord 2, 2 - ld b, 8 - ld c, 15 - call DrawTextBox - call Call_DebugBackpackLoop - jr c, .didnt_use_item - call BattleMenuPack_SelectItem - ld a, [wItemEffectSucceeded] - and a - jr z, .item_menu_loop - call Call_LoadBattleFontsHPBar - call ClearSprites - ld a, 1 - ld [wMenuCursorY], a - call sub_3d832 - ld a, [wWildMon] - and a - jr nz, .asm_3d7eb - call CloseWindow - call BackUpTilesToBuffer - call DrawHUDsAndHPBars - call WaitBGMap - call ClearWindowData - call SetPalettes - and a - ret - -.asm_3d7eb - xor a - ld [wWildMon], a - ld a, 2 - ld [wBattleResult], a - call ClearWindowData - call SetPalettes - scf - ret - -.didnt_use_item - call ClearPalettes - call DelayFrame - call Call_LoadBattleFontsHPBar - call CloseWindow - call BackUpTilesToBuffer - call SetPalettes - jp DisplayBattleMenu - -.ItemsCantBeUsed - ld hl, BattleText_ItemsCantBeUsedHere - call PrintText - jp DisplayBattleMenu - -BattleText_ItemsCantBeUsedHere: - text "ここでは どうぐを" - line "つかうことは できません" - prompt - -sub_3d832: - ld a, [wPlayerSubStatus3] - bit 5, a - jr z, .ok - ld hl, wPlayerRolloutCount - dec [hl] - jr nz, .ok - ld hl, wPlayerSubStatus3 - res 5, [hl] -.ok - ret - -Call_DebugBackpackLoop: - callfar DebugBackpackLoop - ret - -BattleMenuPack_SelectItem: - callfar ScrollingMenu_ClearLeftColumn - call PlaceHollowCursor - predef LoadItemData - callfar CheckItemContext - ld a, [wItemAttributeValue] - ld hl, .item_attribute_jump_table - call CallJumptable - ret - -.item_attribute_jump_table: - dw .cant_use ; ITEMMENU_NOUSE - dw .cant_use ; TM_HOLDER - dw .ball_holder ; BALL_HOLDER - dw .other_bags ; IMPORTANT_BAG/ITEM_BAG - dw .menu_close ; ITEMMENU_CURRENT - dw .normal_item_effect ; ITEMMENU_PARTY - dw .menu_close ; ITEMMENU_CLOSE - -.cant_use: - callfar PrintCantUseText - xor a - ld [wItemEffectSucceeded], a - ret - -.ball_holder: - callfar BallPocket - jr nc, .menu_close - xor a - ld [wItemEffectSucceeded], a - ret - -.other_bags: - callfar FlipPocket2Status - xor a - ld [wSelectedSwapPosition], a - ld [wItemEffectSucceeded], a - ret - -.normal_item_effect: - call DoItemEffect - call ClearPalettes - callfar DrawBackpack - ret - -.menu_close: - call DoItemEffect - ret - -BattleMenu_PKMN: - call LoadStandardMenuHeader - -asm_3d8c0: - call ExitMenu - call LoadStandardMenuHeader - xor a - ld [wPartyMenuActionText], a - predef OpenPartyMenu_ClearGraphics - jp c, asm_3d918 - jp asm_3d8eb - -asm_3d8d5: - ld hl, $c387 - ld bc, $81 - ld a, ' ' - call ByteFill - xor a - ld [wPartyMenuActionText], a - predef OpenPartyMenu - jr c, asm_3d918 - -asm_3d8eb: - callfar FreezeMonIcons - callfar BattleMonMenu - jr c, asm_3d8d5 - call PlaceHollowCursor - ld a, [wMenuCursorY] - cp 1 - jp z, asm_3d982 - cp 2 - jr z, asm_3d912 - cp 3 - jr z, asm_3d918 - jr asm_3d8eb - -asm_3d912: - call sub_3d930 - jp asm_3d8c0 - -asm_3d918: - call ClearSprites - call ClearPalettes - call _LoadHPBar - call CloseWindow - call BackUpTilesToBuffer - call GetMemSGBLayout - call SetPalettes - jp DisplayBattleMenu - -sub_3d930: - call DisableLCD - ld hl, $9310 - ld de, vSprites - ld bc, $0110 - call CopyBytes - ld hl, vFrontPic - ld de, $8110 - ld bc, $0310 - call CopyBytes - call EnableLCD - call ClearSprites - call LowVolume - xor a - ld [wMonType], a - ld hl, wPartyMon1Species - predef StatsScreenMain - call MaxVolume - call DisableLCD - ld hl, vSprites - ld de, $9310 - ld bc, $0110 - call CopyBytes - ld hl, $8110 - ld de, vFrontPic - ld bc, $0310 - call CopyBytes - call EnableLCD - ret - -asm_3d982: - ld a, [wPlayerSubStatus5] - bit 7, a - jr z, asm_3d992 - ld hl, CantBringBackText - call PrintText - jp asm_3d8d5 - -asm_3d992: - ld a, [wCurBattleMon] - ld d, a - ld a, [wCurPartyMon] - cp d - jr nz, asm_3d9a5 - ld hl, IsAlreadyOutText - call PrintText - jp asm_3d8d5 - -asm_3d9a5: - call HasMonFainted - jp z, asm_3d8d5 - ld a, 1 - ld [wFieldMoveSucceeded], a - call ClearPalettes - call ClearSprites - call _LoadHPBar - call CloseWindow - call GetMemSGBLayout - call SetPalettes - -SwitchPlayerMon: - ld a, [wLinkMode] - and a - jr z, asm_3d9cb - call LinkBattleSendRecieveAction - -asm_3d9cb: - call RetreatMon - ld c, 50 - call DelayFrames - call RecallPlayerMon - hlcoord 9, 7 - lb bc, 5, 11 - call ClearBox - ld a, [wCurPartyMon] - ld [wCurBattleMon], a - ld c, a - ld b, 1 - push bc - ld hl, wBattleParticipantsNotFainted - predef SmallFarFlagAction - pop bc - ld hl, wBattleParticipantsIncludingFainted - predef SmallFarFlagAction - call LoadBattleMonFromParty - call ApplyStatMods - call PrintSendOutMonMessage - call sub_3d387 - call SendOutPlayerMon - call PrintEmptyString - call BackUpTilesToBuffer - xor a - ldh [hBattleTurn], a - call SpikesDamage - ld a, 2 - ld [wMenuCursorY], a - and a - ret - -PassedBattleMonEntrance: - ld c, 50 - call DelayFrames - - ld a, [wLinkMode] - and a - jr z, .not_link_battle - - call LinkBattleSendRecieveAction - -.not_link_battle - hlcoord 9, 7 - lb bc, 5, 11 - call ClearBox - - ld a, [wCurPartyMon] - ld [wCurBattleMon], a - ld c, a - ld b, SET_FLAG - push bc - ld hl, wBattleParticipantsNotFainted - predef SmallFarFlagAction - pop bc - ld hl, wBattleParticipantsIncludingFainted - predef SmallFarFlagAction - - call LoadBattleMonFromParty - xor a - ld [wApplyStatLevelMultipliersToEnemy], a - call ApplyStatLevelMultiplierOnAllStats - call SendOutPlayerMon - call PrintEmptyString - call BackUpTilesToBuffer - xor a - ldh [hBattleTurn], a - call SpikesDamage - ret - -IsAlreadyOutText: - text_from_ram wBattleMonNickname - text "はもうでています" - prompt - -CantBringBackText: - text_from_ram wBattleMonNickname - text "を もどすことが" - line "できない!" - prompt - -BattleMenu_Run: - call ReloadTilesFromBuffer - ld a, 3 - ld [wMenuCursorY], a - ld hl, wBattleMonSpeed - ld de, wEnemyMonSpeed - call TryRunningFromBattle - ld a, 0 - ld [wce38], a - ret c - ld a, [wFieldMoveSucceeded] - and a - ret nz - jp DisplayBattleMenu - -MoveSelectionScreen:: - ld hl, wEnemyMonMoves - ld a, [wMoveSelectionMenuType] - dec a - jr z, .got_menu_type - dec a - jr z, .ether_elixer_menu - call .CheckPlayerHasUsableMoves - ret z - ld hl, wBattleMonMoves - jr .got_menu_type - -.ether_elixer_menu - ld a, [wCurPartyMon] - ld hl, wPartyMon1Moves - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - -.got_menu_type - ld de, wListMoves_MoveIndicesBuffer - ld bc, NUM_MOVES - call CopyBytes - xor a - ldh [hBGMapMode], a - hlcoord 0, 17 - (NUM_MOVES * 2) - 1 - ld b, 8 - ld c, 8 - ld a, [wMoveSelectionMenuType] - cp 2 - jr nz, .got_dims - hlcoord 10, 17 - (NUM_MOVES * 2) - 1 - ld b, 8 - ld c, 8 - -.got_dims - call DrawTextBox - hlcoord 2, 17 - (NUM_MOVES * 2) + 1 - ld a, [wMoveSelectionMenuType] - cp 2 - jr nz, .got_start_coord - hlcoord 12, 17 - (NUM_MOVES * 2) + 1 - -.got_start_coord - ld a, SCREEN_WIDTH * 2 - ld [wHPBarMaxHP], a - predef ListMoves - - ld b, 1 - ld a, [wMoveSelectionMenuType] - cp 2 - jr nz, .got_default_coord - ld b, 11 - -.got_default_coord - ld a, 17 - (NUM_MOVES * 2) + 1 - ld [w2DMenuCursorInitY], a - ld a, b - ld [w2DMenuCursorInitX], a - ld a, [wMoveSelectionMenuType] - cp 1 - jr z, .skip_inc - ld a, [wCurMoveNum] - inc a - -.skip_inc - ld [wMenuCursorY], a - ld a, 1 - ld [wMenuCursorX], a - ld a, [wNumMoves] - inc a - ld [w2DMenuNumRows], a - ld a, 1 - ld [w2DMenuNumCols], a - - ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP - ld a, [wMoveSelectionMenuType] - dec a - ld b, D_DOWN | D_UP | A_BUTTON - jr z, .okay - - dec a - ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON - jr z, .okay - - ld a, [wLinkMode] - cp 3 ; LINK_COLOSSEUM - jr z, .okay - - ld a, [wDebugFlags] - bit DEBUG_BATTLE_F, a - ld b, D_DOWN | D_UP | A_BUTTON | B_BUTTON | SELECT - jr z, .okay - - ld b, D_DOWN | D_UP | D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON | START | SELECT - ld c, STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_SELECT | STATICMENU_DISABLE_B | STATICMENU_ENABLE_START | STATICMENU_WRAP - -.okay - ld a, b - ld [wMenuJoypadFilter], a - ld a, c - ld [w2DMenuFlags1], a - xor a - ld [w2DMenuFlags2], a - ld a, $20 - ld [w2DMenuCursorOffsets], a - -.menu_loop - ld a, [wMoveSelectionMenuType] - and a - jr z, .battle_player_moves - - dec a - jr nz, .interpret_joypad - hlcoord 11, 14 - ld de, .Unused_BattleText_MimicWhichMove - call PlaceString - jr .interpret_joypad - -.battle_player_moves - ld a, [wDebugFlags] - bit DEBUG_BATTLE_F, a - jr nz, .interpret_joypad - - call MoveInfoBox - ld a, [wSelectedSwapPosition] - and a - jr z, .interpret_joypad - hlcoord 1, 18 - (NUM_MOVES * 2) - dec a - ld bc, SCREEN_WIDTH * 2 - call AddNTimes - ld [hl], '▷' - -.interpret_joypad - call WaitBGMap - ld a, 1 - ldh [hBGMapMode], a - call ScrollingMenuJoypad - bit D_UP_F, a - jp nz, .pressed_up - bit D_DOWN_F, a - jp nz, .pressed_down - bit SELECT_F, a - jp nz, .pressed_select - bit START_F, a - jp nz, .pressed_start - bit D_RIGHT_F, a - jp nz, .pressed_right - bit D_LEFT_F, a - jp nz, .pressed_left - bit B_BUTTON_F, a - ; A button - push af - - xor a - ld [wSelectedSwapPosition], a - ld a, [wMenuCursorY] - dec a - ld [wMenuCursorY], a - ld b, a - ld a, [wMoveSelectionMenuType] - dec a - jr nz, .not_enemy_moves_process_b - pop af - ret - -.not_enemy_moves_process_b - dec a - ld a, b - ld [wCurMoveNum], a - jr nz, .use_move - - pop af - ret - -.use_move - pop af - ret nz - - ld hl, wBattleMonPP - ld a, [wMenuCursorY] - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - and PP_MASK - jr z, .no_pp_left - - ld a, [wPlayerDisableCount] - swap a - and $f - dec a - cp c - jr z, .move_disabled - - ld a, [wPlayerSubStatus5] - bit SUBSTATUS_TRANSFORMED, a - jr nz, .transformed - ; something was commented out here -.transformed - ld a, [wMenuCursorY] - ld hl, wBattleMonMoves - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - ld [wCurPlayerSelectedMove], a - xor a - ret - -.move_disabled - ld hl, .BattleText_TheMoveIsDisabled - jr .place_textbox_start_over - -.no_pp_left - ld hl, .BattleText_TheresNoPPLeftForThisMove - -.place_textbox_start_over - call PrintText - call ReloadTilesFromBuffer - jp MoveSelectionScreen - - - -.BattleText_TheresNoPPLeftForThisMove: - text "わざの のこりポイントが ない!" - prompt - -.BattleText_TheMoveIsDisabled: - text "わざを ふうじられている!" - prompt - -.Unused_BattleText_MimicWhichMove: - db "どのわざを" - next "ものまねする?@" - -.pressed_up - ld a, [wMenuCursorY] - and a - jp nz, .menu_loop - ld a, [wNumMoves] - inc a - ld [wMenuCursorY], a - jp .menu_loop - -.pressed_down - ld a, [wMenuCursorY] - ld b, a - ld a, [wNumMoves] - inc a - inc a - cp b - jp nz, .menu_loop - ld a, 1 - ld [wMenuCursorY], a - jp .menu_loop - -.DebugMovePreview: -.pressed_start - bit START_F, a - ld a, 0 - jr nz, .player_side - ld a, 1 - -.player_side - ldh [hBattleTurn], a - call ReloadTilesFromBuffer - call .DrawDebugMoveSelection - ld a, [wPlayerDebugSelectedMove] - and a - jp z, MoveSelectionScreen - ld [wFXAnimID], a - xor a - ld [wNumHits], a - ld [wFXAnimID + 1], a - predef PlayBattleAnim - jp MoveSelectionScreen - -.pressed_left - ld a, [wPlayerDebugSelectedMove] - dec a - jr .pressed_left_right_continue - -.pressed_right - ld a, [wPlayerDebugSelectedMove] - inc a - -.pressed_left_right_continue - ld [wPlayerDebugSelectedMove], a - call .DrawDebugMoveSelection - jp MoveSelectionScreen - -.DrawDebugMoveSelection: - hlcoord 10, 16 - lb bc, 2, 10 - call ClearBox - - hlcoord 10, 17 - ld de, wPlayerDebugSelectedMove - lb bc, PRINTNUM_LEADINGZEROS | 1, 3 - call PrintNumber - - ld a, [wPlayerDebugSelectedMove] - and a - ret z - cp NUM_ATTACKS + 1 - ret nc - - ld [wNamedObjectIndexBuffer], a - call GetMoveName - hlcoord 13, 17 - jp PlaceString - -.CheckPlayerHasUsableMoves: - ld a, MOVE_STRUGGLE - ld [wCurPlayerSelectedMove], a - ld a, [wPlayerDisableCount] - and a - ld hl, wBattleMonPP - jr nz, .disabled - - ld a, [hli] - or [hl] - inc hl - or [hl] - inc hl - or [hl] -; BUG: There should be "and PP_MASK" here - ret nz - jr .force_struggle - -.disabled - swap a - and $f - ld b, a - ld d, NUM_MOVES + 1 - xor a -.loop - dec d - jr z, .done - ld c, [hl] - inc hl - dec b - jr z, .loop - or c - jr .loop - -.done - ; BUG: This will result in a move with PP Up confusing the game. - and a ; should be "and PP_MASK" - ret nz - -.force_struggle - ld hl, .BattleText_MonHasNoMovesLeft - call PrintText - ld c, 60 - call DelayFrames - xor a - ret - -.BattleText_MonHasNoMovesLeft: - text_from_ram wBattleMonNickname - text "は だすことの できる" - line "わざが ない!" - done - -.pressed_select - ld a, [wDebugFlags] - bit DEBUG_BATTLE_F, a - jp nz, .DebugMovePreview - - ld a, [wSelectedSwapPosition] - and a - jr z, .start_swap - ld hl, wBattleMonMoves - call .swap_bytes - ld hl, wBattleMonPP - call .swap_bytes - ld hl, wPlayerDisableCount - ld a, [hl] - swap a - and $f - ld b, a - ld a, [wMenuCursorY] - cp b - jr nz, .not_swapping_disabled_move - ld a, [hl] - and $f - ld b, a - ld a, [wSelectedSwapPosition] - swap a - add b - ld [hl], a - jr .swap_moves_in_party_struct - -.not_swapping_disabled_move - ld a, [wSelectedSwapPosition] - cp b - jr nz, .swap_moves_in_party_struct - ld a, [hl] - and $f - ld b, a - ld a, [wMenuCursorY] - swap a - add b - ld [hl], a - -.swap_moves_in_party_struct -; BUG: COOLTRAINER glitch from Generation I still exists here. - ld hl, wPartyMon1Moves - ld a, [wCurBattleMon] - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - push hl - call .swap_bytes - pop hl - ld bc, MON_PP - MON_MOVES - add hl, bc - call .swap_bytes - xor a - ld [wSelectedSwapPosition], a - jp MoveSelectionScreen - -.swap_bytes - push hl - ld a, [wSelectedSwapPosition] - dec a - ld c, a - ld b, 0 - add hl, bc - ld d, h - ld e, l - pop hl - ld a, [wMenuCursorY] - dec a - ld c, a - ld b, 0 - add hl, bc - ld a, [de] - ld b, [hl] - ld [hl], a - ld a, b - ld [de], a - ret - -.start_swap - ld a, [wMenuCursorY] - ld [wSelectedSwapPosition], a - jp MoveSelectionScreen - -MoveInfoBox: - xor a - ldh [hBGMapMode], a - - hlcoord 9, 12 - ld b, 4 - ld c, 9 - call DrawTextBox - - ld a, [wPlayerDisableCount] - and a - jr z, .not_disabled - - swap a - and $f - ld b, a - ld a, [wMenuCursorY] - cp b - jr nz, .not_disabled - - hlcoord 10, 15 - ld de, .Disabled - call PlaceString - jr .done - -.not_disabled - ld hl, wMenuCursorY - dec [hl] - xor a - ldh [hBattleTurn], a - ld hl, wBattleMonMoves - ld a, [wMenuCursorY] - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - ld [wCurPlayerSelectedMove], a - - ld a, [wCurBattleMon] - ld [wCurPartyMon], a - ld a, WILDMON - ld [wMonType], a - callfar GetMaxPPOfMove - - ld hl, wMenuCursorY - ld c, [hl] - inc [hl] - ld b, 0 - ld hl, wBattleMonPP - add hl, bc - ld a, [hl] - and PP_MASK - ld [wStringBuffer1], a - hlcoord 10, 15 - ld de, .Type - call PlaceString - - hlcoord 16, 13 - ld [hl], '/' - hlcoord 14, 16 - ld [hl], '/' - hlcoord 14, 13 - ld de, wStringBuffer1 - lb bc, 1, 2 - call PrintNumber - - hlcoord 17, 13 - ld de, wTempPP - lb bc, 1, 2 - call PrintNumber - - callfar UpdateMoveData - ld a, [wPlayerMoveStruct] - ld b, a - hlcoord 15, 16 - predef PrintMoveType - -.done - jp WaitBGMap - -.Disabled: - db "ふうじられている!@" -.Type: - db "わざタイプ@" - -sub_3de6e: - ld a, [wLinkMode] - and a - jr z, asm_3dea0 - call BackUpTilesToBuffer - ld a, [wFieldMoveSucceeded] - and a - call z, LinkBattleSendRecieveAction - call ReloadTilesFromBuffer - ld a, [wOtherPlayerLinkAction] - cp $e - jp z, asm_3df82 - cp $d - jr z, asm_3df04 - cp 4 - jp nc, asm_3df86 - ld [wCurEnemyMoveNum], a - ld c, a - ld hl, wEnemyMonMoves - ld b, 0 - add hl, bc - ld a, [hl] - jp asm_3df68 - -asm_3dea0: - ld hl, wEnemySubStatus5 - bit 4, [hl] - jr z, asm_3dedc - ld a, [wEnemyEncoreCount] - dec a - ld [wEnemyEncoreCount], a - jr nz, asm_3dec1 - -asm_3deb0: - ld hl, wEnemySubStatus5 - res 4, [hl] - ld a, 1 - ldh [hBattleTurn], a - ld hl, BattleText_TargetsEncoreEnded - call PrintText - jr asm_3dedc - -asm_3dec1: - ld a, [wCurEnemyMove] - and a - jr z, asm_3deb0 - ld hl, wEnemyMonPP - ld a, [wCurEnemyMoveNum] - ld c, a - ld b, 0 - add hl, bc - ld a, [hl] - and $3f - jr z, asm_3deb0 - ld a, [wCurEnemyMove] - jp asm_3df68 - -asm_3dedc: - ld a, [wEnemySubStatus4] - and $60 - jp nz, asm_3df86 - ld hl, wEnemySubStatus3 - ld a, [hl] - and $12 - jp nz, asm_3df86 - ld hl, wEnemySubStatus1 - bit 6, [hl] - jp nz, asm_3df86 - ld a, [wEnemySubStatus3] - and $21 - jp nz, asm_3df86 - ld a, [wPlayerSubStatus3] - bit 5, a - jr asm_3df08 - -asm_3df04: - ld a, $ff - jr asm_3df68 - -asm_3df08: - ld hl, wEnemyMonPP - ld bc, 0 - -asm_3df0e: - inc b - ld a, b - cp 5 - jr z, asm_3df26 - ld a, [hli] - and $3f - jr z, asm_3df0e - ld a, [wEnemyDisableCount] - swap a - and $f - cp b - jr z, asm_3df0e - inc c - jr asm_3df0e - -asm_3df26: - ld a, c - and a - jr z, asm_3df82 - ld a, [wBattleMode] - dec a - jr z, asm_3df3f - ld a, 1 - ld [wTrainerClass], a - callfar AIChooseMove - jr asm_3df6b - -asm_3df3f: - ld hl, wEnemyMonMoves - call BattleRandom - and 3 - ld c, a - ld b, 0 - add hl, bc - ld a, [wEnemyDisableCount] - swap a - and $f - dec a - cp c - jr z, asm_3df3f - ld a, [hl] - and a - jr z, asm_3df3f - ld hl, wEnemyMonPP - add hl, bc - ld b, a - ld a, [hl] - and a - jr z, asm_3df3f - ld a, c - ld [wCurEnemyMoveNum], a - ld a, b - -asm_3df68: - ld [wCurEnemySelectedMove], a - -asm_3df6b: - ld a, 1 - ldh [hBattleTurn], a - callfar UpdateMoveData - ld a, [wEnemyMoveStructEffect] - cp $77 - ret z - xor a - ld [wEnemyFuryCutterCount], a - ret - -asm_3df82: - ld a, $a5 - jr asm_3df68 - -asm_3df86: - xor a - ld [wEnemyFuryCutterCount], a - ret - -LinkBattleSendRecieveAction: - ld a, $ff - ld [wOtherPlayerLinkAction], a - ld a, [wBattlePlayerAction] - and a ; BATTLEPLAYERACTION_USEMOVE? - jr nz, .switch - - ld a, [wCurPlayerSelectedMove] - cp MOVE_STRUGGLE - ld b, BATTLEACTION_STRUGGLE - jr z, .struggle - - dec b - inc a - jr z, .struggle - ld a, [wCurMoveNum] - jr .use_move - -.switch - ld a, [wCurPartyMon] - add BATTLEACTION_SWITCH1 - ld b, a - -.struggle - ld a, b - -.use_move - ld [wPlayerLinkAction], a - callfar PlaceWaitingText - -.waiting - call LinkTransfer - call DelayFrame - ld a, [wOtherPlayerLinkAction] - inc a - jr z, .waiting - ld b, 10 - -.recieve - call DelayFrame - call LinkTransfer - dec b - jr nz, .recieve - ld b, 10 - -.acknowledge - call DelayFrame - call LinkDataReceived - dec b - jr nz, .acknowledge - ret - -BattleText_TargetsEncoreEnded: - text "の" - line "アンコールじょうたいが とけた!" - prompt - -asm_3dff2: - ldh a, [hBattleTurn] - and a - ld hl, wCurEnemySelectedMove - ld de, wEnemyMoveStructPower - ld a, [wCurPlayerSelectedMove] - jr z, asm_3e009 - ld hl, wCurPlayerSelectedMove - ld de, wPlayerMoveStructPower - ld a, [wCurEnemySelectedMove] - -asm_3e009: - cp MOVE_COUNTER - ret nz - ld a, 1 - ld [wAttackMissed], a - ld a, [hl] - cp MOVE_COUNTER - ret z - ld a, [de] - and a - ret z - inc de - ld a, [de] - and a - jr z, asm_3e023 - cp 1 - jr z, asm_3e023 - xor a - ret - -asm_3e023: - ld hl, wCurDamage - ld a, [hli] - or [hl] - ret z - ld a, [hl] - add a - ld [hld], a - ld a, [hl] - adc a - ld [hl], a - jr nc, asm_3e035 - ld a, $ff - ld [hli], a - ld [hl], a - -asm_3e035: - xor a - ld [wAttackMissed], a - callfar BattleCommand_CheckHit - xor a - ret - -; Initialize enemy monster parameters -; To do this we pull the species from wTempEnemyMonSpecies -LoadEnemyMon: -; Notes: -; BattleRandom is used to ensure sync between Game Boys - -; We don't need to be here if we're in a link battle - ld a, [wLinkMode] - and a - jp nz, LoadEnemyMonFromParty - -; Make sure everything knows what species we're working with - ld a, [wTempEnemyMonSpecies] - ld [wEnemyMonSpecies], a - ld [wCurSpecies], a - ld [wCurPartySpecies], a - -; Grab the BaseData for this species - call GetBaseData - -; Let's get the item: - -; Is the item predetermined? - ld a, [wBattleMode] - cp TRAINER_BATTLE - jr nz, .WildItem - -; If we're in a trainer battle, the item is in the party struct - ld a, [wCurPartyMon] - ld hl, wOTPartyMon1Item - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld a, [hl] - jr .UpdateItem - -.WildItem -; ~20% chance of getting an item. - call BattleRandom - cp 79 percent - 1 - ld a, 0 - jr c, .UpdateItem - ld a, [wMonHItems] - -.UpdateItem - ld [wEnemyMonItem], a - ld a, [wEnemySubStatus5] - bit SUBSTATUS_TRANSFORMED, a - ld hl, wEnemyBackupDVs - ld a, [hli] - ld b, [hl] - jr nz, .UpdateDVs - -; Load preset middle-class DVs for trainer battles. - ld a, [wBattleMode] - cp TRAINER_BATTLE - ln a, 9, 8 - ln b, 8, 8 - jr z, .UpdateDVs - -; Otherwise randomly generate DVs for wild encounters - call BattleRandom - ld b, a - call BattleRandom - -.UpdateDVs - ld hl, wEnemyMonDVs - ld [hli], a - ld [hl], b - - ld a, [wCurPartyLevel] - ld [wEnemyMonLevel], a - ld de, wEnemyMonMaxHP - ld b, 0 - ; This address doesn't seem to be referenced anywhere - ld hl, wEnemyMonDVs - (MON_DVS - MON_STAT_EXP + 1) - predef CalcMonStats - - ld a, [wBattleMode] - cp TRAINER_BATTLE - jr z, .OpponentParty - - ld a, [wEnemySubStatus5] - bit SUBSTATUS_TRANSFORMED, a - jr nz, .Moves - -; Zero out status when generating Pokémon - ld hl, wEnemyMonStatus - xor a - ld [hli], a - ld [hli], a - -; Set HP equal to max HP. - ld a, [wEnemyMonMaxHP] - ld [hli], a - ld a, [wEnemyMonMaxHP + 1] - ld [hli], a - jr .Moves - -.OpponentParty -; Get HP from the party struct - ld hl, wOTPartyMon1HP + 1 - ld a, [wCurPartyMon] - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld a, [hld] - ld [wEnemyMonHP + 1], a - ld a, [hld] - ld [wEnemyMonHP], a - -; Make sure everything knows which monster the opponent is using - ld a, [wCurPartyMon] - ld [wCurOTMon], a - -; Get status from the party struct - dec hl - ld a, [hl] - ld [wEnemyMonStatus], a - -.Moves - ld hl, wMonHType1 - ld de, wEnemyMonType1 - ld a, [hli] - ld [de], a - inc de - ld a, [hl] - ld [de], a - - ld de, wEnemyMonMoves - ld a, [wBattleMode] - cp TRAINER_BATTLE - jr nz, .WildMoves - - ld hl, wOTPartyMon1Moves - ld a, [wCurPartyMon] - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld bc, NUM_MOVES - call CopyBytes - jr .PP - -.WildMoves - xor a - ld h, d - ld l, e - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wSkipMovesBeforeLevelUp], a - predef FillMoves - -.PP - ld hl, wEnemyMonMoves - ld de, wEnemyMonPP - predef FillPP - -.Finish - ld hl, wMonHBaseStats - ld de, wEnemyMonBaseStats - ld b, NUM_BATTLE_STATS - -.loop - ld a, [hli] - ld [de], a - inc de - dec b - jr nz, .loop - - ld a, [wMonHCatchRate] - ld [de], a - - inc de - ld a, [wMonHBaseEXP] - ld [de], a - - ld a, [wTempEnemyMonSpecies] - ld [wNamedObjectIndexBuffer], a - - call GetPokemonName - -; Update enemy nickname - ld hl, wStringBuffer1 - ld de, wEnemyMonNickname - ld bc, MON_NAME_LENGTH - call CopyBytes - -; Saw this mon - ld a, [wTempEnemyMonSpecies] - dec a - ld c, a - ld b, 1 - ld hl, wEndPokedexCaught - predef SmallFarFlagAction - ld hl, wEnemyMonStats - ld de, wEnemyStats - ld bc, NUM_BATTLE_STATS * 2 - call CopyBytes - - ld a, 7 - ld b, 8 - ld hl, wEnemyStatLevels - -.InitStatLevel - ld [hli], a - dec b - jr nz, .InitStatLevel - - ld a, 1 - ldh [hBattleTurn], a - callfar GetMonSGBPaletteFlags - ret - -asm_3e193: - push bc - ld a, [wBattleMonLevel] - ld b, a - ld a, [wEnemyMonLevel] - ld [wBattleMonLevel], a - ld a, b - ld [wEnemyMonLevel], a - pop bc - ret - -; A leftover from Generation I, where it had no effect due to no stats actually being selected. -; BUG: Remarkably, this is STILL run from HealStatus despite the stat double/halve bitfields -; being overwritten with variables that are actually used as substatuses. -DoubleOrHalveSelectedStats_Old:: - call DoubleSelectedStats - jp HalveSelectedStats - -DoubleSelectedStats: - ldh a, [hBattleTurn] - and a - ld a, [wPlayerSubStatus1] ; wPlayerStatsToDouble - ld hl, wBattleMonAttack + 1 - jr z, .notEnemyTurn - ld a, [wEnemySubStatus1] ; wEnemyStatsToDouble - ld hl, wEnemyMonAttack + 1 - -.notEnemyTurn - ld c, 4 - ld b, a - -.loop - srl b - call c, .doubleStat - inc hl - inc hl - dec c - ret z - jr .loop - -.doubleStat - ld a, [hl] - add a - ld [hld], a - ld a, [hl] - rl a - ld [hli], a - ret - -HalveSelectedStats: - ldh a, [hBattleTurn] - and a - ld a, [wPlayerSubStatus2] ; wPlayerStatsToHalve - ld hl, wBattleMonAttack - jr z, .notEnemyTurn - ld a, [wEnemySubStatus2] ; wEnemyStatsToHalve - ld hl, wEnemyMonAttack -.notEnemyTurn - ld c, 4 - ld b, a -.loop - srl b - call c, .halveStat - inc hl - inc hl - dec c - ret z - jr .loop - -.halveStat - ld a, [hl] - srl a - ld [hli], a - ld d, a - ld a, [hl] - rr a - ld [hl], a - or d - jr nz, .nonzeroStat - ld a, 1 - ld [hl], a -.nonzeroStat - dec hl - ret - -sub_3e201: - xor a - ld [wTempEnemyMonSpecies], a - ld b, 1 - call GetSGBLayout -; Should be a call instead - callfar sub_3f003 - ld hl, $c2b3 - ld c, 0 - -asm_3e217: - inc c - ld a, c - cp 7 - ret z - ld d, 0 - push bc - push hl - -asm_3e220: - call sub_3e235 - inc hl - ld a, 7 - add d - ld d, a - dec c - jr nz, asm_3e220 - ld c, 4 - call DelayFrames - pop hl - pop bc - dec hl - jr asm_3e217 - -sub_3e235: - push hl - push de - push bc - ld e, 7 - -asm_3e23a: - ld [hl], d - ld bc, $14 - add hl, bc - inc d - dec e - jr nz, asm_3e23a - pop bc - pop de - pop hl - ret - -ApplyStatusEffectOnPlayerStats: - ld a, 1 - jr ApplyStatusEffectOnStats - -ApplyStatusEffectOnEnemyStats: - xor a - -ApplyStatusEffectOnStats: - ldh [hBattleTurn], a - call ApplyPrzEffectOnSpeed - jp ApplyBrnEffectOnAttack - -ApplyPrzEffectOnSpeed: - ldh a, [hBattleTurn] - and a - jr z, .enemy - ld a, [wBattleMonStatus] - and 1 << PAR - ret z - ld hl, wBattleMonSpeed + 1 - ld a, [hld] - ld b, a - ld a, [hl] - srl a - rr b - srl a - rr b - ld [hli], a - or b - jr nz, .player_ok - ld b, 1 - -.player_ok: - ld [hl], b - ret - -.enemy: - ld a, [wEnemyMonStatus] - and 1 << PAR - ret z - ld hl, wEnemyMonSpeed + 1 - ld a, [hld] - ld b, a - ld a, [hl] - srl a - rr b - srl a - rr b - ld [hli], a - or b - jr nz, .enemy_ok - ld b, 1 - -.enemy_ok: - ld [hl], b - ret - -ApplyBrnEffectOnAttack: - ldh a, [hBattleTurn] - and a - jr z, .enemy - ld a, [wBattleMonStatus] - and 1 << BRN - ret z - ld hl, wBattleMonAttack + 1 - ld a, [hld] - ld b, a - ld a, [hl] - srl a - rr b - ld [hli], a - or b - jr nz, .player_ok - ld b, 1 ; min attack - -.player_ok - ld [hl], b - ret - -.enemy - ld a, [wEnemyMonStatus] - and 1 << BRN - ret z - ld hl, wEnemyMonAttack + 1 - ld a, [hld] - ld b, a - ld a, [hl] - srl a - rr b - ld [hli], a - or b - jr nz, .enemy_ok - ld b, 1 ; min attack - -.enemy_ok - ld [hl], b - ret - -ApplyStatLevelMultiplierOnAllStats: - ld c, 0 - -.stat_loop - call ApplyStatLevelMultiplier - inc c - ld a, c - cp NUM_BATTLE_STATS - jr nz, .stat_loop - ret - -ApplyStatLevelMultiplier: - push bc - push bc - ld a, [wApplyStatLevelMultipliersToEnemy] - and a - ld a, c - - ld hl, wBattleMonStats - ld de, wPlayerStats - ld bc, wPlayerStatLevels - jr z, .got_pointers - - ld hl, wEnemyMonStats - ld de, wEnemyStats - ld bc, wEnemyStatLevels - -.got_pointers -; Adds a (battle stat index) to StatLevels, increase b if c overflows. - add c - ld c, a - jr nc, .okay - inc b - -.okay - ld a, [bc] - pop bc -; b = Stat Level - ld b, a - push bc -; c = Stat index * 2. Add to MonStats pointer. - sla c - ld b, 0 - add hl, bc - ld a, c -; Add stat index * 2 to wEnemyStats. - add e - ld e, a - jr nc, .okay2 - inc d - -.okay2 - pop bc - push hl - ld hl, StatLevelMultipliers_Applied -; Get index of stat level from StatLevelMultipliers_Applied. - dec b - sla b - ld c, b - ld b, 0 - add hl, bc -; Load enemy's original stat into Multiplicand. - xor a - ldh [hMultiplicand], a - ld a, [de] - ldh [hMultiplicand + 1], a - inc de - ld a, [de] - ldh [hMultiplicand + 2], a - -; Load multiplication value from StatLevelMultipliers_Applied. - ld a, [hli] - ldh [hMultiplier], a - call Multiply - -; Load division value from same table. - ld a, [hl] - ldh [hDivisor], a - ld b, 4 - call Divide - -; Cap at 999. - pop hl - ldh a, [hQuotient + 3] - sub LOW(MAX_STAT_VALUE) - ldh a, [hQuotient + 2] - sbc HIGH(MAX_STAT_VALUE) - jp c, .okay3 - - ld a, HIGH(MAX_STAT_VALUE) - ldh [hQuotient + 2], a - ld a, LOW(MAX_STAT_VALUE) - ldh [hQuotient + 3], a - -.okay3 -; Load output into MonStat. - ldh a, [hQuotient + 2] - ld [hli], a - ld b, a - ldh a, [hQuotient + 3] - ld [hl], a - or b -; Keep at minimum of 1 - jr nz, .okay4 - inc [hl] - -.okay4 - pop bc - ret - -StatLevelMultipliers_Applied: - INCLUDE "data/battle/stat_multipliers.inc" - -; Checks every odd-numbered badge, and triggers their corresponding boosts. -; Stat boosts are identical to Gen 1, with Special Attack replacing Special. -BadgeStatBoosts: - ld a, [wLinkMode] - cp 3 ; LINK_COLOSSEUM - ret z - - ld a, [wBadges] - ld b, a - ld hl, wBattleMonAttack - ld c, 4 - -.CheckBadge - srl b - call c, BoostStat - inc hl - inc hl -; Check every other badge. - srl b - dec c - jr nz, .CheckBadge - ret - -; Raise stat at hl by 1/8. -BoostStat: - ld a, [hli] - ld d, a - ld e, [hl] - srl d - rr e - srl d - rr e - srl d - rr e - ld a, [hl] - add e - ld [hld], a - ld a, [hl] - adc d - ld [hli], a - -; Cap at 999. - ld a, [hld] - sub LOW(MAX_STAT_VALUE) - ld a, [hl] - sbc HIGH(MAX_STAT_VALUE) - ret c - ld a, HIGH(MAX_STAT_VALUE) - ld [hli], a - ld a, LOW(MAX_STAT_VALUE) - ld [hld], a - ret - -Call_LoadBattleFontsHPBar: - jpfar LoadBattleFontsHPBar - -_LoadHPBar: - jpfar LoadHPBar - - ld de, HpExpBarParts0GFX - ld hl, vChars2 tile $6c - lb bc, BANK(HpExpBarParts0GFX), 04 - call Get1bpp - - ld de, HpExpBarParts1GFX - ld hl, vChars2 tile $73 - lb bc, BANK(HpExpBarParts1GFX), 06 - call Get1bpp - - ld de, ExpBarGFX - ld hl, vChars2 tile $55 - lb bc, BANK(ExpBarGFX), 08 - jp Get2bpp - -PrintEmptyString: - ld hl, .EmptyString - jp PrintText - -.EmptyString: - db "@" - -SECTION "engine/dumps/bank0f.asm@PlayMoveAnimation", ROMX -PlayMoveAnimation: - ld a, e - ld [wFXAnimID], a - ld a, d - ld [wFXAnimID + 1], a - -asm_3e419: - call WaitBGMap - -asm_3e41c: - predef_jump PlayBattleAnim - -sub_3e421: - ld a, [wLinkMode] - and a - ret nz - -asm_3e426: - call sub_3e64b - xor a - ld [wCurPartyMon], a - ld bc, wPartyMon1Species - -asm_3e430: - ld hl, $22 - add hl, bc - ld a, [hli] - or [hl] - jp z, asm_3e613 - push bc - ld hl, wBattleParticipantsNotFainted - ld a, [wCurPartyMon] - ld c, a - -asm_3e441: - ld b, 2 - ld d, 0 - predef SmallFarFlagAction - ld a, c - and a - pop bc - jp z, asm_3e613 - ld hl, $c - add hl, bc - ld d, h - ld e, l - ld hl, wEnemyMonBaseStats - push bc - ld c, 5 - -asm_3e45c: - ld a, [hli] - ld b, a - ld a, [de] - add b - ld [de], a - jr nc, asm_3e471 - dec de - ld a, [de] - inc a - jr z, asm_3e46c - ld [de], a - inc de - jr asm_3e471 - -asm_3e46c: - ld a, $ff - ld [de], a - inc de - ld [de], a - -asm_3e471: - dec c - jr z, asm_3e478 - inc de - inc de - jr asm_3e45c - -asm_3e478: - xor a - ldh [hMultiplicand], a - ldh [hMultiplicand + 1], a - ld a, [wcdff] - ldh [hMultiplicand + 2], a - ld a, [wEnemyMonLevel] - ldh [hMultiplier], a - call Multiply - ld a, 7 - ldh [hDivisor], a - ld b, 4 - call Divide - pop bc - ld hl, 6 - add hl, bc - ld a, [wPlayerID] - cp [hl] - jr nz, asm_3e4a7 - inc hl - ld a, [wPlayerID + 1] - cp [hl] - ld a, 0 - jr z, asm_3e4ac - -asm_3e4a7: - call sub_3e67e - ld a, 1 - -asm_3e4ac: - ld [wcd33], a - ld a, [wBattleMode] - dec a - call nz, sub_3e67e - ld hl, $a - add hl, bc - ld d, [hl] - ldh a, [hQuotient + 3] - ld [wcd32], a - add d - ld [hld], a - ld d, [hl] - ldh a, [hQuotient + 2] - ld [wStringBuffer2], a - adc d - ld [hl], a - jr nc, asm_3e4ce - dec hl - inc [hl] - -asm_3e4ce: - ld a, [wCurPartyMon] - ld e, a - ld d, 0 - ld hl, wPartySpecies - add hl, de - ld a, [hl] - ld [wCurSpecies], a - call GetBaseData - push bc - ld d, MAX_LEVEL - callfar CalcExpAtLevel - pop bc - ld hl, $a - add hl, bc - push bc - ldh a, [hMultiplicand] - ld b, a - ldh a, [hMultiplicand + 1] - ld c, a - ldh a, [hMultiplicand + 2] - ld d, a - ld a, [hld] - sub d - ld a, [hld] - sbc c - ld a, [hl] - sbc b - jr c, asm_3e507 - ld a, b - ld [hli], a - ld a, c - ld [hli], a - ld a, d - ld [hld], a - -asm_3e507: - ld a, [wCurPartyMon] - ld hl, wPartyMonNicknames - call GetNick - ld hl, BoostedExpPointsText - call PrintText - xor a - ld [wMonType], a - predef CopyMonToTempMon - farcall CalcLevel - pop bc - ld hl, $1f - add hl, bc - ld a, [hl] - cp d - jp z, asm_3e613 - ld a, [wCurPartyLevel] - push af - ld a, d - ld [wCurPartyLevel], a - ld [hl], a - ld hl, 0 - add hl, bc - ld a, [hl] - ld [wCurSpecies], a - ld [wNumSetBits], a - call GetBaseData - ld hl, $25 - add hl, bc - ld a, [hld] - ld e, a - ld d, [hl] - push de - ld hl, $24 - add hl, bc - ld d, h - ld e, l - ld hl, $a - add hl, bc - push bc - ld b, 1 - predef CalcMonStats - pop bc - pop de - ld hl, $25 - add hl, bc - ld a, [hld] - sub e - ld e, a - ld a, [hl] - sbc d - ld d, a - dec hl - ld a, [hl] - add e - ld [hld], a - ld a, [hl] - adc d - ld [hl], a - ld a, [wCurBattleMon] - ld d, a - ld a, [wCurPartyMon] - cp d - jr nz, asm_3e5d3 - ld de, wBattleMonHP - ld a, [hli] - ld [de], a - inc de - ld a, [hli] - ld [de], a - ld de, wBattleMonMaxHP - push bc - ld bc, $c - call CopyBytes - pop bc - ld hl, $1f - add hl, bc - ld a, [hl] - ld [wBattleMonLevel], a - ld a, [wPlayerSubStatus5] - bit 3, a - jr nz, asm_3e5ae - ld hl, $26 - add hl, bc - ld de, wPlayerStats - ld bc, $a - call CopyBytes - -asm_3e5ae: - xor a - ld [wApplyStatLevelMultipliersToEnemy], a - call ApplyStatLevelMultiplierOnAllStats -; these three calls should be regular calls - callfar ApplyStatusEffectOnPlayerStats - callfar BadgeStatBoosts - callfar UpdatePlayerHUD - call PrintEmptyString - call BackUpTilesToBuffer - -asm_3e5d3: - ld hl, GrewToLevelText - call PrintText - xor a - ld [wMonType], a - predef CopyMonToTempMon - ld d, 1 - callfar PrintTempMonStats - call TextboxWaitPressAorB_BlinkCursor - call ReloadTilesFromBuffer - xor a - ld [wMonType], a - ld a, [wCurSpecies] - ld [wNumSetBits], a - predef LearnLevelMoves - ld hl, wEvolvableFlags - ld a, [wCurPartyMon] - ld c, a - ld b, 1 - predef SmallFarFlagAction - pop af - ld [wCurPartyLevel], a - -asm_3e613: - ld a, [wPartyCount] - ld b, a - ld a, [wCurPartyMon] - inc a - cp b - jr z, asm_3e62f - ld [wCurPartyMon], a - ld bc, $30 - ld hl, wPartyMon1Species - call AddNTimes - ld b, h - ld c, l - jp asm_3e430 - -asm_3e62f: - ld hl, wBattleParticipantsNotFainted - xor a - ld [hl], a - ld a, [wCurBattleMon] - ld c, a - ld b, 1 - push bc - predef SmallFarFlagAction - ld hl, wBattleParticipantsIncludingFainted - xor a - ld [hl], a - pop bc - predef_jump SmallFarFlagAction - -sub_3e64b: - ld a, [wBattleParticipantsNotFainted] - ld b, a - xor a - ld c, 8 - ld d, 0 - -asm_3e654: - xor a - srl b - adc d - ld d, a - dec c - jr nz, asm_3e654 - cp 2 - ret c - ld [wNumSetBits], a - ld hl, wEnemyMonBaseStats - ld c, 7 - -asm_3e667: - xor a - ldh [hDividend], a - ld a, [hl] - ldh [hDividend + 1], a - ld a, [wNumSetBits] - ldh [hDivisor], a - ld b, 2 - call Divide - ldh a, [hQuotient + 3] - ld [hli], a - dec c - jr nz, asm_3e667 - ret - -sub_3e67e: - push bc - ldh a, [hQuotient + 2] - ld b, a - ldh a, [hQuotient + 3] - ld c, a - srl b - rr c - add c - ldh [hQuotient + 3], a - ldh a, [hQuotient + 2] - adc b - ldh [hQuotient + 2], a - pop bc - ret - -BoostedExpPointsText: - text_from_ram wStringBuffer1 - text "は@" - start_asm - ld a, [wHPBarMaxHP] - ld hl, .BoostedExpPoints1Text - and a - ret nz - ld hl, .BoostedExpPoints3Text - ld a, [wcd33] - and a - ret z - ld hl, .BoostedExpPoints2Text - ret - -.BoostedExpPoints1Text: - text " がくしゅうそうちで@" - start_asm - ld hl, .BoostedExpPoints3Text - ret - -.BoostedExpPoints2Text: - text " おおめに@" - -.BoostedExpPoints3Text: - text_start - line "@" - deciram wStringBuffer2, 2, 4 - text " けいけんちを もらった!" - prompt - -GrewToLevelText: - text_from_ram wStringBuffer1 - text "は" - line "レベル@" - deciram wCurPartyLevel, 1, 3 - text " に あがった!@" - sound_dex_fanfare_50_79 - text_end - -PrintSendOutMonMessage: - ld a, [wLinkMode] - and a - jr z, .not_link - ld hl, GoText - ld a, [wBattleHasJustStarted] - and a - jr nz, .print_text - -.not_link - ld hl, wEnemyMonHP - ld a, [hli] - or [hl] - ld hl, GoText - jr z, .print_text - xor a - ldh [hMultiplicand], a -; enemy mon current HP * 25 - ld hl, wEnemyMonHP - ld a, [hli] - ld [wEnemyHPAtTimeOfPlayerSwitch], a - ldh [hMultiplicand + 1], a - ld a, [hl] - ld [wEnemyHPAtTimeOfPlayerSwitch + 1], a - ldh [hMultiplicand + 2], a - ld a, 25 - ldh [hPrintNumDivisor], a - call Multiply - ld hl, wEnemyMonMaxHP - ld a, [hli] - ld b, [hl] - srl a - rr b - srl a - rr b - ld a, b -; enemy mon max HP divided by 4 - ld b, 4 - ldh [hDivisor], a - call Divide - -; (enemy's current HP * 25) / (enemy's max HP / 4) -; approximates current % of max HP - ldh a, [hQuotient + 3] -; >= 70% - ld hl, GoText - cp 70 - jr nc, .print_text -; 40% <= HP <= 69% - ld hl, DoItText - cp 40 - jr nc, .print_text -; 10% <= HP <= 39% - ld hl, GetmText - cp 10 - jr nc, .print_text -; < 10% - ld hl, EnemysWeakText -.print_text - jp PrintText - -GoText: - text "ゆけっ! @" - start_asm - jr PrintPlayerMon1Text - -DoItText: - text "いってこい! @" - start_asm - jr PrintPlayerMon1Text - -GetmText: - text "がんばれ! @" - start_asm - jr PrintPlayerMon1Text - -EnemysWeakText: - text "あいてが よわっている!" - line "チャンスだ! @" - start_asm - -PrintPlayerMon1Text: - ld hl, .Text - ret -.Text: - text_from_ram wBattleMonNickname - text "!" - done - -RetreatMon: - ld hl, PlayerMon2Text - jp PrintText - -PlayerMon2Text: - text_from_ram wBattleMonNickname - text " @" - start_asm - push de - push bc - ld hl, wEnemyMonHP + 1 - ld de, wEnemyHPAtTimeOfPlayerSwitch + 1 - ld b, [hl] - dec hl - ld a, [de] - sub b - ldh [hMultiplicand + 2], a - dec de - ld b, [hl] - ld a, [de] - sbc b - ldh [hMultiplicand + 1], a - ld a, 25 - ldh [hMultiplier], a - call Multiply - ld hl, wEnemyMonMaxHP - ld a, [hli] - ld b, [hl] - srl a - rr b - srl a - rr b - ld a, b - ld b, 4 - ldh [hDivisor], a - call Divide - pop bc - pop de - ldh a, [hQuotient + 3] -; HP stays the same - ld hl, EnoughText - and a - ret z -; HP went down 1% - 29% - ld hl, ComeBackText - cp 30 - ret c -; HP went down 30% - 69% - ld hl, OKExclamationText - cp 70 - ret c -; HP went down 70% or more - ld hl, GoodText - ret - -EnoughText: - text "もういい!@" - start_asm - jr PrintComeBackText - -OKExclamationText: - text "いいぞ!@" - start_asm - jr PrintComeBackText - -GoodText: - text "よくやった!@" - start_asm - jr PrintComeBackText - -PrintComeBackText: - ld hl, ComeBackText - ret - -ComeBackText: - text_start - line "もどれ!" - done - -sub_3e81b: - ld hl, wcace - ld a, [hl] - and a - jr z, asm_3e828 - dec [hl] - ld hl, Data3e84b - jr asm_3e843 - -asm_3e828: - dec hl - ld a, [hl] - and a - ret z - dec [hl] - ld hl, Data3e861 - jr nz, asm_3e843 - push hl - ld a, [wEnemyMonSpecies] - ld [wCurSpecies], a - call GetBaseData - ld a, [wMonHCatchRate] - ld [wEnemyMonCatchRate], a - pop hl - -asm_3e843: - push hl - call ReloadTilesFromBuffer - pop hl - jp PrintText - -Data3e84b: - text "やせいの@" - text_from_ram wEnemyMonNickname - text "は" - line "エサを たべてる!" - prompt - -Data3e861: - text "やせいの@" - text_from_ram wEnemyMonNickname - text "は" - line "おこってる!" - prompt - -; Calculate the percent exp between this level and the next -; Level in b, then place the exp bar. Split in the final game. -CalcAndPlaceExpBar: - push hl - push de - ld d, b - push de - callfar CalcExpAtLevel - pop de -; exp at current level gets pushed to the stack - ld hl, hMultiplicand - ld a, [hli] - push af - ld a, [hli] - push af - ld a, [hl] - push af -; next level - inc d - callfar CalcExpAtLevel -; back up the next level exp, and subtract the two levels - ld hl, hMultiplicand + 2 - ld a, [hl] - ldh [hMathBuffer + 2], a - pop bc - sub b - ld [hld], a - ld a, [hl] - ldh [hMathBuffer + 1], a - pop bc - sbc b - ld [hld], a - ld a, [hl] - ldh [hMathBuffer], a - pop bc - sbc b - ld [hl], a - pop de - - ld hl, hMultiplicand + 1 - ld a, [hli] - push af - ld a, [hl] - push af -; get the amount of exp remaining to the next level - ld a, [de] - dec de - ld c, a - ldh a, [hMathBuffer + 2] - sub c - ld [hld], a - ld a, [de] - dec de - ld b, a - ldh a, [hMathBuffer + 1] - sbc b - ld [hld], a - ld a, [de] - ld c, a - ldh a, [hMathBuffer] - sbc c - ld [hld], a - xor a - ld [hl], a - ld a, 64 - ldh [hMultiplier], a - call Multiply - pop af - ld c, a - pop af - ld b, a -.loop - ld a, b - and a - jr z, .done - srl b - rr c - ld hl, hProduct - srl [hl] - inc hl - rr [hl] - inc hl - rr [hl] - inc hl - rr [hl] - jr .loop -.done - ld a, c - ldh [hDivisor], a - ld b, 4 - call Divide - pop hl - ld bc, 7 - add hl, bc - ldh a, [hQuotient + 3] - ld b, a - ld a, $40 - sub b - ld b, a - -; Separated into PlaceExpBar in the final game - ld c, 8 -.loop2 - ld a, b - sub 8 - jr c, .next - ld b, a - ld a, $6a ; full bar - ld [hld], a - dec c - jr z, .finish - jr .loop2 - -.next - add 8 - jr z, .loop3 - add $54 ; tile to the left of small exp bar tile - jr .skip - -.loop3 - ld a, $62 ; empty bar - -.skip - ld [hld], a - ld a, $62 ; empty bar - dec c - jr nz, .loop3 -.finish - ret - -GetBattleMonBackpic: - ld a, [wPlayerSubStatus4] - bit SUBSTATUS_SUBSTITUTE, a - ld hl, BattleAnimCmd_RaiseSub - jr nz, GetBattleMonBackpic_DoAnim - -DropPlayerSub: - ld a, [wPlayerMinimized] - and a - ld hl, BattleAnimCmd_MinimizeOpp - jr nz, GetBattleMonBackpic_DoAnim - ld a, [wCurPartySpecies] - push af - ld a, [wBattleMonSpecies] - ld [wCurSpecies], a - ld [wCurPartySpecies], a - call GetBaseData - ld hl, wMonHBackSprite - wMonHeader - call UncompressMonSprite - ld hl, vBackPic - predef GetMonBackpic - pop af - ld [wCurPartySpecies], a - ret - -GetBattleMonBackpic_DoAnim: - ldh a, [hBattleTurn] - push af - xor a - ldh [hBattleTurn], a - ld a, BANK(BattleAnimCmd_RaiseSub) - call FarCall_hl - pop af - ldh [hBattleTurn], a - ret - -GetEnemyMonFrontpic: - ld a, [wEnemySubStatus4] - bit SUBSTATUS_SUBSTITUTE, a - ld hl, BattleAnimCmd_RaiseSub - jr nz, GetEnemyMonFrontpic_DoAnim - -DropEnemySub: - ld a, [wEnemyMinimized] - and a - ld hl, BattleAnimCmd_MinimizeOpp - jr nz, GetEnemyMonFrontpic_DoAnim - ld a, [wCurPartySpecies] - push af - ld a, [wEnemyMonSpecies] - ld [wCurSpecies], a - ld [wCurPartySpecies], a - call GetBaseData - ld hl, wEnemyMonDVs - predef GetUnownLetter - ld de, vFrontPic - call LoadMonFrontSprite - pop af - ld [wCurPartySpecies], a - ret - -GetEnemyMonFrontpic_DoAnim: - ldh a, [hBattleTurn] - push af - ld a, 1 - ldh [hBattleTurn], a - ld a, BANK(BattleAnimCmd_RaiseSub) - call FarCall_hl - pop af - ldh [hBattleTurn], a - ret - -_LoadWildMons: - xor a - ld hl, wWildMons - ld bc, GRASS_WILDDATA_LENGTH - call ByteFill - ld a, [wMapGroup] - ld d, a - ld a, [wMapId] - ld e, a - ld bc, GRASS_WILDDATA_LENGTH - ld hl, GrassWildMons -.find - ld a, [hl] - cp -1 - ret z - cp d - jr nz, .got_map_group - inc hl - ld a, [hl] - dec hl - cp e - jr z, .got_map -.got_map_group - add hl, bc - jr .find -.got_map - inc hl - inc hl - ld de, wWildMons - ld bc, GRASS_WILDDATA_LENGTH - 2 - jp CopyBytes - -; Load nest landmarks into wTilemap[0,0] -FindNest: - hlcoord 0, 0 - ld bc, SCREEN_WIDTH * SCREEN_HEIGHT - xor a - call ByteFill - ld hl, GrassWildMons - decoord 0, 0 - -.FindGrass: - ld a, [hl] - cp -1 - jr z, .done - - push hl - ld b, a - inc hl - ld c, [hl] - call .SearchMapForMon - jr nc, .next_grass - - push de - call GetWorldMapLocation - call .AppendNest - pop de - jr c, .next_grass - ld [de], a - inc de - -.next_grass - pop hl - ld bc, GRASS_WILDDATA_LENGTH - add hl, bc - jr .FindGrass - -.done: - ret - -.SearchMapForMon: -rept 5 - inc hl -endr - ld a, NUM_GRASSMON * 3 - -.ScanMapLoop: - push af - ld a, [wNamedObjectIndexBuffer] - cp [hl] - jr z, .found - inc hl - inc hl - pop af - dec a - jr nz, .ScanMapLoop - and a - ret - -.found - pop af - scf - ret - -.AppendNest: - ld c, a - ld hl, wTileMap - ld de, SCREEN_WIDTH * SCREEN_HEIGHT -.AppendNestLoop: - ld a, [hli] - cp c - jr z, .found_nest - - dec de - ld a, e - or d - jr nz, .AppendNestLoop - - ld a, c - and a - ret - -.found_nest - scf - ret - -SECTION "engine/dumps/bank0f.asm@Function3ee3e", ROMX -Function3ee3e: - ld a, [wRepelEffect] - and a - jr z, asm_3ee4b - dec a - jp z, asm_3eeba - ld [wRepelEffect], a - -asm_3ee4b: - call sub_3eec8 - jr nc, asm_3eebd - call sub_3ef0e - ld c, a - ld b, 0 - ld hl, wWildMons - add hl, bc - ld a, [hl] - ld b, a - call Random - ldh a, [hRandomAdd] - cp b - jr nc, asm_3eebd - call Random - ld b, a - ld hl, Data3eedf - call sub_3ef0e - cp 1 - ld bc, 0 - jr c, asm_3ee7d - ld bc, 6 - jr z, asm_3ee7d - ld bc, $e - -asm_3ee7d: - add hl, bc - -asm_3ee7e: - call Random - cp $64 - jr nc, asm_3ee7e - ld b, a - ld c, 0 - -asm_3ee88: - ld a, [hli] - add c - ld c, a - cp b - jr nc, asm_3ee91 - inc hl - jr asm_3ee88 - -asm_3ee91: - ld c, [hl] - ld b, 0 - ld hl, wOTPartyMon1Moves + 1 - add hl, bc - ld a, [hli] - ld [wCurPartyLevel], a - ld a, [hl] - call sub_3ef03 - jr c, asm_3eebd - ld [wCurPartySpecies], a - ld [wTempEnemyMonSpecies], a - ld a, [wRepelEffect] - and a - jr z, asm_3eec1 - ld a, [wPartyMon1Level] - ld b, a - ld a, [wCurPartyLevel] - cp b - jr c, asm_3eebd - jr asm_3eec1 - -asm_3eeba: - ld [wRepelEffect], a - -asm_3eebd: - ld a, 1 - and a - ret - -asm_3eec1: - ld a, 1 - ld [wBattleMode], a - xor a - ret - -sub_3eec8: - ld a, [wPlayerTile] - ld hl, Data3eed5 - ld de, 1 - call FindItemInTable - ret - -Data3eed5: - db $8 - db $18 - db $28 - db $29 - db $48 - db $49 - db $4a - db $4b - db $4c - db -1 - -Data3eedf: - db $1 - db $0 - db $4 - db $2 - db $5 - db $4 - db $1 - db $6 - db $4 - db $8 - db $f - db $a - db $14 - db $c - db $5 - db $e - db $a - db $10 - db $14 - db $12 - db $f - db $14 - db $5 - db $16 - db $5 - db $18 - db $14 - db $1a - db $a - db $1c - db $5 - db $1e - db $4 - db $20 - db $1 - db $22 - -sub_3ef03: - and a - jr z, .return - cp $fc - jr nc, .return - and a - ret - -.return - scf - ret - -sub_3ef0e: - ld a, [wTimeOfDay] - inc a - and 3 - cp 3 - ret nz - dec a - ret - -Function3ef19: - ld a, [wOtherTrainerClass] - and a - jr nz, InitBattleCommon - ld a, [wTempWildMonSpecies] - and a - jr z, InitBattleCommon - ld [wCurPartySpecies], a - ld [wTempEnemyMonSpecies], a - -InitBattleCommon: - ld a, [wTimeOfDayPal] - push af - ld hl, wTextboxFlags - ld a, [hl] - push af - res TEXT_DELAY_F, [hl] - ldh a, [hMapAnims] - ld [wce26], a - call PlayBattleMusic - call ShowLinkBattleParticipants - call InitBattleVariables - ld a, [wOtherTrainerClass] - and a - jr nz, .asm_3ef4f - call sub_3efdb - jr _InitBattleCommon -.asm_3ef4f - call sub_3ef9a - -_InitBattleCommon: - ld b, 0 - call GetSGBLayout - ld hl, wStateFlags - res SPRITE_UPDATES_DISABLED_F, [hl] - call InitBattleDisplay - call BattleStartMessage - xor a - ldh [hBGMapMode], a - call PrintEmptyString - ld hl, $c335 - ld bc, $050a - call ClearBox - ld hl, $c2a1 - ld bc, $040a - call ClearBox - call ClearSprites - ld a, [wBattleMode] - cp 1 - call z, UpdateEnemyHUD - call StartBattle - call ExitBattle - pop af - ld [wTextboxFlags], a - pop af - ld [wTimeOfDayPal], a - ld a, [wce26] - ldh [hMapAnims], a - scf - ret - -sub_3ef9a: - ld [wTrainerClass], a - callfar GetTrainerAttributes - callfar ReadTrainerParty - ld a, [wTrainerClass] - cp 9 - jr nz, asm_3efb8 - xor a - ld [wOTPartyMon1Item], a - -asm_3efb8: - call sub_3f003 - xor a - ld [wTempEnemyMonSpecies], a - ldh [hGraphicStartTile], a - dec a - ld [wEnemyItemState], a - ld hl, $c2ac - ld bc, $0707 - predef PlaceGraphic - ld a, $ff - ld [wCurOTMon], a - ld a, 2 - ld [wBattleMode], a - ret - -sub_3efdb: - ld a, 1 - ld [wBattleMode], a - call LoadEnemyMon - ld hl, wEnemyMonDVs - predef GetUnownLetter - ld de, vFrontPic - call LoadMonFrontSprite - xor a - ld [wTrainerClass], a - ldh [hGraphicStartTile], a - ld hl, $c2ac - ld bc, $0707 - predef PlaceGraphic - ret - -sub_3f003: - ld a, [wEnemyTrainerGraphicsPointer] - ld e, a - ld a, [wEnemyTrainerGraphicsPointer + 1] - ld d, a - ld a, $12 - call UncompressSpriteFromDE - ld de, vFrontPic - ld a, $77 - ld c, a - jp LoadUncompressedSpriteData - -PlaceGraphic: - ld de, $14 - ld a, [wSpriteFlipped] - and a - jr nz, asm_3f033 - ldh a, [hGraphicStartTile] - -asm_3f024: - push bc - push hl - -asm_3f026: - ld [hl], a - add hl, de - inc a - dec c - jr nz, asm_3f026 - pop hl - inc hl - pop bc - dec b - jr nz, asm_3f024 - ret - -asm_3f033: - push bc - ld b, 0 - dec c - add hl, bc - pop bc - ldh a, [hGraphicStartTile] - -asm_3f03b: - push bc - push hl - -asm_3f03d: - ld [hl], a - add hl, de - inc a - dec c - jr nz, asm_3f03d - pop hl - dec hl - pop bc - dec b - jr nz, asm_3f03b - ret - -LoadMonBackPic: - ld a, [wTempBattleMonSpecies] - ld [wCurPartySpecies], a - hlcoord 1, 5 - ld b, 7 - ld c, 8 - call ClearBox - ld hl, wMonHBackSprite - wMonHeader - call UncompressMonSprite - ld hl, vBackPic - predef_jump GetMonBackpic - -Function3f068: - ld de, $a203 - ld hl, $a187 - call sub_3f0a5 - call sub_3f07d - ld de, $a38b - ld hl, $a30f - call sub_3f0a5 - -sub_3f07d: - ld b, 3 -asm_3f07f: - ld c, $1c -asm_3f081: - push bc - ld a, [de] - ld bc, $ffc9 - call sub_3f0bf - ld a, [de] - dec de - swap a - ld bc, $37 - call sub_3f0bf - pop bc - dec c - jr nz, asm_3f081 - dec de - dec de - dec de - dec de - ld a, b - ld bc, $ffc8 - add hl, bc - ld b, a - dec b - jr nz, asm_3f07f - ret - -sub_3f0a5: - ld a, $1c - ldh [hTextBoxCursorBlinkInterval], a - ld bc, $ffff - -asm_3f0ac: - ld a, [de] - dec de - swap a - call sub_3f0bf - ldh a, [hTextBoxCursorBlinkInterval] - dec a - ldh [hTextBoxCursorBlinkInterval], a - jr nz, asm_3f0ac - dec de - dec de - dec de - dec de - ret - -sub_3f0bf: - push hl - and $f - ld hl, Data3f0d0 - add l - ld l, a - jr nc, asm_3f0ca - inc h - -asm_3f0ca: - ld a, [hl] - pop hl - ld [hld], a - ld [hl], a - add hl, bc - ret - -Data3f0d0: - db $0 - db $3 - db $c - db $f - db $30 - db $33 - db $3c - db $3f - db $c0 - db $c3 - db $cc - db $cf - db $f0 - db $f3 - db $fc - db $ff - -InitBattleVariables: - xor a - ld [wFieldMoveSucceeded], a - ld [wBattleResult], a - ld hl, wcd3c - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wMenuScrollPosition], a - ld [wCriticalHit], a - ld [wBattleMonSpecies], a - ld [wBattleParticipantsNotFainted], a - ld [wCurBattleMon], a - ld [wBattleEnded], a - ld [wTimeOfDayPal], a - ld [wEnemyTurnsTaken], a - ld hl, wPlayerHPPal - ld [hli], a - ld [hl], a - ld hl, wBattleMonDVs - ld [hli], a - ld [hl], a - ld hl, wEnemyMonDVs - ld [hli], a - ld [hl], a - ld hl, wEnemyMoveStruct - ld bc, $012c - xor a - call ByteFill - call ClearWindowData - ld hl, hBGMapAddress - xor a - ld [hli], a - ld [hl], HIGH(vBGMap0) - ld a, $a3 - ldh [rLCDC], a - ld a, [wMapId] - cp $d9 ; SAFARI_ZONE_EAST - jr c, .return - cp $dd ; SAFARI_ZONE_CENTER_REST_HOUSE - jr nc, .return - ld a, 2 - ld [wBattleType], a -.return - ret - -ExitBattle: - call IsLinkBattle - jr nz, .HandleEndOfBattle - call ShowLinkBattleParticipantsAfterEnd - jr .CheckEvolution - -.HandleEndOfBattle - ld a, [wBattleResult] - and a - jr nz, .CleanUpBattleRAM - ; WIN - call CheckPayDay - -.CheckEvolution - xor a - ld [wForceEvolution], a - predef EvolveAfterBattle - -.CleanUpBattleRAM: - xor a - ld [wLowHealthAlarmBuffer], a - ld [wBattleMode], a - ld [wBattleType], a - ld [wAttackMissed], a - ld [wTempWildMonSpecies], a - ld [wOtherTrainerClass], a - ld [wce38], a - ld [wce39], a - ld [wBattleEnded], a - ld hl, wcd3c - ld [hli], a - ld [hli], a - ld [hli], a - ld [hl], a - ld [wMenuScrollPosition], a - ld hl, wPlayerSubStatus1 - ld b, wEnemyFuryCutterCount - wPlayerSubStatus1 -.loop - ld [hli], a - dec b - jr nz, .loop - ld hl, wd4a7 - set 0, [hl] - call WaitSFX - - ld a, $e3 - ldh [rLCDC], a - ld hl, wd14f - res 7, [hl] - call ClearPalettes - ret - -CheckPayDay: - ld hl, wPayDayMoney - ld a, [hli] - or [hl] - inc hl - or [hl] - ret z - - ld a, [wBattleMonItem] - ld b, a - callfar GetItemHeldEffect - ld a, b - cp HELD_AMULET_COIN - jr nz, AddBattleMoneyToAccount - - ld hl, wPayDayMoney + 2 - sla [hl] - dec hl - rl [hl] - dec hl - rl [hl] - jr nc, AddBattleMoneyToAccount - - ld a, $ff - ld [hli], a - ld [hli], a - ld [hl], a - -AddBattleMoneyToAccount: - ld hl, wPayDayMoney + 2 - ld de, wMoney + 2 - ld c, 3 - and a -.loop - ld a, [de] - adc [hl] - ld [de], a - dec de - dec hl - dec c - jr nz, .loop - ld hl, BattleText_PlayerPickedUpPayDayMoney - call PrintText - ret - -BattleText_PlayerPickedUpPayDayMoney: - text "は @" - deciram wPayDayMoney, 3, 6 - text "円" - line "ひろった!" - prompt - -ShowLinkBattleParticipantsAfterEnd: - ld a, [wCurOTMon] - ld hl, wOTPartyMon1Status - ld bc, PARTYMON_STRUCT_LENGTH - call AddNTimes - ld a, [wEnemyMonStatus] - ld [hl], a - call ClearTileMap - call _ShowLinkBattleParticipants - ld a, [wBattleResult] - cp LOSE - ld de, WonAgainstText - jr c, .store_result - ld de, LostAgainstText - jr z, .store_result - ld de, TiedAgainstText - -.store_result - hlcoord 6, 8 - call PlaceString - ld c, 200 - call DelayFrames - ret - -WonAgainstText: - db "あなたの かち@" - -LostAgainstText: - db "あなたの まけ@" - -TiedAgainstText: - db "  ひきわけ@" - -PlayBattleMusic: - push hl - push de - push bc - xor a - ld [wMusicFade], a - ld de, 0 - call PlayMusic - call DelayFrame - call MaxVolume -; plays vs. gym leader music regardless of the battle type - ld de, MUSIC_LEADER_BATTLE - call PlayMusic - pop bc - pop de - pop hl - ret - -InitBattleDisplay: - call InitBackPic - ld hl, $c390 - ld b, 4 - ld c, $12 - call DrawTextBox - ld hl, $c305 - ld bc, $0307 - call ClearBox - call DisableLCD - call LoadFont - call Call_LoadBattleFontsHPBar - ld hl, vBGMap0 - ld bc, $0400 - ld a, $7f - call ByteFill - call LoadMapTimeOfDay.PushAttrMap - call EnableLCD - xor a - ldh [hMapAnims], a - ldh [hSCY], a - ld a, $90 - ldh [hWY], a - ldh [rWY], a - call WaitBGMap - xor a - ldh [hBGMapMode], a - call BattleIntroSlidingPics - ld a, 1 - ldh [hBGMapMode], a - ld a, $31 - ldh [hGraphicStartTile], a - ld hl, $c31a - ld bc, $0606 - predef PlaceGraphic - xor a - ldh [hWY], a - ldh [rWY], a - call WaitBGMap - ld b, 1 - call GetSGBLayout - call HideSprites - ld a, $90 - ldh [hWY], a - xor a - ldh [hSCX], a - ret - - -BattleIntroSlidingPics: - ld b, $70 - ld c, $90 - ld a, c - ldh [hSCX], a - call DelayFrame - ld a, $e4 - ldh [rBGP], a - ldh [rOBP0], a - ldh [rOBP1], a -.loop1 - push bc - ld h, b - ld l, $40 - call .Subfunction2 - ld h, 0 - ld l, $60 - call .Subfunction2 - call .Subfunction1 - pop bc - ld a, c - ldh [hSCX], a - inc b - inc b - dec c - dec c - jr nz, .loop1 - ret - -.Subfunction1: - push bc - ld hl, wShadowOAMSprite00XCoord - ld c, $12 - ld de, 4 -.loop2 - dec [hl] - dec [hl] - add hl, de - dec c - jr nz, .loop2 - pop bc - ret - -.Subfunction2: -.loop3 - ldh a, [rLY] - cp l - jr nz, .loop3 - ld a, h - ldh [rSCX], a -.loop4 - ldh a, [rLY] - cp h - jr z, .loop4 - ret - -InitBackPic: - ld de, PlayerBacksprite - ld a, BANK(PlayerBacksprite) - call UncompressSpriteFromDE - ld hl, vTitleLogo2 - predef GetMonBackpic - ld a, 0 - call OpenSRAM - ld hl, vSprites - ld de, sSpriteBuffer1 - ldh a, [hROMBank] - ld b, a - ld c, 7 * 7 - call Request2bpp - call CloseSRAM - call LoadTrainerBackpicAsOAM - ld a, $31 - ldh [hGraphicStartTile], a - ld hl, $c31a - ld bc, $0606 - predef PlaceGraphic - ret - -LoadTrainerBackpicAsOAM: - ld hl, wShadowOAMSprite00 - xor a - ldh [hTextBoxCursorBlinkInterval], a - ld b, 6 - ld e, $a8 - -.outer_loop - ld c, 3 - ld d, $40 - -.inner_loop - ld [hl], d - inc hl - ld [hl], e - inc hl - ldh a, [hTextBoxCursorBlinkInterval] - ld [hli], a - inc a - ldh [hTextBoxCursorBlinkInterval], a - inc hl - ld a, d - add 8 - ld d, a - dec c - jr nz, .inner_loop - ldh a, [hTextBoxCursorBlinkInterval] - add 3 - ldh [hTextBoxCursorBlinkInterval], a - ld a, e - add 8 - ld e, a - dec b - jr nz, .outer_loop - ret - -PlayerBacksprite: -INCBIN "gfx/trainer/protagonist_back.pic" - -Unused_OldManBacksprite: -INCBIN "gfx/trainer/oldman_back.pic" - -BattleStartMessage: - ld a, [wBattleMode] - dec a - jr z, .wild - ld de, SFX_SHINE - call PlaySFX - call WaitSFX - ld c, 20 - call DelayFrames - callfar Battle_GetTrainerName - ld hl, WantsToBattleText - jr .PlaceBattleStartText - -.wild - ld a, $f - ld [wCryTracks], a - ld a, [wTempEnemyMonSpecies] - call PlayStereoCry - ld hl, WildPokemonAppearedText - ld a, [wAttackMissed] - and a - jr z, .PlaceBattleStartText - ld hl, HookedPokemonAttackedText - -.PlaceBattleStartText: - push hl - callfar BattleStart_TrainerHuds - pop hl - call PrintText - ret - -WildPokemonAppearedText: - text "あ! やせいの" - line "@" - text_from_ram wEnemyMonNickname - text "が とびだしてきた!" - prompt - -HookedPokemonAttackedText: - text "つりあげた @" - text_from_ram wEnemyMonNickname - text "が" - line "とびかかってきた!" - prompt - -WantsToBattleText: - text_from_ram wOTClassName - text "の @" - text_from_ram wStringBuffer1 - text "が" - line "しょうぶを しかけてきた!" - prompt - -ShowLinkBattleParticipants: - call IsLinkBattle - jr nz, .ok - call _ShowLinkBattleParticipants - call ClearTileMap -.ok - call DelayFrame - predef DoBattleTransition - call Call_LoadBattleFontsHPBar - ld a, 1 - ldh [hBGMapMode], a - call ClearSprites - call ClearTileMap - xor a - ldh [hBGMapMode], a - ldh [hWY], a - ldh [rWY], a - ldh [hMapAnims], a - ret - -_ShowLinkBattleParticipants: - call LoadFontExtra - hlcoord 3, 4 - ld b, 7 - ld c, 12 - call DrawTextBox - hlcoord 4, 6 - ld de, wPlayerName - call PlaceString - hlcoord 4, 10 - ld de, wOTPlayerName - call PlaceString - hlcoord 9, 8 - ld a, "V" - ld [hli], a - ld [hl], "S" - callfar LinkBattle_TrainerHuds - ld c, 150 - jp DelayFrames - -IsLinkBattle: - push bc - push af - ld a, [wLinkMode] - cp 3 - pop bc - ld a, b - pop bc - ret - diff --git a/engine/dumps/bank14.asm b/engine/dumps/bank14.asm index b9d4817..fb593e5 100644 --- a/engine/dumps/bank14.asm +++ b/engine/dumps/bank14.asm @@ -1074,12 +1074,12 @@ OpenPartyMenu:: ld [w2DMenuNumRows], a ld b, a - ld a, [wce38] + ld a, [wFailedToFlee] and a ld a, $03 jr z, .asm_507b4 - xor a - ld [wce38], a + xor a ; FALSE + ld [wFailedToFlee], a ld a, $01 .asm_507b4 ld [wMenuJoypadFilter], a diff --git a/engine/overworld/wildmons.asm b/engine/overworld/wildmons.asm new file mode 100644 index 0000000..3641bed --- /dev/null +++ b/engine/overworld/wildmons.asm @@ -0,0 +1,264 @@ +INCLUDE "constants.asm" + +SECTION "engine/overworld/wildmons.asm", ROMX + +_LoadWildMonData:: + xor a + ld hl, wWildMonData + ld bc, GRASS_WILDDATA_LENGTH + call ByteFill + ld a, [wMapGroup] + ld d, a + ld a, [wMapId] + ld e, a + ld bc, GRASS_WILDDATA_LENGTH + ld hl, GrassWildMons +.find + ld a, [hl] + cp -1 + ret z + cp d + jr nz, .got_map_group + inc hl + ld a, [hl] + dec hl + cp e + jr z, .got_map +.got_map_group + add hl, bc + jr .find +.got_map + inc hl + inc hl + ld de, wWildMonData + ld bc, GRASS_WILDDATA_LENGTH - 2 + jp CopyBytes + +; Load nest landmarks into wTilemap[0,0] +FindNest: + hlcoord 0, 0 + ld bc, SCREEN_WIDTH * SCREEN_HEIGHT + xor a + call ByteFill + ld hl, GrassWildMons + decoord 0, 0 + +.FindGrass: + ld a, [hl] + cp -1 + jr z, .done + + push hl + ld b, a + inc hl + ld c, [hl] + call .SearchMapForMon + jr nc, .next_grass + + push de + call GetWorldMapLocation + call .AppendNest + pop de + jr c, .next_grass + ld [de], a + inc de + +.next_grass + pop hl + ld bc, GRASS_WILDDATA_LENGTH + add hl, bc + jr .FindGrass + +.done: + ret + +.SearchMapForMon: +rept 5 + inc hl +endr + ld a, NUM_GRASSMON + +.ScanMapLoop: + push af + ld a, [wNamedObjectIndexBuffer] + cp [hl] + jr z, .found + inc hl + inc hl + pop af + dec a + jr nz, .ScanMapLoop + and a + ret + +.found + pop af + scf + ret + +.AppendNest: + ld c, a + ld hl, wTileMap + ld de, SCREEN_WIDTH * SCREEN_HEIGHT +.AppendNestLoop: + ld a, [hli] + cp c + jr z, .found_nest + + dec de + ld a, e + or d + jr nz, .AppendNestLoop + + ld a, c + and a + ret + +.found_nest + scf + ret + +INCLUDE "data/wild/grassmons.inc" + +TryWildBattle:: +; If there is no active Repel, there's no need to be here. + ld a, [wRepelEffect] + and a + jr z, .encounter + + dec a + jp z, .repel_wore_off + ld [wRepelEffect], a + +.encounter + call .CheckGrassCollision + jr nc, .no_battle + +; Get encounter rate for the time of day. + call WildMon_GetTimeOfDay + ld c, a + ld b, 0 + ld hl, wWildMonData + add hl, bc + ld a, [hl] + ld b, a + + call Random + ldh a, [hRandomAdd] + cp b + jr nc, .no_battle + + call Random + ld b, a + ld hl, GrassMonProbTable + + call WildMon_GetTimeOfDay + cp NITE_F + ld bc, 0 + jr c, .got_time + ld bc, GRASS_WILDDATA_DAYBLOCK_START * 2 + jr z, .got_time + ld bc, GRASS_WILDDATA_NITEBLOCK_START * 2 + +.got_time + add hl, bc + +.random_loop + call Random + cp 100 + jr nc, .random_loop + ld b, a + ld c, 0 + +.prob_bracket_loop + ld a, [hli] + add c + ld c, a + cp b + jr nc, .got_it + inc hl + jr .prob_bracket_loop + +.got_it + ld c, [hl] + ld b, 0 + ld hl, wWildMons + add hl, bc + ld a, [hli] + ld [wCurPartyLevel], a + ld a, [hl] + call ValidateTempWildMonSpecies + jr c, .no_battle + + ld [wCurPartySpecies], a + ld [wTempEnemyMonSpecies], a + ld a, [wRepelEffect] + and a + jr z, .ok + + ld a, [wPartyMon1Level] + ld b, a + ld a, [wCurPartyLevel] + cp b + jr c, .no_battle + + jr .ok + +.repel_wore_off + ld [wRepelEffect], a + +.no_battle + ld a, 1 + and a + ret + +.ok + ld a, WILD_BATTLE + ld [wBattleMode], a + xor a + ret + +.CheckGrassCollision: + ld a, [wPlayerTile] + ld hl, .blocks + ld de, 1 + call FindItemInTable + ret + +.blocks + db COLLISION_08 + db COLLISION_GRASS + db COLLISION_WATER_28 + db COLLISION_WATER + db COLLISION_48 + db COLLISION_49 + db COLLISION_4A + db COLLISION_4B + db COLLISION_4C + db -1 + +INCLUDE "data/wild/probabilities.inc" + +; This actually works as intended in the proto! +; In the final game, due to a development oversight, +; this function is called with the wild Pokemon's level, not its species, in a. +ValidateTempWildMonSpecies: + and a + jr z, .nowildmon ; = 0 + cp NUM_POKEMON + 1 ; 252 + jr nc, .nowildmon ; >= 252 + and a ; 1 <= Species <= 251 + ret + +.nowildmon + scf + ret + +WildMon_GetTimeOfDay: + ld a, [wTimeOfDay] + inc a + maskbits NUM_DAYTIMES + cp MORN_F + ret nz + dec a + ret diff --git a/home/copy.asm b/home/copy.asm index a1549a5..e7b08a1 100644 --- a/home/copy.asm +++ b/home/copy.asm @@ -78,12 +78,14 @@ UncompressSpriteFromDE:: ld [hl], d jp UncompressSpriteData +; TODO: Rename to LoadTilemapToTempTilemap BackUpTilesToBuffer:: hlcoord 0, 0 decoord 0, 0, wTileMapBackup ld bc, SCREEN_HEIGHT * SCREEN_WIDTH jp CopyBytes +; TODO: Rename to SafeLoadTempTilemapToTilemap ReloadTilesFromBuffer:: xor a ldh [hBGMapMode], a diff --git a/home/map.asm b/home/map.asm index 725ef73..db40030 100644 --- a/home/map.asm +++ b/home/map.asm @@ -299,7 +299,7 @@ MapSetup_Reload:: ld [wMusicFade], a ld b, 9 ; TODO: constantify this call GetSGBLayout - call LoadWildMons + call LoadWildMonData call FadeIn ret @@ -345,7 +345,7 @@ MapSetup_Continue:: ld [wMusicFade], a ld b, 9 ; TODO: constantify this call GetSGBLayout - call LoadWildMons + call LoadWildMonData call Function242c ; TODO call FadeIn ret @@ -373,7 +373,7 @@ MapSetup_Warp:: call PlayMapMusic ld b, 9 ; TODO: constantify this call GetSGBLayout - call LoadWildMons + call LoadWildMonData call FadeIn call Function2407 ; TODO ret @@ -419,8 +419,8 @@ LoadMapTimeOfDay:: jr nz, .row ret -LoadWildMons:: - callfar _LoadWildMons +LoadWildMonData:: + callfar _LoadWildMonData ret LoadGraphics:: @@ -484,7 +484,7 @@ MapSetup_Connection:: call FadeToMapMusic ld b, 9 ; TODO: constantify this call GetSGBLayout - call LoadWildMons + call LoadWildMonData scf ret diff --git a/home/misc_32c8.asm b/home/misc_32c8.asm index 895d239..770fe86 100644 --- a/home/misc_32c8.asm +++ b/home/misc_32c8.asm @@ -2,7 +2,7 @@ INCLUDE "constants.asm" SECTION "home/misc_32c8.asm@Unknown 32c8", ROM0 -Function32c8:: +Call_GetItemAmount:: predef GetItemAmount ld a, b and a diff --git a/home/tilemap.asm b/home/tilemap.asm index 4230a6f..6f85f8a 100644 --- a/home/tilemap.asm +++ b/home/tilemap.asm @@ -22,6 +22,7 @@ WaitBGMap:: call DelayFrames ret +; TODO: Change to SetDefaultBGPAndOBP SetPalettes:: ld a, %11100100 ldh [rBGP], a diff --git a/home/unknown_388f.asm b/home/unknown_388f.asm index cb91215..bad5628 100644 --- a/home/unknown_388f.asm +++ b/home/unknown_388f.asm @@ -50,7 +50,7 @@ TestWildBattleStart:: ret z ; if no directions are down, don't try and trigger a wild encounter call CheckBPressedDebug jp nz, xor_a ; if b button is down, clear acc - callfar Function3ee3e + callfar TryWildBattle ld a, [wBattleMode] and a ret z ; if no battle, return @@ -60,7 +60,7 @@ TestWildBattleStart:: ret OverworldLoop_StartBattle:: - predef Function3ef19 + predef StartBattle ld a, $f3 ldh [hMapEntryMethod], a ld hl, wd4a9 diff --git a/home/util.asm b/home/util.asm index 136c111..5af8a70 100644 --- a/home/util.asm +++ b/home/util.asm @@ -70,7 +70,7 @@ AddNTimes:: jr nz, .loop ret -memcmp:: ; TODO: rename +CompareBytes:: ; Compare c bytes at hl and de ; Returns z if all equal, nz otherwise. .loop: diff --git a/layout.link b/layout.link index 8f23bb2..523c33f 100644 --- a/layout.link +++ b/layout.link @@ -280,11 +280,9 @@ ROMX $0e ROMX $0f org $4000 - "engine/dumps/bank0f.asm@StartBattle" - "engine/battle/core.asm" - "engine/dumps/bank0f.asm@PlayMoveAnimation" - "data/wild.asm" - "engine/dumps/bank0f.asm@Function3ee3e" + "engine/battle/core.asm@DoBattle" + "engine/overworld/wildmons.asm" + "engine/battle/core.asm@StartBattle" ROMX $10 org $4000 diff --git a/ram/wram.asm b/ram/wram.asm index 02e70bd..7ad7d69 100644 --- a/ram/wram.asm +++ b/ram/wram.asm @@ -626,8 +626,7 @@ wEnemyEvaLevel:: db wForceEvolution:: db -wAILayer2Encouragement:: -wEnemyTurnsTaken:: ds 1 +wEnemyTurnsTaken:: db ds 1 @@ -639,10 +638,8 @@ wPlayerDebugSelectedMove:: ds 1 wMoveSelectionMenuType:: ds 1 -; TODO: Replace these with just wCurPlayer/EnemyMove -; and replace the original wCurPlayerMove/wCurEnemyMove with wLastPlayer/EnemyCounterMove -wCurPlayerSelectedMove:: db -wCurEnemySelectedMove:: db +wCurPlayerMove:: db +wCurEnemyMove:: db wLinkBattleRNCount:: db @@ -661,27 +658,21 @@ wcacb:: ds 1 wcacc:: ds 1 ENDU -wcacd:: ds 1 -wcace:: ds 1 +wUnused_SafariEscapeFactor:: db +wUnused_SafariBaitFactor:: db ds 1 wEnemyBackupDVs:: dw -wAlreadyDisobeyed:: -wcad2:: ds 1 +wAlreadyDisobeyed:: db -wDisabledMove:: ds 1 -wEnemyDisabledMove:: ds 1 -wcad5:: ds 1 +wDisabledMove:: db +wEnemyDisabledMove:: db +wWhichMonFaintedFirst:: db -UNION -wCurPlayerMove:: ds 1 -wCurEnemyMove:: ds 1 -NEXTU -wcad6:: ds 1 -wcad7:: ds 1 -ENDU +wLastPlayerCounterMove:: db +wLastEnemyCounterMove:: db wEnemyMinimized:: db wAlreadyFailed:: db @@ -690,11 +681,8 @@ wBattleParticipantsIncludingFainted:: db wBattleLowHealthAlarm:: db wPlayerMinimized:: db -wPlayerScreens:: -wcadd:: db - -wEnemyScreens:: -wcade:: db +wPlayerScreens:: db +wEnemyScreens:: db wPlayerSafeguardCount:: db wEnemySafeguardCount:: db @@ -710,6 +698,7 @@ ENDU SECTION "CB14", WRAM0[$CB14] +wBattleEnd:: UNION wRedrawRowOrColumnSrcTiles:: @@ -730,7 +719,8 @@ ENDU SECTION "CB56", WRAM0[$CB4C] UNION wOtherPlayerLinkMode:: db -wOtherPlayerLinkAction:: db +wOtherPlayerLinkAction:: +wBattleAction:: db ds 3 ; TODO wPlayerLinkAction:: db @@ -1064,6 +1054,11 @@ wHPBarTempHP:: dw NEXTU wStringBuffer2:: ds STRING_BUFFER_LENGTH +NEXTU + + ds 2 +wGainBoostedExp:: db + NEXTU wcd31:: db @@ -1074,7 +1069,6 @@ ENDU SECTION "CD3C", WRAM0[$CD3C] -wcd3c:: wPartyMenuCursor:: wBillsPCCursor:: db wRegularItemsCursor:: db @@ -1087,8 +1081,7 @@ wCurMoveNum:: db wCurBattleMon:: db wTMHolderCursor:: db -wFieldDebugMenuCursorBuffer:: -wcd43:: db +wFieldDebugMenuCursorBuffer:: db wRegularItemsScrollPosition:: db wBackpackAndKeyItemsScrollPosition:: db wBillsPCScrollPosition:: db @@ -1198,6 +1191,7 @@ wPrevWarp:: db wEvolvableFlags:: db UNION +wBoostExpByExpAll:: wSkipMovesBeforeLevelUp:: wListMovesLineSpacing:: wFieldMoveScriptID:: db @@ -1278,14 +1272,15 @@ wTempBattleMonSpecies:: ds 1 wEnemyMon:: battle_struct wEnemyMon wEnemyMonBaseStats:: ds NUM_EXP_STATS - wEnemyMonCatchRate:: db -wcdff:: ds 1 +wEnemyMonBaseExp:: db +wEnemyMonEnd:: + wBattleMode:: db wTempWildMonSpecies:: ds 1 wOtherTrainerClass:: ds 1 wBattleType:: db -wce04:: ds 1 +wUnused_GymLeaderNo:: ds 1 ; Unused wOtherTrainerID:: ds 1 wBattleEnded:: ds 1 @@ -1354,7 +1349,7 @@ wMonHLearnset:: wMonHeaderEnd:: -wce26:: ds 1 +wMapAnimsBackup:: db ds 2 @@ -1388,10 +1383,8 @@ wApplyStatLevelMultipliersToEnemy:: wce37:: db -wce38:: ds 1 - -wNumFleeAttempts:: -wce39:: ds 1 +wFailedToFlee:: db +wNumFleeAttempts:: db wMonTriedToEvolve:: db @@ -1840,8 +1833,16 @@ wOTPartySpeciesEnd:: db SECTION "Wild mon buffer", WRAM0[$D91B] UNION -wWildMons:: - ds 41 +wWildMonData:: + +wMornEncounterRate:: db +wDayEncounterRate:: db +wNiteEncounterRate:: db + +wWildMons:: ds NUM_GRASSMON * 2 + + ds 2 + NEXTU wOTPartyMons:: ; wOTPartyMon1 - wOTPartyMon6