2014-05-22 22:13:20 +00:00
BattleCore:
; These are move effects (second value from the Moves table in bank $E).
2016-06-12 00:24:04 +00:00
ResidualEffects1:
2015-01-31 17:26:05 +00:00
; most non-side effects
2014-05-22 22:13:20 +00:00
db CONVERSION_EFFECT
db HAZE_EFFECT
db SWITCH_AND_TELEPORT_EFFECT
db MIST_EFFECT
db FOCUS_ENERGY_EFFECT
db CONFUSION_EFFECT
db HEAL_EFFECT
db TRANSFORM_EFFECT
db LIGHT_SCREEN_EFFECT
db REFLECT_EFFECT
db POISON_EFFECT
db PARALYZE_EFFECT
db SUBSTITUTE_EFFECT
db MIMIC_EFFECT
db LEECH_SEED_EFFECT
db SP LASH_EFFECT
db - 1
2016-06-12 00:24:04 +00:00
SetDamageEffects:
2014-05-22 22:13:20 +00:00
; moves that do damage but not through normal calculations
; e.g., Super Fang, Psywave
db SUPER_FANG_EFFECT
db SP ECIAL_DAMAGE_EFFECT
db - 1
2016-06-12 00:24:04 +00:00
ResidualEffects2:
2015-01-31 17:26:05 +00:00
; non-side effects not included in ResidualEffects1
2015-01-04 16:47:21 +00:00
; stat-affecting moves, sleep-inflicting moves, and Bide
2014-05-22 22:13:20 +00:00
; e.g., Meditate, Bide, Hypnosis
db $ 01
db ATTACK_UP1_EFFECT
db DEFENSE_UP1_EFFECT
db SP EED_UP1_EFFECT
db SP ECIAL_UP1_EFFECT
db ACCURACY_UP1_EFFECT
db EVASION_UP1_EFFECT
db ATTACK_DOWN1_EFFECT
db DEFENSE_DOWN1_EFFECT
db SP EED_DOWN1_EFFECT
db SP ECIAL_DOWN1_EFFECT
db ACCURACY_DOWN1_EFFECT
db EVASION_DOWN1_EFFECT
db BIDE_EFFECT
db SLEEP_EFFECT
db ATTACK_UP2_EFFECT
db DEFENSE_UP2_EFFECT
db SP EED_UP2_EFFECT
db SP ECIAL_UP2_EFFECT
db ACCURACY_UP2_EFFECT
db EVASION_UP2_EFFECT
db ATTACK_DOWN2_EFFECT
db DEFENSE_DOWN2_EFFECT
db SP EED_DOWN2_EFFECT
db SP ECIAL_DOWN2_EFFECT
db ACCURACY_DOWN2_EFFECT
db EVASION_DOWN2_EFFECT
db - 1
2016-06-12 00:24:04 +00:00
AlwaysHappenSideEffects:
2014-05-22 22:13:20 +00:00
; Attacks that aren't finished after they faint the opponent.
db DRAIN_HP_EFFECT
db EXPLODE_EFFECT
db DREAM_EATER_EFFECT
db PAY_DAY_EFFECT
db TWO_TO_FIVE_ATTACKS_EFFECT
db $ 1 E
db ATTACK_TWICE_EFFECT
db RECOIL_EFFECT
db TWINEEDLE_EFFECT
db RAGE_EFFECT
db - 1
2016-06-12 00:24:04 +00:00
SpecialEffects:
2015-01-04 16:47:21 +00:00
; Effects from arrays 2, 4, and 5B, minus Twineedle and Rage.
2015-01-23 03:05:13 +00:00
; Includes all effects that do not need to be called at the end of
2015-01-04 16:47:21 +00:00
; ExecutePlayerMove (or ExecuteEnemyMove), because they have already been handled
2014-05-22 22:13:20 +00:00
db DRAIN_HP_EFFECT
db EXPLODE_EFFECT
db DREAM_EATER_EFFECT
db PAY_DAY_EFFECT
db SWIFT_EFFECT
db TWO_TO_FIVE_ATTACKS_EFFECT
db $ 1 E
db CH ARGE_EFFECT
db SUPER_FANG_EFFECT
db SP ECIAL_DAMAGE_EFFECT
db FLY_EFFECT
db ATTACK_TWICE_EFFECT
db JUMP_KICK_EFFECT
db RECOIL_EFFECT
; fallthrough to Next EffectsArray
2016-06-12 00:24:04 +00:00
SpecialEffectsCont:
2015-01-04 16:47:21 +00:00
; damaging moves whose effect is executed prior to damage calculation
2014-05-22 22:13:20 +00:00
db THRASH_PETAL_DANCE_EFFECT
db TRAPPING_EFFECT
db - 1
2016-06-12 00:24:04 +00:00
SlidePlayerAndEnemySilhouettesOnScreen:
2014-08-09 05:39:13 +00:00
call LoadPlayerBackPic
2015-02-07 20:27:36 +00:00
ld a , MESSAGE_BOX ; the usual text box at the bottom of the screen
2015-02-07 10:43:08 +00:00
ld [ wTextBoxID ], a
2014-05-22 22:13:20 +00:00
call Di sp layTextBoxID
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-08-05 21:20:29 +00:00
lb bc , 3 , 7
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
call Di sableLCD
call LoadFontTilePatterns
2014-08-09 05:39:13 +00:00
call LoadHudAndHpBarAndStatusTilePatterns
2014-05-29 08:31:46 +00:00
ld hl , vBGMap0
2014-05-22 22:13:20 +00:00
ld bc , $ 400
2014-08-09 05:39:13 +00:00
.clearBackgroundLoop
2015-08-05 21:20:29 +00:00
ld a , " "
2014-05-22 22:13:20 +00:00
ld [ hli ], a
dec bc
ld a , b
or c
2014-08-09 05:39:13 +00:00
jr nz , .clearBackgroundLoop
; copy the work RAM tile map to VRAM
2015-07-18 20:52:03 +00:00
coord hl , 0 , 0
2014-05-29 08:31:46 +00:00
ld de , vBGMap0
2014-08-09 05:39:13 +00:00
ld b , 18 ; number of rows
.copyRowLoop
ld c , 20 ; number of columns
.copyColumnLoop
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc e
dec c
2014-08-09 05:39:13 +00:00
jr nz , .copyColumnLoop
ld a , 12 ; number of off screen tiles to the right of screen in VRAM
add e ; skip the off screen tiles
2014-05-22 22:13:20 +00:00
ld e , a
2014-08-09 05:39:13 +00:00
jr nc , .noCarry
2014-05-22 22:13:20 +00:00
inc d
2014-08-09 05:39:13 +00:00
.noCarry
2014-05-22 22:13:20 +00:00
dec b
2014-08-09 05:39:13 +00:00
jr nz , .copyRowLoop
2014-05-22 22:13:20 +00:00
call EnableLCD
ld a , $ 90
2014-09-23 22:02:03 +00:00
ld [ hWY ], a
2014-08-09 05:39:13 +00:00
ld [ rWY ], a
2014-05-22 22:13:20 +00:00
xor a
2014-09-14 18:29:18 +00:00
ld [ hTilesetType ], a
2014-09-23 22:02:03 +00:00
ld [ hSCY ], a
2014-05-22 22:13:20 +00:00
dec a
2014-09-13 07:50:56 +00:00
ld [ wUpdateSpritesEnabled ], a
2014-05-22 22:13:20 +00:00
call Delay3
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
ld b , $ 70
ld c , $ 90
ld a , c
2014-09-23 22:02:03 +00:00
ld [ hSCX ], a
2014-05-22 22:13:20 +00:00
call DelayFrame
2014-08-09 05:39:13 +00:00
ld a , % 11100100 ; inverted palette for silhouette effect
ld [ rBGP ], a
ld [ rOBP0 ], a
ld [ rOBP1 ], a
.slideSilhouettesLoop ; slide silhouettes of the player's pic and the enemy's pic onto the screen
2014-05-22 22:13:20 +00:00
ld h , b
ld l , $ 40
2014-08-09 05:39:13 +00:00
call SetScrollXForSlidingPlayerBodyLeft ; begin background scrolling on line $40
2014-05-22 22:13:20 +00:00
inc b
inc b
ld h , $ 0
ld l , $ 60
2014-08-09 05:39:13 +00:00
call SetScrollXForSlidingPlayerBodyLeft ; end background scrolling on line $60
call SlidePlayerHeadLeft
2014-05-22 22:13:20 +00:00
ld a , c
2014-09-23 22:02:03 +00:00
ld [ hSCX ], a
2014-05-22 22:13:20 +00:00
dec c
dec c
2014-08-09 05:39:13 +00:00
jr nz , .slideSilhouettesLoop
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
ld a , $ 31
2015-07-24 03:48:35 +00:00
ld [ hStartTileID ], a
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-07-03 19:37:53 +00:00
predef CopyUncompressedPicToTilemap
2014-05-22 22:13:20 +00:00
xor a
2014-09-23 22:02:03 +00:00
ld [ hWY ], a
2014-08-09 05:39:13 +00:00
ld [ rWY ], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
call Delay3
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE
call RunPaletteCommand
2014-05-23 22:34:35 +00:00
call HideSprites
2015-07-19 18:56:13 +00:00
jpab PrintBeginningBattleText
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
; when a battle is starting, silhouettes of the player's pic and the enemy's pic are slid onto the screen
; the lower of the player's pic (his body) is part of the background, but his head is a sprite
; the reason for this is that it shares Y coordinates with the lower part of the enemy pic, so background scrolling wouldn't work for both pics
; instead, the enemy pic is part of the background and uses the scroll register, while the player's head is a sprite and is slid by changing its X coordinates in a loop
2016-06-12 00:24:04 +00:00
SlidePlayerHeadLeft:
2014-05-22 22:13:20 +00:00
push bc
2014-05-26 21:04:56 +00:00
ld hl , wOAMBuffer + $ 01
2014-08-09 05:39:13 +00:00
ld c , $ 15 ; number of OAM entries
ld de , $ 4 ; size of OAM entry
.loop
dec [ hl ] ; decrement X
dec [ hl ] ; decrement X
add hl , de ; next OAM entry
2014-05-22 22:13:20 +00:00
dec c
2014-08-09 05:39:13 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
pop bc
ret
2016-06-12 00:24:04 +00:00
SetScrollXForSlidingPlayerBodyLeft:
2014-08-09 05:39:13 +00:00
ld a , [ rLY ]
2014-05-22 22:13:20 +00:00
cp l
2014-08-09 05:39:13 +00:00
jr nz , SetScrollXForSlidingPlayerBodyLeft
2014-05-22 22:13:20 +00:00
ld a , h
2014-08-09 05:39:13 +00:00
ld [ rSCX ], a
.loop
ld a , [ rLY ]
2014-05-22 22:13:20 +00:00
cp h
2014-08-09 05:39:13 +00:00
jr z , .loop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
StartBattle:
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wPartyGainExpFlags ], a
ld [ wPartyFoughtCurrentEnemyFlags ], a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-22 22:13:20 +00:00
inc a
2015-07-25 03:27:59 +00:00
ld [ wFirstMonsNotOutYet ], a
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMon1HP
ld bc , wEnemyMon2 - wEnemyMon1 - 1
2014-05-22 22:13:20 +00:00
ld d , $ 3
2014-08-09 05:39:13 +00:00
.findFirstAliveEnemyMonLoop
2014-05-22 22:13:20 +00:00
inc d
ld a , [ hli ]
or [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .foundFirstAliveEnemyMon
2014-05-22 22:13:20 +00:00
add hl , bc
2014-08-09 05:39:13 +00:00
jr .findFirstAliveEnemyMonLoop
.foundFirstAliveEnemyMon
2014-05-22 22:13:20 +00:00
ld a , d
2015-02-07 10:43:08 +00:00
ld [ wSerialExchangeNybbleReceiveData ], a
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-08-09 05:39:13 +00:00
dec a ; is it a trainer battle?
call nz , EnemySendOutFirstMon ; if it is a trainer battle, send out enemy mon
ld c , 40
2014-05-22 22:13:20 +00:00
call DelayFrames
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
.checkAnyPartyAlive
2014-06-16 20:03:05 +00:00
call AnyPartyAlive
2014-05-22 22:13:20 +00:00
ld a , d
and a
2014-08-09 05:39:13 +00:00
jp z , HandlePlayerBlackOut ; jump if no mon is alive
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-08-09 05:39:13 +00:00
and a ; is it a normal battle?
jp z , .playerSendOutFirstMon ; if so, send out player mon
; safari zone battle
.displaySafariZoneBattleMenu
call Di sp layBattleMenu
ret c ; return if the player ran from battle
2015-07-15 06:16:06 +00:00
ld a , [ wActionResultOrTookBattleTurn ]
2014-08-09 05:39:13 +00:00
and a ; was the item used successfully?
jr z , .displaySafariZoneBattleMenu ; if not, display the menu again; XXX does this ever jump?
2015-08-31 02:38:41 +00:00
ld a , [ wNumSafariBalls ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr nz , .notOutOfSafariBalls
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
ld hl , .outOfSafariBallsText
2014-05-22 22:13:20 +00:00
jp PrintText
2014-08-09 05:39:13 +00:00
.notOutOfSafariBalls
2014-05-22 22:13:20 +00:00
callab PrintSafariZoneBattleText
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpeed + 1 ]
2014-05-22 22:13:20 +00:00
add a
2014-08-09 05:39:13 +00:00
ld b , a ; init b (which is later compared with random value) to (enemy speed % 256) * 2
jp c , EnemyRan ; if (enemy speed % 256) > 127, the enemy runs
ld a , [ wSafariBaitFactor ]
and a ; is bait factor 0?
jr z , .checkEscapeFactor
; bait factor is not 0
; divide b by 4 (making the mon less likely to run)
2014-05-22 22:13:20 +00:00
srl b
srl b
2014-08-09 05:39:13 +00:00
.checkEscapeFactor
ld a , [ wSafariEscapeFactor ]
and a ; is escape factor 0?
jr z , .compareWithRandomValue
; escape factor is not 0
; multiply b by 2 (making the mon more likely to run)
2014-05-22 22:13:20 +00:00
sla b
2014-08-09 05:39:13 +00:00
jr nc , .compareWithRandomValue
; cap b at 255
2014-05-22 22:13:20 +00:00
ld b , $ ff
2014-08-09 05:39:13 +00:00
.compareWithRandomValue
2014-05-24 18:40:38 +00:00
call Random
2014-05-22 22:13:20 +00:00
cp b
2014-08-09 05:39:13 +00:00
jr nc , .checkAnyPartyAlive
jr EnemyRan ; if b was greater than the random value, the enemy runs
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.outOfSafariBallsText
2014-05-22 22:13:20 +00:00
TX_FAR _OutOfSafariBallsText
db "@"
2014-08-09 05:39:13 +00:00
.playerSendOutFirstMon
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wWhichPokemon ], a
.findFirstAliveMonLoop
call HasMonFainted
jr nz , .foundFirstAliveMon
; fainted, go to the next one
ld hl , wWhichPokemon
2014-05-22 22:13:20 +00:00
inc [ hl ]
2014-08-09 05:39:13 +00:00
jr .findFirstAliveMonLoop
.foundFirstAliveMon
ld a , [ wWhichPokemon ]
ld [ wPlayerMonNumber ], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld hl , wPartySpecies - 1
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
2014-08-09 05:39:13 +00:00
ld a , [ hl ] ; species
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-06-14 11:12:40 +00:00
ld [ wBattleMonSpecies2 ], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2014-05-22 22:13:20 +00:00
ld a , $ 9
2014-08-09 05:39:13 +00:00
call SlideTrainerPicOffScreen
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2014-05-22 22:13:20 +00:00
ld c , a
2015-07-20 03:45:34 +00:00
ld b , FLAG_SET
2014-05-22 22:13:20 +00:00
push bc
2014-08-09 05:39:13 +00:00
ld hl , wPartyGainExpFlags
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
ld hl , wPartyFoughtCurrentEnemyFlags
2014-05-22 22:13:20 +00:00
pop bc
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
call LoadBattleMonFromParty
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
call SendOutMon
2014-05-22 22:13:20 +00:00
jr MainInBattleLoop
2014-08-09 05:39:13 +00:00
; wild mon or link battle enemy ran from battle
2016-06-12 00:24:04 +00:00
EnemyRan:
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
ld hl , WildRanText
2014-08-09 05:39:13 +00:00
jr nz , .printText
; link battle
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wBattleResult ], a
2014-05-22 22:13:20 +00:00
ld hl , EnemyRanText
2014-08-09 05:39:13 +00:00
.printText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-22 01:58:19 +00:00
ld a , SFX_RUN
2014-05-22 22:13:20 +00:00
call PlaySoundWaitForCurrent
xor a
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2015-07-24 21:39:45 +00:00
jpab AnimationSlideEnemyMonOff
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
WildRanText:
2014-05-22 22:13:20 +00:00
TX_FAR _WildRanText
db "@"
2016-06-12 00:24:04 +00:00
EnemyRanText:
2014-05-22 22:13:20 +00:00
TX_FAR _EnemyRanText
db "@"
2016-06-12 00:24:04 +00:00
MainInBattleLoop:
2014-05-22 22:13:20 +00:00
call ReadPlayerMonCurHPAndStatus
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; is battle mon HP 0?
jp z , HandlePlayerMonFainted ; if battle mon HP is 0, jump
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; is enemy mon HP 0?
jp z , HandleEnemyMonFainted ; if enemy mon HP is 0, jump
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
xor a
2015-07-25 03:27:59 +00:00
ld [ wFirstMonsNotOutYet ], a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus2 ]
2015-02-03 19:51:53 +00:00
and ( 1 << NeedsToRecharge ) | ( 1 << UsingRage ) ; check if the player is using Rage or needs to recharge
2014-08-09 05:39:13 +00:00
jr nz , .selectEnemyMove
; the player is not using Rage and doesn't need to recharge
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res Flinched , [ hl ] ; reset flinch bit
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res Flinched , [ hl ] ; reset flinch bit
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-02-03 19:51:53 +00:00
and ( 1 << ThrashingAbout ) | ( 1 << Ch argingUp ) ; check if the player is thrashing about or charging for an attack
2014-08-09 05:39:13 +00:00
jr nz , .selectEnemyMove ; if so, jump
; the player is neither thrashing about nor charging for an attack
call Di sp layBattleMenu ; show battle menu
ret c ; return if player ran from battle
ld a , [ wEscapedFromBattle ]
and a
ret nz ; return if pokedoll was used to escape from battle
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonStatus ]
2014-08-09 05:39:13 +00:00
and ( 1 << FRZ ) | SLP ; is mon frozen or asleep?
jr nz , .selectEnemyMove ; if so, jump
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2015-02-03 19:51:53 +00:00
and ( 1 << StoringEnergy ) | ( 1 << UsingTrappingMove ) ; check player is using Bide or using a multi-turn attack like wrap
2014-08-09 05:39:13 +00:00
jr nz , .selectEnemyMove ; if so, jump
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; check if enemy is using a multi-turn attack like wrap
2014-08-09 05:39:13 +00:00
jr z , .selectPlayerMove ; if not, jump
2015-01-04 16:47:21 +00:00
; enemy is using a mult-turn attack like wrap, so player is trapped and cannot execute a move
2014-05-22 22:13:20 +00:00
ld a , $ ff
2014-05-26 21:04:56 +00:00
ld [ wPlayerSelectedMove ], a
2014-08-09 05:39:13 +00:00
jr .selectEnemyMove
.selectPlayerMove
2015-07-15 06:16:06 +00:00
ld a , [ wActionResultOrTookBattleTurn ]
and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon)
2014-08-09 05:39:13 +00:00
jr nz , .selectEnemyMove
2014-05-26 21:04:56 +00:00
ld [ wMoveMenuType ], a
2014-05-22 22:13:20 +00:00
inc a
2015-08-31 02:38:41 +00:00
ld [ wAnimationID ], a
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wMenuItemToSwap ], a
2014-05-22 22:13:20 +00:00
call MoveSelectionMenu
push af
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
pop af
2014-08-09 05:39:13 +00:00
jr nz , MainInBattleLoop ; if the player didn't select a move, jump
.selectEnemyMove
2014-05-22 22:13:20 +00:00
call SelectEnemyMove
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr nz , .noLinkBattle
2014-08-09 05:39:13 +00:00
; link battle
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_RUN
2014-08-09 05:39:13 +00:00
jp z , EnemyRan
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_STRUGGLE
2014-05-22 22:13:20 +00:00
jr z , .noLinkBattle
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_NO_ACTION
2014-05-22 22:13:20 +00:00
jr z , .noLinkBattle
2016-10-29 08:44:13 +00:00
sub 4
2014-05-22 22:13:20 +00:00
jr c , .noLinkBattle
2014-08-09 05:39:13 +00:00
; the link battle enemy has switched mons
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; check if using multi-turn move like Wrap
2016-06-12 04:30:05 +00:00
jr z , .specialMoveNotUsed
2014-05-26 21:04:56 +00:00
ld a , [ wPlayerMoveListIndex ]
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ hl ]
2015-03-31 18:16:31 +00:00
cp METRONOME ; a MIRROR MOVE check is missing, might lead to a desync in link battles
; when combined with multi-turn moves
2016-06-12 04:30:05 +00:00
jr nz , .specialMoveNotUsed
2014-05-22 22:13:20 +00:00
ld [ wPlayerSelectedMove ], a
2016-06-12 04:30:05 +00:00
.specialMoveNotUsed
2014-08-09 05:39:13 +00:00
callab SwitchEnemyMon
2014-05-22 22:13:20 +00:00
.noLinkBattle
ld a , [ wPlayerSelectedMove ]
cp QUICK_ATTACK
jr nz , .playerDidNotUseQuickAttack
ld a , [ wEnemySelectedMove ]
cp QUICK_ATTACK
2014-08-09 05:39:13 +00:00
jr z , .compareSpeed ; if both used Quick Attack
jp .playerMovesFirst ; if player used Quick Attack and enemy didn't
2014-05-22 22:13:20 +00:00
.playerDidNotUseQuickAttack
ld a , [ wEnemySelectedMove ]
cp QUICK_ATTACK
2014-08-09 05:39:13 +00:00
jr z , .enemyMovesFirst ; if enemy used Quick Attack and player didn't
2014-05-22 22:13:20 +00:00
ld a , [ wPlayerSelectedMove ]
cp COUNTER
jr nz , .playerDidNotUseCounter
ld a , [ wEnemySelectedMove ]
cp COUNTER
2014-08-09 05:39:13 +00:00
jr z , .compareSpeed ; if both used Counter
jr .enemyMovesFirst ; if player used Counter and enemy didn't
2014-05-22 22:13:20 +00:00
.playerDidNotUseCounter
ld a , [ wEnemySelectedMove ]
cp COUNTER
2014-08-09 05:39:13 +00:00
jr z , .playerMovesFirst ; if enemy used Counter and player didn't
2014-05-22 22:13:20 +00:00
.compareSpeed
2014-06-14 11:12:40 +00:00
ld de , wBattleMonSpeed ; player speed value
ld hl , wEnemyMonSpeed ; enemy speed value
2014-05-22 22:13:20 +00:00
ld c , $ 2
call StringCmp ; compare speed values
jr z , .speedEqual
2014-08-09 05:39:13 +00:00
jr nc , .playerMovesFirst ; if player is faster
jr .enemyMovesFirst ; if enemy is faster
2015-01-04 16:47:21 +00:00
.speedEqual ; 50/50 chance for both players
2016-10-29 17:32:03 +00:00
ld a , [ hSerialConnectionStatus ]
cp USING_INTERNAL_CLOCK
2014-05-22 22:13:20 +00:00
jr z , .invertOutcome
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $ 80
jr c , .playerMovesFirst
jr .enemyMovesFirst
.invertOutcome
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $ 80
jr c , .enemyMovesFirst
jr .playerMovesFirst
.enemyMovesFirst
ld a , $ 1
ld [ H_WHOSETURN ], a
callab TrainerAI
jr c , .AIActionUsedEnemyFirst
2014-08-09 05:39:13 +00:00
call ExecuteEnemyMove
ld a , [ wEscapedFromBattle ]
and a ; was Teleport, Road, or Whirlwind used to escape from battle?
ret nz ; if so, return
2014-05-22 22:13:20 +00:00
ld a , b
and a
2015-01-23 03:05:13 +00:00
jp z , HandlePlayerMonFainted
2014-05-22 22:13:20 +00:00
.AIActionUsedEnemyFirst
call HandlePoisonBurnLeechSeed
jp z , HandleEnemyMonFainted
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
call ExecutePlayerMove
ld a , [ wEscapedFromBattle ]
and a ; was Teleport, Road, or Whirlwind used to escape from battle?
ret nz ; if so, return
2014-05-22 22:13:20 +00:00
ld a , b
and a
jp z , HandleEnemyMonFainted
call HandlePoisonBurnLeechSeed
jp z , HandlePlayerMonFainted
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
call Ch eckNumAttacksLeft
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
.playerMovesFirst
2014-08-09 05:39:13 +00:00
call ExecutePlayerMove
ld a , [ wEscapedFromBattle ]
and a ; was Teleport, Road, or Whirlwind used to escape from battle?
ret nz ; if so, return
2014-05-22 22:13:20 +00:00
ld a , b
and a
jp z , HandleEnemyMonFainted
call HandlePoisonBurnLeechSeed
jp z , HandlePlayerMonFainted
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
ld a , $ 1
ld [ H_WHOSETURN ], a
callab TrainerAI
jr c , .AIActionUsedPlayerFirst
2014-08-09 05:39:13 +00:00
call ExecuteEnemyMove
ld a , [ wEscapedFromBattle ]
and a ; was Teleport, Road, or Whirlwind used to escape from battle?
ret nz ; if so, return
2014-05-22 22:13:20 +00:00
ld a , b
and a
jp z , HandlePlayerMonFainted
.AIActionUsedPlayerFirst
call HandlePoisonBurnLeechSeed
jp z , HandleEnemyMonFainted
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
call Ch eckNumAttacksLeft
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
2016-06-12 00:24:04 +00:00
HandlePoisonBurnLeechSeed:
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
ld de , wBattleMonStatus
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .playersTurn
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonHP
ld de , wEnemyMonStatus
2014-05-22 22:13:20 +00:00
.playersTurn
ld a , [ de ]
and ( 1 << BRN ) | ( 1 << PSN )
jr z , .notBurnedOrPoisoned
push hl
ld hl , HurtByPoisonText
ld a , [ de ]
and 1 << BRN
jr z , .poisoned
ld hl , HurtByBurnText
.poisoned
call PrintText
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , BURN_PSN_ANIM
call PlayMoveAnimation ; play burn/poison animation
pop hl
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
.notBurnedOrPoisoned
2015-08-31 02:38:41 +00:00
ld de , wPlayerBattleStatus2
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .playersTurn2
2015-08-31 02:38:41 +00:00
ld de , wEnemyBattleStatus2
2014-05-22 22:13:20 +00:00
.playersTurn2
ld a , [ de ]
add a
jr nc , .notLeechSeeded
push hl
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
push af
xor $ 1
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , ABSORB
call PlayMoveAnimation ; play leech seed animation (from opposing mon)
pop af
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
pop hl
call HandlePoisonBurnLeechSeed_DecreaseOwnHP
call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
push hl
ld hl , HurtByLeechSeedText
call PrintText
pop hl
.notLeechSeeded
ld a , [ hli ]
or [ hl ]
ret nz ; test if fainted
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
2015-07-03 19:37:53 +00:00
ld c , 20
2014-05-22 22:13:20 +00:00
call DelayFrames
xor a
ret
2016-06-12 00:24:04 +00:00
HurtByPoisonText:
2014-05-22 22:13:20 +00:00
TX_FAR _HurtByPoisonText
db "@"
2016-06-12 00:24:04 +00:00
HurtByBurnText:
2014-05-22 22:13:20 +00:00
TX_FAR _HurtByBurnText
db "@"
2016-06-12 00:24:04 +00:00
HurtByLeechSeedText:
2014-05-22 22:13:20 +00:00
TX_FAR _HurtByLeechSeedText
db "@"
; decreases the mon's current HP by 1/16 of the Max HP (multiplied by number of toxic ticks if active)
; note that the toxic ticks are considered even if the damage is not poison (hence the Leech Seed glitch)
; hl: HP pointer
; bc (out): total damage
2016-06-12 00:24:04 +00:00
HandlePoisonBurnLeechSeed_DecreaseOwnHP:
2014-05-22 22:13:20 +00:00
push hl
push hl
ld bc , $ e ; skip to max HP
add hl , bc
ld a , [ hli ] ; load max HP
ld [ wHPBarMaxHP + 1 ], a
ld b , a
ld a , [ hl ]
ld [ wHPBarMaxHP ], a
ld c , a
srl b
rr c
srl b
rr c
srl c
srl c ; c = max HP/16 (assumption: HP < 1024)
ld a , c
and a
jr nz , .nonZeroDamage
inc c ; damage is at least 1
.nonZeroDamage
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus3
ld de , wPlayerToxicCounter
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .playersTurn
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus3
2016-06-12 04:30:05 +00:00
ld de , wEnemyToxicCounter
2014-05-22 22:13:20 +00:00
.playersTurn
2015-02-03 19:51:53 +00:00
bit BadlyPoisoned , [ hl ]
2014-05-22 22:13:20 +00:00
jr z , .noToxic
ld a , [ de ] ; increment toxic counter
inc a
ld [ de ], a
ld hl , $ 0000
.toxicTicksLoop
add hl , bc
dec a
jr nz , .toxicTicksLoop
ld b , h ; bc = damage * toxic counter
ld c , l
.noToxic
pop hl
inc hl
ld a , [ hl ] ; subtract total damage from current HP
ld [ wHPBarOldHP ], a
sub c
ld [ hld ], a
ld [ wHPBarNewHP ], a
ld a , [ hl ]
ld [ wHPBarOldHP + 1 ], a
sbc b
ld [ hl ], a
ld [ wHPBarNewHP + 1 ], a
jr nc , .noOverkill
xor a ; overkill: zero HP
ld [ hli ], a
ld [ hl ], a
ld [ wHPBarNewHP ], a
ld [ wHPBarNewHP + 1 ], a
.noOverkill
call UpdateCurMonHPBar
pop hl
ret
; adds bc to enemy HP
2015-01-04 16:47:21 +00:00
; bc isn't updated if HP substracted was capped to prevent overkill
2016-06-12 00:24:04 +00:00
HandlePoisonBurnLeechSeed_IncreaseEnemyHP:
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonMaxHP
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .playersTurn
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonMaxHP
2014-05-22 22:13:20 +00:00
.playersTurn
ld a , [ hli ]
ld [ wHPBarMaxHP + 1 ], a
ld a , [ hl ]
ld [ wHPBarMaxHP ], a
2015-08-05 21:20:29 +00:00
ld de , wBattleMonHP - wBattleMonMaxHP
add hl , de ; skip back from max hp to current hp
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
ld [ wHPBarOldHP ], a ; add bc to current HP
add c
ld [ hld ], a
ld [ wHPBarNewHP ], a
ld a , [ hl ]
ld [ wHPBarOldHP + 1 ], a
adc b
ld [ hli ], a
ld [ wHPBarNewHP + 1 ], a
ld a , [ wHPBarMaxHP ]
ld c , a
ld a , [ hld ]
sub c
ld a , [ wHPBarMaxHP + 1 ]
ld b , a
ld a , [ hl ]
sbc b
jr c , .noOverfullHeal
ld a , b ; overfull heal, set HP to max HP
ld [ hli ], a
ld [ wHPBarNewHP + 1 ], a
ld a , c
ld [ hl ], a
ld [ wHPBarNewHP ], a
.noOverfullHeal
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
xor $ 1
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
call UpdateCurMonHPBar
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
xor $ 1
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
pop hl
ret
2016-06-12 00:24:04 +00:00
UpdateCurMonHPBar:
2015-07-18 20:52:03 +00:00
coord hl , 10 , 9 ; tile pointer to player HP bar
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
ld a , $ 1
jr z , .playersTurn
2015-07-18 20:52:03 +00:00
coord hl , 2 , 2 ; tile pointer to enemy HP bar
2014-05-22 22:13:20 +00:00
xor a
.playersTurn
push bc
2015-02-08 06:18:42 +00:00
ld [ wHPBarType ], a
2014-06-16 20:57:26 +00:00
predef UpdateHPBar2
2014-05-22 22:13:20 +00:00
pop bc
ret
2016-06-12 00:24:04 +00:00
CheckNumAttacksLeft:
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerNumAttacksLeft ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr nz , .checkEnemy
; player has 0 attacks left
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove , [ hl ] ; player not using multi-turn attack like wrap any more
2014-08-09 05:39:13 +00:00
.checkEnemy
ld a , [ wEnemyNumAttacksLeft ]
2014-05-22 22:13:20 +00:00
and a
ret nz
2014-08-09 05:39:13 +00:00
; enemy has 0 attacks left
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove , [ hl ] ; enemy not using multi-turn attack like wrap any more
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
HandleEnemyMonFainted:
2014-05-22 22:13:20 +00:00
xor a
2015-08-14 07:36:06 +00:00
ld [ wInHandlePlayerMonFainted ], a
2014-05-22 22:13:20 +00:00
call FaintEnemyPokemon
2014-06-16 20:03:05 +00:00
call AnyPartyAlive
2014-05-22 22:13:20 +00:00
ld a , d
and a
2014-08-09 05:39:13 +00:00
jp z , HandlePlayerBlackOut ; if no party mons are alive, the player blacks out
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; is battle mon HP zero?
call nz , DrawPlayerHUDAndHPBar ; if battle mon HP is not zero, draw player HD and HP bar
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ret z ; return if it's a wild battle
2014-05-22 22:13:20 +00:00
call AnyEnemyPokemonAliveCheck
jp z , TrainerBattleVictory
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; does battle mon have 0 HP?
jr nz , .skipReplacingBattleMon ; if not, skip replacing battle mon
call DoUseNextMonDialogue ; this call is useless in a trainer battle. it shouldn't be here
2014-05-22 22:13:20 +00:00
ret c
2014-08-09 05:39:13 +00:00
call Ch ooseNextMon
.skipReplacingBattleMon
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-08-09 05:39:13 +00:00
call ReplaceFaintedEnemyMon
jp z , EnemyRan
2014-05-22 22:13:20 +00:00
xor a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
2016-06-12 07:19:19 +00:00
FaintEnemyPokemon:
2014-05-22 22:13:20 +00:00
call ReadPlayerMonCurHPAndStatus
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
jr z , .wild
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonPartyPos ]
ld hl , wEnemyMon1HP
2014-08-09 05:39:13 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
xor a
ld [ hli ], a
ld [ hl ], a
.wild
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res AttackingMultipleTimes , [ hl ]
2015-08-07 06:53:23 +00:00
; Bug. This only zeroes the high byte of the player's accumulated damage,
; setting the accumulated damage to itself mod 256 instead of 0 as was probably
; intended. That alone is problematic, but this mistake has another more severe
; effect. This function's counterpart for when the player mon faints,
; RemoveFaintedPlayerMon, zeroes both the high byte and the low byte. In a link
; battle, the other player's Game Boy will call that function in response to
; the enemy mon (the player mon from the other side's perspective) fainting,
; and the states of the two Game Boys will go out of sync unless the damage
; was congruent to 0 modulo 256.
2014-05-22 22:13:20 +00:00
xor a
2015-08-07 06:53:23 +00:00
ld [ wPlayerBideAccumulatedDamage ], a
2015-02-08 09:44:41 +00:00
ld hl , wEnemyStatsToDouble ; clear enemy statuses
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld [ wEnemyDisabledMove ], a
2015-04-08 23:17:56 +00:00
ld [ wEnemyDisabledMoveNumber ], a
2015-07-12 22:51:04 +00:00
ld [ wEnemyMonMinimized ], a
2015-01-31 17:26:05 +00:00
ld hl , wPlayerUsedMove
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
2015-07-18 20:52:03 +00:00
coord hl , 12 , 5
coord de , 12 , 6
2014-08-09 05:39:13 +00:00
call SlideDownFaintedMonPic
2015-07-18 20:52:03 +00:00
coord hl , 0 , 0
2015-08-05 21:20:29 +00:00
lb bc , 4 , 11
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
jr z , .wild_win
xor a
2015-08-09 05:32:44 +00:00
ld [ wFrequencyModifier ], a
ld [ wTempoModifier ], a
2015-07-22 01:58:19 +00:00
ld a , SFX_FAINT_FALL
2014-05-22 22:13:20 +00:00
call PlaySoundWaitForCurrent
.sfxwait
2016-07-28 03:08:13 +00:00
ld a , [ wChannelSoundIDs + Ch 4 ]
2015-07-22 01:58:19 +00:00
cp SFX_FAINT_FALL
2014-05-22 22:13:20 +00:00
jr z , .sfxwait
2015-07-22 01:58:19 +00:00
ld a , SFX_FAINT_THUD
2014-05-22 22:13:20 +00:00
call PlaySound
call WaitForSoundToFinish
jr .sfxplayed
.wild_win
2015-03-31 18:50:49 +00:00
call EndLowHealthAlarm
2014-05-22 22:13:20 +00:00
ld a , MUSIC_DEFEATED_WILD_MON
call PlayBattleVictoryMusic
.sfxplayed
2016-06-12 04:30:05 +00:00
; bug: win sfx is played for wild battles before checking for player mon HP
; this can lead to odd scenarios where both player and enemy faint, as the win sfx plays yet the player never won the battle
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
or [ hl ]
jr nz , .playermonnotfaint
2015-08-14 07:36:06 +00:00
ld a , [ wInHandlePlayerMonFainted ]
and a ; was this called by HandlePlayerMonFainted?
jr nz , .playermonnotfaint ; if so, don't call RemoveFaintedPlayerMon twice
2014-08-09 05:39:13 +00:00
call RemoveFaintedPlayerMon
2014-05-22 22:13:20 +00:00
.playermonnotfaint
2014-06-16 20:03:05 +00:00
call AnyPartyAlive
2014-05-22 22:13:20 +00:00
ld a , d
and a
ret z
ld hl , EnemyMonFaintedText
call PrintText
2014-08-09 05:39:13 +00:00
call PrintEmptyString
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
xor a
2014-08-09 05:39:13 +00:00
ld [ wBattleResult ], a
2015-12-15 04:09:30 +00:00
ld b , EXP_ALL
2014-05-22 22:13:20 +00:00
call IsItemInBag
push af
2014-08-09 05:39:13 +00:00
jr z , .giveExpToMonsThatFought ; if no exp all, then jump
; the player has exp all
; first, we halve the values that determine exp gain
; the enemy mon base stats are added to stat exp, so they are halved
; the base exp (which determines normal exp) is also halved
ld hl , wEnemyMonBaseStats
2014-05-22 22:13:20 +00:00
ld b , $ 7
2014-08-09 05:39:13 +00:00
.halveExpDataLoop
2014-05-22 22:13:20 +00:00
srl [ hl ]
inc hl
dec b
2014-08-09 05:39:13 +00:00
jr nz , .halveExpDataLoop
; give exp (divided evenly) to the mons that actually fought in battle against the enemy mon that has fainted
; if exp all is in the bag, this will be only be half of the stat exp and normal exp, due to the above loop
.giveExpToMonsThatFought
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 18:28:42 +00:00
ld [ wBoostExpByExpAll ], a
2014-05-22 22:13:20 +00:00
callab GainExperience
pop af
2014-08-09 05:39:13 +00:00
ret z ; return if no exp all
; the player has exp all
; now, set the gain exp flag for every party member
; half of the total stat exp and normal exp will divided evenly amongst every party member
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-03-31 18:28:42 +00:00
ld [ wBoostExpByExpAll ], a
2014-08-09 05:39:13 +00:00
ld a , [ wPartyCount ]
ld b , 0
.gainExpFlagsLoop
2014-05-22 22:13:20 +00:00
scf
rl b
dec a
2014-08-09 05:39:13 +00:00
jr nz , .gainExpFlagsLoop
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
ld [ wPartyGainExpFlags ], a
2015-07-19 18:56:13 +00:00
jpab GainExperience
2014-05-22 22:13:20 +00:00
2016-06-12 07:19:19 +00:00
EnemyMonFaintedText:
2014-05-22 22:13:20 +00:00
TX_FAR _EnemyMonFaintedText
db "@"
2016-06-12 00:24:04 +00:00
EndLowHealthAlarm:
2015-08-14 07:36:06 +00:00
; This function is called when the player has the won the battle. It turns off
; the low health alarm and prevents it from reactivating until the next battle.
2014-05-22 22:13:20 +00:00
xor a
2015-08-14 07:36:06 +00:00
ld [ wLowHealthAlarm ], a ; turn off low health alarm
2016-07-28 03:08:13 +00:00
ld [ wChannelSoundIDs + Ch 4 ], a
2014-05-22 22:13:20 +00:00
inc a
2015-08-14 07:36:06 +00:00
ld [ wLowHealthAlarmDisabled ], a ; prevent it from reactivating
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
AnyEnemyPokemonAliveCheck:
2014-08-09 05:39:13 +00:00
ld a , [ wEnemyPartyCount ]
2014-05-22 22:13:20 +00:00
ld b , a
xor a
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMon1HP
2015-02-03 19:51:53 +00:00
ld de , wEnemyMon2 - wEnemyMon1
.nextPokemon
2014-05-22 22:13:20 +00:00
or [ hl ]
inc hl
or [ hl ]
dec hl
add hl , de
dec b
2015-02-03 19:51:53 +00:00
jr nz , .nextPokemon
2014-05-22 22:13:20 +00:00
and a
ret
2014-08-09 05:39:13 +00:00
; stores whether enemy ran in Z flag
2016-06-12 00:24:04 +00:00
ReplaceFaintedEnemyMon:
2015-08-12 09:16:56 +00:00
ld hl , wEnemyHPBarColor
2014-05-22 22:13:20 +00:00
ld e , $ 30
call GetBattleHealthBarColor
callab DrawEnemyPokeballs
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-02-03 19:51:53 +00:00
jr nz , .notLinkBattle
2014-08-09 05:39:13 +00:00
; link battle
call LinkBattleExchangeData
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_RUN
2014-05-22 22:13:20 +00:00
ret z
call LoadScreenTilesFromBuffer1
2015-02-03 19:51:53 +00:00
.notLinkBattle
2014-05-22 22:13:20 +00:00
call EnemySendOut
xor a
2015-08-31 02:38:41 +00:00
ld [ wEnemyMoveNum ], a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2015-03-31 18:40:22 +00:00
ld [ wAILayer2Encouragement ], a
2014-08-09 05:39:13 +00:00
inc a ; reset Z flag
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
TrainerBattleVictory:
2015-03-31 18:50:49 +00:00
call EndLowHealthAlarm
2014-05-22 22:13:20 +00:00
ld b , MUSIC_DEFEATED_GYM_LEADER
2015-08-31 02:38:41 +00:00
ld a , [ wGymLeaderNo ]
2014-05-22 22:13:20 +00:00
and a
jr nz , .gymleader
ld b , MUSIC_DEFEATED_TRAINER
.gymleader
2015-08-31 02:38:41 +00:00
ld a , [ wTrainerClass ]
2014-05-22 22:13:20 +00:00
cp SONY3 ; final battle against rival
jr nz , .notrival
ld b , MUSIC_DEFEATED_GYM_LEADER
2015-08-31 02:38:41 +00:00
ld hl , wFlags_D733
2014-05-22 22:13:20 +00:00
set 1 , [ hl ]
.notrival
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
ld a , b
call nz , PlayBattleVictoryMusic
ld hl , TrainerDefeatedText
call PrintText
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
ret z
call ScrollTrainerPicAfterBattle
2015-07-03 19:37:53 +00:00
ld c , 40
2014-05-22 22:13:20 +00:00
call DelayFrames
2014-09-14 18:29:18 +00:00
call PrintEndBattleText
2015-06-11 22:41:33 +00:00
; win money
2014-05-22 22:13:20 +00:00
ld hl , MoneyForWinningText
call PrintText
2014-08-09 05:39:13 +00:00
ld de , wPlayerMoney + 2
2015-04-09 11:05:57 +00:00
ld hl , wAmountMoneyWon + 2
2014-05-22 22:13:20 +00:00
ld c , $ 3
2014-06-16 20:57:26 +00:00
predef_jump AddBCDPredef
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MoneyForWinningText:
2014-05-22 22:13:20 +00:00
TX_FAR _MoneyForWinningText
db "@"
2016-06-12 00:24:04 +00:00
TrainerDefeatedText:
2014-05-22 22:13:20 +00:00
TX_FAR _TrainerDefeatedText
db "@"
2016-06-12 00:24:04 +00:00
PlayBattleVictoryMusic:
2014-05-22 22:13:20 +00:00
push af
ld a , $ ff
2015-08-09 05:32:44 +00:00
ld [ wNewSoundID ], a
2014-05-22 22:13:20 +00:00
call PlaySoundWaitForCurrent
ld c , BANK ( Music_DefeatedTrainer )
pop af
call PlayMusic
jp Delay3
2016-06-12 00:24:04 +00:00
HandlePlayerMonFainted:
2015-08-14 07:36:06 +00:00
ld a , 1
ld [ wInHandlePlayerMonFainted ], a
2014-08-09 05:39:13 +00:00
call RemoveFaintedPlayerMon
2014-06-16 20:03:05 +00:00
call AnyPartyAlive ; test if any more mons are alive
2014-05-22 22:13:20 +00:00
ld a , d
and a
jp z , HandlePlayerBlackOut
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; is enemy mon's HP 0?
jr nz , .doUseNextMonDialogue ; if not, jump
; the enemy mon has 0 HP
2014-05-22 22:13:20 +00:00
call FaintEnemyPokemon
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
ret z ; if wild encounter, battle is over
call AnyEnemyPokemonAliveCheck
jp z , TrainerBattleVictory
2014-08-09 05:39:13 +00:00
.doUseNextMonDialogue
call DoUseNextMonDialogue
ret c ; return if the player ran from battle
call Ch ooseNextMon
jp nz , MainInBattleLoop ; if the enemy mon has more than 0 HP, go back to battle loop
; the enemy mon has 0 HP
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-08-09 05:39:13 +00:00
call ReplaceFaintedEnemyMon
jp z , EnemyRan ; if enemy ran from battle rather than sending out another mon, jump
2014-05-22 22:13:20 +00:00
xor a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
2014-08-09 05:39:13 +00:00
; resets flags, slides mon's pic down, plays cry, and prints fainted message
2016-06-12 00:24:04 +00:00
RemoveFaintedPlayerMon:
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMonNumber ]
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
ld hl , wPartyGainExpFlags
2015-07-20 03:45:34 +00:00
ld b , FLAG_RESET
2014-08-09 05:39:13 +00:00
predef FlagActionPredef ; clear gain exp flag for fainted mon
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-05-22 22:13:20 +00:00
res 2 , [ hl ] ; reset "attacking multiple times" flag
2015-03-12 14:49:35 +00:00
ld a , [ wLowHealthAlarm ]
2014-05-22 22:13:20 +00:00
bit 7 , a ; skip sound flag (red bar (?))
jr z , .skipWaitForSound
ld a , $ ff
2015-03-12 14:49:35 +00:00
ld [ wLowHealthAlarm ], a ;disable low health alarm
2014-05-22 22:13:20 +00:00
call WaitForSoundToFinish
.skipWaitForSound
2015-08-07 06:53:23 +00:00
; a is 0, so this zeroes the enemy's accumulated damage.
2015-02-07 12:23:34 +00:00
ld hl , wEnemyBideAccumulatedDamage
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
2014-08-09 05:39:13 +00:00
ld [ wBattleMonStatus ], a
2014-05-22 22:13:20 +00:00
call ReadPlayerMonCurHPAndStatus
2015-07-18 20:52:03 +00:00
coord hl , 9 , 7
2015-08-05 21:20:29 +00:00
lb bc , 5 , 11
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-07-18 20:52:03 +00:00
coord hl , 1 , 10
coord de , 1 , 11
2014-08-09 05:39:13 +00:00
call SlideDownFaintedMonPic
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ wBattleResult ], a
2015-08-14 07:36:06 +00:00
; When the player mon and enemy mon faint at the same time and the fact that the
; enemy mon has fainted is detected first (e.g. when the player mon knocks out
; the enemy mon using a move with recoil and faints due to the recoil), don't
; play the player mon's cry or show the "[player mon] fainted!" message.
ld a , [ wInHandlePlayerMonFainted ]
and a ; was this called by HandleEnemyMonFainted?
ret z ; if so, return
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonSpecies ]
2014-05-22 22:13:20 +00:00
call PlayCry
ld hl , PlayerMonFaintedText
jp PrintText
2016-06-12 00:24:04 +00:00
PlayerMonFaintedText:
2014-05-22 22:13:20 +00:00
TX_FAR _PlayerMonFaintedText
db "@"
2014-08-09 05:39:13 +00:00
; asks if you want to use next mon
; stores whether you ran in C flag
2016-06-12 00:24:04 +00:00
DoUseNextMonDialogue:
2014-08-09 05:39:13 +00:00
call PrintEmptyString
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
and a
dec a
2014-08-09 05:39:13 +00:00
ret nz ; return if it's a trainer battle
2014-05-22 22:13:20 +00:00
ld hl , UseNextMonText
call PrintText
2014-08-09 05:39:13 +00:00
.displayYesNoBox
2015-07-18 20:52:03 +00:00
coord hl , 13 , 9
2015-08-05 21:20:29 +00:00
lb bc , 10 , 14
2015-02-07 20:27:36 +00:00
ld a , TWO_OPTION_MENU
2015-02-07 10:43:08 +00:00
ld [ wTextBoxID ], a
2014-05-22 22:13:20 +00:00
call Di sp layTextBoxID
2015-07-13 06:00:48 +00:00
ld a , [ wMenuExitMethod ]
cp CH OSE_SECOND_ITEM ; did the player choose NO?
2014-08-09 05:39:13 +00:00
jr z , .tryRunning ; if the player chose NO, try running
and a ; reset carry
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
.tryRunning
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .displayYesNoBox ; xxx when does this happen?
2014-06-14 11:12:40 +00:00
ld hl , wPartyMon1Speed
ld de , wEnemyMonSpeed
2014-08-09 05:39:13 +00:00
jp TryRunningFromBattle
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
UseNextMonText:
2014-05-22 22:13:20 +00:00
TX_FAR _UseNextMonText
db "@"
2014-08-09 05:39:13 +00:00
; choose next player mon to send out
; stores whether enemy mon has no HP left in Z flag
2016-06-12 00:24:04 +00:00
ChooseNextMon:
2015-07-13 22:40:33 +00:00
ld a , BATTLE_PARTY_MENU
ld [ wPartyMenuTypeOrMessageID ], a
2014-05-22 22:13:20 +00:00
call Di sp layPartyMenu
2014-08-09 05:39:13 +00:00
.checkIfMonChosen
jr nc , .monChosen
.goBackToPartyMenu
2014-05-22 22:13:20 +00:00
call GoBackToPartyMenu
2014-08-09 05:39:13 +00:00
jr .checkIfMonChosen
.monChosen
call HasMonFainted
jr z , .goBackToPartyMenu ; if mon fainted, you have to choose another
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-02-03 19:51:53 +00:00
jr nz , .notLinkBattle
2014-05-22 22:13:20 +00:00
inc a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-08-09 05:39:13 +00:00
call LinkBattleExchangeData
2015-02-03 19:51:53 +00:00
.notLinkBattle
2014-05-22 22:13:20 +00:00
xor a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
ld [ wPlayerMonNumber ], a
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
ld hl , wPartyGainExpFlags
2015-07-20 03:45:34 +00:00
ld b , FLAG_SET
2014-05-22 22:13:20 +00:00
push bc
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
ld hl , wPartyFoughtCurrentEnemyFlags
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
call LoadBattleMonFromParty
2014-05-22 22:13:20 +00:00
call GBPalWhiteOut
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
call GBPalNormal
2014-08-09 05:39:13 +00:00
call SendOutMon
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
or [ hl ]
ret
; called when player is out of usable mons.
; prints approriate lose message, sets carry flag if player blacked out (special case for initial rival fight)
2016-06-12 00:24:04 +00:00
HandlePlayerBlackOut:
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr z , .notSony1Battle
2015-08-31 02:38:41 +00:00
ld a , [ wCurOpponent ]
2015-08-10 16:09:16 +00:00
cp OPP_SONY1
2014-05-22 22:13:20 +00:00
jr nz , .notSony1Battle
2015-07-18 20:52:03 +00:00
coord hl , 0 , 0 ; sony 1 battle
2015-08-05 21:20:29 +00:00
lb bc , 8 , 21
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
call ScrollTrainerPicAfterBattle
2015-07-03 19:37:53 +00:00
ld c , 40
2014-05-22 22:13:20 +00:00
call DelayFrames
ld hl , Sony1WinText
call PrintText
2015-08-31 02:38:41 +00:00
ld a , [ wCurMap ]
2014-05-22 22:13:20 +00:00
cp OAKS_LAB
ret z ; starter battle in oak's lab: don't black out
.notSony1Battle
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE_BLACK
call RunPaletteCommand
2014-05-22 22:13:20 +00:00
ld hl , PlayerBlackedOutText2
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr nz , .noLinkBattle
ld hl , LinkBattleLostText
.noLinkBattle
call PrintText
2014-05-26 21:04:56 +00:00
ld a , [ wd732 ]
2014-05-22 22:13:20 +00:00
res 5 , a
2014-05-26 21:04:56 +00:00
ld [ wd732 ], a
2014-05-22 22:13:20 +00:00
call Cl earScreen
scf
ret
2016-06-12 00:24:04 +00:00
Sony1WinText:
2014-05-22 22:13:20 +00:00
TX_FAR _Sony1WinText
db "@"
2016-06-12 00:24:04 +00:00
PlayerBlackedOutText2:
2014-05-22 22:13:20 +00:00
TX_FAR _PlayerBlackedOutText2
db "@"
2016-06-12 00:24:04 +00:00
LinkBattleLostText:
2014-05-22 22:13:20 +00:00
TX_FAR _LinkBattleLostText
db "@"
2014-08-09 05:39:13 +00:00
; slides pic of fainted mon downwards until it disappears
; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
2016-06-12 00:24:04 +00:00
SlideDownFaintedMonPic:
2014-05-26 21:04:56 +00:00
ld a , [ wd730 ]
2014-05-22 22:13:20 +00:00
push af
set 6 , a
2014-05-26 21:04:56 +00:00
ld [ wd730 ], a
2014-08-09 05:39:13 +00:00
ld b , 7 ; number of times to slide
.slideStepLoop ; each iteration, the mon is slid down one row
2014-05-22 22:13:20 +00:00
push bc
push de
push hl
2014-08-09 05:39:13 +00:00
ld b , 6 ; number of rows
.rowLoop
2014-05-22 22:13:20 +00:00
push bc
push hl
push de
ld bc , $ 7
call CopyData
pop de
pop hl
2016-06-12 04:30:05 +00:00
ld bc , - SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
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
2014-08-09 05:39:13 +00:00
jr nz , .rowLoop
2016-06-12 04:30:05 +00:00
ld bc , SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
add hl , bc
ld de , SevenSpacesText
call PlaceString
2014-08-09 05:39:13 +00:00
ld c , 2
2014-05-22 22:13:20 +00:00
call DelayFrames
pop hl
pop de
pop bc
dec b
2014-08-09 05:39:13 +00:00
jr nz , .slideStepLoop
2014-05-22 22:13:20 +00:00
pop af
2014-05-26 21:04:56 +00:00
ld [ wd730 ], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
SevenSpacesText:
2014-05-22 22:13:20 +00:00
db " @"
2014-08-09 05:39:13 +00:00
; slides the player or enemy trainer off screen
; a is the number of tiles to slide it horizontally (always 9 for the player trainer or 8 for the enemy trainer)
; if a is 8, the slide is to the right, else it is to the left
; bug: when this is called, [H_AUTOBGTRANSFERENABLED] is non-zero, so there is screen tearing
2016-06-12 00:24:04 +00:00
SlideTrainerPicOffScreen:
2015-07-18 15:17:29 +00:00
ld [ hSlideAmount ], a
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
.slideStepLoop ; each iteration, the trainer pic is slid one tile left/right
2014-05-22 22:13:20 +00:00
push bc
push hl
2014-08-09 05:39:13 +00:00
ld b , 7 ; number of rows
.rowLoop
2014-05-22 22:13:20 +00:00
push hl
2015-07-18 15:17:29 +00:00
ld a , [ hSlideAmount ]
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
.columnLoop
2015-07-18 15:17:29 +00:00
ld a , [ hSlideAmount ]
2014-08-09 05:39:13 +00:00
cp 8
jr z , .slideRight
.slideLeft ; slide player sprite off screen
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
ld [ hli ], a
inc hl
2014-08-09 05:39:13 +00:00
jr .nextColumn
.slideRight ; slide enemy trainer sprite off screen
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ hld ], a
dec hl
2014-08-09 05:39:13 +00:00
.nextColumn
2014-05-22 22:13:20 +00:00
dec c
2014-08-09 05:39:13 +00:00
jr nz , .columnLoop
2014-05-22 22:13:20 +00:00
pop hl
2014-08-09 05:39:13 +00:00
ld de , 20
2014-05-22 22:13:20 +00:00
add hl , de
dec b
2014-08-09 05:39:13 +00:00
jr nz , .rowLoop
ld c , 2
2014-05-22 22:13:20 +00:00
call DelayFrames
pop hl
pop bc
dec c
2014-08-09 05:39:13 +00:00
jr nz , .slideStepLoop
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; send out a trainer's mon
2016-06-12 00:24:04 +00:00
EnemySendOut:
2014-08-09 05:39:13 +00:00
ld hl , wPartyGainExpFlags
2014-05-22 22:13:20 +00:00
xor a
ld [ hl ], a
2014-05-26 21:04:56 +00:00
ld a ,[ wPlayerMonNumber ]
2014-05-22 22:13:20 +00:00
ld c , a
2015-07-20 03:45:34 +00:00
ld b , FLAG_SET
2014-05-22 22:13:20 +00:00
push bc
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
ld hl , wPartyFoughtCurrentEnemyFlags
2014-05-22 22:13:20 +00:00
xor a
ld [ hl ], a
pop bc
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
; don't change wPartyGainExpFlags or wPartyFoughtCurrentEnemyFlags
2016-06-12 00:24:04 +00:00
EnemySendOutFirstMon:
2014-05-22 22:13:20 +00:00
xor a
2015-02-08 09:44:41 +00:00
ld hl , wEnemyStatsToDouble ; clear enemy statuses
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld [ wEnemyDisabledMove ], a
2015-04-08 23:17:56 +00:00
ld [ wEnemyDisabledMoveNumber ], a
2015-07-12 22:51:04 +00:00
ld [ wEnemyMonMinimized ], a
2015-01-31 17:26:05 +00:00
ld hl , wPlayerUsedMove
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
dec a
ld [ wAICount ], a
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-05-22 22:13:20 +00:00
res 5 ,[ hl ]
2015-07-18 20:52:03 +00:00
coord hl , 18 , 0
2014-05-22 22:13:20 +00:00
ld a , 8
2014-08-09 05:39:13 +00:00
call SlideTrainerPicOffScreen
call PrintEmptyString
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2015-02-07 10:43:08 +00:00
ld a ,[ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr nz , .next
2015-02-07 10:43:08 +00:00
ld a ,[ wSerialExchangeNybbleReceiveData ]
2014-05-22 22:13:20 +00:00
sub 4
ld [ wWhichPokemon ], a
jr .next3
.next
ld b , $ FF
.next2
inc b
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonPartyPos ]
2014-05-22 22:13:20 +00:00
cp b
jr z , .next2
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMon1
2014-05-22 22:13:20 +00:00
ld a , b
ld [ wWhichPokemon ], a
push bc
2014-06-14 11:12:40 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
pop bc
inc hl
ld a ,[ hli ]
ld c , a
ld a ,[ hl ]
or c
jr z , .next2
.next3
ld a ,[ wWhichPokemon ]
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMon1Level
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a ,[ hl ]
2015-08-31 02:38:41 +00:00
ld [ wCurEnemyLVL ], a
2014-05-22 22:13:20 +00:00
ld a ,[ wWhichPokemon ]
inc a
2014-05-26 21:04:56 +00:00
ld hl , wEnemyPartyCount
2014-05-22 22:13:20 +00:00
ld c , a
ld b , 0
add hl , bc
ld a ,[ hl ]
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonSpecies2 ], a
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-08-09 05:39:13 +00:00
call LoadEnemyMonData
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
2015-07-24 03:48:35 +00:00
ld [ wLastSwitchInEnemyMonHP ], a
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-07-24 03:48:35 +00:00
ld [ wLastSwitchInEnemyMonHP + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , 1
2014-05-26 21:04:56 +00:00
ld [ wCurrentMenuItem ], a
2015-07-25 03:27:59 +00:00
ld a ,[ wFirstMonsNotOutYet ]
2014-05-22 22:13:20 +00:00
dec a
jr z , .next4
2014-06-14 11:12:40 +00:00
ld a ,[ wPartyCount ]
2014-05-22 22:13:20 +00:00
dec a
jr z , .next4
2015-02-07 10:43:08 +00:00
ld a ,[ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr z , .next4
2015-08-31 02:38:41 +00:00
ld a ,[ wOptions ]
2014-05-22 22:13:20 +00:00
bit 6 , a
jr nz , .next4
ld hl , TrainerAboutToUseText
call PrintText
2015-07-18 20:52:03 +00:00
coord hl , 0 , 7
2015-08-05 21:20:29 +00:00
lb bc , 8 , 1
2015-02-07 20:27:36 +00:00
ld a , TWO_OPTION_MENU
2015-02-07 10:43:08 +00:00
ld [ wTextBoxID ], a
2014-05-22 22:13:20 +00:00
call Di sp layTextBoxID
2014-05-26 21:04:56 +00:00
ld a ,[ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
and a
jr nz , .next4
2015-07-13 22:40:33 +00:00
ld a , BATTLE_PARTY_MENU
ld [ wPartyMenuTypeOrMessageID ], a
2014-05-22 22:13:20 +00:00
call Di sp layPartyMenu
.next9
ld a , 1
2014-05-26 21:04:56 +00:00
ld [ wCurrentMenuItem ], a
2014-05-22 22:13:20 +00:00
jr c , .next7
2014-05-26 21:04:56 +00:00
ld hl , wPlayerMonNumber
2014-05-22 22:13:20 +00:00
ld a ,[ wWhichPokemon ]
cp [ hl ]
jr nz , .next6
ld hl , Al readyOutText
call PrintText
.next8
call GoBackToPartyMenu
jr .next9
.next6
2014-08-09 05:39:13 +00:00
call HasMonFainted
2014-05-22 22:13:20 +00:00
jr z , .next8
xor a
2014-05-26 21:04:56 +00:00
ld [ wCurrentMenuItem ], a
2014-05-22 22:13:20 +00:00
.next7
call GBPalWhiteOut
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
.next4
2014-05-23 22:34:35 +00:00
call Cl earSprites
2015-07-18 20:52:03 +00:00
coord hl , 0 , 0
2015-08-05 21:20:29 +00:00
lb bc , 4 , 11
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE
call RunPaletteCommand
2014-05-22 22:13:20 +00:00
call GBPalNormal
ld hl , TrainerSentOutText
call PrintText
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonSpecies2 ]
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-05-29 08:31:46 +00:00
ld de , vFrontPic
2014-05-22 22:13:20 +00:00
call LoadMonFrontSprite
2015-07-24 03:48:35 +00:00
ld a , - $ 31
ld [ hStartTileID ], a
2015-07-18 20:52:03 +00:00
coord hl , 15 , 6
2015-07-03 19:37:53 +00:00
predef AnimateSendingOutMon
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonSpecies2 ]
2014-05-22 22:13:20 +00:00
call PlayCry
2014-08-09 05:39:13 +00:00
call DrawEnemyHUDAndHPBar
2014-05-26 21:04:56 +00:00
ld a ,[ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
and a
ret nz
xor a
2014-08-09 05:39:13 +00:00
ld [ wPartyGainExpFlags ], a
ld [ wPartyFoughtCurrentEnemyFlags ], a
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
jp SwitchPlayerMon
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
TrainerAboutToUseText:
2014-05-22 22:13:20 +00:00
TX_FAR _TrainerAboutToUseText
db "@"
2016-06-12 00:24:04 +00:00
TrainerSentOutText:
2014-05-22 22:13:20 +00:00
TX_FAR _TrainerSentOutText
db "@"
; tests if the player has any pokemon that are not fainted
; sets d = 0 if all fainted, d != 0 if some mons are still alive
2016-06-12 00:24:04 +00:00
AnyPartyAlive:
2014-08-09 05:39:13 +00:00
ld a , [ wPartyCount ]
2014-05-22 22:13:20 +00:00
ld e , a
xor a
2014-08-09 05:39:13 +00:00
ld hl , wPartyMon1HP
2014-06-14 11:12:40 +00:00
ld bc , wPartyMon2 - wPartyMon1 - 1
2014-05-22 22:13:20 +00:00
.partyMonsLoop
or [ hl ]
inc hl
or [ hl ]
add hl , bc
dec e
jr nz , .partyMonsLoop
ld d , a
ret
2014-08-09 05:39:13 +00:00
; tests if player mon has fainted
; stores whether mon has fainted in Z flag
2016-06-12 00:24:04 +00:00
HasMonFainted:
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
ld hl , wPartyMon1HP
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , [ hli ]
or [ hl ]
ret nz
2015-07-25 03:27:59 +00:00
ld a , [ wFirstMonsNotOutYet ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr nz , .done
2014-05-22 22:13:20 +00:00
ld hl , NoWillText
call PrintText
2014-08-09 05:39:13 +00:00
.done
2014-05-22 22:13:20 +00:00
xor a
ret
2016-06-12 00:24:04 +00:00
NoWillText:
2014-05-22 22:13:20 +00:00
TX_FAR _NoWillText
db "@"
2014-08-09 05:39:13 +00:00
; try to run from battle (hl = player speed, de = enemy speed)
; stores whether the attempt was successful in carry flag
2016-06-12 00:24:04 +00:00
TryRunningFromBattle:
2014-05-22 22:13:20 +00:00
call IsGhostBattle
2014-08-09 05:39:13 +00:00
jp z , .canEscape ; jump if it's a ghost battle
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
jp z , .canEscape ; jump if it's a safari battle
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
jp z , .canEscape
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
jr nz , .trainerBattle ; jump if it's a trainer battle
ld a , [ wNumRunAttempts ]
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ wNumRunAttempts ], a
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-07-18 15:17:29 +00:00
ld [ hEnemySpeed ], a
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2015-07-18 15:17:29 +00:00
ld [ hEnemySpeed + 1 ], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
ld de , H_MULTIPLICAND + 1
2015-07-18 15:17:29 +00:00
ld hl , hEnemySpeed
ld c , 2
2014-05-22 22:13:20 +00:00
call StringCmp
2014-08-09 05:39:13 +00:00
jr nc , .canEscape ; jump if player speed greater than enemy speed
xor a
2015-01-23 03:05:13 +00:00
ld [ H_MULTIPLICAND ], a
2014-08-09 05:39:13 +00:00
ld a , 32
ld [ H_MULTIPLIER ], a
call Multiply ; multiply player speed by 32
ld a , [ H_PRODUCT + 2 ]
ld [ H_DIVIDEND ], a
ld a , [ H_PRODUCT + 3 ]
ld [ H_DIVIDEND + 1 ], a
2015-07-18 15:17:29 +00:00
ld a , [ hEnemySpeed ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-07-18 15:17:29 +00:00
ld a , [ hEnemySpeed + 1 ]
2014-08-09 05:39:13 +00:00
; divide enemy speed by 4
2014-05-22 22:13:20 +00:00
srl b
rr a
srl b
rr a
and a
2014-08-09 05:39:13 +00:00
jr z , .canEscape ; jump if enemy speed divided by 4, mod 256 is 0
ld [ H_DIVISOR ], a ; ((enemy speed / 4) % 256)
2014-05-22 22:13:20 +00:00
ld b , $ 2
2014-08-09 05:39:13 +00:00
call Di vide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
ld a , [ H_QUOTIENT + 2 ]
and a ; is the quotient greater than 256?
jr nz , .canEscape ; if so, the player can escape
ld a , [ wNumRunAttempts ]
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
; add 30 to the quotient for each run attempt
.loop
2014-05-22 22:13:20 +00:00
dec c
2014-08-09 05:39:13 +00:00
jr z , .compareWithRandomValue
ld b , 30
ld a , [ H_QUOTIENT + 3 ]
2014-05-22 22:13:20 +00:00
add b
2014-08-09 05:39:13 +00:00
ld [ H_QUOTIENT + 3 ], a
jr c , .canEscape
jr .loop
.compareWithRandomValue
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ H_QUOTIENT + 3 ]
2014-05-22 22:13:20 +00:00
cp b
2015-06-11 22:41:33 +00:00
jr nc , .canEscape ; if the random value was less than or equal to the quotient
2015-03-31 18:16:31 +00:00
; plus 30 times the number of attempts, the player can escape
2014-08-09 05:39:13 +00:00
; can't escape
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a ; you lose your turn when you can't escape
2014-05-22 22:13:20 +00:00
ld hl , CantEscapeText
2014-08-09 05:39:13 +00:00
jr .printCantEscapeOrNoRunningText
.trainerBattle
2014-05-22 22:13:20 +00:00
ld hl , NoRunningText
2014-08-09 05:39:13 +00:00
.printCantEscapeOrNoRunningText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-25 03:27:59 +00:00
ld a , 1
ld [ wForcePlayerToChooseMon ], a
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
and a ; reset carry
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
.canEscape
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
ld a , $ 2
2014-08-09 05:39:13 +00:00
jr nz , .playSound
; link battle
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
xor a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2016-10-29 08:44:13 +00:00
ld a , LINKBATTLE_RUN
2014-08-09 05:39:13 +00:00
ld [ wPlayerMoveListIndex ], a
call LinkBattleExchangeData
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_RUN
2014-05-22 22:13:20 +00:00
ld a , $ 2
2014-08-09 05:39:13 +00:00
jr z , .playSound
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
.playSound
ld [ wBattleResult ], a
2015-07-22 01:58:19 +00:00
ld a , SFX_RUN
2014-05-22 22:13:20 +00:00
call PlaySoundWaitForCurrent
ld hl , GotAwayText
call PrintText
call WaitForSoundToFinish
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
scf ; set carry
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
CantEscapeText:
2014-05-22 22:13:20 +00:00
TX_FAR _CantEscapeText
db "@"
2016-06-12 00:24:04 +00:00
NoRunningText:
2014-05-22 22:13:20 +00:00
TX_FAR _NoRunningText
db "@"
2016-06-12 00:24:04 +00:00
GotAwayText:
2014-05-22 22:13:20 +00:00
TX_FAR _GotAwayText
db "@"
2014-08-09 05:39:13 +00:00
; copies from party data to battle mon data when sending out a new player mon
2016-06-12 00:24:04 +00:00
LoadBattleMonFromParty:
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2015-07-24 08:49:33 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-08-09 05:39:13 +00:00
ld hl , wPartyMon1Species
2014-05-22 22:13:20 +00:00
call AddNTimes
2014-06-14 11:12:40 +00:00
ld de , wBattleMonSpecies
2015-07-24 08:49:33 +00:00
ld bc , wBattleMonDVs - wBattleMonSpecies
2014-05-22 22:13:20 +00:00
call CopyData
2015-07-24 08:49:33 +00:00
ld bc , wPartyMon1DVs - wPartyMon1OTID
2014-05-22 22:13:20 +00:00
add hl , bc
2014-06-14 11:12:40 +00:00
ld de , wBattleMonDVs
2015-07-24 08:49:33 +00:00
ld bc , NUM_DVS
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld de , wBattleMonPP
2015-07-24 08:49:33 +00:00
ld bc , NUM_MOVES
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld de , wBattleMonLevel
2016-02-20 21:54:52 +00:00
ld bc , wBattleMonPP - wBattleMonLevel
2014-05-22 22:13:20 +00:00
call CopyData
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonSpecies2 ]
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-08-09 05:39:13 +00:00
ld hl , wPartyMonNicks
ld a , [ wPlayerMonNumber ]
2014-05-22 22:13:20 +00:00
call SkipFixedLengthTextEntries
2014-06-14 11:12:40 +00:00
ld de , wBattleMonNick
2015-08-11 04:51:20 +00:00
ld bc , NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonLevel
ld de , wPlayerMonUnmodifiedLevel ; block of memory used for unmodified stats
2015-07-24 08:49:33 +00:00
ld bc , 1 + NUM_STATS * 2
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
call ApplyBurnAndParalysisPenaltiesToPlayer
call ApplyBadgeStatBoosts
ld a , $ 7 ; default stat modifier
2015-07-24 08:49:33 +00:00
ld b , NUM_STAT_MODS
2014-08-09 05:39:13 +00:00
ld hl , wPlayerMonAttackMod
.statModLoop
2014-05-22 22:13:20 +00:00
ld [ hli ], a
dec b
2014-08-09 05:39:13 +00:00
jr nz , .statModLoop
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; copies from enemy party data to current enemy mon data when sending out a new enemy mon
2016-06-12 00:24:04 +00:00
LoadEnemyMonFromParty:
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2015-07-24 08:49:33 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMons
2014-05-22 22:13:20 +00:00
call AddNTimes
2014-06-14 11:12:40 +00:00
ld de , wEnemyMonSpecies
2015-07-24 08:49:33 +00:00
ld bc , wEnemyMonDVs - wEnemyMonSpecies
2014-05-22 22:13:20 +00:00
call CopyData
2015-07-24 08:49:33 +00:00
ld bc , wEnemyMon1DVs - wEnemyMon1OTID
2014-05-22 22:13:20 +00:00
add hl , bc
2014-06-14 11:12:40 +00:00
ld de , wEnemyMonDVs
2015-07-24 08:49:33 +00:00
ld bc , NUM_DVS
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonPP
2015-07-24 08:49:33 +00:00
ld bc , NUM_MOVES
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonLevel
2016-02-20 21:54:52 +00:00
ld bc , wEnemyMonPP - wEnemyMonLevel
2014-05-22 22:13:20 +00:00
call CopyData
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies ]
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonNicks
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2014-05-22 22:13:20 +00:00
call SkipFixedLengthTextEntries
2014-06-14 11:12:40 +00:00
ld de , wEnemyMonNick
2015-08-11 04:51:20 +00:00
ld bc , NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonLevel
ld de , wEnemyMonUnmodifiedLevel ; block of memory used for unmodified stats
2015-07-24 08:49:33 +00:00
ld bc , 1 + NUM_STATS * 2
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
call ApplyBurnAndParalysisPenaltiesToEnemy
2015-08-31 02:38:41 +00:00
ld hl , wMonHBaseStats
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonBaseStats
2015-07-24 08:49:33 +00:00
ld b , NUM_STATS
2014-08-09 05:39:13 +00:00
.copyBaseStatsLoop
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc de
dec b
2014-08-09 05:39:13 +00:00
jr nz , .copyBaseStatsLoop
ld a , $ 7 ; default stat modifier
2015-07-24 08:49:33 +00:00
ld b , NUM_STAT_MODS
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatMods
.statModLoop
2014-05-22 22:13:20 +00:00
ld [ hli ], a
dec b
2014-08-09 05:39:13 +00:00
jr nz , .statModLoop
ld a , [ wWhichPokemon ]
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonPartyPos ], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
SendOutMon:
2014-08-09 05:39:13 +00:00
callab PrintSendOutMonMessage
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
or [ hl ] ; is enemy mon HP zero?
jp z , .skipDrawingEnemyHUDAndHPBar ; if HP is zero, skip drawing the HUD and HP bar
call DrawEnemyHUDAndHPBar
.skipDrawingEnemyHUDAndHPBar
call DrawPlayerHUDAndHPBar
2014-06-16 20:57:26 +00:00
predef LoadMonBackPic
2014-05-22 22:13:20 +00:00
xor a
2015-07-24 03:48:35 +00:00
ld [ hStartTileID ], a
2015-07-16 03:04:58 +00:00
ld hl , wBattleAndStartSavedMenuItem
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
2015-03-31 18:28:42 +00:00
ld [ wBoostExpByExpAll ], a
ld [ wDamageMultipliers ], a
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveNum ], a
2015-01-31 17:26:05 +00:00
ld hl , wPlayerUsedMove
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
2015-02-08 09:44:41 +00:00
ld hl , wPlayerStatsToDouble
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld [ wPlayerDisabledMove ], a
2015-04-08 23:17:56 +00:00
ld [ wPlayerDisabledMoveNumber ], a
2015-07-12 22:51:04 +00:00
ld [ wPlayerMonMinimized ], a
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE
call RunPaletteCommand
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove , [ hl ]
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
ld a , POOF_ANIM
call PlayMoveAnimation
2015-07-18 20:52:03 +00:00
coord hl , 4 , 11
2015-07-03 19:37:53 +00:00
predef AnimateSendingOutMon
2014-05-26 21:04:56 +00:00
ld a , [ wcf91 ]
2014-05-22 22:13:20 +00:00
call PlayCry
2014-08-09 05:39:13 +00:00
call PrintEmptyString
2014-05-22 22:13:20 +00:00
jp SaveScreenTilesToBuffer1
2015-07-15 06:16:06 +00:00
; show 2 stages of the player mon getting smaller before disappearing
2016-06-12 00:24:04 +00:00
AnimateRetreatingPlayerMon:
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-07-24 03:48:35 +00:00
lb bc , 7 , 7
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-07-18 20:52:03 +00:00
coord hl , 3 , 7
2015-07-24 03:48:35 +00:00
lb bc , 5 , 5
2014-05-22 22:13:20 +00:00
xor a
2015-07-15 06:16:06 +00:00
ld [ wDownscaledMonSize ], a
2015-07-24 03:48:35 +00:00
ld [ hBaseTileID ], a
2015-07-15 06:16:06 +00:00
predef CopyDownscaledMonTiles
2015-07-03 19:37:53 +00:00
ld c , 4
2014-05-22 22:13:20 +00:00
call DelayFrames
2014-08-09 05:39:13 +00:00
call .clearScreenArea
2015-07-18 20:52:03 +00:00
coord hl , 4 , 9
2015-07-24 03:48:35 +00:00
lb bc , 3 , 3
ld a , 1
2015-07-15 06:16:06 +00:00
ld [ wDownscaledMonSize ], a
2014-05-22 22:13:20 +00:00
xor a
2015-07-24 03:48:35 +00:00
ld [ hBaseTileID ], a
2015-07-15 06:16:06 +00:00
predef CopyDownscaledMonTiles
2014-05-22 22:13:20 +00:00
call Delay3
2014-08-09 05:39:13 +00:00
call .clearScreenArea
2014-05-22 22:13:20 +00:00
ld a , $ 4 c
2014-06-25 20:58:27 +00:00
Coorda 5 , 11
2014-08-09 05:39:13 +00:00
.clearScreenArea
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-07-24 03:48:35 +00:00
lb bc , 7 , 7
2014-05-22 22:13:20 +00:00
jp Cl earScreenArea
2014-06-14 11:12:40 +00:00
; reads player's current mon's HP into wBattleMonHP
2016-06-12 00:24:04 +00:00
ReadPlayerMonCurHPAndStatus:
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMonNumber ]
ld hl , wPartyMon1HP
2014-06-14 11:12:40 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld d , h
ld e , l
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld bc , $ 4 ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
jp CopyData
2016-06-12 00:24:04 +00:00
DrawHUDsAndHPBars:
2014-08-09 05:39:13 +00:00
call DrawPlayerHUDAndHPBar
jp DrawEnemyHUDAndHPBar
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
DrawPlayerHUDAndHPBar:
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2015-07-18 20:52:03 +00:00
coord hl , 9 , 7
2015-08-05 21:20:29 +00:00
lb bc , 5 , 11
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
callab PlacePlayerHUDTiles
2015-07-18 20:52:03 +00:00
coord hl , 18 , 9
2014-05-22 22:13:20 +00:00
ld [ hl ], $ 73
2014-06-14 11:12:40 +00:00
ld de , wBattleMonNick
2015-07-18 20:52:03 +00:00
coord hl , 10 , 7
2014-08-09 05:39:13 +00:00
call CenterMonName
2014-05-22 22:13:20 +00:00
call PlaceString
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonSpecies
2015-02-08 02:37:40 +00:00
ld de , wLoadedMon
2016-02-20 21:54:52 +00:00
ld bc , wBattleMonDVs - wBattleMonSpecies
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonLevel
2015-02-08 02:37:40 +00:00
ld de , wLoadedMonLevel
2016-02-20 21:54:52 +00:00
ld bc , wBattleMonPP - wBattleMonLevel
2014-05-22 22:13:20 +00:00
call CopyData
2015-07-18 20:52:03 +00:00
coord hl , 14 , 8
2014-05-22 22:13:20 +00:00
push hl
inc hl
2015-02-08 02:37:40 +00:00
ld de , wLoadedMonStatus
2014-05-22 22:13:20 +00:00
call PrintStatusConditionNotFainted
pop hl
2016-06-12 04:30:05 +00:00
jr nz , .doNotPrintLevel
2014-05-22 22:13:20 +00:00
call PrintLevel
2016-06-12 04:30:05 +00:00
.doNotPrintLevel
2015-02-08 02:37:40 +00:00
ld a , [ wLoadedMonSpecies ]
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2015-07-18 20:52:03 +00:00
coord hl , 10 , 9
2015-01-23 03:05:13 +00:00
predef DrawHP
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2015-08-12 09:16:56 +00:00
ld hl , wPlayerHPBarColor
2014-05-22 22:13:20 +00:00
call GetBattleHealthBarColor
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
or [ hl ]
2016-06-12 04:30:05 +00:00
jr z , .fainted
2015-08-14 07:36:06 +00:00
ld a , [ wLowHealthAlarmDisabled ]
and a ; has the alarm been disabled because the player has already won?
ret nz ; if so, return
2015-08-12 09:16:56 +00:00
ld a , [ wPlayerHPBarColor ]
cp HP_BAR_RED
2016-06-12 04:30:05 +00:00
jr z , .setLowHealthAlarm
.fainted
2015-03-12 14:49:35 +00:00
ld hl , wLowHealthAlarm
bit 7 , [ hl ] ;low health alarm enabled?
2014-05-22 22:13:20 +00:00
ld [ hl ], $ 0
ret z
xor a
2016-07-28 03:08:13 +00:00
ld [ wChannelSoundIDs + Ch 4 ], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 04:30:05 +00:00
.setLowHealthAlarm
2015-03-12 14:49:35 +00:00
ld hl , wLowHealthAlarm
set 7 , [ hl ] ;enable low health alarm
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
DrawEnemyHUDAndHPBar:
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2015-07-18 20:52:03 +00:00
coord hl , 0 , 0
2015-08-05 21:20:29 +00:00
lb bc , 4 , 12
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
callab PlaceEnemyHUDTiles
2014-06-14 11:12:40 +00:00
ld de , wEnemyMonNick
2015-07-18 20:52:03 +00:00
coord hl , 1 , 0
2014-08-09 05:39:13 +00:00
call CenterMonName
2014-05-22 22:13:20 +00:00
call PlaceString
2015-07-18 20:52:03 +00:00
coord hl , 4 , 1
2014-05-22 22:13:20 +00:00
push hl
inc hl
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonStatus
2014-05-22 22:13:20 +00:00
call PrintStatusConditionNotFainted
pop hl
2014-08-09 05:39:13 +00:00
jr nz , .skipPrintLevel ; if the mon has a status condition, skip printing the level
ld a , [ wEnemyMonLevel ]
2015-02-08 02:37:40 +00:00
ld [ wLoadedMonLevel ], a
2014-05-22 22:13:20 +00:00
call PrintLevel
2014-08-09 05:39:13 +00:00
.skipPrintLevel
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 2 ], a
or [ hl ] ; is current HP zero?
jr nz , .hpNonzero
; current HP is 0
; set variables for DrawHPBar
2014-05-22 22:13:20 +00:00
ld c , a
ld e , a
ld d , $ 6
2014-08-09 05:39:13 +00:00
jp .drawHPBar
.hpNonzero
xor a
ld [ H_MULTIPLICAND ], a
ld a , 48
ld [ H_MULTIPLIER ], a
call Multiply ; multiply current HP by 48
ld hl , wEnemyMonMaxHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , a
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ H_DIVISOR ], a
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
and a ; is max HP > 255?
jr z , .doDivide
; if max HP > 255, scale both (current HP * 48) and max HP by dividing by 4 so that max HP fits in one byte
; (it needs to be one byte so it can be used as the divisor for the Divide function)
ld a , [ H_DIVISOR ]
2014-05-22 22:13:20 +00:00
srl b
rr a
srl b
rr a
2014-08-09 05:39:13 +00:00
ld [ H_DIVISOR ], a
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
ld b , a
srl b
2014-08-09 05:39:13 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
rr a
srl b
rr a
2014-08-09 05:39:13 +00:00
ld [ H_PRODUCT + 3 ], a
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
ld [ H_PRODUCT + 2 ], a
.doDivide
ld a , [ H_PRODUCT + 2 ]
ld [ H_DIVIDEND ], a
ld a , [ H_PRODUCT + 3 ]
ld [ H_DIVIDEND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , $ 2
ld b , a
2014-08-09 05:39:13 +00:00
call Di vide ; divide (current HP * 48) by max HP
ld a , [ H_QUOTIENT + 3 ]
; set variables for DrawHPBar
2014-05-22 22:13:20 +00:00
ld e , a
ld a , $ 6
ld d , a
ld c , a
2014-08-09 05:39:13 +00:00
.drawHPBar
2014-05-22 22:13:20 +00:00
xor a
2015-02-08 06:18:42 +00:00
ld [ wHPBarType ], a
2015-07-18 20:52:03 +00:00
coord hl , 2 , 2
2014-05-22 22:13:20 +00:00
call DrawHPBar
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2015-08-12 09:16:56 +00:00
ld hl , wEnemyHPBarColor
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
GetBattleHealthBarColor:
2014-05-22 22:13:20 +00:00
ld b , [ hl ]
call GetHealthBarColor
ld a , [ hl ]
cp b
ret z
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE
jp RunPaletteCommand
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
; center's mon's name on the battle screen
2015-03-31 18:16:31 +00:00
; 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)
2016-06-12 00:24:04 +00:00
CenterMonName:
2014-05-22 22:13:20 +00:00
push de
inc hl
inc hl
ld b , $ 2
2014-08-09 05:39:13 +00:00
.loop
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2015-08-05 21:20:29 +00:00
cp "@"
2014-08-09 05:39:13 +00:00
jr z , .done
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2015-08-05 21:20:29 +00:00
cp "@"
2014-08-09 05:39:13 +00:00
jr z , .done
2014-05-22 22:13:20 +00:00
dec hl
dec b
2014-08-09 05:39:13 +00:00
jr nz , .loop
.done
2014-05-22 22:13:20 +00:00
pop de
ret
2016-06-12 00:24:04 +00:00
DisplayBattleMenu:
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1 ; restore saved screen
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-05-22 22:13:20 +00:00
and a
jr nz , .nonstandardbattle
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
call PrintEmptyString
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
.nonstandardbattle
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2015-02-07 20:27:36 +00:00
ld a , BATTLE_MENU_TEMPLATE
2014-05-22 22:13:20 +00:00
jr nz , .menuselected
2015-02-07 20:27:36 +00:00
ld a , SAFARI_BATTLE_MENU_TEMPLATE
2014-05-22 22:13:20 +00:00
.menuselected
2015-02-07 10:43:08 +00:00
ld [ wTextBoxID ], a
2014-05-22 22:13:20 +00:00
call Di sp layTextBoxID
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
jp nz , .handleBattleMenuInput ; handle menu input if it's not the old man tutorial
; the following happens for the old man tutorial
ld hl , wPlayerName
2015-08-31 02:38:41 +00:00
ld de , wGrassRate
2015-08-11 04:51:20 +00:00
ld bc , NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData ; temporarily save the player name in unused space,
; which is supposed to get overwritten when entering a
2015-02-03 19:51:53 +00:00
; map with wild Pokémon. Due to an oversight, the data
2014-05-22 22:13:20 +00:00
; may not get overwritten (cinnabar) and the infamous
2015-02-03 19:51:53 +00:00
; Missingno. glitch can show up.
2014-08-09 05:39:13 +00:00
ld hl , .oldManName
ld de , wPlayerName
2015-08-11 04:51:20 +00:00
ld bc , NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
2015-02-03 19:51:53 +00:00
; the following simulates the keystrokes by drawing menus on screen
2015-07-18 20:52:03 +00:00
coord hl , 9 , 14
2014-05-22 22:13:20 +00:00
ld [ hl ], "▶"
2015-07-03 19:37:53 +00:00
ld c , 80
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-05 21:20:29 +00:00
ld [ hl ], " "
2015-07-18 20:52:03 +00:00
coord hl , 9 , 16
2014-05-22 22:13:20 +00:00
ld [ hl ], "▶"
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2016-07-18 06:17:03 +00:00
ld [ hl ], "▷"
2014-08-09 05:39:13 +00:00
ld a , $ 2 ; select the "ITEM" menu
jp .upperLeftMenuItemWasNotSelected
.oldManName
2014-05-22 22:13:20 +00:00
db "OLD MAN@"
2014-08-09 05:39:13 +00:00
.handleBattleMenuInput
2015-07-16 03:04:58 +00:00
ld a , [ wBattleAndStartSavedMenuItem ]
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
ld [ wLastMenuItem ], a
sub 2 ; check if the cursor is in the left column
jr c , .leftColumn
; cursor is in the right column
ld [ wCurrentMenuItem ], a
ld [ wLastMenuItem ], a
jr .rightColumn
.leftColumn ; put cursor in left column of menu
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-05-22 22:13:20 +00:00
ld a , " "
2014-08-09 05:39:13 +00:00
jr z , .safariLeftColumn
; put cursor in left column for normal battle menu (i.e. when it's not a Safari battle)
Coorda 15 , 14 ; clear upper cursor position in right column
Coorda 15 , 16 ; clear lower cursor position in right column
ld b , $ 9 ; top menu item X
jr .leftColumn_WaitForInput
.safariLeftColumn
2014-06-25 20:58:27 +00:00
Coorda 13 , 14
Coorda 13 , 16
2015-07-18 20:52:03 +00:00
coord hl , 7 , 14
2015-08-31 02:38:41 +00:00
ld de , wNumSafariBalls
2015-07-28 01:48:44 +00:00
lb bc , 1 , 2
2014-05-22 22:13:20 +00:00
call PrintNumber
2014-08-09 05:39:13 +00:00
ld b , $ 1 ; top menu item X
.leftColumn_WaitForInput
ld hl , wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , $ e
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wTopMenuItemX
2014-05-22 22:13:20 +00:00
inc hl
inc hl
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wMaxMenuItem
ld [ hl ], D_RIGHT | A_BUTTON ; wMenuWatchedKeys
2014-05-22 22:13:20 +00:00
call HandleMenuInput
2014-08-09 05:39:13 +00:00
bit 4 , a ; check if right was pressed
jr nz , .rightColumn
jr .AButtonPressed ; the A button was pressed
.rightColumn ; put cursor in right column of menu
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-05-22 22:13:20 +00:00
ld a , " "
2014-08-09 05:39:13 +00:00
jr z , .safariRightColumn
; put cursor in right column for normal battle menu (i.e. when it's not a Safari battle)
Coorda 9 , 14 ; clear upper cursor position in left column
Coorda 9 , 16 ; clear lower cursor position in left column
ld b , $ f ; top menu item X
jr .rightColumn_WaitForInput
.safariRightColumn
Coorda 1 , 14 ; clear upper cursor position in left column
Coorda 1 , 16 ; clear lower cursor position in left column
2015-07-18 20:52:03 +00:00
coord hl , 7 , 14
2015-08-31 02:38:41 +00:00
ld de , wNumSafariBalls
2015-07-28 01:48:44 +00:00
lb bc , 1 , 2
2014-05-22 22:13:20 +00:00
call PrintNumber
2014-08-09 05:39:13 +00:00
ld b , $ d ; top menu item X
.rightColumn_WaitForInput
ld hl , wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , $ e
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wTopMenuItemX
2014-05-22 22:13:20 +00:00
inc hl
inc hl
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wMaxMenuItem
ld a , D_LEFT | A_BUTTON
ld [ hli ], a ; wMenuWatchedKeys
2014-05-22 22:13:20 +00:00
call HandleMenuInput
2014-08-09 05:39:13 +00:00
bit 5 , a ; check if left was pressed
jr nz , .leftColumn ; if left was pressed, jump
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
add $ 2 ; if we're in the right column, the actual id is +2
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
.AButtonPressed
2014-05-22 22:13:20 +00:00
call PlaceUnfilledArrowMenuCursor
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2015-07-16 03:04:58 +00:00
ld [ wBattleAndStartSavedMenuItem ], a
2014-08-09 05:39:13 +00:00
jr z , .handleMenuSelection
; not Safari battle
2015-03-31 18:16:31 +00:00
; swap the IDs of the item menu and party menu (this is probably because they swapped the positions
; of these menu items in first generation English versions)
2014-08-09 05:39:13 +00:00
cp $ 1 ; was the item menu selected?
jr nz , .notItemMenu
; item menu was selected
inc a ; increment a to 2
jr .handleMenuSelection
.notItemMenu
cp $ 2 ; was the party menu selected?
jr nz , .handleMenuSelection
; party menu selected
dec a ; decrement a to 1
.handleMenuSelection
and a
jr nz , .upperLeftMenuItemWasNotSelected
; the upper left menu item was selected
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
jr z , .throwSafariBallWasSelected
; the "FIGHT" menu was selected
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wNumRunAttempts ], a
jp LoadScreenTilesFromBuffer1 ; restore saved screen and return
.throwSafariBallWasSelected
2014-05-22 22:13:20 +00:00
ld a , SAFARI_BALL
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-09-20 04:57:27 +00:00
jr UseBagItem
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
2014-05-22 22:13:20 +00:00
cp $ 2
2014-09-20 04:57:27 +00:00
jp nz , PartyMenuOrRockOrRun
2014-08-09 05:39:13 +00:00
; either the bag (normal battle) or bait (safari battle) was selected
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
jr nz , .notLinkBattle
2014-09-20 04:57:27 +00:00
2014-08-09 05:39:13 +00:00
; can't use items in link battles
2014-05-22 22:13:20 +00:00
ld hl , ItemsCantBeUsedHereText
call PrintText
2014-08-09 05:39:13 +00:00
jp Di sp layBattleMenu
2014-09-20 04:57:27 +00:00
2014-08-09 05:39:13 +00:00
.notLinkBattle
call SaveScreenTilesToBuffer2
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-09-20 04:57:27 +00:00
jr nz , BagWasSelected
2014-08-09 05:39:13 +00:00
; bait was selected
2014-05-22 22:13:20 +00:00
ld a , SAFARI_BAIT
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-09-20 04:57:27 +00:00
jr UseBagItem
BagWasSelected:
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-08-09 05:39:13 +00:00
and a ; is it a normal battle?
jr nz , .next
2014-09-20 04:57:27 +00:00
2014-08-09 05:39:13 +00:00
; normal battle
call DrawHUDsAndHPBars
.next
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-08-09 05:39:13 +00:00
dec a ; is it the old man tutorial?
2014-09-20 04:57:27 +00:00
jr nz , Di sp layPlayerBag ; no, it is a normal battle
2014-05-22 22:13:20 +00:00
ld hl , OldManItemList
ld a , l
2015-07-15 06:16:06 +00:00
ld [ wListPointer ], a
2014-05-22 22:13:20 +00:00
ld a , h
2015-07-15 06:16:06 +00:00
ld [ wListPointer + 1 ], a
2014-09-20 04:57:27 +00:00
jr Di sp layBagMenu
2014-05-22 22:13:20 +00:00
2014-09-20 04:57:27 +00:00
OldManItemList:
2014-08-08 04:17:44 +00:00
db 1 ; # items
db POKE_BALL , 50
db - 1
2014-05-22 22:13:20 +00:00
2014-09-20 04:57:27 +00:00
DisplayPlayerBag:
; get the pointer to player's bag when in a normal battle
2014-08-09 05:39:13 +00:00
ld hl , wNumBagItems
2014-05-22 22:13:20 +00:00
ld a , l
2015-07-15 06:16:06 +00:00
ld [ wListPointer ], a
2014-05-22 22:13:20 +00:00
ld a , h
2015-07-15 06:16:06 +00:00
ld [ wListPointer + 1 ], a
2014-09-20 04:57:27 +00:00
DisplayBagMenu:
2014-05-22 22:13:20 +00:00
xor a
2015-07-13 06:00:48 +00:00
ld [ wPrintItemPrices ], a
2014-08-09 05:39:13 +00:00
ld a , ITEMLISTMENU
ld [ wListMenuID ], a
2015-07-16 03:04:58 +00:00
ld a , [ wBagSavedMenuItem ]
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2014-05-22 22:13:20 +00:00
call Di sp layListMenuID
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2015-07-16 03:04:58 +00:00
ld [ wBagSavedMenuItem ], a
2014-05-22 22:13:20 +00:00
ld a , $ 0
2015-07-13 07:32:03 +00:00
ld [ wMenuWatchMovingOutOfBounds ], a
2014-08-09 05:39:13 +00:00
ld [ wMenuItemToSwap ], a
jp c , Di sp layBattleMenu ; go back to battle menu if an item was not selected
2014-09-20 04:57:27 +00:00
UseBagItem:
; either use an item from the bag or use a safari zone item
2014-05-26 21:04:56 +00:00
ld a , [ wcf91 ]
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetItemName
call CopyStringToCF4B ; copy name
xor a
2015-07-26 02:26:54 +00:00
ld [ wPseudoItemID ], a
2014-05-22 22:13:20 +00:00
call UseItem
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
jr z , .checkIfMonCaptured
2014-09-20 04:57:27 +00:00
2015-07-15 06:16:06 +00:00
ld a , [ wActionResultOrTookBattleTurn ]
2014-08-09 05:39:13 +00:00
and a ; was the item used successfully?
2014-09-20 04:57:27 +00:00
jp z , BagWasSelected ; if not, go back to the bag menu
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; is the player using a multi-turn move like wrap?
2014-08-09 05:39:13 +00:00
jr z , .checkIfMonCaptured
ld hl , wPlayerNumAttacksLeft
2014-05-22 22:13:20 +00:00
dec [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .checkIfMonCaptured
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove , [ hl ] ; not using multi-turn move any more
2014-09-20 04:57:27 +00:00
2014-08-09 05:39:13 +00:00
.checkIfMonCaptured
2015-07-25 03:27:59 +00:00
ld a , [ wCapturedMonSpecies ]
2014-08-09 05:39:13 +00:00
and a ; was the enemy mon captured with a ball?
jr nz , .returnAfterCapturingMon
2014-09-20 04:57:27 +00:00
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
jr z , .returnAfterUsingItem_NoCapture
; not a safari battle
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
call DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
call Delay3
2014-08-09 05:39:13 +00:00
.returnAfterUsingItem_NoCapture
2014-09-20 04:57:27 +00:00
2014-05-22 22:13:20 +00:00
call GBPalNormal
2014-08-09 05:39:13 +00:00
and a ; reset carry
2014-05-22 22:13:20 +00:00
ret
2014-09-20 04:57:27 +00:00
2014-08-09 05:39:13 +00:00
.returnAfterCapturingMon
2014-05-22 22:13:20 +00:00
call GBPalNormal
xor a
2015-07-25 03:27:59 +00:00
ld [ wCapturedMonSpecies ], a
2014-05-22 22:13:20 +00:00
ld a , $ 2
2014-08-09 05:39:13 +00:00
ld [ wBattleResult ], a
scf ; set carry
2014-05-22 22:13:20 +00:00
ret
2014-09-20 04:57:27 +00:00
ItemsCantBeUsedHereText:
2014-05-22 22:13:20 +00:00
TX_FAR _ItemsCantBeUsedHereText
db "@"
2014-09-20 04:57:27 +00:00
PartyMenuOrRockOrRun:
2014-08-09 05:39:13 +00:00
dec a ; was Run selected?
jp nz , BattleMenu_RunWasSelected
; party menu or rock was selected
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer2
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2015-08-30 06:35:58 +00:00
cp BATTLE_TYPE_SAFARI
2014-08-09 05:39:13 +00:00
jr nz , .partyMenuWasSelected
; safari battle
2014-05-22 22:13:20 +00:00
ld a , SAFARI_ROCK
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-09-20 04:57:27 +00:00
jp UseBagItem
2014-08-09 05:39:13 +00:00
.partyMenuWasSelected
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-07-13 22:40:33 +00:00
xor a ; NORMAL_PARTY_MENU
ld [ wPartyMenuTypeOrMessageID ], a
2014-08-09 05:39:13 +00:00
ld [ wMenuItemToSwap ], a
2014-05-22 22:13:20 +00:00
call Di sp layPartyMenu
2014-08-09 05:39:13 +00:00
.checkIfPartyMonWasSelected
jp nc , .partyMonWasSelected ; if a party mon was selected, jump, else we quit the party menu
.quitPartyMenu
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-05-22 22:13:20 +00:00
call GBPalWhiteOut
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer2
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
call GBPalNormal
2014-08-09 05:39:13 +00:00
jp Di sp layBattleMenu
.partyMonDeselected
2015-07-18 20:52:03 +00:00
coord hl , 11 , 11
2015-08-10 04:56:20 +00:00
ld bc , 6 * SCREEN_WIDTH + 9
2015-08-05 21:20:29 +00:00
ld a , " "
2014-05-22 22:13:20 +00:00
call FillMemory
2015-07-13 22:40:33 +00:00
xor a ; NORMAL_PARTY_MENU
ld [ wPartyMenuTypeOrMessageID ], a
2014-05-22 22:13:20 +00:00
call GoBackToPartyMenu
2014-08-09 05:39:13 +00:00
jr .checkIfPartyMonWasSelected
.partyMonWasSelected
2015-02-07 20:27:36 +00:00
ld a , SWITCH_STATS_CANCEL_MENU_TEMPLATE
2015-02-07 10:43:08 +00:00
ld [ wTextBoxID ], a
2014-05-22 22:13:20 +00:00
call Di sp layTextBoxID
2014-08-09 05:39:13 +00:00
ld hl , wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , $ c
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wTopMenuItemY
ld [ hli ], a ; wTopMenuItemX
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wCurrentMenuItem
2014-05-22 22:13:20 +00:00
inc hl
ld a , $ 2
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; wMaxMenuItem
ld a , B_BUTTON | A_BUTTON
ld [ hli ], a ; wMenuWatchedKeys
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ hl ], a ; wLastMenuItem
2014-05-22 22:13:20 +00:00
call HandleMenuInput
2014-08-09 05:39:13 +00:00
bit 1 , a ; was A pressed?
jr nz , .partyMonDeselected ; if B was pressed, jump
; A was pressed
2014-05-22 22:13:20 +00:00
call PlaceUnfilledArrowMenuCursor
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
cp $ 2 ; was Cancel selected?
jr z , .quitPartyMenu ; if so, quit the party menu entirely
and a ; was Switch selected?
jr z , .switchMon ; if so, jump
; Stats was selected
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [ wMonDataLocation ], a
2014-08-09 05:39:13 +00:00
ld hl , wPartyMon1
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-08-09 05:39:13 +00:00
; display the two status screens
2014-06-16 20:57:26 +00:00
predef StatusScreen
predef StatusScreen2
2014-08-09 05:39:13 +00:00
; now we need to reload the enemy mon pic
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit HasSubstituteUp , a ; does the enemy mon have a substitute?
2014-05-22 22:13:20 +00:00
ld hl , AnimationSubstitute
2014-08-09 05:39:13 +00:00
jr nz , .doEnemyMonAnimation
; enemy mon doesn't have substitute
2015-07-12 22:51:04 +00:00
ld a , [ wEnemyMonMinimized ]
2014-08-09 05:39:13 +00:00
and a ; has the enemy mon used Minimise?
2014-05-22 22:13:20 +00:00
ld hl , AnimationMinimizeMon
2014-08-09 05:39:13 +00:00
jr nz , .doEnemyMonAnimation
; enemy mon is not minimised
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies ]
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-05-29 08:31:46 +00:00
ld de , vFrontPic
2014-05-22 22:13:20 +00:00
call LoadMonFrontSprite
2014-08-09 05:39:13 +00:00
jr .enemyMonPicReloaded
.doEnemyMonAnimation
2014-05-22 22:13:20 +00:00
ld b , BANK ( AnimationSubstitute ) ; BANK(AnimationMinimizeMon)
call Bankswitch
2014-08-09 05:39:13 +00:00
.enemyMonPicReloaded ; enemy mon pic has been reloaded, so return to the party menu
jp .partyMenuWasSelected
.switchMon
ld a , [ wPlayerMonNumber ]
2014-05-22 22:13:20 +00:00
ld d , a
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
cp d ; check if the mon to switch to is already out
jr nz , .notAlreadyOut
; mon is already out
2014-05-22 22:13:20 +00:00
ld hl , Al readyOutText
call PrintText
2014-08-09 05:39:13 +00:00
jp .partyMonDeselected
.notAlreadyOut
call HasMonFainted
jp z , .partyMonDeselected ; can't switch to fainted mon
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-22 22:13:20 +00:00
call GBPalWhiteOut
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
call GBPalNormal
2014-08-09 05:39:13 +00:00
; fall through to SwitchPlayerMon
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SwitchPlayerMon:
2014-05-22 22:13:20 +00:00
callab RetreatMon
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2014-08-09 05:39:13 +00:00
call AnimateRetreatingPlayerMon
ld a , [ wWhichPokemon ]
ld [ wPlayerMonNumber ], a
2014-05-22 22:13:20 +00:00
ld c , a
2015-07-20 03:45:34 +00:00
ld b , FLAG_SET
2014-05-22 22:13:20 +00:00
push bc
2014-08-09 05:39:13 +00:00
ld hl , wPartyGainExpFlags
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
ld hl , wPartyFoughtCurrentEnemyFlags
2014-06-16 20:57:26 +00:00
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
call LoadBattleMonFromParty
call SendOutMon
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
ld a , $ 2
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2014-05-22 22:13:20 +00:00
and a
ret
2016-06-12 00:24:04 +00:00
AlreadyOutText:
2014-05-22 22:13:20 +00:00
TX_FAR _AlreadyOutText
db "@"
2016-06-12 00:24:04 +00:00
BattleMenu_RunWasSelected:
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
ld a , $ 3
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonSpeed
ld de , wEnemyMonSpeed
2014-08-09 05:39:13 +00:00
call TryRunningFromBattle
2015-07-25 03:27:59 +00:00
ld a , 0
ld [ wForcePlayerToChooseMon ], a
2014-05-22 22:13:20 +00:00
ret c
2015-07-15 06:16:06 +00:00
ld a , [ wActionResultOrTookBattleTurn ]
2014-05-22 22:13:20 +00:00
and a
2015-07-15 06:16:06 +00:00
ret nz ; return if the player couldn't escape
2014-08-09 05:39:13 +00:00
jp Di sp layBattleMenu
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MoveSelectionMenu:
2014-05-22 22:13:20 +00:00
ld a , [ wMoveMenuType ]
dec a
jr z , .mimicmenu
dec a
jr z , .relearnmenu
jr .regularmenu
.loadmoves
2015-02-08 08:17:03 +00:00
ld de , wMoves
ld bc , NUM_MOVES
2014-05-22 22:13:20 +00:00
call CopyData
2015-02-08 08:17:03 +00:00
callab FormatMovesString
2014-05-22 22:13:20 +00:00
ret
.writemoves
2015-02-08 08:17:03 +00:00
ld de , wMovesString
2015-02-08 00:24:16 +00:00
ld a , [ hFlags_0xFFF6 ]
2014-05-22 22:13:20 +00:00
set 2 , a
2015-02-08 00:24:16 +00:00
ld [ hFlags_0xFFF6 ], a
2014-05-22 22:13:20 +00:00
call PlaceString
2015-02-08 00:24:16 +00:00
ld a , [ hFlags_0xFFF6 ]
2014-05-22 22:13:20 +00:00
res 2 , a
2015-02-08 00:24:16 +00:00
ld [ hFlags_0xFFF6 ], a
2014-05-22 22:13:20 +00:00
ret
.regularmenu
2015-01-31 17:26:05 +00:00
call AnyMoveToSelect
2014-05-22 22:13:20 +00:00
ret z
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-05-22 22:13:20 +00:00
call .loadmoves
2015-07-18 20:52:03 +00:00
coord hl , 4 , 12
2016-06-12 04:30:05 +00:00
ld b , 4
ld c , 14
di ; out of pure coincidence, it is possible for vblank to occur between the di and ei
; so it is necessary to put the di ei block to not cause tearing
2014-05-22 22:13:20 +00:00
call TextBoxBorder
2015-07-18 20:52:03 +00:00
coord hl , 4 , 12
2014-05-22 22:13:20 +00:00
ld [ hl ], $ 7 a
2015-07-18 20:52:03 +00:00
coord hl , 10 , 12
2014-05-22 22:13:20 +00:00
ld [ hl ], $ 7 e
ei
2015-07-18 20:52:03 +00:00
coord hl , 6 , 13
2014-05-22 22:13:20 +00:00
call .writemoves
ld b , $ 5
ld a , $ c
jr .menuset
.mimicmenu
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2014-05-22 22:13:20 +00:00
call .loadmoves
2015-07-18 20:52:03 +00:00
coord hl , 0 , 7
2016-06-12 04:30:05 +00:00
ld b , 4
ld c , 14
2014-05-22 22:13:20 +00:00
call TextBoxBorder
2015-07-18 20:52:03 +00:00
coord hl , 2 , 8
2014-05-22 22:13:20 +00:00
call .writemoves
ld b , $ 1
ld a , $ 7
jr .menuset
.relearnmenu
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
ld hl , wPartyMon1Moves
2015-08-05 21:20:29 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
call .loadmoves
2015-07-18 20:52:03 +00:00
coord hl , 4 , 7
2016-06-12 04:30:05 +00:00
ld b , 4
ld c , 14
2014-05-22 22:13:20 +00:00
call TextBoxBorder
2015-07-18 20:52:03 +00:00
coord hl , 6 , 8
2014-05-22 22:13:20 +00:00
call .writemoves
ld b , $ 5
ld a , $ 7
.menuset
2014-08-09 05:39:13 +00:00
ld hl , wTopMenuItemY
2015-07-15 06:16:06 +00:00
ld [ hli ], a ; wTopMenuItemY
2014-05-22 22:13:20 +00:00
ld a , b
2015-07-15 06:16:06 +00:00
ld [ hli ], a ; wTopMenuItemX
2014-05-22 22:13:20 +00:00
ld a , [ wMoveMenuType ]
cp $ 1
jr z , .selectedmoveknown
ld a , $ 1
jr nc , .selectedmoveknown
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMoveListIndex ]
2014-05-22 22:13:20 +00:00
inc a
.selectedmoveknown
2015-07-15 06:16:06 +00:00
ld [ hli ], a ; wCurrentMenuItem
2014-05-22 22:13:20 +00:00
inc hl ; wTileBehindCursor untouched
2015-07-15 06:16:06 +00:00
ld a , [ wNumMovesMinusOne ]
2014-05-22 22:13:20 +00:00
inc a
inc a
2015-07-15 06:16:06 +00:00
ld [ hli ], a ; wMaxMenuItem
2014-05-22 22:13:20 +00:00
ld a , [ wMoveMenuType ]
dec a
2015-07-15 06:16:06 +00:00
ld b , D_UP | D_DOWN | A_BUTTON
2014-05-22 22:13:20 +00:00
jr z , .matchedkeyspicked
dec a
2015-07-15 06:16:06 +00:00
ld b , D_UP | D_DOWN | A_BUTTON | B_BUTTON
2014-05-22 22:13:20 +00:00
jr z , .matchedkeyspicked
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr z , .matchedkeyspicked
2015-08-31 02:38:41 +00:00
ld a , [ wFlags_D733 ]
2015-08-14 02:13:47 +00:00
bit BIT_TEST_BATTLE , a
2015-07-15 06:16:06 +00:00
ld b , D_UP | D_DOWN | A_BUTTON | B_BUTTON | SELECT
2014-05-22 22:13:20 +00:00
jr z , .matchedkeyspicked
ld b , $ ff
.matchedkeyspicked
ld a , b
2015-07-15 06:16:06 +00:00
ld [ hli ], a ; wMenuWatchedKeys
2014-05-22 22:13:20 +00:00
ld a , [ wMoveMenuType ]
cp $ 1
jr z , .movelistindex1
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMoveListIndex ]
2014-05-22 22:13:20 +00:00
inc a
.movelistindex1
2014-08-09 05:39:13 +00:00
ld [ hl ], a
2015-01-31 17:26:05 +00:00
; fallthrough
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SelectMenuItem:
2014-05-22 22:13:20 +00:00
ld a , [ wMoveMenuType ]
and a
jr z , .battleselect
dec a
jr nz , .select
2015-07-18 20:52:03 +00:00
coord hl , 1 , 14
2014-08-09 05:39:13 +00:00
ld de , WhichTechniqueString
2014-05-22 22:13:20 +00:00
call PlaceString
jr .select
.battleselect
2015-08-31 02:38:41 +00:00
ld a , [ wFlags_D733 ]
2015-08-14 02:13:47 +00:00
bit BIT_TEST_BATTLE , a
2014-05-22 22:13:20 +00:00
jr nz , .select
2015-01-31 17:26:05 +00:00
call PrintMenuItem
2014-08-09 05:39:13 +00:00
ld a , [ wMenuItemToSwap ]
2014-05-22 22:13:20 +00:00
and a
jr z , .select
2015-07-18 20:52:03 +00:00
coord hl , 5 , 13
2014-05-22 22:13:20 +00:00
dec a
2015-08-05 21:20:29 +00:00
ld bc , SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
call AddNTimes
2016-07-18 06:17:03 +00:00
ld [ hl ], "▷"
2014-05-22 22:13:20 +00:00
.select
2015-02-08 00:24:16 +00:00
ld hl , hFlags_0xFFF6
2014-05-22 22:13:20 +00:00
set 1 , [ hl ]
call HandleMenuInput
2015-02-08 00:24:16 +00:00
ld hl , hFlags_0xFFF6
2014-05-22 22:13:20 +00:00
res 1 , [ hl ]
bit 6 , a
2016-06-12 04:30:05 +00:00
jp nz , SelectMenuItem_CursorUp ; up
2014-05-22 22:13:20 +00:00
bit 7 , a
2016-06-12 04:30:05 +00:00
jp nz , SelectMenuItem_CursorDown ; down
2014-05-22 22:13:20 +00:00
bit 2 , a
2014-08-09 05:39:13 +00:00
jp nz , SwapMovesInMenu ; select
2014-05-22 22:13:20 +00:00
bit 1 , a ; B, but was it reset above?
push af
xor a
2014-08-09 05:39:13 +00:00
ld [ wMenuItemToSwap ], a
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2014-05-22 22:13:20 +00:00
ld b , a
ld a , [ wMoveMenuType ]
dec a ; if not mimic
2016-06-12 04:30:05 +00:00
jr nz , .notB
2014-05-22 22:13:20 +00:00
pop af
ret
2016-06-12 04:30:05 +00:00
.notB
2014-05-22 22:13:20 +00:00
dec a
ld a , b
2014-08-09 05:39:13 +00:00
ld [ wPlayerMoveListIndex ], a
2014-05-22 22:13:20 +00:00
jr nz , .moveselected
pop af
ret
.moveselected
pop af
ret nz
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonPP
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld a , [ hl ]
and $ 3 f
2016-06-12 04:30:05 +00:00
jr z , .noPP
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerDisabledMove ]
2014-05-22 22:13:20 +00:00
swap a
and $ f
dec a
cp c
jr z , .disabled
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus3 ]
2014-05-22 22:13:20 +00:00
bit 3 , a ; transformed
jr nz , .dummy ; game freak derp
.dummy
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ wPlayerSelectedMove ], a
2014-05-22 22:13:20 +00:00
xor a
ret
.disabled
ld hl , MoveDisabledText
jr .print
2016-06-12 04:30:05 +00:00
.noPP
2014-05-22 22:13:20 +00:00
ld hl , MoveNoPPText
.print
call PrintText
call LoadScreenTilesFromBuffer1
jp MoveSelectionMenu
2016-06-12 00:24:04 +00:00
MoveNoPPText:
2014-05-22 22:13:20 +00:00
TX_FAR _MoveNoPPText
db "@"
2016-06-12 00:24:04 +00:00
MoveDisabledText:
2014-05-22 22:13:20 +00:00
TX_FAR _MoveDisabledText
db "@"
2016-06-12 00:24:04 +00:00
WhichTechniqueString:
2014-05-22 22:13:20 +00:00
db "WHICH TECHNIQUE?@"
2016-06-12 04:30:05 +00:00
SelectMenuItem_CursorUp:
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jp nz , SelectMenuItem
2014-05-22 22:13:20 +00:00
call EraseMenuCursor
2015-07-15 06:16:06 +00:00
ld a , [ wNumMovesMinusOne ]
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2015-01-31 17:26:05 +00:00
jp SelectMenuItem
2014-05-22 22:13:20 +00:00
2016-06-12 04:30:05 +00:00
SelectMenuItem_CursorDown:
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-07-15 06:16:06 +00:00
ld a , [ wNumMovesMinusOne ]
2014-05-22 22:13:20 +00:00
inc a
inc a
cp b
2015-01-31 17:26:05 +00:00
jp nz , SelectMenuItem
2014-05-22 22:13:20 +00:00
call EraseMenuCursor
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ wCurrentMenuItem ], a
2015-01-31 17:26:05 +00:00
jp SelectMenuItem
2016-06-12 00:24:04 +00:00
AnyMoveToSelect:
2015-01-31 17:26:05 +00:00
; return z and Struggle as the selected move if all moves have 0 PP and/or are disabled
2014-08-09 05:39:13 +00:00
ld a , STRUGGLE
ld [ wPlayerSelectedMove ], a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerDisabledMove ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonPP
2016-06-12 04:30:05 +00:00
jr nz , .handleDisabledMove
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
or [ hl ]
inc hl
or [ hl ]
inc hl
or [ hl ]
and $ 3 f
ret nz
2016-06-12 04:30:05 +00:00
jr .noMovesLeft
.handleDisabledMove
2014-05-22 22:13:20 +00:00
swap a
2016-06-12 04:30:05 +00:00
and $ f ; get disabled move
2014-05-22 22:13:20 +00:00
ld b , a
2016-06-12 04:30:05 +00:00
ld d , NUM_MOVES + 1
2014-05-22 22:13:20 +00:00
xor a
2016-06-12 04:30:05 +00:00
.handleDisabledMovePPLoop
2014-05-22 22:13:20 +00:00
dec d
2016-06-12 04:30:05 +00:00
jr z , .allMovesChecked
ld c , [ hl ] ; get move PP
2014-05-22 22:13:20 +00:00
inc hl
2016-06-12 04:30:05 +00:00
dec b ; is this the disabled move?
jr z , .handleDisabledMovePPLoop ; if so, ignore its PP value
2014-05-22 22:13:20 +00:00
or c
2016-06-12 04:30:05 +00:00
jr .handleDisabledMovePPLoop
.allMovesChecked
and a ; any PP left?
ret nz ; return if a move has PP left
.noMovesLeft
2014-05-22 22:13:20 +00:00
ld hl , NoMovesLeftText
call PrintText
2015-07-03 19:37:53 +00:00
ld c , 60
2014-05-22 22:13:20 +00:00
call DelayFrames
xor a
ret
2016-06-12 00:24:04 +00:00
NoMovesLeftText:
2014-05-22 22:13:20 +00:00
TX_FAR _NoMovesLeftText
db "@"
2016-06-12 00:24:04 +00:00
SwapMovesInMenu:
2014-08-09 05:39:13 +00:00
ld a , [ wMenuItemToSwap ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .noMenuItemSelected
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-08-09 05:39:13 +00:00
call .swapBytes ; swap moves
ld hl , wBattleMonPP
call .swapBytes ; swap move PP
; update the index of the disabled move if necessary
2015-08-31 02:38:41 +00:00
ld hl , wPlayerDisabledMove
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
swap a
and $ f
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
cp b
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
and $ f
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wMenuItemToSwap ]
2014-05-22 22:13:20 +00:00
swap a
add b
ld [ hl ], a
2014-08-09 05:39:13 +00:00
jr .swapMovesInPartyMon
.next
ld a , [ wMenuItemToSwap ]
2014-05-22 22:13:20 +00:00
cp b
2014-08-09 05:39:13 +00:00
jr nz , .swapMovesInPartyMon
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
and $ f
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
swap a
add b
ld [ hl ], a
2014-08-09 05:39:13 +00:00
.swapMovesInPartyMon
ld hl , wPartyMon1Moves
ld a , [ wPlayerMonNumber ]
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
push hl
2014-08-09 05:39:13 +00:00
call .swapBytes ; swap moves
2014-05-22 22:13:20 +00:00
pop hl
2015-08-05 21:20:29 +00:00
ld bc , wPartyMon1PP - wPartyMon1Moves
2014-05-22 22:13:20 +00:00
add hl , bc
2014-08-09 05:39:13 +00:00
call .swapBytes ; swap move PP
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wMenuItemToSwap ], a ; deselect the item
2014-05-22 22:13:20 +00:00
jp MoveSelectionMenu
2014-08-09 05:39:13 +00:00
.swapBytes
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld a , [ wMenuItemToSwap ]
2014-05-22 22:13:20 +00:00
dec a
ld c , a
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
ld d , h
ld e , l
pop hl
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
dec a
ld c , a
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ de ]
ld b , [ hl ]
ld [ hl ], a
ld a , b
ld [ de ], a
ret
2014-08-09 05:39:13 +00:00
.noMenuItemSelected
ld a , [ wCurrentMenuItem ]
ld [ wMenuItemToSwap ], a ; select the current menu item for swapping
2014-05-22 22:13:20 +00:00
jp MoveSelectionMenu
2016-06-12 00:24:04 +00:00
PrintMenuItem:
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2015-07-18 20:52:03 +00:00
coord hl , 0 , 8
2016-06-12 04:30:05 +00:00
ld b , 3
ld c , 9
2014-05-22 22:13:20 +00:00
call TextBoxBorder
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerDisabledMove ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr z , .notDisabled
2014-05-22 22:13:20 +00:00
swap a
and $ f
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
cp b
2015-01-31 17:26:05 +00:00
jr nz , .notDisabled
2015-07-18 20:52:03 +00:00
coord hl , 1 , 10
2014-05-22 22:13:20 +00:00
ld de , Di sabledText
call PlaceString
2015-01-31 17:26:05 +00:00
jr .moveDisabled
.notDisabled
2014-08-09 05:39:13 +00:00
ld hl , wCurrentMenuItem
2014-05-22 22:13:20 +00:00
dec [ hl ]
xor a
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld c , a
2015-01-31 17:26:05 +00:00
ld b , $ 0 ; which item in the menu is the cursor pointing to? (0-3)
add hl , bc ; point to the item (move) in memory
2015-06-11 22:41:33 +00:00
ld a , [ hl ]
ld [ wPlayerSelectedMove ], a ; update wPlayerSelectedMove even if the move
2015-01-31 17:26:05 +00:00
; isn't actually selected (just pointed to by the cursor)
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMonNumber ]
ld [ wWhichPokemon ], a
2015-07-16 03:04:58 +00:00
ld a , BATTLE_MON_DATA
ld [ wMonDataLocation ], a
2014-05-22 22:13:20 +00:00
callab GetMaxPP
2014-08-09 05:39:13 +00:00
ld hl , wCurrentMenuItem
2014-05-22 22:13:20 +00:00
ld c , [ hl ]
inc [ hl ]
ld b , $ 0
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonPP
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ hl ]
and $ 3 f
2014-05-26 21:04:56 +00:00
ld [ wcd6d ], a
2015-06-11 22:41:33 +00:00
; print TYPE/<type> and <curPP>/<maxPP>
2015-07-18 20:52:03 +00:00
coord hl , 1 , 9
2014-05-22 22:13:20 +00:00
ld de , TypeText
call PlaceString
2015-07-18 20:52:03 +00:00
coord hl , 7 , 11
2014-05-22 22:13:20 +00:00
ld [ hl ], "/"
2015-07-18 20:52:03 +00:00
coord hl , 5 , 9
2014-05-22 22:13:20 +00:00
ld [ hl ], "/"
2015-07-18 20:52:03 +00:00
coord hl , 5 , 11
2014-05-26 21:04:56 +00:00
ld de , wcd6d
2015-07-28 01:48:44 +00:00
lb bc , 1 , 2
2014-05-22 22:13:20 +00:00
call PrintNumber
2015-07-18 20:52:03 +00:00
coord hl , 8 , 11
2015-08-07 12:20:37 +00:00
ld de , wMaxPP
2015-07-28 01:48:44 +00:00
lb bc , 1 , 2
2014-05-22 22:13:20 +00:00
call PrintNumber
2015-06-11 22:41:33 +00:00
call GetCurrentMove
2015-07-18 20:52:03 +00:00
coord hl , 2 , 10
2015-02-08 00:24:16 +00:00
predef PrintMoveType
2015-01-31 17:26:05 +00:00
.moveDisabled
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
jp Delay3
2016-06-12 00:24:04 +00:00
DisabledText:
2014-05-22 22:13:20 +00:00
db "disabled!@"
2016-06-12 00:24:04 +00:00
TypeText:
2014-05-22 22:13:20 +00:00
db "TYPE@"
2016-06-12 00:24:04 +00:00
SelectEnemyMove:
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
2015-07-15 06:16:06 +00:00
sub LINK_STATE_BATTLING
2014-05-22 22:13:20 +00:00
jr nz , .noLinkBattle
2014-08-09 05:39:13 +00:00
; link battle
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
call LinkBattleExchangeData
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_STRUGGLE
2016-06-12 04:30:05 +00:00
jp z , .linkedOpponentUsedStruggle
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_NO_ACTION
2015-02-03 19:51:53 +00:00
jr z , .unableToSelectMove
2016-10-29 08:44:13 +00:00
cp 4
2014-05-22 22:13:20 +00:00
ret nc
2014-05-26 21:04:56 +00:00
ld [ wEnemyMoveListIndex ], a
2014-05-22 22:13:20 +00:00
ld c , a
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2016-10-29 08:44:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ hl ]
jr .done
.noLinkBattle
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
and ( 1 << NeedsToRecharge ) | ( 1 << UsingRage ) ; need to recharge or using rage
2014-05-22 22:13:20 +00:00
ret nz
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-02-03 19:51:53 +00:00
and ( 1 << Ch argingUp ) | ( 1 << ThrashingAbout ) ; using a charging move or thrash/petal dance
2014-05-22 22:13:20 +00:00
ret nz
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonStatus ]
2014-05-22 22:13:20 +00:00
and SLP | 1 << FRZ ; sleeping or frozen
ret nz
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus1 ]
2015-02-03 19:51:53 +00:00
and ( 1 << UsingTrappingMove ) | ( 1 << StoringEnergy ) ; using a trapping move like wrap or bide
2014-05-22 22:13:20 +00:00
ret nz
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; caught in player's trapping move (e.g. wrap)
jr z , .canSelectMove
.unableToSelectMove
2014-05-22 22:13:20 +00:00
ld a , $ ff
jr .done
2015-02-03 19:51:53 +00:00
.canSelectMove
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves + 1 ; 2nd enemy move
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
and a
jr nz , .atLeastTwoMovesAvailable
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyDisabledMove ]
2014-05-22 22:13:20 +00:00
and a
ld a , STRUGGLE ; struggle if the only move is disabled
jr nz , .done
.atLeastTwoMovesAvailable
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
jr z , .chooseRandomMove ; wild encounter
callab AIEnemyTrainerChooseMoves
.chooseRandomMove
push hl
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
ld b , $ 1
2015-07-25 03:27:59 +00:00
cp $ 3 f ; select move 1, [0,3e] (63/256 chance)
2014-05-22 22:13:20 +00:00
jr c , .moveChosen
inc hl
inc b
2015-07-25 03:27:59 +00:00
cp $ 7 f ; select move 2, [3f,7e] (64/256 chance)
2014-05-22 22:13:20 +00:00
jr c , .moveChosen
inc hl
inc b
2015-07-25 03:27:59 +00:00
cp $ be ; select move 3, [7f,bd] (63/256 chance)
2014-05-22 22:13:20 +00:00
jr c , .moveChosen
inc hl
2015-07-25 03:27:59 +00:00
inc b ; select move 4, [be,ff] (66/256 chance)
2014-05-22 22:13:20 +00:00
.moveChosen
ld a , b
dec a
ld [ wEnemyMoveListIndex ], a
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyDisabledMove ]
2014-05-22 22:13:20 +00:00
swap a
and $ f
cp b
ld a , [ hl ]
pop hl
jr z , .chooseRandomMove ; move disabled, try again
and a
jr z , .chooseRandomMove ; move non-existant, try again
.done
ld [ wEnemySelectedMove ], a
ret
2016-06-12 04:30:05 +00:00
.linkedOpponentUsedStruggle
2014-08-09 05:39:13 +00:00
ld a , STRUGGLE
2014-05-22 22:13:20 +00:00
jr .done
2014-08-09 05:39:13 +00:00
; this appears to exchange data with the other gameboy during link battles
2016-06-12 00:24:04 +00:00
LinkBattleExchangeData:
2014-05-22 22:13:20 +00:00
ld a , $ ff
2015-02-07 10:43:08 +00:00
ld [ wSerialExchangeNybbleReceiveData ], a
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMoveListIndex ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_RUN ; is the player running from battle?
2015-07-15 06:16:06 +00:00
jr z , .doExchange
ld a , [ wActionResultOrTookBattleTurn ]
and a ; is the player switching in another mon?
jr nz , .switching
; the player used a move
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerSelectedMove ]
cp STRUGGLE
2016-10-29 08:44:13 +00:00
ld b , LINKBATTLE_STRUGGLE
2015-07-15 06:16:06 +00:00
jr z , .next
2016-10-29 09:04:48 +00:00
dec b ; LINKBATTLE_NO_ACTION
inc a ; does move equal -1 (i.e. no action)?
2015-07-15 06:16:06 +00:00
jr z , .next
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMoveListIndex ]
2015-07-15 06:16:06 +00:00
jr .doExchange
.switching
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2015-07-15 06:16:06 +00:00
add 4
2014-05-22 22:13:20 +00:00
ld b , a
2015-07-15 06:16:06 +00:00
.next
2014-05-22 22:13:20 +00:00
ld a , b
2015-07-15 06:16:06 +00:00
.doExchange
2015-02-07 10:43:08 +00:00
ld [ wSerialExchangeNybbleSendData ], a
2014-05-22 22:13:20 +00:00
callab PrintWaitingText
2015-07-15 06:16:06 +00:00
.syncLoop1
2015-02-07 10:43:08 +00:00
call Serial_ExchangeNybble
2014-05-22 22:13:20 +00:00
call DelayFrame
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2014-05-22 22:13:20 +00:00
inc a
2015-07-15 06:16:06 +00:00
jr z , .syncLoop1
ld b , 10
.syncLoop2
2014-05-22 22:13:20 +00:00
call DelayFrame
2015-02-07 10:43:08 +00:00
call Serial_ExchangeNybble
2014-05-22 22:13:20 +00:00
dec b
2015-07-15 06:16:06 +00:00
jr nz , .syncLoop2
ld b , 10
.syncLoop3
2014-05-22 22:13:20 +00:00
call DelayFrame
2015-02-07 10:43:08 +00:00
call Serial_SendZeroByte
2014-05-22 22:13:20 +00:00
dec b
2015-07-15 06:16:06 +00:00
jr nz , .syncLoop3
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
ExecutePlayerMove:
2014-05-22 22:13:20 +00:00
xor a
2015-01-04 16:47:21 +00:00
ld [ H_WHOSETURN ], a ; set player's turn
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerSelectedMove ]
2014-05-22 22:13:20 +00:00
inc a
2015-01-20 19:21:16 +00:00
jp z , ExecutePlayerMoveDone ; for selected move = FF, skip most of player's turn
2014-05-22 22:13:20 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2015-03-31 18:40:22 +00:00
ld [ wMonIsDisobedient ], a
2015-03-31 18:28:42 +00:00
ld [ wMoveDidntMiss ], a
2014-05-22 22:13:20 +00:00
ld a , $ a
2015-03-31 18:28:42 +00:00
ld [ wDamageMultipliers ], a
2015-07-15 06:16:06 +00:00
ld a , [ wActionResultOrTookBattleTurn ]
and a ; has the player already used the turn (e.g. by using an item, trying to run or switching pokemon)
2015-01-20 19:21:16 +00:00
jp nz , ExecutePlayerMoveDone
2014-05-22 22:13:20 +00:00
call PrintGhostText
2015-01-20 19:21:16 +00:00
jp z , ExecutePlayerMoveDone
2014-08-09 05:39:13 +00:00
call Ch eckPlayerStatusConditions
2015-01-31 17:26:05 +00:00
jr nz , .playerHasNoSpecialCondition
2014-05-22 22:13:20 +00:00
jp [ hl ]
2015-01-31 17:26:05 +00:00
.playerHasNoSpecialCondition
2014-05-22 22:13:20 +00:00
call GetCurrentMove
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
bit Ch argingUp , [ hl ] ; charging up for attack
2015-01-20 19:21:16 +00:00
jr nz , PlayerCanExecuteChargingMove
2014-08-09 05:39:13 +00:00
call Ch eckForDisobedience
2015-01-20 19:21:16 +00:00
jp z , ExecutePlayerMoveDone
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
CheckIfPlayerNeedsToChargeUp:
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp CH ARGE_EFFECT
2014-08-09 05:39:13 +00:00
jp z , JumpMoveEffect
2014-05-22 22:13:20 +00:00
cp FLY_EFFECT
2014-08-09 05:39:13 +00:00
jp z , JumpMoveEffect
2015-01-20 19:21:16 +00:00
jr PlayerCanExecuteMove
2014-05-22 22:13:20 +00:00
; in-battle stuff
2016-06-12 00:24:04 +00:00
PlayerCanExecuteChargingMove:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res Ch argingUp ,[ hl ] ; reset charging up and invulnerability statuses if mon was charging up for an attack
2015-03-31 18:16:31 +00:00
; being fully paralyzed or hurting oneself in confusion removes charging up status
; resulting in the Pokemon being invulnerable for the whole battle
2015-02-03 19:51:53 +00:00
res Invulnerable ,[ hl ]
2016-06-12 00:24:04 +00:00
PlayerCanExecuteMove:
2014-05-22 22:13:20 +00:00
call PrintMonName1Text
ld hl , DecrementPP
2014-05-26 21:04:56 +00:00
ld de , wPlayerSelectedMove ; pointer to the move just used
2014-05-22 22:13:20 +00:00
ld b , BANK ( DecrementPP )
call Bankswitch
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ] ; effect of the move just used
2015-01-20 19:21:16 +00:00
ld hl , ResidualEffects1
2014-05-22 22:13:20 +00:00
ld de , 1
call IsInArray
2015-06-11 22:41:33 +00:00
jp c , JumpMoveEffect ; ResidualEffects1 moves skip damage calculation and accuracy tests
; unless executed as part of their exclusive effect functions
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , Sp ecialEffectsCont
2014-05-22 22:13:20 +00:00
ld de , 1
call IsInArray
2015-06-11 22:41:33 +00:00
call c , JumpMoveEffect ; execute the effects of SpecialEffectsCont moves (e.g. Wrap, Thrash) but don't skip anything
2016-06-12 00:24:04 +00:00
PlayerCalcMoveDamage:
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , SetDamageEffects
2014-05-22 22:13:20 +00:00
ld de , 1
2015-01-23 03:05:13 +00:00
call IsInArray
jp c , .moveHitTest ; SetDamageEffects moves (e.g. Seismic Toss and Super Fang) skip damage calculation
2014-05-22 22:13:20 +00:00
call CriticalHitTest
call HandleCounterMove
2015-03-31 20:22:12 +00:00
jr z , handleIfPlayerMoveMissed
2014-08-09 05:39:13 +00:00
call GetDamageVarsForPlayerAttack
2014-05-22 22:13:20 +00:00
call CalculateDamage
2015-03-31 20:22:12 +00:00
jp z , playerCheckIfFlyOrChargeEffect ; for moves with 0 BP, skip any further damage calculation and, for now, skip MoveHitTest
2015-01-31 17:26:05 +00:00
; for these moves, accuracy tests will only occur if they are called as part of the effect itself
2014-05-22 22:13:20 +00:00
call AdjustDamageForMoveType
2014-08-09 05:39:13 +00:00
call RandomizeDamage
2015-01-20 19:21:16 +00:00
.moveHitTest
2014-05-22 22:13:20 +00:00
call MoveHitTest
2016-06-12 04:30:05 +00:00
handleIfPlayerMoveMissed:
2015-08-31 02:38:41 +00:00
ld a ,[ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-03-31 20:22:12 +00:00
jr z , getPlayerAnimationType
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-06-11 22:41:33 +00:00
sub a , EXPLODE_EFFECT
2015-03-31 20:22:12 +00:00
jr z , playPlayerMoveAnimation ; don't play any animation if the move missed, unless it was EXPLODE_EFFECT
jr playerCheckIfFlyOrChargeEffect
2016-06-12 04:30:05 +00:00
getPlayerAnimationType:
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
and a
2015-03-31 20:22:12 +00:00
ld a , 4 ; move has no effect other than dealing damage
jr z , playPlayerMoveAnimation
ld a , 5 ; move has effect
2016-06-12 04:30:05 +00:00
playPlayerMoveAnimation:
2014-05-22 22:13:20 +00:00
push af
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus2 ]
2015-07-12 22:51:04 +00:00
bit HasSubstituteUp , a
ld hl , HideSubstituteShowMonAnim
ld b , BANK ( HideSubstituteShowMonAnim )
2014-05-22 22:13:20 +00:00
call nz , Bankswitch
pop af
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveNum ]
2014-05-22 22:13:20 +00:00
call PlayMoveAnimation
2015-01-20 19:21:16 +00:00
call HandleExplodingAnimation
2014-08-09 05:39:13 +00:00
call DrawPlayerHUDAndHPBar
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus2 ]
2015-07-12 22:51:04 +00:00
bit HasSubstituteUp , a
ld hl , ReshowSubstituteAnim
ld b , BANK ( ReshowSubstituteAnim )
2014-05-22 22:13:20 +00:00
call nz , Bankswitch
2015-01-20 19:21:16 +00:00
jr MirrorMoveCheck
2016-06-12 04:30:05 +00:00
playerCheckIfFlyOrChargeEffect:
2015-07-03 19:37:53 +00:00
ld c , 30
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , FLY_EFFECT
2015-01-20 19:21:16 +00:00
jr z , .playAnim
2014-05-22 22:13:20 +00:00
cp a , CH ARGE_EFFECT
2015-01-20 19:21:16 +00:00
jr z , .playAnim
jr MirrorMoveCheck
.playAnim
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , STATUS_AFFECTED_ANIM
call PlayMoveAnimation
2016-06-12 04:30:05 +00:00
MirrorMoveCheck:
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , MIRROR_MOVE_EFFECT
2015-01-20 19:21:16 +00:00
jr nz , .metronomeCheck
2014-05-22 22:13:20 +00:00
call MirrorMoveCopyMove
2015-01-20 19:21:16 +00:00
jp z , ExecutePlayerMoveDone
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 18:40:22 +00:00
ld [ wMonIsDisobedient ], a
2015-02-03 19:51:53 +00:00
jp Ch eckIfPlayerNeedsToChargeUp ; if Mirror Move was successful go back to damage calculation for copied move
2015-01-20 19:21:16 +00:00
.metronomeCheck
2014-05-22 22:13:20 +00:00
cp a , METRONOME_EFFECT
2015-01-20 19:21:16 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
call MetronomePickMove
2015-02-03 19:51:53 +00:00
jp Ch eckIfPlayerNeedsToChargeUp ; Go back to damage calculation for the move picked by Metronome
2015-01-20 19:21:16 +00:00
.next
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , ResidualEffects2
2014-05-22 22:13:20 +00:00
ld de , 1
call IsInArray
2015-01-20 19:21:16 +00:00
jp c , JumpMoveEffect ; done here after executing effects of ResidualEffects2
2015-08-31 02:38:41 +00:00
ld a ,[ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .moveDidNotMiss
2014-05-22 22:13:20 +00:00
call PrintMoveFailureText
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-01-04 16:47:21 +00:00
cp a , EXPLODE_EFFECT ; even if Explosion or Selfdestruct missed, its effect still needs to be activated
2015-01-20 19:21:16 +00:00
jr z , .notDone
2015-01-23 03:05:13 +00:00
jp ExecutePlayerMoveDone ; otherwise, we're done if the move missed
2015-01-20 19:21:16 +00:00
.moveDidNotMiss
2014-05-22 22:13:20 +00:00
call ApplyAttackToEnemyPokemon
2014-08-09 05:39:13 +00:00
call PrintCriticalOHKOText
2014-05-22 22:13:20 +00:00
callab Di sp layEffectiveness
ld a , 1
2015-03-31 18:28:42 +00:00
ld [ wMoveDidntMiss ], a
2015-01-20 19:21:16 +00:00
.notDone
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , Al waysHappenSideEffects
2014-05-22 22:13:20 +00:00
ld de , 1
call IsInArray
2015-01-20 19:21:16 +00:00
call c , JumpMoveEffect ; not done after executing effects of AlwaysHappenSideEffects
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b ,[ hl ]
or b
2015-01-04 16:47:21 +00:00
ret z ; don't do anything else if the enemy fainted
2014-05-22 22:13:20 +00:00
call HandleBuildingRage
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
bit AttackingMultipleTimes ,[ hl ]
2015-01-20 19:21:16 +00:00
jr z , .executeOtherEffects
2014-08-09 05:39:13 +00:00
ld a ,[ wPlayerNumAttacksLeft ]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [ wPlayerNumAttacksLeft ], a
2015-06-11 22:41:33 +00:00
jp nz , getPlayerAnimationType ; for multi-hit moves, apply attack until PlayerNumAttacksLeft hits 0 or the enemy faints.
2015-03-31 20:22:12 +00:00
; damage calculation and accuracy tests only happen for the first hit
2015-02-03 19:51:53 +00:00
res AttackingMultipleTimes ,[ hl ] ; clear attacking multiple times status when all attacks are over
2014-05-22 22:13:20 +00:00
ld hl , MultiHitText
call PrintText
xor a
2015-02-07 10:43:08 +00:00
ld [ wPlayerNumHits ], a
2015-01-20 19:21:16 +00:00
.executeOtherEffects
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jp z , ExecutePlayerMoveDone
ld hl , Sp ecialEffects
2014-05-22 22:13:20 +00:00
ld de , 1
call IsInArray
2015-01-31 17:26:05 +00:00
call nc , JumpMoveEffect ; move effects not included in SpecialEffects or in either of the ResidualEffect arrays,
2015-03-31 18:16:31 +00:00
; which are the effects not covered yet. Rage effect will be executed for a second time (though it's irrelevant).
; Includes side effects that only need to be called if the target didn't faint.
; Responsible for executing Twineedle's second side effect (poison).
2015-01-20 19:21:16 +00:00
jp ExecutePlayerMoveDone
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MultiHitText:
2014-05-22 22:13:20 +00:00
TX_FAR _MultiHitText
db "@"
2016-06-12 00:24:04 +00:00
ExecutePlayerMoveDone:
2014-05-22 22:13:20 +00:00
xor a
2015-07-15 06:16:06 +00:00
ld [ wActionResultOrTookBattleTurn ], a
2014-05-22 22:13:20 +00:00
ld b , 1
ret
2016-06-12 00:24:04 +00:00
PrintGhostText:
2014-05-22 22:13:20 +00:00
; print the ghost battle messages
call IsGhostBattle
ret nz
ld a ,[ H_WHOSETURN ]
and a
jr nz , .Ghost
2014-06-14 11:12:40 +00:00
ld a ,[ wBattleMonStatus ] ; player’ s turn
2014-05-22 22:13:20 +00:00
and a , SLP | ( 1 << FRZ )
ret nz
ld hl , ScaredText
call PrintText
xor a
ret
.Ghost ; ghost’ s turn
ld hl , GetOutText
call PrintText
xor a
ret
2016-06-12 00:24:04 +00:00
ScaredText:
2014-05-22 22:13:20 +00:00
TX_FAR _ScaredText
db "@"
2016-06-12 00:24:04 +00:00
GetOutText:
2014-05-22 22:13:20 +00:00
TX_FAR _GetOutText
db "@"
2016-06-12 00:24:04 +00:00
IsGhostBattle:
2015-08-31 02:38:41 +00:00
ld a ,[ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
ret nz
2015-08-31 02:38:41 +00:00
ld a ,[ wCurMap ]
2014-05-22 22:13:20 +00:00
cp a , POKEMONTOWER_1
jr c , .next
cp a , LAVENDER_HOUSE_1
jr nc , .next
ld b , SI LPH_SCOPE
2014-08-09 05:39:13 +00:00
call IsItemInBag
2014-05-22 22:13:20 +00:00
ret z
.next
ld a , 1
and a
ret
2014-08-09 05:39:13 +00:00
; checks for various status conditions affecting the player mon
; stores whether the mon cannot use a move this turn in Z flag
2016-06-12 00:24:04 +00:00
CheckPlayerStatusConditions:
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonStatus
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2014-08-09 05:39:13 +00:00
and a , SLP ; sleep mask
jr z , .FrozenCheck
; sleeping
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [ wBattleMonStatus ], a ; decrement number of turns left
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .WakeUp ; if the number of turns hit 0, wake up
; fast asleep
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , SLP_ANIM - 1
call PlayMoveAnimation
ld hl , FastAsleepText
call PrintText
jr .sleepDone
.WakeUp
ld hl , WokeUpText
call PrintText
.sleepDone
xor a
2015-01-31 17:26:05 +00:00
ld [ wPlayerUsedMove ], a
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; player can't move this turn
jp .returnToHL
2014-05-22 22:13:20 +00:00
.FrozenCheck
bit FRZ ,[ hl ] ; frozen?
2014-08-09 05:39:13 +00:00
jr z , .HeldInPlaceCheck
2014-05-22 22:13:20 +00:00
ld hl , IsFrozenText
call PrintText
xor a
2015-01-31 17:26:05 +00:00
ld [ wPlayerUsedMove ], a
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; player can't move this turn
jp .returnToHL
2014-05-22 22:13:20 +00:00
.HeldInPlaceCheck
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; is enemy using a mult-turn move like wrap?
2014-08-09 05:39:13 +00:00
jp z , .FlinchedCheck
2014-05-22 22:13:20 +00:00
ld hl , CantMoveText
call PrintText
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; player can't move this turn
jp .returnToHL
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.FlinchedCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
bit Flinched ,[ hl ]
2014-08-09 05:39:13 +00:00
jp z , .HyperBeamCheck
2015-02-03 19:51:53 +00:00
res Flinched ,[ hl ] ; reset player's flinch status
2014-05-22 22:13:20 +00:00
ld hl , FlinchedText
call PrintText
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; player can't move this turn
jp .returnToHL
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.HyperBeamCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2015-02-03 19:51:53 +00:00
bit NeedsToRecharge ,[ hl ]
2014-08-09 05:39:13 +00:00
jr z , .AnyMoveDisabledCheck
2015-02-03 19:51:53 +00:00
res NeedsToRecharge ,[ hl ] ; reset player's recharge status
2014-05-22 22:13:20 +00:00
ld hl , MustRechargeText
call PrintText
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; player can't move this turn
jp .returnToHL
2014-08-09 05:39:13 +00:00
.AnyMoveDisabledCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerDisabledMove
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
and a
2014-08-09 05:39:13 +00:00
jr z , .ConfusedCheck
2014-05-22 22:13:20 +00:00
dec a
ld [ hl ], a
2015-04-08 23:17:56 +00:00
and $ f ; did Disable counter hit 0?
2014-08-09 05:39:13 +00:00
jr nz , .ConfusedCheck
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-04-08 23:17:56 +00:00
ld [ wPlayerDisabledMoveNumber ], a
2014-05-22 22:13:20 +00:00
ld hl , Di sabledNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
.ConfusedCheck
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus1 ]
2015-01-04 16:47:21 +00:00
add a ; is player confused?
2014-08-09 05:39:13 +00:00
jr nc , .TriedToUseDisabledMoveCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerConfusedCounter
2014-05-22 22:13:20 +00:00
dec [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .IsConfused
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res Confused ,[ hl ] ; if confused counter hit 0, reset confusion status
2014-05-22 22:13:20 +00:00
ld hl , ConfusedNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
jr .TriedToUseDisabledMoveCheck
.IsConfused
2014-05-22 22:13:20 +00:00
ld hl , IsConfusedText
call PrintText
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , CONF_ANIM - 1
call PlayMoveAnimation
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-04 16:47:21 +00:00
cp a , $ 80 ; 50% chance to hurt itself
2014-08-09 05:39:13 +00:00
jr c , .TriedToUseDisabledMoveCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-08-31 02:38:41 +00:00
and a , 1 << Confused ; if mon hurts itself, clear every other status from wPlayerBattleStatus1
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-01-04 16:47:21 +00:00
call HandleSelfConfusionDamage
2014-08-09 05:39:13 +00:00
jr .MonHurtItselfOrFullyParalysed
.TriedToUseDisabledMoveCheck
2015-04-08 23:17:56 +00:00
; prevents a disabled move that was selected before being disabled from being used
ld a ,[ wPlayerDisabledMoveNumber ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .ParalysisCheck
2014-05-26 21:04:56 +00:00
ld hl , wPlayerSelectedMove
2014-05-22 22:13:20 +00:00
cp [ hl ]
jr nz , .ParalysisCheck
call PrintMoveIsDisabledText
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone ; if a disabled move was somehow selected, player can't move this turn
jp .returnToHL
2014-08-09 05:39:13 +00:00
2014-05-22 22:13:20 +00:00
.ParalysisCheck
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonStatus
2014-05-22 22:13:20 +00:00
bit PAR ,[ hl ]
2014-08-09 05:39:13 +00:00
jr z , .BideCheck
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-04 16:47:21 +00:00
cp a , $ 3 F ; 25% to be fully paralyzed
2014-08-09 05:39:13 +00:00
jr nc , .BideCheck
2014-05-22 22:13:20 +00:00
ld hl , FullyParalyzedText
call PrintText
2014-08-09 05:39:13 +00:00
.MonHurtItselfOrFullyParalysed
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-06-11 22:41:33 +00:00
; clear bide, thrashing, charging up, and trapping moves such as warp (already cleared for confusion damage)
and $ ff ^ (( 1 << StoringEnergy ) | ( 1 << ThrashingAbout ) | ( 1 << Ch argingUp ) | ( 1 << UsingTrappingMove ))
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , FLY_EFFECT
2014-08-09 05:39:13 +00:00
jr z , .FlyOrChargeEffect
2014-05-22 22:13:20 +00:00
cp a , CH ARGE_EFFECT
2014-08-09 05:39:13 +00:00
jr z , .FlyOrChargeEffect
jr .NotFlyOrChargeEffect
.FlyOrChargeEffect
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , STATUS_AFFECTED_ANIM
call PlayMoveAnimation
2014-08-09 05:39:13 +00:00
.NotFlyOrChargeEffect
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone
jp .returnToHL ; if using a two-turn move, we need to recharge the first turn
2014-08-09 05:39:13 +00:00
.BideCheck
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
bit StoringEnergy ,[ hl ] ; is mon using bide?
2014-08-09 05:39:13 +00:00
jr z , .ThrashingAboutCheck
2014-05-22 22:13:20 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveNum ], a
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b , a
ld c ,[ hl ]
2015-02-07 10:43:08 +00:00
ld hl , wPlayerBideAccumulatedDamage + 1
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-01-04 16:47:21 +00:00
add c ; acumulate damage taken
2014-05-22 22:13:20 +00:00
ld [ hld ], a
ld a ,[ hl ]
adc b
ld [ hl ], a
2014-08-09 05:39:13 +00:00
ld hl , wPlayerNumAttacksLeft
2015-01-04 16:47:21 +00:00
dec [ hl ] ; did Bide counter hit 0?
2014-08-09 05:39:13 +00:00
jr z , .UnleashEnergy
2015-01-20 19:21:16 +00:00
ld hl , ExecutePlayerMoveDone
jp .returnToHL ; unless mon unleashes energy, can't move this turn
2014-08-09 05:39:13 +00:00
.UnleashEnergy
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res StoringEnergy ,[ hl ] ; not using bide any more
2014-05-22 22:13:20 +00:00
ld hl , UnleashedEnergyText
call PrintText
ld a , 1
2015-08-31 02:38:41 +00:00
ld [ wPlayerMovePower ], a
2015-02-07 10:43:08 +00:00
ld hl , wPlayerBideAccumulatedDamage + 1
2014-05-22 22:13:20 +00:00
ld a ,[ hld ]
add a
ld b , a
2015-08-31 02:38:41 +00:00
ld [ wDamage + 1 ], a
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-01-04 16:47:21 +00:00
rl a ; double the damage
2015-08-31 02:38:41 +00:00
ld [ wDamage ], a
2014-05-22 22:13:20 +00:00
or b
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
ld a , 1
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2014-08-09 05:39:13 +00:00
.next
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a
ld [ hl ], a
ld a , BIDE
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveNum ], a
2015-03-31 20:22:12 +00:00
ld hl , handleIfPlayerMoveMissed ; skip damage calculation, DecrementPP and MoveHitTest
2015-01-20 19:21:16 +00:00
jp .returnToHL
2014-08-09 05:39:13 +00:00
.ThrashingAboutCheck
2015-02-03 19:51:53 +00:00
bit ThrashingAbout ,[ hl ] ; is mon using thrash or petal dance?
2014-08-09 05:39:13 +00:00
jr z , .MultiturnMoveCheck
2014-05-22 22:13:20 +00:00
ld a , THRASH
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveNum ], a
2014-05-22 22:13:20 +00:00
ld hl , ThrashingAboutText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl , wPlayerNumAttacksLeft
2015-04-09 09:30:04 +00:00
dec [ hl ] ; did Thrashing About counter hit 0?
2015-01-31 17:26:05 +00:00
ld hl , PlayerCalcMoveDamage ; skip DecrementPP
2015-06-11 22:41:33 +00:00
jp nz , .returnToHL
2014-05-22 22:13:20 +00:00
push hl
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-04-09 09:30:04 +00:00
res ThrashingAbout ,[ hl ] ; no longer thrashing about
2015-02-03 19:51:53 +00:00
set Confused ,[ hl ] ; confused
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and a , 3
inc a
2015-01-04 16:47:21 +00:00
inc a ; confused for 2-5 turns
2015-08-31 02:38:41 +00:00
ld [ wPlayerConfusedCounter ], a
2015-01-04 16:47:21 +00:00
pop hl ; skip DecrementPP
2015-01-20 19:21:16 +00:00
jp .returnToHL
2014-08-09 05:39:13 +00:00
.MultiturnMoveCheck
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove ,[ hl ] ; is mon using multi-turn move?
2014-08-09 05:39:13 +00:00
jp z , .RageCheck
2014-05-22 22:13:20 +00:00
ld hl , AttackContinuesText
call PrintText
2014-08-09 05:39:13 +00:00
ld a ,[ wPlayerNumAttacksLeft ]
2015-01-04 16:47:21 +00:00
dec a ; did multi-turn move end?
2014-08-09 05:39:13 +00:00
ld [ wPlayerNumAttacksLeft ], a
2015-06-11 22:41:33 +00:00
ld hl , getPlayerAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
2015-03-31 18:16:31 +00:00
; DecrementPP and MoveHitTest
2015-01-20 19:21:16 +00:00
jp nz , .returnToHL
jp .returnToHL
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.RageCheck
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit UsingRage , a ; is mon using rage?
2015-01-31 17:26:05 +00:00
jp z , .checkPlayerStatusConditionsDone ; if we made it this far, mon can move normally this turn
2014-05-22 22:13:20 +00:00
ld a , RAGE
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B
xor a
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveEffect ], a
2015-01-20 19:21:16 +00:00
ld hl , PlayerCanExecuteMove
jp .returnToHL
2014-05-22 22:13:20 +00:00
2015-01-20 19:21:16 +00:00
.returnToHL
2014-05-22 22:13:20 +00:00
xor a
ret
2015-01-31 17:26:05 +00:00
.checkPlayerStatusConditionsDone
2014-05-22 22:13:20 +00:00
ld a , $ 1
and a
ret
2016-06-12 00:24:04 +00:00
FastAsleepText:
2014-05-22 22:13:20 +00:00
TX_FAR _FastAsleepText
db "@"
2016-06-12 00:24:04 +00:00
WokeUpText:
2014-05-22 22:13:20 +00:00
TX_FAR _WokeUpText
db "@"
2016-06-12 00:24:04 +00:00
IsFrozenText:
2014-05-22 22:13:20 +00:00
TX_FAR _IsFrozenText
db "@"
2016-06-12 00:24:04 +00:00
FullyParalyzedText:
2014-05-22 22:13:20 +00:00
TX_FAR _FullyParalyzedText
db "@"
2016-06-12 00:24:04 +00:00
FlinchedText:
2014-05-22 22:13:20 +00:00
TX_FAR _FlinchedText
db "@"
2016-06-12 00:24:04 +00:00
MustRechargeText:
2014-05-22 22:13:20 +00:00
TX_FAR _MustRechargeText
db "@"
2016-06-12 00:24:04 +00:00
DisabledNoMoreText:
2014-05-22 22:13:20 +00:00
TX_FAR _DisabledNoMoreText
db "@"
2016-06-12 00:24:04 +00:00
IsConfusedText:
2014-05-22 22:13:20 +00:00
TX_FAR _IsConfusedText
db "@"
2016-06-12 00:24:04 +00:00
HurtItselfText:
2014-05-22 22:13:20 +00:00
TX_FAR _HurtItselfText
db "@"
2016-06-12 00:24:04 +00:00
ConfusedNoMoreText:
2014-05-22 22:13:20 +00:00
TX_FAR _ConfusedNoMoreText
db "@"
2016-06-12 00:24:04 +00:00
SavingEnergyText:
2014-05-22 22:13:20 +00:00
TX_FAR _SavingEnergyText
db "@"
2016-06-12 00:24:04 +00:00
UnleashedEnergyText:
2014-05-22 22:13:20 +00:00
TX_FAR _UnleashedEnergyText
db "@"
2016-06-12 00:24:04 +00:00
ThrashingAboutText:
2014-05-22 22:13:20 +00:00
TX_FAR _ThrashingAboutText
db "@"
2016-06-12 00:24:04 +00:00
AttackContinuesText:
2014-05-22 22:13:20 +00:00
TX_FAR _AttackContinuesText
db "@"
2016-06-12 00:24:04 +00:00
CantMoveText:
2014-05-22 22:13:20 +00:00
TX_FAR _CantMoveText
db "@"
2016-06-12 00:24:04 +00:00
PrintMoveIsDisabledText:
2014-08-09 05:39:13 +00:00
ld hl , wPlayerSelectedMove
2015-08-31 02:38:41 +00:00
ld de , wPlayerBattleStatus1
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-02-03 19:51:53 +00:00
jr z , .removeChargingUp
2014-05-22 22:13:20 +00:00
inc hl
2015-08-31 02:38:41 +00:00
ld de , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
.removeChargingUp
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-06-11 22:41:33 +00:00
res Ch argingUp , a ; end the pokemon's
2014-05-22 22:13:20 +00:00
ld [ de ], a
ld a , [ hl ]
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetMoveName
ld hl , MoveIsDisabledText
jp PrintText
2016-06-12 00:24:04 +00:00
MoveIsDisabledText:
2014-05-22 22:13:20 +00:00
TX_FAR _MoveIsDisabledText
db "@"
2016-06-12 00:24:04 +00:00
HandleSelfConfusionDamage:
2014-05-22 22:13:20 +00:00
ld hl , HurtItselfText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonDefense
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
push af
ld a , [ hld ]
push af
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonDefense ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonDefense + 1 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMoveEffect
2014-05-22 22:13:20 +00:00
push hl
ld a , [ hl ]
push af
xor a
ld [ hli ], a
2015-01-04 16:47:21 +00:00
ld [ wCriticalHitOrOHKO ], a ; self-inflicted confusion damage can't be a Critical Hit
2015-02-03 19:51:53 +00:00
ld a , 40 ; 40 base power
2014-05-22 22:13:20 +00:00
ld [ hli ], a
xor a
ld [ hl ], a
2014-08-09 05:39:13 +00:00
call GetDamageVarsForPlayerAttack
2015-03-31 18:16:31 +00:00
call CalculateDamage ; ignores AdjustDamageForMoveType (type-less damage), RandomizeDamage,
; and MoveHitTest (always hits)
2014-05-22 22:13:20 +00:00
pop af
pop hl
ld [ hl ], a
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonDefense + 1
2014-05-22 22:13:20 +00:00
pop af
ld [ hld ], a
pop af
ld [ hl ], a
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
call PlayMoveAnimation
2014-08-09 05:39:13 +00:00
call DrawPlayerHUDAndHPBar
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
jp ApplyDamageToPlayerPokemon
2016-06-12 00:24:04 +00:00
PrintMonName1Text:
2014-05-22 22:13:20 +00:00
ld hl , MonName1Text
jp PrintText
2015-06-12 18:37:20 +00:00
; this function wastes time calling DetermineExclamationPointTextNum
; and choosing between Used1Text and Used2Text, even though
; those text strings are identical and both continue at PrintInsteadText
2015-06-12 18:45:52 +00:00
; this likely had to do with Japanese grammar that got translated,
; but the functionality didn't get removed
2016-06-12 00:24:04 +00:00
MonName1Text:
2014-05-22 22:13:20 +00:00
TX_FAR _MonName1Text
2015-07-03 19:58:50 +00:00
TX_ASM
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2015-01-31 17:26:05 +00:00
ld hl , wPlayerUsedMove
2016-06-12 04:30:05 +00:00
jr z , .playerTurn
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2015-01-31 17:26:05 +00:00
ld hl , wEnemyUsedMove
2016-06-12 04:30:05 +00:00
.playerTurn
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2015-06-12 18:37:20 +00:00
call DetermineExclamationPointTextNum
2015-03-31 18:40:22 +00:00
ld a , [ wMonIsDisobedient ]
2014-05-22 22:13:20 +00:00
and a
ld hl , Used2Text
ret nz
2014-05-26 21:04:56 +00:00
ld a , [ wd11e ]
2015-03-31 20:22:12 +00:00
cp 3
2014-05-22 22:13:20 +00:00
ld hl , Used2Text
ret c
ld hl , Used1Text
ret
2016-06-12 00:24:04 +00:00
Used1Text:
2014-05-22 22:13:20 +00:00
TX_FAR _Used1Text
2015-07-03 19:58:50 +00:00
TX_ASM
2014-05-22 22:13:20 +00:00
jr PrintInsteadText
2016-06-12 00:24:04 +00:00
Used2Text:
2014-05-22 22:13:20 +00:00
TX_FAR _Used2Text
2015-07-03 19:58:50 +00:00
TX_ASM
2015-06-12 18:37:20 +00:00
; fall through
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PrintInsteadText:
2015-03-31 18:40:22 +00:00
ld a , [ wMonIsDisobedient ]
2014-05-22 22:13:20 +00:00
and a
2015-06-12 18:37:20 +00:00
jr z , PrintMoveName
2014-05-22 22:13:20 +00:00
ld hl , InsteadText
ret
2016-06-12 00:24:04 +00:00
InsteadText:
2014-05-22 22:13:20 +00:00
TX_FAR _InsteadText
2015-07-03 19:58:50 +00:00
TX_ASM
2015-06-12 18:37:20 +00:00
; fall through
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PrintMoveName:
2015-06-12 18:37:20 +00:00
ld hl , _PrintMoveName
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
_PrintMoveName:
2014-05-22 22:13:20 +00:00
TX_FAR _CF4BText
2015-07-03 19:58:50 +00:00
TX_ASM
2014-05-22 22:13:20 +00:00
ld hl , ExclamationPointPointerTable
2015-06-12 18:37:20 +00:00
ld a , [ wd11e ] ; exclamation point num
2014-05-22 22:13:20 +00:00
add a
push bc
ld b , $ 0
ld c , a
add hl , bc
pop bc
ld a , [ hli ]
ld h , [ hl ]
ld l , a
ret
2016-06-12 00:24:04 +00:00
ExclamationPointPointerTable:
2014-05-22 22:13:20 +00:00
dw ExclamationPoint1Text
dw ExclamationPoint2Text
dw ExclamationPoint3Text
dw ExclamationPoint4Text
dw ExclamationPoint5Text
2016-06-12 00:24:04 +00:00
ExclamationPoint1Text:
2014-05-22 22:13:20 +00:00
TX_FAR _ExclamationPoint1Text
db "@"
2016-06-12 00:24:04 +00:00
ExclamationPoint2Text:
2014-05-22 22:13:20 +00:00
TX_FAR _ExclamationPoint2Text
db "@"
2016-06-12 00:24:04 +00:00
ExclamationPoint3Text:
2014-05-22 22:13:20 +00:00
TX_FAR _ExclamationPoint3Text
db "@"
2016-06-12 00:24:04 +00:00
ExclamationPoint4Text:
2014-05-22 22:13:20 +00:00
TX_FAR _ExclamationPoint4Text
db "@"
2016-06-12 00:24:04 +00:00
ExclamationPoint5Text:
2014-05-22 22:13:20 +00:00
TX_FAR _ExclamationPoint5Text
db "@"
2015-06-12 18:37:20 +00:00
; this function does nothing useful
; if the move being used is in set [1-4] from ExclamationPointMoveSets,
; use ExclamationPoint[1-4]Text
; otherwise, use ExclamationPoint5Text
2015-07-03 19:37:53 +00:00
; but all five text strings are identical
2015-06-12 18:45:52 +00:00
; this likely had to do with Japanese grammar that got translated,
; but the functionality didn't get removed
2016-06-12 00:24:04 +00:00
DetermineExclamationPointTextNum:
2014-05-22 22:13:20 +00:00
push bc
2015-06-12 18:37:20 +00:00
ld a , [ wd11e ] ; move ID
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
2015-06-12 18:37:20 +00:00
ld hl , ExclamationPointMoveSets
.loop
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
cp $ ff
2015-06-12 18:37:20 +00:00
jr z , .done
2014-05-22 22:13:20 +00:00
cp c
2015-06-12 18:37:20 +00:00
jr z , .done
2014-05-22 22:13:20 +00:00
and a
2015-06-12 18:37:20 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
inc b
2015-06-12 18:37:20 +00:00
jr .loop
.done
2014-05-22 22:13:20 +00:00
ld a , b
2015-06-12 18:37:20 +00:00
ld [ wd11e ], a ; exclamation point num
2014-05-22 22:13:20 +00:00
pop bc
ret
2016-06-12 00:24:04 +00:00
ExclamationPointMoveSets:
2014-05-22 22:13:20 +00:00
db SWORDS_DANCE , GROWTH
db $ 00
db RECOVER , BIDE , SELFDESTRUCT , AMNESIA
db $ 00
db MEDITATE , AGILITY , TELEPORT , MIMIC , DOUBLE_TEAM , BARRAGE
db $ 00
db POUND , SCRATCH , VICEGRIP , WING_ATTACK , FLY , BIND , SLAM , HORN_ATTACK , BODY_SLAM
db WRAP , THRASH , TAIL_WHIP , LEER , BITE , GROWL , ROAR , SI NG , PECK , COUNTER
db STRENGTH , ABSORB , STRING_SHOT , EARTHQUAKE , FISSURE , DI G , TOXIC , SCREECH , HARDEN
db MINIMIZE , WITHDRAW , DEFENSE_CURL , METRONOME , LICK , CL AMP , CONSTRICT , POISON_GAS
db LEECH_LIFE , BUBBLE , FLASH , SP LASH , ACID_ARMOR , FURY_SWIPES , REST , SHARPEN , SLASH , SUBSTITUTE
db $ 00
db $ FF ; terminator
2016-06-12 00:24:04 +00:00
PrintMoveFailureText:
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .playersTurn
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveEffect
2014-08-09 05:39:13 +00:00
.playersTurn
ld hl , DoesntAffectMonText
2015-03-31 18:28:42 +00:00
ld a , [ wDamageMultipliers ]
2014-05-22 22:13:20 +00:00
and $ 7 f
2015-02-03 19:51:53 +00:00
jr z , .gotTextToPrint
2014-08-09 05:39:13 +00:00
ld hl , AttackMissedText
ld a , [ wCriticalHitOrOHKO ]
2014-05-22 22:13:20 +00:00
cp $ ff
2015-02-03 19:51:53 +00:00
jr nz , .gotTextToPrint
2014-08-09 05:39:13 +00:00
ld hl , UnaffectedText
2015-02-03 19:51:53 +00:00
.gotTextToPrint
2014-05-22 22:13:20 +00:00
push de
call PrintText
xor a
2014-08-09 05:39:13 +00:00
ld [ wCriticalHitOrOHKO ], a
2014-05-22 22:13:20 +00:00
pop de
ld a , [ de ]
cp JUMP_KICK_EFFECT
ret nz
2015-01-04 16:47:21 +00:00
; if you get here, the mon used jump kick or hi jump kick and missed
2015-08-31 02:38:41 +00:00
ld hl , wDamage ; since the move missed, wDamage will always contain 0 at this point.
2015-06-11 22:41:33 +00:00
; Thus, recoil damage will always be equal to 1
2015-03-31 20:22:12 +00:00
; even if it was intended to be potential damage/8.
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , [ hl ]
srl a
rr b
srl a
rr b
srl a
rr b
ld [ hl ], b
dec hl
ld [ hli ], a
or b
2015-01-20 19:21:16 +00:00
jr nz , .applyRecoil
2014-05-22 22:13:20 +00:00
inc a
ld [ hl ], a
2015-01-20 19:21:16 +00:00
.applyRecoil
2014-08-09 05:39:13 +00:00
ld hl , KeptGoingAndCrashedText
2014-05-22 22:13:20 +00:00
call PrintText
ld b , $ 4
2015-07-12 23:24:03 +00:00
predef PredefShakeScreenHorizontally
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr nz , .enemyTurn
2014-05-22 22:13:20 +00:00
jp ApplyDamageToPlayerPokemon
2015-01-20 19:21:16 +00:00
.enemyTurn
2014-05-22 22:13:20 +00:00
jp ApplyDamageToEnemyPokemon
2016-06-12 00:24:04 +00:00
AttackMissedText:
2014-05-22 22:13:20 +00:00
TX_FAR _AttackMissedText
db "@"
2016-06-12 00:24:04 +00:00
KeptGoingAndCrashedText:
2014-05-22 22:13:20 +00:00
TX_FAR _KeptGoingAndCrashedText
db "@"
2016-06-12 00:24:04 +00:00
UnaffectedText:
2014-05-22 22:13:20 +00:00
TX_FAR _UnaffectedText
db "@"
2016-06-12 00:24:04 +00:00
PrintDoesntAffectText:
2014-08-09 05:39:13 +00:00
ld hl , DoesntAffectMonText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
DoesntAffectMonText:
2014-05-22 22:13:20 +00:00
TX_FAR _DoesntAffectMonText
db "@"
2014-08-09 05:39:13 +00:00
; if there was a critical hit or an OHKO was successful, print the corresponding text
2016-06-12 00:24:04 +00:00
PrintCriticalOHKOText:
2014-08-09 05:39:13 +00:00
ld a , [ wCriticalHitOrOHKO ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .done ; do nothing if there was no critical hit or successful OHKO
2014-05-22 22:13:20 +00:00
dec a
add a
2014-08-09 05:39:13 +00:00
ld hl , CriticalOHKOTextPointers
2014-05-22 22:13:20 +00:00
ld b , $ 0
ld c , a
add hl , bc
ld a , [ hli ]
ld h , [ hl ]
ld l , a
call PrintText
xor a
2014-08-09 05:39:13 +00:00
ld [ wCriticalHitOrOHKO ], a
.done
2015-07-03 19:37:53 +00:00
ld c , 20
2014-05-22 22:13:20 +00:00
jp DelayFrames
2016-06-12 00:24:04 +00:00
CriticalOHKOTextPointers:
2014-05-22 22:13:20 +00:00
dw CriticalHitText
dw OHKOText
2016-06-12 00:24:04 +00:00
CriticalHitText:
2014-05-22 22:13:20 +00:00
TX_FAR _CriticalHitText
db "@"
2016-06-12 00:24:04 +00:00
OHKOText:
2014-05-22 22:13:20 +00:00
TX_FAR _OHKOText
db "@"
2014-08-09 05:39:13 +00:00
; checks if a traded mon will disobey due to lack of badges
; stores whether the mon will use a move in Z flag
2016-06-12 00:24:04 +00:00
CheckForDisobedience:
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 18:40:22 +00:00
ld [ wMonIsDisobedient ], a
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
jr nz , .checkIfMonIsTraded
2014-05-22 22:13:20 +00:00
ld a , $ 1
and a
ret
2014-08-09 05:39:13 +00:00
; compare the mon's original trainer ID with the player's ID to see if it was traded
.checkIfMonIsTraded
ld hl , wPartyMon1OTID
ld bc , wPartyMon2 - wPartyMon1
ld a , [ wPlayerMonNumber ]
2014-05-22 22:13:20 +00:00
call AddNTimes
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerID ]
2014-05-22 22:13:20 +00:00
cp [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .monIsTraded
2014-05-22 22:13:20 +00:00
inc hl
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerID + 1 ]
2014-05-22 22:13:20 +00:00
cp [ hl ]
2014-08-09 05:39:13 +00:00
jp z , .canUseMove
; it was traded
.monIsTraded
2014-05-22 22:13:20 +00:00
; what level might disobey?
2015-08-31 02:38:41 +00:00
ld hl , wObtainedBadges
2014-05-22 22:13:20 +00:00
bit 7 , [ hl ]
ld a , 101
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
bit 5 , [ hl ]
ld a , 70
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
bit 3 , [ hl ]
ld a , 50
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
bit 1 , [ hl ]
ld a , 30
2014-08-09 05:39:13 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
ld a , 10
2014-08-09 05:39:13 +00:00
.next
2014-05-22 22:13:20 +00:00
ld b , a
ld c , a
2014-08-09 05:39:13 +00:00
ld a , [ wBattleMonLevel ]
2014-05-22 22:13:20 +00:00
ld d , a
add b
ld b , a
2014-08-09 05:39:13 +00:00
jr nc , .noCarry
ld b , $ ff ; cap b at $ff
.noCarry
2014-05-22 22:13:20 +00:00
ld a , c
cp d
2014-08-09 05:39:13 +00:00
jp nc , .canUseMove
.loop1
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
swap a
cp b
2014-08-09 05:39:13 +00:00
jr nc , .loop1
2014-05-22 22:13:20 +00:00
cp c
2014-08-09 05:39:13 +00:00
jp c , .canUseMove
.loop2
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
2014-08-09 05:39:13 +00:00
jr nc , .loop2
2014-05-22 22:13:20 +00:00
cp c
2014-08-09 05:39:13 +00:00
jr c , .useRandomMove
2014-05-22 22:13:20 +00:00
ld a , d
sub c
ld b , a
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
swap a
sub b
2014-08-09 05:39:13 +00:00
jr c , .monNaps
2014-05-22 22:13:20 +00:00
cp b
2014-08-09 05:39:13 +00:00
jr nc , .monDoesNothing
2014-05-22 22:13:20 +00:00
ld hl , WontObeyText
call PrintText
2015-01-04 16:47:21 +00:00
call HandleSelfConfusionDamage
2014-08-09 05:39:13 +00:00
jp .cannotUseMove
.monNaps
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
add a
swap a
2014-08-09 05:39:13 +00:00
and SLP ; sleep mask
jr z , .monNaps ; keep trying until we get at least 1 turn of sleep
ld [ wBattleMonStatus ], a
2014-05-22 22:13:20 +00:00
ld hl , BeganToNapText
2014-08-09 05:39:13 +00:00
jr .printText
.monDoesNothing
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
ld hl , LoafingAroundText
and a
2014-08-09 05:39:13 +00:00
jr z , .printText
2014-05-22 22:13:20 +00:00
ld hl , WontObeyText
dec a
2014-08-09 05:39:13 +00:00
jr z , .printText
2014-05-22 22:13:20 +00:00
ld hl , TurnedAwayText
dec a
2014-08-09 05:39:13 +00:00
jr z , .printText
2014-05-22 22:13:20 +00:00
ld hl , IgnoredOrdersText
2014-08-09 05:39:13 +00:00
.printText
2014-05-22 22:13:20 +00:00
call PrintText
2014-08-09 05:39:13 +00:00
jr .cannotUseMove
.useRandomMove
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonMoves + 1 ]
2014-08-09 05:39:13 +00:00
and a ; is the second move slot empty?
jr z , .monDoesNothing ; mon will not use move if it only knows one move
2015-04-08 23:17:56 +00:00
ld a , [ wPlayerDisabledMoveNumber ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr nz , .monDoesNothing
ld a , [ wPlayerSelectedMove ]
cp STRUGGLE
jr z , .monDoesNothing ; mon will not use move if struggling
; check if only one move has remaining PP
ld hl , wBattleMonPP
2014-05-22 22:13:20 +00:00
push hl
ld a , [ hli ]
and $ 3 f
ld b , a
ld a , [ hli ]
and $ 3 f
add b
ld b , a
ld a , [ hli ]
and $ 3 f
add b
ld b , a
ld a , [ hl ]
and $ 3 f
add b
pop hl
push af
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld a , [ hl ]
and $ 3 f
ld b , a
pop af
cp b
2014-08-09 05:39:13 +00:00
jr z , .monDoesNothing ; mon will not use move if only one move has remaining PP
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-03-31 18:40:22 +00:00
ld [ wMonIsDisobedient ], a
2014-08-09 05:39:13 +00:00
ld a , [ wMaxMenuItem ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld c , a
2014-08-09 05:39:13 +00:00
.chooseMove
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
cp b
2014-08-09 05:39:13 +00:00
jr nc , .chooseMove ; if the random number is greater than the move count, choose another
2014-05-22 22:13:20 +00:00
cp c
2014-08-09 05:39:13 +00:00
jr z , .chooseMove ; if the random number matches the move the player selected, choose another
ld [ wCurrentMenuItem ], a
ld hl , wBattleMonPP
2014-05-22 22:13:20 +00:00
ld e , a
ld d , $ 0
add hl , de
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
and a ; does the move have any PP left?
jr z , .chooseMove ; if the move has no PP left, choose another
ld a , [ wCurrentMenuItem ]
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ wPlayerSelectedMove ], a
2014-05-22 22:13:20 +00:00
call GetCurrentMove
2014-08-09 05:39:13 +00:00
.canUseMove
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
and a ; clear Z flag
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
.cannotUseMove
xor a ; set Z flag
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
LoafingAroundText:
2014-05-22 22:13:20 +00:00
TX_FAR _LoafingAroundText
db "@"
2016-06-12 00:24:04 +00:00
BeganToNapText:
2014-05-22 22:13:20 +00:00
TX_FAR _BeganToNapText
db "@"
2016-06-12 00:24:04 +00:00
WontObeyText:
2014-05-22 22:13:20 +00:00
TX_FAR _WontObeyText
db "@"
2016-06-12 00:24:04 +00:00
TurnedAwayText:
2014-05-22 22:13:20 +00:00
TX_FAR _TurnedAwayText
db "@"
2016-06-12 00:24:04 +00:00
IgnoredOrdersText:
2014-05-22 22:13:20 +00:00
TX_FAR _IgnoredOrdersText
db "@"
2014-08-09 05:39:13 +00:00
; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the player mon
2016-06-12 00:24:04 +00:00
GetDamageVarsForPlayerAttack:
2014-05-22 22:13:20 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld hl , wDamage ; damage to eventually inflict, initialise to zero
2014-05-22 22:13:20 +00:00
ldi [ hl ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMovePower
2014-08-09 05:39:13 +00:00
ld a , [ hli ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
ld d , a ; d = move power
ret z ; return if move power is zero
2015-08-31 02:38:41 +00:00
ld a , [ hl ] ; a = [wPlayerMoveType]
2014-08-09 05:39:13 +00:00
cp FIRE ; types >= FIRE are all special
2014-05-22 22:13:20 +00:00
jr nc , .specialAttack
.physicalAttack
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonDefense
ld a , [ hli ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld c , [ hl ] ; bc = enemy defense
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit HasReflectUp , a ; check for Reflect
2014-08-09 05:39:13 +00:00
jr z , .physicalAttackCritCheck
; if the enemy has used Reflect, double the enemy's defense
sla c
2015-01-23 03:05:13 +00:00
rl b
2014-08-09 05:39:13 +00:00
.physicalAttackCritCheck
ld hl , wBattleMonAttack
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .scaleStats
; in the case of a critical hit, reset the player's attack and the enemy's defense to their base values
ld c , 3 ; defense stat
call GetEnemyMonStat
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
ld c , a
push bc
2014-06-14 11:12:40 +00:00
ld hl , wPartyMon1Attack
2014-05-22 22:13:20 +00:00
ld a , [ wPlayerMonNumber ]
2014-06-14 11:12:40 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
pop bc
2014-08-09 05:39:13 +00:00
jr .scaleStats
2014-05-22 22:13:20 +00:00
.specialAttack
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonSpecial
ld a , [ hli ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld c , [ hl ] ; bc = enemy special
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit HasLightScreenUp , a ; check for Light Screen
2014-08-09 05:39:13 +00:00
jr z , .specialAttackCritCheck
; if the enemy has used Light Screen, double the enemy's special
sla c
2014-05-22 22:13:20 +00:00
rl b
2015-01-04 16:47:21 +00:00
; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if
2015-01-23 03:05:13 +00:00
; a Pokemon with 512 or more Defense has ued Reflect, or if a Pokemon with 512 or more Special has used Light Screen
2014-08-09 05:39:13 +00:00
.specialAttackCritCheck
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonSpecial
2014-08-09 05:39:13 +00:00
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .scaleStats
; in the case of a critical hit, reset the player's and enemy's specials to their base values
ld c , 5 ; special stat
call GetEnemyMonStat
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
ld c , a
push bc
2014-06-14 11:12:40 +00:00
ld hl , wPartyMon1Special
2014-05-22 22:13:20 +00:00
ld a , [ wPlayerMonNumber ]
2014-06-14 11:12:40 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
pop bc
2014-08-09 05:39:13 +00:00
; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
; this allows values with up to 10 bits (values up to 1023) to be handled
; anything larger will wrap around
.scaleStats
ld a , [ hli ]
2014-05-22 22:13:20 +00:00
ld l , [ hl ]
2014-08-09 05:39:13 +00:00
ld h , a ; hl = player's offensive stat
or b ; is either high byte nonzero?
jr z , .next ; if not, we don't need to scale
2015-01-04 16:47:21 +00:00
; bc /= 4 (scale enemy's defensive stat)
2014-08-09 05:39:13 +00:00
srl b
2014-05-22 22:13:20 +00:00
rr c
srl b
rr c
2015-01-23 03:05:13 +00:00
; defensive stat can actually end up as 0, leading to a division by 0 freeze during damage calculation
2015-01-04 16:47:21 +00:00
; hl /= 4 (scale player's offensive stat)
2014-08-09 05:39:13 +00:00
srl h
2014-05-22 22:13:20 +00:00
rr l
srl h
rr l
ld a , l
2014-08-09 05:39:13 +00:00
or h ; is the player's offensive stat 0?
jr nz , .next
inc l ; if the player's offensive stat is 0, bump it up to 1
.next
2015-03-31 18:16:31 +00:00
ld b , l ; b = player's offensive stat (possibly scaled)
; (c already contains enemy's defensive stat (possibly scaled))
2014-08-09 05:39:13 +00:00
ld a , [ wBattleMonLevel ]
ld e , a ; e = level
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .done
sla e ; double level if it was a critical hit
.done
ld a , 1
2014-05-22 22:13:20 +00:00
and a
ret
2014-08-09 05:39:13 +00:00
; sets b, c, d, and e for the CalculateDamage routine in the case of an attack by the enemy mon
2016-06-12 00:24:04 +00:00
GetDamageVarsForEnemyAttack:
2015-08-31 02:38:41 +00:00
ld hl , wDamage ; damage to eventually inflict, initialise to zero
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMovePower
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld d , a ; d = move power
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
ret z ; return if move power is zero
2015-08-31 02:38:41 +00:00
ld a , [ hl ] ; a = [wEnemyMoveType]
2014-08-09 05:39:13 +00:00
cp FIRE ; types >= FIRE are all special
jr nc , .specialAttack
.physicalAttack
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonDefense
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , a
2014-08-09 05:39:13 +00:00
ld c , [ hl ] ; bc = player defense
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit HasReflectUp , a ; check for Reflect
2014-08-09 05:39:13 +00:00
jr z , .physicalAttackCritCheck
; if the player has used Reflect, double the player's defense
2014-05-22 22:13:20 +00:00
sla c
rl b
2014-08-09 05:39:13 +00:00
.physicalAttackCritCheck
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonAttack
2014-08-09 05:39:13 +00:00
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .scaleStats
; in the case of a critical hit, reset the player's defense and the enemy's attack to their base values
2014-06-14 11:12:40 +00:00
ld hl , wPartyMon1Defense
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerMonNumber ]
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , [ hli ]
ld b , a
ld c , [ hl ]
push bc
2014-08-09 05:39:13 +00:00
ld c , 2 ; attack stat
call GetEnemyMonStat
2015-02-03 19:51:53 +00:00
ld hl , H_PRODUCT + 2
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
jr .scaleStats
.specialAttack
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonSpecial
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , a
ld c , [ hl ]
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit HasLightScreenUp , a ; check for Light Screen
2014-08-09 05:39:13 +00:00
jr z , .specialAttackCritCheck
; if the player has used Light Screen, double the player's special
2014-05-22 22:13:20 +00:00
sla c
rl b
2015-01-04 16:47:21 +00:00
; reflect and light screen boosts do not cap the stat at 999, so weird things will happen during stats scaling if
2015-01-23 03:05:13 +00:00
; a Pokemon with 512 or more Defense has ued Reflect, or if a Pokemon with 512 or more Special has used Light Screen
2014-08-09 05:39:13 +00:00
.specialAttackCritCheck
ld hl , wEnemyMonSpecial
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .scaleStats
; in the case of a critical hit, reset the player's and enemy's specials to their base values
ld hl , wPartyMon1Special
ld a , [ wPlayerMonNumber ]
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , [ hli ]
ld b , a
ld c , [ hl ]
push bc
2014-08-09 05:39:13 +00:00
ld c , 5 ; special stat
call GetEnemyMonStat
2015-02-03 19:51:53 +00:00
ld hl , H_PRODUCT + 2
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
; if either the offensive or defensive stat is too large to store in a byte, scale both stats by dividing them by 4
; this allows values with up to 10 bits (values up to 1023) to be handled
; anything larger will wrap around
.scaleStats
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld l , [ hl ]
2014-08-09 05:39:13 +00:00
ld h , a ; hl = enemy's offensive stat
or b ; is either high byte nonzero?
jr z , .next ; if not, we don't need to scale
; bc /= 4 (scale player's defensive stat)
2014-05-22 22:13:20 +00:00
srl b
rr c
srl b
rr c
2015-01-23 03:05:13 +00:00
; defensive stat can actually end up as 0, leading to a division by 0 freeze during damage calculation
2014-08-09 05:39:13 +00:00
; hl /= 4 (scale enemy's offensive stat)
2014-05-22 22:13:20 +00:00
srl h
rr l
srl h
rr l
ld a , l
2014-08-09 05:39:13 +00:00
or h ; is the enemy's offensive stat 0?
jr nz , .next
inc l ; if the enemy's offensive stat is 0, bump it up to 1
.next
2015-03-31 18:16:31 +00:00
ld b , l ; b = enemy's offensive stat (possibly scaled)
; (c already contains player's defensive stat (possibly scaled))
2014-08-09 05:39:13 +00:00
ld a , [ wEnemyMonLevel ]
2014-05-22 22:13:20 +00:00
ld e , a
2014-08-09 05:39:13 +00:00
ld a , [ wCriticalHitOrOHKO ]
and a ; check for critical hit
jr z , .done
sla e ; double level if it was a critical hit
.done
2014-05-22 22:13:20 +00:00
ld a , $ 1
and a
and a
ret
2014-08-09 05:39:13 +00:00
; get stat c of enemy mon
; c: stat to get (HP=1,Attack=2,Defense=3,Speed=4,Special=5)
2016-06-12 00:24:04 +00:00
GetEnemyMonStat:
2014-05-22 22:13:20 +00:00
push de
push bc
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-01-20 19:21:16 +00:00
jr nz , .notLinkBattle
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMon1Stats
2014-05-22 22:13:20 +00:00
dec c
sla c
ld b , $ 0
add hl , bc
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonPartyPos ]
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , [ hli ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
pop bc
pop de
ret
2015-01-20 19:21:16 +00:00
.notLinkBattle
2014-08-09 05:39:13 +00:00
ld a , [ wEnemyMonLevel ]
2015-08-31 02:38:41 +00:00
ld [ wCurEnemyLVL ], a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies ]
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonDVs
2015-02-08 02:37:40 +00:00
ld de , wLoadedMonSpeedExp
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc de
ld a , [ hl ]
ld [ de ], a
pop bc
ld b , $ 0
2015-02-08 02:37:40 +00:00
ld hl , wLoadedMonSpeedExp - $ b ; this base address makes CalcStat look in [wLoadedMonSpeedExp] for DVs
2014-05-22 22:13:20 +00:00
call CalcStat
pop de
ret
2016-06-12 00:24:04 +00:00
CalculateDamage:
2014-05-22 22:13:20 +00:00
; input:
2016-07-28 03:33:48 +00:00
; b: attack
; c: opponent defense
; d: base power
; e: level
2014-05-22 22:13:20 +00:00
2015-03-31 18:50:49 +00:00
ld a , [ H_WHOSETURN ] ; whose turn?
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
jr z , .effect
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
.effect
; EXPLODE_EFFECT halves defense.
cp a , EXPLODE_EFFECT
jr nz , .ok
srl c
jr nz , .ok
inc c ; ...with a minimum value of 1 (used as a divisor later on)
.ok
; Multi-hit attacks may or may not have 0 bp.
cp a , TWO_TO_FIVE_ATTACKS_EFFECT
jr z , .skipbp
cp a , $ 1 e
jr z , .skipbp
; Calculate OHKO damage based on remaining HP.
cp a , OHKO_EFFECT
2015-03-31 18:50:49 +00:00
jp z , JumpToOHKOMoveEffect
2014-05-22 22:13:20 +00:00
; Don't calculate damage for moves that don't do any.
ld a , d ; base power
and a
ret z
.skipbp
xor a
ld hl , H_DIVIDEND
ldi [ hl ], a
ldi [ hl ], a
ld [ hl ], a
; Multiply level by 2
ld a , e ; level
add a
jr nc , .nc
push af
ld a , 1
ld [ hl ], a
pop af
.nc
inc hl
ldi [ hl ], a
; Divide by 5
ld a , 5
ldd [ hl ], a
push bc
ld b , 4
call Di vide
pop bc
; Add 2
inc [ hl ]
inc [ hl ]
inc hl ; multiplier
; Multiply by attack base power
ld [ hl ], d
call Multiply
; Multiply by attack stat
ld [ hl ], b
call Multiply
; Divide by defender's defense stat
ld [ hl ], c
ld b , 4
call Di vide
; Divide by 50
ld [ hl ], 50
ld b , 4
call Di vide
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld b , [ hl ]
ld a , [ H_QUOTIENT + 3 ]
add b
ld [ H_QUOTIENT + 3 ], a
jr nc , .asm_3dfd0
ld a , [ H_QUOTIENT + 2 ]
inc a
ld [ H_QUOTIENT + 2 ], a
and a
jr z , .asm_3e004
.asm_3dfd0
ld a , [ H_QUOTIENT ]
ld b , a
ld a , [ H_QUOTIENT + 1 ]
or a
jr nz , .asm_3e004
ld a , [ H_QUOTIENT + 2 ]
cp 998 / $ 100
jr c , .asm_3dfe8
cp 998 / $ 100 + 1
jr nc , .asm_3e004
ld a , [ H_QUOTIENT + 3 ]
cp 998 % $ 100
jr nc , .asm_3e004
.asm_3dfe8
inc hl
ld a , [ H_QUOTIENT + 3 ]
ld b , [ hl ]
add b
ld [ hld ], a
ld a , [ H_QUOTIENT + 2 ]
ld b , [ hl ]
adc b
ld [ hl ], a
jr c , .asm_3e004
ld a , [ hl ]
cp 998 / $ 100
jr c , .asm_3e00a
cp 998 / $ 100 + 1
jr nc , .asm_3e004
inc hl
ld a , [ hld ]
cp 998 % $ 100
jr c , .asm_3e00a
.asm_3e004
2015-01-04 16:47:21 +00:00
; cap at 997
2014-05-22 22:13:20 +00:00
ld a , 997 / $ 100
ld [ hli ], a
ld a , 997 % $ 100
ld [ hld ], a
.asm_3e00a
2015-01-04 16:47:21 +00:00
; add 2
2014-05-22 22:13:20 +00:00
inc hl
ld a , [ hl ]
add 2
ld [ hld ], a
jr nc , .done
inc [ hl ]
2015-01-23 03:05:13 +00:00
2014-05-22 22:13:20 +00:00
.done
2015-01-04 16:47:21 +00:00
; minimum damage is 1
2014-05-22 22:13:20 +00:00
ld a , 1
and a
ret
2016-06-12 00:24:04 +00:00
JumpToOHKOMoveEffect:
2014-08-09 05:39:13 +00:00
call JumpMoveEffect
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
dec a
ret
2016-06-12 00:24:04 +00:00
UnusedHighCriticalMoves:
2014-05-22 22:13:20 +00:00
db KARATE_CHOP
db RAZOR_LEAF
db CRABHAMMER
db SLASH
db $ FF
; determines if attack is a critical hit
; azure heights claims "the fastest pokémon (who are,not coincidentally,
; among the most popular) tend to CH about 20 to 25% of the time."
2016-06-12 00:24:04 +00:00
CriticalHitTest:
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wCriticalHitOrOHKO ], a
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies ]
2016-06-12 04:30:05 +00:00
jr nz , .handleEnemy
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonSpecies ]
2016-06-12 04:30:05 +00:00
.handleEnemy
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2015-08-31 02:38:41 +00:00
ld a , [ wMonHBaseSpeed ]
2014-05-22 22:13:20 +00:00
ld b , a
srl b ; (effective (base speed/2))
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMovePower
ld de , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
jr z , .calcCriticalHitProbability
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMovePower
ld de , wEnemyBattleStatus2
2015-07-03 19:37:53 +00:00
.calcCriticalHitProbability
2014-05-22 22:13:20 +00:00
ld a , [ hld ] ; read base power from RAM
and a
ret z ; do nothing if zero
dec hl
ld c , [ hl ] ; read move id
ld a , [ de ]
2015-02-03 19:51:53 +00:00
bit GettingPumped , a ; test for focus energy
2014-05-22 22:13:20 +00:00
jr nz , .focusEnergyUsed ; bug: using focus energy causes a shift to the right instead of left,
; resulting in 1/4 the usual crit chance
sla b ; (effective (base speed/2)*2)
jr nc , .noFocusEnergyUsed
ld b , $ ff ; cap at 255/256
jr .noFocusEnergyUsed
.focusEnergyUsed
srl b
.noFocusEnergyUsed
2015-01-04 16:47:21 +00:00
ld hl , HighCriticalMoves ; table of high critical hit moves
2014-05-22 22:13:20 +00:00
.Loop
ld a , [ hli ] ; read move from move table
cp c ; does it match the move about to be used?
jr z , .HighCritical ; if so, the move about to be used is a high critical hit ratio move
inc a ; move on to the next move, FF terminates loop
jr nz , .Loop ; check the next move in HighCriticalMoves
srl b ; /2 for regular move (effective (base speed / 2))
jr .SkipHighCritical ; continue as a normal move
.HighCritical
sla b ; *2 for high critical hit moves
jr nc , .noCarry
ld b , $ ff ; cap at 255/256
.noCarry
sla b ; *4 for high critical move (effective (base speed/2)*8))
jr nc , .SkipHighCritical
ld b , $ ff
.SkipHighCritical
2015-01-04 16:47:21 +00:00
call BattleRandom ; generates a random value, in "a"
2014-05-22 22:13:20 +00:00
rlc a
rlc a
rlc a
cp b ; check a against calculated crit rate
ret nc ; no critical hit if no borrow
ld a , $ 1
2015-01-04 16:47:21 +00:00
ld [ wCriticalHitOrOHKO ], a ; set critical hit flag
2014-05-22 22:13:20 +00:00
ret
; high critical hit moves
2016-06-12 00:24:04 +00:00
HighCriticalMoves:
2014-05-22 22:13:20 +00:00
db KARATE_CHOP
db RAZOR_LEAF
db CRABHAMMER
db SLASH
db $ FF
; function to determine if Counter hits and if so, how much damage it does
2016-06-12 00:24:04 +00:00
HandleCounterMove:
2015-01-23 03:05:13 +00:00
; The variables checked by Counter are updated whenever the cursor points to a new move in the battle selection menu.
; This is irrelevant for the opponent's side outside of link battles, since the move selection is controlled by the AI.
; However, in the scenario where the player switches out and the opponent uses Counter,
2015-01-04 16:47:21 +00:00
; the outcome may be affected by the player's actions in the move selection menu prior to switching the Pokemon.
; This might also lead to desync glitches in link battles.
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ] ; whose turn
and a
; player's turn
ld hl , wEnemySelectedMove
2015-08-31 02:38:41 +00:00
ld de , wEnemyMovePower
2014-05-22 22:13:20 +00:00
ld a ,[ wPlayerSelectedMove ]
jr z , .next
; enemy's turn
ld hl , wPlayerSelectedMove
2015-08-31 02:38:41 +00:00
ld de , wPlayerMovePower
2014-05-22 22:13:20 +00:00
ld a ,[ wEnemySelectedMove ]
.next
cp a , COUNTER
ret nz ; return if not using Counter
ld a , $ 01
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a ; initialize the move missed variable to true (it is set to false below if the move hits)
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
cp a , COUNTER
2015-01-04 16:47:21 +00:00
ret z ; miss if the opponent's last selected move is Counter.
2014-05-22 22:13:20 +00:00
ld a ,[ de ]
and a
2015-01-04 16:47:21 +00:00
ret z ; miss if the opponent's last selected move's Base Power is 0.
; check if the move the target last selected was Normal or Fighting type
2014-05-22 22:13:20 +00:00
inc de
ld a ,[ de ]
and a ; normal type
jr z , .counterableType
cp a , FIGHTING
jr z , .counterableType
; if the move wasn't Normal or Fighting type, miss
xor a
ret
.counterableType
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
or [ hl ]
2015-01-04 16:47:21 +00:00
ret z ; If we made it here, Counter still misses if the last move used in battle did no damage to its target.
2015-08-31 02:38:41 +00:00
; wDamage is shared by both players, so Counter may strike back damage dealt by the Counter user itself
2015-01-31 17:26:05 +00:00
; if the conditions meet, even though 99% of the times damage will come from the target.
2015-01-04 16:47:21 +00:00
; if it did damage, double it
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
add a
ldd [ hl ], a
ld a ,[ hl ]
adc a
ld [ hl ], a
jr nc , .noCarry
; damage is capped at 0xFFFF
ld a , $ ff
ld [ hli ], a
ld [ hl ], a
.noCarry
xor a
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2014-05-22 22:13:20 +00:00
call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
xor a
ret
2016-06-12 00:24:04 +00:00
ApplyAttackToEnemyPokemon:
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , OHKO_EFFECT
jr z , ApplyDamageToEnemyPokemon
cp a , SUPER_FANG_EFFECT
jr z , .superFangEffect
cp a , SP ECIAL_DAMAGE_EFFECT
jr z , .specialDamage
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMovePower ]
2014-05-22 22:13:20 +00:00
and a
2015-01-04 16:47:21 +00:00
jp z , ApplyAttackToEnemyPokemonDone ; no attack to apply if base power is 0
2014-05-22 22:13:20 +00:00
jr ApplyDamageToEnemyPokemon
.superFangEffect
; set the damage to half the target's HP
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2015-08-31 02:38:41 +00:00
ld de , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
srl a
ld [ de ], a
inc de
ld b , a
ld a ,[ hl ]
rr a
ld [ de ], a
or b
jr nz , ApplyDamageToEnemyPokemon
; make sure Super Fang's damage is always at least 1
ld a , $ 01
ld [ de ], a
jr ApplyDamageToEnemyPokemon
.specialDamage
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonLevel
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
2015-01-04 16:47:21 +00:00
ld b , a ; Seismic Toss deals damage equal to the user's level
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveNum ]
2015-01-23 03:05:13 +00:00
cp a , SEISMIC_TOSS
2014-05-22 22:13:20 +00:00
jr z , .storeDamage
cp a , NIGHT_SHADE
jr z , .storeDamage
2015-01-04 16:47:21 +00:00
ld b , SONICBOOM_DAMAGE ; 20
2014-05-22 22:13:20 +00:00
cp a , SONICBOOM
jr z , .storeDamage
2015-01-04 16:47:21 +00:00
ld b , DRAGON_RAGE_DAMAGE ; 40
2014-05-22 22:13:20 +00:00
cp a , DRAGON_RAGE
jr z , .storeDamage
; Psywave
ld a ,[ hl ]
ld b , a
srl a
add b
ld b , a ; b = level * 1.5
; loop until a random number in the range [1, b) is found
.loop
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and a
jr z , .loop
cp b
jr nc , .loop
ld b , a
2015-01-04 16:47:21 +00:00
.storeDamage ; store damage value at b
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a
ld a , b
ld [ hl ], a
2016-06-12 00:24:04 +00:00
ApplyDamageToEnemyPokemon:
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b , a
ld a ,[ hl ]
or b
jr z , ApplyAttackToEnemyPokemonDone ; we're done if damage is 0
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit HasSubstituteUp , a ; does the enemy have a substitute?
2014-05-22 22:13:20 +00:00
jp nz , AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP
ld a ,[ hld ]
ld b , a
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonHP + 1 ]
2014-05-22 22:13:20 +00:00
ld [ wHPBarOldHP ], a
sub b
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonHP + 1 ], a
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
ld b , a
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonHP ]
2014-05-22 22:13:20 +00:00
ld [ wHPBarOldHP + 1 ], a
sbc b
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonHP ], a
2014-05-22 22:13:20 +00:00
jr nc , .animateHpBar
2015-08-31 02:38:41 +00:00
; if more damage was done than the current HP, zero the HP and set the damage (wDamage)
2014-05-22 22:13:20 +00:00
; equal to how much HP the pokemon had before the attack
ld a ,[ wHPBarOldHP + 1 ]
ld [ hli ], a
ld a ,[ wHPBarOldHP ]
ld [ hl ], a
xor a
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
.animateHpBar
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMaxHP
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld [ wHPBarMaxHP + 1 ], a
ld a ,[ hl ]
ld [ wHPBarMaxHP ], a
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld [ wHPBarNewHP + 1 ], a
ld a ,[ hl ]
ld [ wHPBarNewHP ], a
2015-07-18 20:52:03 +00:00
coord hl , 2 , 2
2014-05-22 22:13:20 +00:00
xor a
2015-02-08 06:18:42 +00:00
ld [ wHPBarType ], a
2014-06-16 20:57:26 +00:00
predef UpdateHPBar2 ; animate the HP bar shortening
2016-06-12 00:24:04 +00:00
ApplyAttackToEnemyPokemonDone:
2014-08-09 05:39:13 +00:00
jp DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ApplyAttackToPlayerPokemon:
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , OHKO_EFFECT
jr z , ApplyDamageToPlayerPokemon
cp a , SUPER_FANG_EFFECT
jr z , .superFangEffect
cp a , SP ECIAL_DAMAGE_EFFECT
jr z , .specialDamage
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMovePower ]
2014-05-22 22:13:20 +00:00
and a
jp z , ApplyAttackToPlayerPokemonDone
jr ApplyDamageToPlayerPokemon
.superFangEffect
; set the damage to half the target's HP
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonHP
2015-08-31 02:38:41 +00:00
ld de , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
srl a
ld [ de ], a
inc de
ld b , a
ld a ,[ hl ]
rr a
ld [ de ], a
or b
jr nz , ApplyDamageToPlayerPokemon
; make sure Super Fang's damage is always at least 1
ld a , $ 01
ld [ de ], a
jr ApplyDamageToPlayerPokemon
.specialDamage
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonLevel
2014-05-22 22:13:20 +00:00
ld a ,[ hl ]
ld b , a
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveNum ]
2014-05-22 22:13:20 +00:00
cp a , SEISMIC_TOSS
jr z , .storeDamage
cp a , NIGHT_SHADE
jr z , .storeDamage
ld b , SONICBOOM_DAMAGE
cp a , SONICBOOM
jr z , .storeDamage
ld b , DRAGON_RAGE_DAMAGE
cp a , DRAGON_RAGE
jr z , .storeDamage
; Psywave
ld a ,[ hl ]
ld b , a
srl a
add b
ld b , a ; b = attacker's level * 1.5
; loop until a random number in the range [0, b) is found
; this differs from the range when the player attacks, which is [1, b)
; it's possible for the enemy to do 0 damage with Psywave, but the player always does at least 1 damage
.loop
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
jr nc , .loop
ld b , a
.storeDamage
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a
ld a , b
ld [ hl ], a
2016-06-12 00:24:04 +00:00
ApplyDamageToPlayerPokemon:
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b , a
ld a ,[ hl ]
or b
jr z , ApplyAttackToPlayerPokemonDone ; we're done if damage is 0
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit HasSubstituteUp , a ; does the player have a substitute?
2014-05-22 22:13:20 +00:00
jp nz , AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP and the new HP at wHPBarNewHP
ld a ,[ hld ]
ld b , a
2014-06-14 11:12:40 +00:00
ld a ,[ wBattleMonHP + 1 ]
2014-05-22 22:13:20 +00:00
ld [ wHPBarOldHP ], a
sub b
2014-06-14 11:12:40 +00:00
ld [ wBattleMonHP + 1 ], a
2014-05-22 22:13:20 +00:00
ld [ wHPBarNewHP ], a
ld b ,[ hl ]
2014-06-14 11:12:40 +00:00
ld a ,[ wBattleMonHP ]
2014-05-22 22:13:20 +00:00
ld [ wHPBarOldHP + 1 ], a
sbc b
2014-06-14 11:12:40 +00:00
ld [ wBattleMonHP ], a
2014-05-22 22:13:20 +00:00
ld [ wHPBarNewHP + 1 ], a
jr nc , .animateHpBar
2015-08-31 02:38:41 +00:00
; if more damage was done than the current HP, zero the HP and set the damage (wDamage)
2014-05-22 22:13:20 +00:00
; equal to how much HP the pokemon had before the attack
ld a ,[ wHPBarOldHP + 1 ]
ld [ hli ], a
ld a ,[ wHPBarOldHP ]
ld [ hl ], a
xor a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
ld hl , wHPBarNewHP
ld [ hli ], a
ld [ hl ], a
.animateHpBar
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMaxHP
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld [ wHPBarMaxHP + 1 ], a
ld a ,[ hl ]
ld [ wHPBarMaxHP ], a
2015-07-18 20:52:03 +00:00
coord hl , 10 , 9
2014-05-22 22:13:20 +00:00
ld a , $ 01
2015-02-08 06:18:42 +00:00
ld [ wHPBarType ], a
2014-06-16 20:57:26 +00:00
predef UpdateHPBar2 ; animate the HP bar shortening
2016-06-12 04:30:05 +00:00
ApplyAttackToPlayerPokemonDone:
2014-08-09 05:39:13 +00:00
jp DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
AttackSubstitute:
2015-01-04 16:47:21 +00:00
; Unlike the two ApplyAttackToPokemon functions, Attack Substitute is shared by player and enemy.
; Self-confusion damage as well as Hi-Jump Kick and Jump Kick recoil cause a momentary turn swap before being applied.
2015-06-11 22:41:33 +00:00
; If the user has a Substitute up and would take damage because of that,
2015-03-31 18:16:31 +00:00
; damage will be applied to the other player's Substitute.
2015-06-11 22:41:33 +00:00
; Normal recoil such as from Double-Edge isn't affected by this glitch,
2015-03-31 18:16:31 +00:00
; because this function is never called in that case.
2015-01-04 16:47:21 +00:00
2014-05-22 22:13:20 +00:00
ld hl , SubstituteTookDamageText
call PrintText
; values for player turn
ld de , wEnemySubstituteHP
2015-08-31 02:38:41 +00:00
ld bc , wEnemyBattleStatus2
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
jr z , .applyDamageToSubstitute
; values for enemy turn
ld de , wPlayerSubstituteHP
2015-08-31 02:38:41 +00:00
ld bc , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
.applyDamageToSubstitute
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
and a
jr nz , .substituteBroke ; damage > 0xFF always breaks substitutes
; subtract damage from HP of substitute
ld a ,[ de ]
sub [ hl ]
ld [ de ], a
ret nc
.substituteBroke
2015-08-31 02:38:41 +00:00
; If the target's Substitute breaks, wDamage isn't updated with the amount of HP
2015-03-31 18:16:31 +00:00
; the Substitute had before being attacked.
2014-05-22 22:13:20 +00:00
ld h , b
ld l , c
2015-03-31 18:50:49 +00:00
res HasSubstituteUp ,[ hl ] ; unset the substitute bit
2014-05-22 22:13:20 +00:00
ld hl , SubstituteBrokeText
call PrintText
; flip whose turn it is for the next function call
ld a ,[ H_WHOSETURN ]
xor a , $ 01
ld [ H_WHOSETURN ], a
2015-07-12 22:51:04 +00:00
callab HideSubstituteShowMonAnim ; animate the substitute breaking
2014-05-22 22:13:20 +00:00
; flip the turn back to the way it was
ld a ,[ H_WHOSETURN ]
xor a , $ 01
ld [ H_WHOSETURN ], a
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMoveEffect ; value for player's turn
2014-05-22 22:13:20 +00:00
and a
jr z , .nullifyEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMoveEffect ; value for enemy's turn
2014-05-22 22:13:20 +00:00
.nullifyEffect
xor a
ld [ hl ], a ; zero the effect of the attacker's move
2014-08-09 05:39:13 +00:00
jp DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SubstituteTookDamageText:
2014-05-22 22:13:20 +00:00
TX_FAR _SubstituteTookDamageText
db "@"
2016-06-12 00:24:04 +00:00
SubstituteBrokeText:
2014-05-22 22:13:20 +00:00
TX_FAR _SubstituteBrokeText
db "@"
; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
2016-06-12 00:24:04 +00:00
HandleBuildingRage:
2014-05-22 22:13:20 +00:00
; values for the player turn
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2014-05-22 22:13:20 +00:00
ld de , wEnemyMonStatMods
2015-08-31 02:38:41 +00:00
ld bc , wEnemyMoveNum
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
jr z , .next
; values for the enemy turn
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
ld de , wPlayerMonStatMods
2015-08-31 02:38:41 +00:00
ld bc , wPlayerMoveNum
2014-05-22 22:13:20 +00:00
.next
2015-02-03 19:51:53 +00:00
bit UsingRage ,[ hl ] ; is the pokemon being attacked under the effect of Rage?
2014-05-22 22:13:20 +00:00
ret z ; return if not
ld a ,[ de ]
cp a , $ 0 d ; maximum stat modifier value
ret z ; return if attack modifier is already maxed
ld a ,[ H_WHOSETURN ]
xor a , $ 01 ; flip turn for the stat modifier raising function
ld [ H_WHOSETURN ], a
2015-02-03 19:51:53 +00:00
; temporarily change the target pokemon's move to $00 and the effect to the one
2014-05-22 22:13:20 +00:00
; that causes the attack modifier to go up one stage
ld h , b
ld l , c
ld [ hl ], $ 00 ; null move number
inc hl
ld [ hl ], ATTACK_UP1_EFFECT
push hl
ld hl , BuildingRageText
call PrintText
call StatModifierUpEffect ; stat modifier raising function
pop hl
xor a
ldd [ hl ], a ; null move effect
ld a , RAGE
ld [ hl ], a ; restore the target pokemon's move number to Rage
ld a ,[ H_WHOSETURN ]
xor a , $ 01 ; flip turn back to the way it was
ld [ H_WHOSETURN ], a
ret
2016-06-12 00:24:04 +00:00
BuildingRageText:
2014-05-22 22:13:20 +00:00
TX_FAR _BuildingRageText
db "@"
; copy last move for Mirror Move
; sets zero flag on failure and unsets zero flag on success
2016-06-12 00:24:04 +00:00
MirrorMoveCopyMove:
2015-01-31 17:26:05 +00:00
; Mirror Move makes use of ccf1 (wPlayerUsedMove) and ccf2 (wEnemyUsedMove) addresses,
; which are mainly used to print the "[Pokemon] used [Move]" text.
2015-01-04 16:47:21 +00:00
; Both are set to 0 whenever a new Pokemon is sent out
; ccf1 is also set to 0 whenever the player is fast asleep or frozen solid.
; ccf2 is also set to 0 whenever the enemy is fast asleep or frozen solid.
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
; values for player turn
2015-01-31 17:26:05 +00:00
ld a ,[ wEnemyUsedMove ]
2014-05-22 22:13:20 +00:00
ld hl , wPlayerSelectedMove
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveNum
2014-05-22 22:13:20 +00:00
jr z , .next
; values for enemy turn
2015-01-31 17:26:05 +00:00
ld a ,[ wPlayerUsedMove ]
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveNum
2014-05-22 22:13:20 +00:00
ld hl , wEnemySelectedMove
.next
ld [ hl ], a
2015-01-04 16:47:21 +00:00
cp a , MIRROR_MOVE ; did the target Pokemon last use Mirror Move, and miss?
2014-05-22 22:13:20 +00:00
jr z , .mirrorMoveFailed
2015-01-31 17:26:05 +00:00
and a ; has the target selected any move yet?
2014-05-22 22:13:20 +00:00
jr nz , ReloadMoveData
.mirrorMoveFailed
ld hl , MirrorMoveFailedText
call PrintText
xor a
ret
2016-06-12 00:24:04 +00:00
MirrorMoveFailedText:
2014-05-22 22:13:20 +00:00
TX_FAR _MirrorMoveFailedText
db "@"
; function used to reload move data for moves like Mirror Move and Metronome
2016-06-12 00:24:04 +00:00
ReloadMoveData:
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
dec a
ld hl , Moves
2015-08-10 04:56:20 +00:00
ld bc , MoveEnd - Moves
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , BANK ( Moves )
call FarCopyData ; copy the move's stats
call IncrementMovePP
; the follow two function calls are used to reload the move name
call GetMoveName
call CopyStringToCF4B
ld a , $ 01
and a
ret
; function that picks a random move for metronome
2016-06-12 00:24:04 +00:00
MetronomePickMove:
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , METRONOME
call PlayMoveAnimation ; play Metronome's animation
; values for player turn
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveNum
2014-05-22 22:13:20 +00:00
ld hl , wPlayerSelectedMove
ld a ,[ H_WHOSETURN ]
and a
jr z , .pickMoveLoop
; values for enemy turn
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveNum
2014-05-22 22:13:20 +00:00
ld hl , wEnemySelectedMove
; loop to pick a random number in the range [1, $a5) to be the move used by Metronome
.pickMoveLoop
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and a
jr z , .pickMoveLoop
2014-06-14 11:12:40 +00:00
cp a , NUM_ATTACKS + 1 ; max normal move number + 1 (this is Struggle's move number)
2014-05-22 22:13:20 +00:00
jr nc , .pickMoveLoop
cp a , METRONOME
jr z , .pickMoveLoop
ld [ hl ], a
jr ReloadMoveData
; this function increments the current move's PP
; it's used to prevent moves that run another move within the same turn
; (like Mirror Move and Metronome) from losing 2 PP
2016-06-12 00:24:04 +00:00
IncrementMovePP:
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
; values for player turn
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonPP
ld de , wPartyMon1PP
2014-05-22 22:13:20 +00:00
ld a ,[ wPlayerMoveListIndex ]
jr z , .next
; values for enemy turn
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonPP
ld de , wEnemyMon1PP
2014-05-22 22:13:20 +00:00
ld a ,[ wEnemyMoveListIndex ]
.next
ld b , $ 00
ld c , a
add hl , bc
inc [ hl ] ; increment PP in the currently battling pokemon memory location
ld h , d
ld l , e
add hl , bc
ld a ,[ H_WHOSETURN ]
and a
ld a ,[ wPlayerMonNumber ] ; value for player turn
2015-01-20 19:21:16 +00:00
jr z , .updatePP
2014-06-14 11:12:40 +00:00
ld a ,[ wEnemyMonPartyPos ] ; value for enemy turn
2015-01-20 19:21:16 +00:00
.updatePP
2014-06-14 11:12:40 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
inc [ hl ] ; increment PP in the party memory location
ret
; function to adjust the base damage of an attack to account for type effectiveness
2016-06-12 00:24:04 +00:00
AdjustDamageForMoveType:
2014-05-22 22:13:20 +00:00
; values for player turn
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonType
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b , a ; b = type 1 of attacker
ld c ,[ hl ] ; c = type 2 of attacker
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonType
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld d , a ; d = type 1 of defender
ld e ,[ hl ] ; e = type 2 of defender
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveType ]
2015-08-07 12:20:37 +00:00
ld [ wMoveType ], a
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
jr z , .next
; values for enemy turn
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonType
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld b , a ; b = type 1 of attacker
ld c ,[ hl ] ; c = type 2 of attacker
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonType
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld d , a ; d = type 1 of defender
ld e ,[ hl ] ; e = type 2 of defender
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveType ]
2015-08-07 12:20:37 +00:00
ld [ wMoveType ], a
2014-05-22 22:13:20 +00:00
.next
2015-08-07 12:20:37 +00:00
ld a ,[ wMoveType ]
2014-05-22 22:13:20 +00:00
cp b ; does the move type match type 1 of the attacker?
jr z , .sameTypeAttackBonus
cp c ; does the move type match type 2 of the attacker?
jr z , .sameTypeAttackBonus
jr .skipSameTypeAttackBonus
.sameTypeAttackBonus
; if the move type matches one of the attacker's types
2015-08-31 02:38:41 +00:00
ld hl , wDamage + 1
2014-05-22 22:13:20 +00:00
ld a ,[ hld ]
ld h ,[ hl ]
ld l , a ; hl = damage
ld b , h
ld c , l ; bc = damage
srl b
rr c ; bc = floor(0.5 * damage)
add hl , bc ; hl = floor(1.5 * damage)
; store damage
ld a , h
2015-08-31 02:38:41 +00:00
ld [ wDamage ], a
2014-05-22 22:13:20 +00:00
ld a , l
2015-08-31 02:38:41 +00:00
ld [ wDamage + 1 ], a
2015-03-31 18:28:42 +00:00
ld hl , wDamageMultipliers
2014-05-22 22:13:20 +00:00
set 7 ,[ hl ]
.skipSameTypeAttackBonus
2015-08-07 12:20:37 +00:00
ld a ,[ wMoveType ]
ld b , a
2014-05-22 22:13:20 +00:00
ld hl , TypeEffects
.loop
ld a ,[ hli ] ; a = "attacking type" of the current type pair
cp a , $ ff
jr z , .done
cp b ; does move type match "attacking type"?
jr nz , .nextTypePair
ld a ,[ hl ] ; a = "defending type" of the current type pair
cp d ; does type 1 of defender match "defending type"?
jr z , .matchingPairFound
cp e ; does type 2 of defender match "defending type"?
jr z , .matchingPairFound
jr .nextTypePair
.matchingPairFound
; if the move type matches the "attacking type" and one of the defender's types matches the "defending type"
push hl
push bc
inc hl
2015-03-31 18:28:42 +00:00
ld a ,[ wDamageMultipliers ]
2014-05-22 22:13:20 +00:00
and a , $ 80
ld b , a
ld a ,[ hl ] ; a = damage multiplier
ld [ H_MULTIPLIER ], a
add b
2015-03-31 18:28:42 +00:00
ld [ wDamageMultipliers ], a
2014-05-22 22:13:20 +00:00
xor a
ld [ H_MULTIPLICAND ], a
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a ,[ hli ]
ld [ H_MULTIPLICAND + 1 ], a
ld a ,[ hld ]
ld [ H_MULTIPLICAND + 2 ], a
call Multiply
ld a , 10
ld [ H_DIVISOR ], a
ld b , $ 04
call Di vide
ld a ,[ H_QUOTIENT + 2 ]
ld [ hli ], a
ld b , a
ld a ,[ H_QUOTIENT + 3 ]
ld [ hl ], a
or b ; is damage 0?
jr nz , .skipTypeImmunity
.typeImmunity
; if damage is 0, make the move miss
2015-01-04 16:47:21 +00:00
; this only occurs if a move that would do 2 or 3 damage is 0.25x effective against the target
2014-05-22 22:13:20 +00:00
inc a
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2014-05-22 22:13:20 +00:00
.skipTypeImmunity
pop bc
pop hl
.nextTypePair
inc hl
inc hl
jp .loop
.done
ret
; function to tell how effective the type of an enemy attack is on the player's current pokemon
; this doesn't take into account the effects that dual types can have
; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
2015-08-07 12:20:37 +00:00
; the result is stored in [wTypeEffectiveness]
2014-05-22 22:13:20 +00:00
; ($05 is not very effective, $10 is neutral, $14 is super effective)
; as far is can tell, this is only used once in some AI code to help decide which move to use
2016-06-12 00:24:04 +00:00
AIGetTypeEffectiveness:
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveType ]
2015-08-07 12:20:37 +00:00
ld d , a ; d = type of enemy move
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonType
2015-08-07 12:20:37 +00:00
ld b ,[ hl ] ; b = type 1 of player's pokemon
2014-05-22 22:13:20 +00:00
inc hl
2015-08-07 12:20:37 +00:00
ld c ,[ hl ] ; c = type 2 of player's pokemon
2014-05-22 22:13:20 +00:00
ld a , $ 10
2015-08-07 12:20:37 +00:00
ld [ wTypeEffectiveness ], a ; initialize to neutral effectiveness
2014-05-22 22:13:20 +00:00
ld hl , TypeEffects
.loop
ld a ,[ hli ]
cp a , $ ff
ret z
2015-08-07 12:20:37 +00:00
cp d ; match the type of the move
2014-05-22 22:13:20 +00:00
jr nz , .nextTypePair1
ld a ,[ hli ]
2015-08-07 12:20:37 +00:00
cp b ; match with type 1 of pokemon
2014-05-22 22:13:20 +00:00
jr z , .done
2015-08-07 12:20:37 +00:00
cp c ; or match with type 2 of pokemon
2014-05-22 22:13:20 +00:00
jr z , .done
jr .nextTypePair2
.nextTypePair1
inc hl
.nextTypePair2
inc hl
jr .loop
.done
ld a ,[ hl ]
2015-08-07 12:20:37 +00:00
ld [ wTypeEffectiveness ], a ; store damage multiplier
2014-05-22 22:13:20 +00:00
ret
INCLUDE "data/type_effects.asm"
; some tests that need to pass for a move to hit
2016-06-12 00:24:04 +00:00
MoveHitTest:
2014-05-22 22:13:20 +00:00
; player's turn
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
ld de , wPlayerMoveEffect
2014-06-14 11:12:40 +00:00
ld bc , wEnemyMonStatus
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
jr z , .dreamEaterCheck
; enemy's turn
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
ld de , wEnemyMoveEffect
2014-06-14 11:12:40 +00:00
ld bc , wBattleMonStatus
2014-05-22 22:13:20 +00:00
.dreamEaterCheck
ld a ,[ de ]
cp a , DREAM_EATER_EFFECT
jr nz , .swiftCheck
ld a ,[ bc ]
2015-02-03 19:51:53 +00:00
and a , SLP ; is the target pokemon sleeping?
2014-05-22 22:13:20 +00:00
jp z , .moveMissed
.swiftCheck
ld a ,[ de ]
cp a , SWIFT_EFFECT
ret z ; Swift never misses (interestingly, Azure Heights lists this is a myth, but it appears to be true)
call Ch eckTargetSubstitute ; substitute check (note that this overwrites a)
jr z , .checkForDigOrFlyStatus
; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
; since $7b79 overwrites a with either $00 or $01, it never works.
2014-08-09 05:39:13 +00:00
cp a , DRAIN_HP_EFFECT
2014-05-22 22:13:20 +00:00
jp z , .moveMissed
2014-08-09 05:39:13 +00:00
cp a , DREAM_EATER_EFFECT
2014-05-22 22:13:20 +00:00
jp z , .moveMissed
.checkForDigOrFlyStatus
2015-02-03 19:51:53 +00:00
bit Invulnerable ,[ hl ]
2014-05-22 22:13:20 +00:00
jp nz , .moveMissed
ld a ,[ H_WHOSETURN ]
and a
jr nz , .enemyTurn
.playerTurn
; this checks if the move effect is disallowed by mist
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , ATTACK_DOWN1_EFFECT
jr c , .skipEnemyMistCheck
2015-02-03 19:51:53 +00:00
cp a , HAZE_EFFECT + 1
2014-05-22 22:13:20 +00:00
jr c , .enemyMistCheck
2015-02-03 19:51:53 +00:00
cp a , ATTACK_DOWN2_EFFECT
2014-05-22 22:13:20 +00:00
jr c , .skipEnemyMistCheck
2015-02-03 19:51:53 +00:00
cp a , REFLECT_EFFECT + 1
2014-05-22 22:13:20 +00:00
jr c , .enemyMistCheck
jr .skipEnemyMistCheck
.enemyMistCheck
; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
; i.e. the following moves
; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
2015-02-03 19:51:53 +00:00
; FLASH, CONVERSION*, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
2014-05-22 22:13:20 +00:00
; the moves that are marked with an asterisk are not affected since this
; function is not called when those moves are used
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit ProtectedByMist , a ; is mon protected by mist?
2014-05-22 22:13:20 +00:00
jp nz , .moveMissed
.skipEnemyMistCheck
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit UsingXAccuracy , a ; is the player using X Accuracy?
2014-05-22 22:13:20 +00:00
ret nz ; if so, always hit regardless of accuracy/evasion
jr .calcHitChance
.enemyTurn
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp a , ATTACK_DOWN1_EFFECT
jr c , .skipPlayerMistCheck
2015-02-03 19:51:53 +00:00
cp a , HAZE_EFFECT + 1
2014-05-22 22:13:20 +00:00
jr c , .playerMistCheck
2015-02-03 19:51:53 +00:00
cp a , ATTACK_DOWN2_EFFECT
2014-05-22 22:13:20 +00:00
jr c , .skipPlayerMistCheck
2015-02-03 19:51:53 +00:00
cp a , REFLECT_EFFECT + 1
2014-05-22 22:13:20 +00:00
jr c , .playerMistCheck
jr .skipPlayerMistCheck
.playerMistCheck
; similar to enemy mist check
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit ProtectedByMist , a ; is mon protected by mist?
2014-05-22 22:13:20 +00:00
jp nz , .moveMissed
.skipPlayerMistCheck
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit UsingXAccuracy , a ; is the enemy using X Accuracy?
2014-05-22 22:13:20 +00:00
ret nz ; if so, always hit regardless of accuracy/evasion
.calcHitChance
call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
2015-08-31 02:38:41 +00:00
ld a ,[ wPlayerMoveAccuracy ]
2014-05-22 22:13:20 +00:00
ld b , a
ld a ,[ H_WHOSETURN ]
and a
jr z , .doAccuracyCheck
2015-08-31 02:38:41 +00:00
ld a ,[ wEnemyMoveAccuracy ]
2014-05-22 22:13:20 +00:00
ld b , a
.doAccuracyCheck
; if the random number generated is greater than or equal to the scaled accuracy, the move misses
; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
jr nc , .moveMissed
ret
.moveMissed
xor a
2015-08-31 02:38:41 +00:00
ld hl , wDamage ; zero the damage
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], a
inc a
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
jr z , .playerTurn2
.enemyTurn2
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove ,[ hl ] ; end multi-turn attack e.g. wrap
2014-05-22 22:13:20 +00:00
ret
.playerTurn2
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-03 19:51:53 +00:00
res UsingTrappingMove ,[ hl ] ; end multi-turn attack e.g. wrap
2014-05-22 22:13:20 +00:00
ret
; values for player turn
2016-06-12 00:24:04 +00:00
CalcHitChance:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMoveAccuracy
2014-05-22 22:13:20 +00:00
ld a ,[ H_WHOSETURN ]
and a
ld a ,[ wPlayerMonAccuracyMod ]
ld b , a
ld a ,[ wEnemyMonEvasionMod ]
ld c , a
jr z , .next
; values for enemy turn
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMoveAccuracy
2014-05-22 22:13:20 +00:00
ld a ,[ wEnemyMonAccuracyMod ]
ld b , a
ld a ,[ wPlayerMonEvasionMod ]
ld c , a
.next
ld a , $ 0 e
sub c
2015-03-31 18:16:31 +00:00
ld c , a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion
; decreases the hit chance instead of increasing the hit chance)
2014-05-22 22:13:20 +00:00
; zero the high bytes of the multiplicand
xor a
ld [ H_MULTIPLICAND ], a
ld [ H_MULTIPLICAND + 1 ], a
ld a ,[ hl ]
ld [ H_MULTIPLICAND + 2 ], a ; set multiplicand to move accuracy
push hl
ld d , $ 02 ; loop has two iterations
2015-03-31 18:16:31 +00:00
; loop to do the calculations, the first iteration multiplies by the accuracy ratio and
; the second iteration multiplies by the evasion ratio
2014-05-22 22:13:20 +00:00
.loop
push bc
2015-07-03 19:37:53 +00:00
ld hl , StatModifierRatios ; stat modifier ratios
2014-05-22 22:13:20 +00:00
dec b
sla b
ld c , b
ld b , $ 00
add hl , bc ; hl = address of stat modifier ratio
pop bc
ld a ,[ hli ]
ld [ H_MULTIPLIER ], a ; set multiplier to the numerator of the ratio
call Multiply
ld a ,[ hl ]
2015-03-31 18:16:31 +00:00
ld [ H_DIVISOR ], a ; set divisor to the the denominator of the ratio
; (the dividend is the product of the previous multiplication)
2014-05-22 22:13:20 +00:00
ld b , $ 04 ; number of bytes in the dividend
call Di vide
ld a ,[ H_QUOTIENT + 3 ]
ld b , a
ld a ,[ H_QUOTIENT + 2 ]
or b
jp nz , .nextCalculation
; make sure the result is always at least one
ld [ H_QUOTIENT + 2 ], a
ld a , $ 01
ld [ H_QUOTIENT + 3 ], a
.nextCalculation
ld b , c
dec d
jr nz , .loop
ld a ,[ H_QUOTIENT + 2 ]
and a ; is the calculated hit chance over 0xFF?
ld a ,[ H_QUOTIENT + 3 ]
jr z , .storeAccuracy
; if calculated hit chance over 0xFF
ld a , $ ff ; set the hit chance to 0xFF
.storeAccuracy
pop hl
ld [ hl ], a ; store the hit chance in the move accuracy variable
ret
2014-08-09 05:39:13 +00:00
; multiplies damage by a random percentage from ~85% to 100%
2016-06-12 00:24:04 +00:00
RandomizeDamage:
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
and a
2014-08-09 05:39:13 +00:00
jr nz , .DamageGreaterThanOne
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
cp 2
2015-01-04 16:47:21 +00:00
ret c ; return if damage is equal to 0 or 1
2014-08-09 05:39:13 +00:00
.DamageGreaterThanOne
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND ], a
2014-05-22 22:13:20 +00:00
dec hl
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 2 ], a
; loop until a random number greater than or equal to 217 is generated
.loop
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
rrca
2014-08-09 05:39:13 +00:00
cp 217
jr c , .loop
ld [ H_MULTIPLIER ], a
call Multiply ; multiply damage by the random number, which is in the range [217, 255]
ld a , 255
ld [ H_DIVISOR ], a
2014-05-22 22:13:20 +00:00
ld b , $ 4
2014-08-09 05:39:13 +00:00
call Di vide ; divide the result by 255
; store the modified damage
ld a , [ H_QUOTIENT + 2 ]
2015-08-31 02:38:41 +00:00
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2014-08-09 05:39:13 +00:00
ld a , [ H_QUOTIENT + 3 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
ret
2015-03-31 20:22:12 +00:00
; for more detailed commentary, see equivalent function for player side (ExecutePlayerMove)
2016-06-12 00:24:04 +00:00
ExecuteEnemyMove:
2014-08-09 05:39:13 +00:00
ld a , [ wEnemySelectedMove ]
2014-05-22 22:13:20 +00:00
inc a
2015-01-31 17:26:05 +00:00
jp z , ExecuteEnemyMoveDone
2014-05-22 22:13:20 +00:00
call PrintGhostText
2015-01-31 17:26:05 +00:00
jp z , ExecuteEnemyMoveDone
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-02-03 19:51:53 +00:00
jr nz , .executeEnemyMove
2014-05-22 22:13:20 +00:00
ld b , $ 1
2015-02-07 10:43:08 +00:00
ld a , [ wSerialExchangeNybbleReceiveData ]
2016-10-29 08:44:13 +00:00
cp LINKBATTLE_STRUGGLE
2015-02-03 19:51:53 +00:00
jr z , .executeEnemyMove
2016-10-29 08:44:13 +00:00
cp 4
2014-05-22 22:13:20 +00:00
ret nc
2015-02-03 19:51:53 +00:00
.executeEnemyMove
2015-03-31 18:40:22 +00:00
ld hl , wAILayer2Encouragement
2014-05-22 22:13:20 +00:00
inc [ hl ]
xor a
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2015-03-31 18:28:42 +00:00
ld [ wMoveDidntMiss ], a
2014-05-22 22:13:20 +00:00
ld a , $ a
2015-03-31 18:28:42 +00:00
ld [ wDamageMultipliers ], a
2014-08-09 05:39:13 +00:00
call Ch eckEnemyStatusConditions
2015-01-31 17:26:05 +00:00
jr nz , .enemyHasNoSpecialConditions
2014-05-22 22:13:20 +00:00
jp [ hl ]
2015-01-31 17:26:05 +00:00
.enemyHasNoSpecialConditions
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
bit Ch argingUp , [ hl ] ; is the enemy charging up for attack?
jr nz , EnemyCanExecuteChargingMove ; if so, jump
2014-05-22 22:13:20 +00:00
call GetCurrentMove
2016-06-12 00:24:04 +00:00
CheckIfEnemyNeedsToChargeUp:
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp CH ARGE_EFFECT
2014-08-09 05:39:13 +00:00
jp z , JumpMoveEffect
2014-05-22 22:13:20 +00:00
cp FLY_EFFECT
2014-08-09 05:39:13 +00:00
jp z , JumpMoveEffect
2015-02-03 19:51:53 +00:00
jr EnemyCanExecuteMove
2016-06-12 00:24:04 +00:00
EnemyCanExecuteChargingMove:
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res Ch argingUp , [ hl ] ; no longer charging up for attack
res Invulnerable , [ hl ] ; no longer invulnerable to typical attacks
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-08-08 04:17:44 +00:00
ld a , BANK ( MoveNames )
2014-05-26 21:04:56 +00:00
ld [ wPredefBank ], a
2014-05-22 22:13:20 +00:00
ld a , MOVE_NAME
2015-02-08 09:44:41 +00:00
ld [ wNameListType ], a
2014-05-22 22:13:20 +00:00
call GetName
2014-05-26 21:04:56 +00:00
ld de , wcd6d
2014-05-22 22:13:20 +00:00
call CopyStringToCF4B
2016-06-12 00:24:04 +00:00
EnemyCanExecuteMove:
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 18:40:22 +00:00
ld [ wMonIsDisobedient ], a
2014-05-22 22:13:20 +00:00
call PrintMonName1Text
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , ResidualEffects1
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c , JumpMoveEffect
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , Sp ecialEffectsCont
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2014-08-09 05:39:13 +00:00
call c , JumpMoveEffect
2016-06-12 00:24:04 +00:00
EnemyCalcMoveDamage:
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , SetDamageEffects
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2015-03-31 20:22:12 +00:00
jp c , EnemyMoveHitTest
2014-05-22 22:13:20 +00:00
call CriticalHitTest
call HandleCounterMove
2015-03-31 20:22:12 +00:00
jr z , handleIfEnemyMoveMissed
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
call GetDamageVarsForEnemyAttack
call SwapPlayerAndEnemyLevels
call CalculateDamage
2015-03-31 20:22:12 +00:00
jp z , EnemyCheckIfFlyOrChargeEffect
2014-05-22 22:13:20 +00:00
call AdjustDamageForMoveType
2014-08-09 05:39:13 +00:00
call RandomizeDamage
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
EnemyMoveHitTest:
2014-05-22 22:13:20 +00:00
call MoveHitTest
2016-06-12 00:24:04 +00:00
handleIfEnemyMoveMissed:
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr z , .moveDidNotMiss
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp EXPLODE_EFFECT
2016-06-12 04:30:05 +00:00
jr z , handleExplosionMiss
2015-03-31 20:22:12 +00:00
jr EnemyCheckIfFlyOrChargeEffect
2016-06-12 04:30:05 +00:00
.moveDidNotMiss
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
GetEnemyAnimationType:
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
and a
ld a , $ 1
2015-03-31 20:22:12 +00:00
jr z , playEnemyMoveAnimation
2014-05-22 22:13:20 +00:00
ld a , $ 2
2015-03-31 20:22:12 +00:00
jr playEnemyMoveAnimation
2016-06-12 04:30:05 +00:00
handleExplosionMiss:
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2014-05-22 22:13:20 +00:00
xor a
2016-06-12 00:24:04 +00:00
playEnemyMoveAnimation:
2014-05-22 22:13:20 +00:00
push af
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit HasSubstituteUp , a ; does mon have a substitute?
2015-07-12 22:51:04 +00:00
ld hl , HideSubstituteShowMonAnim
ld b , BANK ( HideSubstituteShowMonAnim )
2014-05-22 22:13:20 +00:00
call nz , Bankswitch
pop af
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2014-05-22 22:13:20 +00:00
call PlayMoveAnimation
2015-01-20 19:21:16 +00:00
call HandleExplodingAnimation
2014-08-09 05:39:13 +00:00
call DrawEnemyHUDAndHPBar
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit HasSubstituteUp , a ; does mon have a substitute?
2015-07-12 22:51:04 +00:00
ld hl , ReshowSubstituteAnim
ld b , BANK ( ReshowSubstituteAnim )
2014-05-22 22:13:20 +00:00
call nz , Bankswitch ; slide the substitute's sprite out
2015-03-31 20:22:12 +00:00
jr EnemyCheckIfMirrorMoveEffect
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
EnemyCheckIfFlyOrChargeEffect:
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2015-07-03 19:37:53 +00:00
ld c , 30
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp FLY_EFFECT
2015-03-31 20:22:12 +00:00
jr z , .playAnim
2014-05-22 22:13:20 +00:00
cp CH ARGE_EFFECT
2015-03-31 20:22:12 +00:00
jr z , .playAnim
jr EnemyCheckIfMirrorMoveEffect
.playAnim
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , STATUS_AFFECTED_ANIM
call PlayMoveAnimation
2016-06-12 00:24:04 +00:00
EnemyCheckIfMirrorMoveEffect:
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp MIRROR_MOVE_EFFECT
jr nz , .notMirrorMoveEffect
call MirrorMoveCopyMove
2015-01-31 17:26:05 +00:00
jp z , ExecuteEnemyMoveDone
2015-02-03 19:51:53 +00:00
jp Ch eckIfEnemyNeedsToChargeUp
2014-05-22 22:13:20 +00:00
.notMirrorMoveEffect
cp METRONOME_EFFECT
jr nz , .notMetronomeEffect
call MetronomePickMove
2015-02-03 19:51:53 +00:00
jp Ch eckIfEnemyNeedsToChargeUp
2014-05-22 22:13:20 +00:00
.notMetronomeEffect
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , ResidualEffects2
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c , JumpMoveEffect
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr z , .moveDidNotMiss
2014-05-22 22:13:20 +00:00
call PrintMoveFailureText
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp EXPLODE_EFFECT
2016-06-12 04:30:05 +00:00
jr z , .handleExplosionMiss
2015-01-31 17:26:05 +00:00
jp ExecuteEnemyMoveDone
2016-06-12 04:30:05 +00:00
.moveDidNotMiss
2014-05-22 22:13:20 +00:00
call ApplyAttackToPlayerPokemon
2014-08-09 05:39:13 +00:00
call PrintCriticalOHKOText
2014-05-22 22:13:20 +00:00
callab Di sp layEffectiveness
2014-08-09 05:39:13 +00:00
ld a , 1
2015-03-31 18:28:42 +00:00
ld [ wMoveDidntMiss ], a
2016-06-12 04:30:05 +00:00
.handleExplosionMiss
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-01-20 19:21:16 +00:00
ld hl , Al waysHappenSideEffects
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2014-08-09 05:39:13 +00:00
call c , JumpMoveEffect
ld hl , wBattleMonHP
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , [ hl ]
or b
ret z
call HandleBuildingRage
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
bit AttackingMultipleTimes , [ hl ] ; is mon hitting multiple times? (example: double kick)
2016-06-12 04:30:05 +00:00
jr z , .notMultiHitMove
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld hl , wEnemyNumAttacksLeft
2014-05-22 22:13:20 +00:00
dec [ hl ]
pop hl
2015-03-31 20:22:12 +00:00
jp nz , GetEnemyAnimationType
2015-02-03 19:51:53 +00:00
res AttackingMultipleTimes , [ hl ] ; mon is no longer hitting multiple times
2014-08-09 05:39:13 +00:00
ld hl , HitXTimesText
2014-05-22 22:13:20 +00:00
call PrintText
xor a
2015-02-07 10:43:08 +00:00
ld [ wEnemyNumHits ], a
2016-06-12 04:30:05 +00:00
.notMultiHitMove
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr z , ExecuteEnemyMoveDone
2015-01-20 19:21:16 +00:00
ld hl , Sp ecialEffects
2014-05-22 22:13:20 +00:00
ld de , $ 1
call IsInArray
2014-08-09 05:39:13 +00:00
call nc , JumpMoveEffect
2015-01-31 17:26:05 +00:00
jr ExecuteEnemyMoveDone
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
HitXTimesText:
2014-05-22 22:13:20 +00:00
TX_FAR _HitXTimesText
db "@"
2016-06-12 00:24:04 +00:00
ExecuteEnemyMoveDone:
2014-05-22 22:13:20 +00:00
ld b , $ 1
ret
2014-08-09 05:39:13 +00:00
; checks for various status conditions affecting the enemy mon
; stores whether the mon cannot use a move this turn in Z flag
2016-06-12 00:24:04 +00:00
CheckEnemyStatusConditions:
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatus
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
and SLP ; sleep mask
jr z , .checkIfFrozen
dec a ; decrement number of turns left
ld [ wEnemyMonStatus ], a
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .wokeUp ; if the number of turns hit 0, wake up
2014-05-22 22:13:20 +00:00
ld hl , FastAsleepText
call PrintText
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , SLP_ANIM
call PlayMoveAnimation
2015-04-08 23:17:56 +00:00
jr .sleepDone
2014-08-09 05:39:13 +00:00
.wokeUp
2014-05-22 22:13:20 +00:00
ld hl , WokeUpText
call PrintText
2015-04-08 23:17:56 +00:00
.sleepDone
2014-05-22 22:13:20 +00:00
xor a
2015-01-31 17:26:05 +00:00
ld [ wEnemyUsedMove ], a
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; enemy can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfFrozen
bit FRZ , [ hl ]
jr z , .checkIfTrapped
2014-05-22 22:13:20 +00:00
ld hl , IsFrozenText
call PrintText
xor a
2015-01-31 17:26:05 +00:00
ld [ wEnemyUsedMove ], a
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; enemy can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfTrapped
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , a ; is the player using a multi-turn attack like warp
2014-08-09 05:39:13 +00:00
jp z , .checkIfFlinched
2014-05-22 22:13:20 +00:00
ld hl , CantMoveText
call PrintText
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; enemy can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfFlinched
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
bit Flinched , [ hl ] ; check if enemy mon flinched
2014-08-09 05:39:13 +00:00
jp z , .checkIfMustRecharge
2015-02-03 19:51:53 +00:00
res Flinched , [ hl ]
2014-05-22 22:13:20 +00:00
ld hl , FlinchedText
call PrintText
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; enemy can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfMustRecharge
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2015-02-03 19:51:53 +00:00
bit NeedsToRecharge , [ hl ] ; check if enemy mon has to recharge after using a move
2014-08-09 05:39:13 +00:00
jr z , .checkIfAnyMoveDisabled
2015-02-03 19:51:53 +00:00
res NeedsToRecharge , [ hl ]
2014-05-22 22:13:20 +00:00
ld hl , MustRechargeText
call PrintText
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; enemy can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfAnyMoveDisabled
2015-08-31 02:38:41 +00:00
ld hl , wEnemyDisabledMove
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
and a
2014-08-09 05:39:13 +00:00
jr z , .checkIfConfused
2015-04-08 23:17:56 +00:00
dec a ; decrement disable counter
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-04-08 23:17:56 +00:00
and $ f ; did disable counter hit 0?
2014-08-09 05:39:13 +00:00
jr nz , .checkIfConfused
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-04-08 23:17:56 +00:00
ld [ wEnemyDisabledMoveNumber ], a
2014-05-22 22:13:20 +00:00
ld hl , Di sabledNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
.checkIfConfused
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus1 ]
2014-08-09 05:39:13 +00:00
add a ; check if enemy mon is confused
jp nc , .checkIfTriedToUseDisabledMove
2015-08-31 02:38:41 +00:00
ld hl , wEnemyConfusedCounter
2014-05-22 22:13:20 +00:00
dec [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .isConfused
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-04-08 23:17:56 +00:00
res Confused , [ hl ] ; if confused counter hit 0, reset confusion status
2014-05-22 22:13:20 +00:00
ld hl , ConfusedNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
jp .checkIfTriedToUseDisabledMove
.isConfused
2014-05-22 22:13:20 +00:00
ld hl , IsConfusedText
call PrintText
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , CONF_ANIM
call PlayMoveAnimation
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $ 80
2014-08-09 05:39:13 +00:00
jr c , .checkIfTriedToUseDisabledMove
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-08-31 02:38:41 +00:00
and 1 << Confused ; if mon hurts itself, clear every other status from wEnemyBattleStatus1
2014-05-22 22:13:20 +00:00
ld [ hl ], a
ld hl , HurtItselfText
call PrintText
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonDefense
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
push af
ld a , [ hld ]
push af
2014-08-09 05:39:13 +00:00
ld a , [ wEnemyMonDefense ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonDefense + 1 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMoveEffect
2014-05-22 22:13:20 +00:00
push hl
ld a , [ hl ]
push af
xor a
ld [ hli ], a
2014-08-09 05:39:13 +00:00
ld [ wCriticalHitOrOHKO ], a
2015-02-03 19:51:53 +00:00
ld a , 40
2014-05-22 22:13:20 +00:00
ld [ hli ], a
xor a
ld [ hl ], a
2014-08-09 05:39:13 +00:00
call GetDamageVarsForEnemyAttack
call CalculateDamage
2014-05-22 22:13:20 +00:00
pop af
pop hl
ld [ hl ], a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonDefense + 1
2014-05-22 22:13:20 +00:00
pop af
ld [ hld ], a
pop af
ld [ hl ], a
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
ld a , POUND
call PlayMoveAnimation
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
2014-05-22 22:13:20 +00:00
call ApplyDamageToEnemyPokemon
2014-08-09 05:39:13 +00:00
jr .monHurtItselfOrFullyParalysed
.checkIfTriedToUseDisabledMove
2015-04-08 23:17:56 +00:00
; prevents a disabled move that was selected before being disabled from being used
ld a , [ wEnemyDisabledMoveNumber ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .checkIfParalysed
ld hl , wEnemySelectedMove
2014-05-22 22:13:20 +00:00
cp [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .checkIfParalysed
2014-05-22 22:13:20 +00:00
call PrintMoveIsDisabledText
2015-04-08 23:17:56 +00:00
ld hl , ExecuteEnemyMoveDone ; if a disabled move was somehow selected, player can't move this turn
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfParalysed
ld hl , wEnemyMonStatus
bit PAR , [ hl ]
jr z , .checkIfUsingBide
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-04-08 23:17:56 +00:00
cp $ 3 f ; 25% to be fully paralysed
2014-08-09 05:39:13 +00:00
jr nc , .checkIfUsingBide
2014-05-22 22:13:20 +00:00
ld hl , FullyParalyzedText
call PrintText
2014-08-09 05:39:13 +00:00
.monHurtItselfOrFullyParalysed
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-06-11 22:41:33 +00:00
; clear bide, thrashing about, charging up, and multi-turn moves such as warp
2015-04-09 09:30:04 +00:00
and $ ff ^ (( 1 << StoringEnergy ) | ( 1 << ThrashingAbout ) | ( 1 << Ch argingUp ) | ( 1 << UsingTrappingMove ))
2014-05-22 22:13:20 +00:00
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
cp FLY_EFFECT
2014-08-09 05:39:13 +00:00
jr z , .flyOrChargeEffect
2014-05-22 22:13:20 +00:00
cp CH ARGE_EFFECT
2014-08-09 05:39:13 +00:00
jr z , .flyOrChargeEffect
jr .notFlyOrChargeEffect
.flyOrChargeEffect
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , STATUS_AFFECTED_ANIM
call PlayMoveAnimation
2014-08-09 05:39:13 +00:00
.notFlyOrChargeEffect
2015-01-31 17:26:05 +00:00
ld hl , ExecuteEnemyMoveDone
2015-04-08 23:17:56 +00:00
jp .enemyReturnToHL ; if using a two-turn move, enemy needs to recharge the first turn
2014-08-09 05:39:13 +00:00
.checkIfUsingBide
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
bit StoringEnergy , [ hl ] ; is mon using bide?
2014-08-09 05:39:13 +00:00
jr z , .checkIfThrashingAbout
2014-05-22 22:13:20 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld [ wEnemyMoveNum ], a
ld hl , wDamage
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , a
ld c , [ hl ]
2015-02-07 10:43:08 +00:00
ld hl , wEnemyBideAccumulatedDamage + 1
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-04-08 23:17:56 +00:00
add c ; accumulate damage taken
2014-05-22 22:13:20 +00:00
ld [ hld ], a
ld a , [ hl ]
adc b
ld [ hl ], a
2014-08-09 05:39:13 +00:00
ld hl , wEnemyNumAttacksLeft
2015-04-08 23:17:56 +00:00
dec [ hl ] ; did Bide counter hit 0?
2014-08-09 05:39:13 +00:00
jr z , .unleashEnergy
2015-01-31 17:26:05 +00:00
ld hl , ExecuteEnemyMoveDone
2015-04-08 23:17:56 +00:00
jp .enemyReturnToHL ; unless mon unleashes energy, can't move this turn
2014-08-09 05:39:13 +00:00
.unleashEnergy
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res StoringEnergy , [ hl ] ; not using bide any more
2014-05-22 22:13:20 +00:00
ld hl , UnleashedEnergyText
call PrintText
ld a , $ 1
2015-08-31 02:38:41 +00:00
ld [ wEnemyMovePower ], a
2015-02-07 10:43:08 +00:00
ld hl , wEnemyBideAccumulatedDamage + 1
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
add a
ld b , a
2015-08-31 02:38:41 +00:00
ld [ wDamage + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-04-08 23:17:56 +00:00
rl a ; double the damage
2015-08-31 02:38:41 +00:00
ld [ wDamage ], a
2014-05-22 22:13:20 +00:00
or b
2015-04-08 23:17:56 +00:00
jr nz , .next
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-08-31 02:38:41 +00:00
ld [ wMoveMissed ], a
2015-04-08 23:17:56 +00:00
.next
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a
ld [ hl ], a
ld a , BIDE
2015-08-31 02:38:41 +00:00
ld [ wEnemyMoveNum ], a
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2015-04-08 23:17:56 +00:00
ld hl , handleIfEnemyMoveMissed ; skip damage calculation, DecrementPP and MoveHitTest
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfThrashingAbout
2015-02-03 19:51:53 +00:00
bit ThrashingAbout , [ hl ] ; is mon using thrash or petal dance?
2014-08-09 05:39:13 +00:00
jr z , .checkIfUsingMultiturnMove
2014-05-22 22:13:20 +00:00
ld a , THRASH
2015-08-31 02:38:41 +00:00
ld [ wEnemyMoveNum ], a
2014-05-22 22:13:20 +00:00
ld hl , ThrashingAboutText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl , wEnemyNumAttacksLeft
2015-04-09 09:30:04 +00:00
dec [ hl ] ; did Thrashing About counter hit 0?
2015-04-08 23:17:56 +00:00
ld hl , EnemyCalcMoveDamage ; skip DecrementPP
2015-01-31 17:26:05 +00:00
jp nz , .enemyReturnToHL
2014-05-22 22:13:20 +00:00
push hl
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-03 19:51:53 +00:00
res ThrashingAbout , [ hl ] ; mon is no longer using thrash or petal dance
set Confused , [ hl ] ; mon is now confused
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
inc a
2015-04-08 23:17:56 +00:00
inc a ; confused for 2-5 turns
2015-08-31 02:38:41 +00:00
ld [ wEnemyConfusedCounter ], a
2015-04-08 23:17:56 +00:00
pop hl ; skip DecrementPP
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfUsingMultiturnMove
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , [ hl ] ; is mon using multi-turn move?
2014-08-09 05:39:13 +00:00
jp z , .checkIfUsingRage
2014-05-22 22:13:20 +00:00
ld hl , AttackContinuesText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl , wEnemyNumAttacksLeft
2015-04-08 23:17:56 +00:00
dec [ hl ] ; did multi-turn move end?
2015-06-11 22:41:33 +00:00
ld hl , GetEnemyAnimationType ; if it didn't, skip damage calculation (deal damage equal to last hit),
2015-04-08 23:17:56 +00:00
; DecrementPP and MoveHitTest
2015-01-31 17:26:05 +00:00
jp nz , .enemyReturnToHL
jp .enemyReturnToHL
2014-08-09 05:39:13 +00:00
.checkIfUsingRage
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus2 ]
2015-02-03 19:51:53 +00:00
bit UsingRage , a ; is mon using rage?
2015-04-08 23:17:56 +00:00
jp z , .checkEnemyStatusConditionsDone ; if we made it this far, mon can move normally this turn
2014-05-22 22:13:20 +00:00
ld a , RAGE
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B
xor a
2015-08-31 02:38:41 +00:00
ld [ wEnemyMoveEffect ], a
2015-02-03 19:51:53 +00:00
ld hl , EnemyCanExecuteMove
2015-01-31 17:26:05 +00:00
jp .enemyReturnToHL
.enemyReturnToHL
2014-08-09 05:39:13 +00:00
xor a ; set Z flag
2014-05-22 22:13:20 +00:00
ret
2015-01-31 17:26:05 +00:00
.checkEnemyStatusConditionsDone
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
and a ; clear Z flag
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
GetCurrentMove:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jp z , .player
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveNum
2014-08-09 05:39:13 +00:00
ld a , [ wEnemySelectedMove ]
2014-05-22 22:13:20 +00:00
jr .selected
.player
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveNum
ld a , [ wFlags_D733 ]
2015-08-14 02:13:47 +00:00
bit BIT_TEST_BATTLE , a
ld a , [ wTestBattlePlayerSelectedMove ]
2014-05-22 22:13:20 +00:00
jr nz , .selected
2014-08-09 05:39:13 +00:00
ld a , [ wPlayerSelectedMove ]
2014-05-22 22:13:20 +00:00
.selected
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld hl , Moves
2015-08-10 04:56:20 +00:00
ld bc , MoveEnd - Moves
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , BANK ( Moves )
call FarCopyData
2014-08-08 04:17:44 +00:00
ld a , BANK ( MoveNames )
2014-05-26 21:04:56 +00:00
ld [ wPredefBank ], a
2014-08-08 04:17:44 +00:00
ld a , MOVE_NAME
2015-02-08 09:44:41 +00:00
ld [ wNameListType ], a
2014-05-22 22:13:20 +00:00
call GetName
2014-05-26 21:04:56 +00:00
ld de , wcd6d
2014-05-22 22:13:20 +00:00
jp CopyStringToCF4B
2016-06-12 00:24:04 +00:00
LoadEnemyMonData:
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
jp z , LoadEnemyMonFromParty
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies2 ]
ld [ wEnemyMonSpecies ], a
2014-05-26 21:04:56 +00:00
ld [ wd0b5 ], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit Transformed , a ; is enemy mon transformed?
2015-08-14 07:36:06 +00:00
ld hl , wTransformedEnemyMonOriginalDVs ; original DVs before transforming
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , [ hl ]
2014-08-09 05:39:13 +00:00
jr nz , .storeDVs
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-08-09 05:39:13 +00:00
cp $ 2 ; is it a trainer battle?
; fixed DVs for trainer mon
2014-05-22 22:13:20 +00:00
ld a , $ 98
ld b , $ 88
2014-08-09 05:39:13 +00:00
jr z , .storeDVs
; random DVs for wild mon
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
ld b , a
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-08-09 05:39:13 +00:00
.storeDVs
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonDVs
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hl ], b
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonLevel
2015-08-31 02:38:41 +00:00
ld a , [ wCurEnemyLVL ]
2014-05-22 22:13:20 +00:00
ld [ de ], a
inc de
ld b , $ 0
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonHP
2014-05-22 22:13:20 +00:00
push hl
call CalcStats
pop hl
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-08-09 05:39:13 +00:00
cp $ 2 ; is it a trainer battle?
jr z , .copyHPAndStatusFromPartyData
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus3 ]
2015-02-03 19:51:53 +00:00
bit Transformed , a ; is enemy mon transformed?
2014-08-09 05:39:13 +00:00
jr nz , .copyTypes ; if transformed, jump
; if it's a wild mon and not transformed, init the current HP to max HP and the status to 0
ld a , [ wEnemyMonMaxHP ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonMaxHP + 1 ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
xor a
inc hl
2014-08-09 05:39:13 +00:00
ld [ hl ], a ; init status to 0
jr .copyTypes
; if it's a trainer mon, copy the HP and status from the enemy party data
.copyHPAndStatusFromPartyData
ld hl , wEnemyMon1HP
ld a , [ wWhichPokemon ]
2014-06-14 11:12:40 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld [ wEnemyMonHP ], a
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonHP + 1 ], a
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonPartyPos ], a
2014-05-22 22:13:20 +00:00
inc hl
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ wEnemyMonStatus ], a
jr .copyTypes
.copyTypes
2015-08-31 02:38:41 +00:00
ld hl , wMonHTypes
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonType
2014-05-22 22:13:20 +00:00
ld a , [ hli ] ; copy type 1
ld [ de ], a
inc de
ld a , [ hli ] ; copy type 2
ld [ de ], a
inc de
ld a , [ hli ] ; copy catch rate
ld [ de ], a
inc de
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-08-09 05:39:13 +00:00
cp $ 2 ; is it a trainer battle?
jr nz , .copyStandardMoves
; if it's a trainer battle, copy moves from enemy party data
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMon1Moves
2014-08-09 05:39:13 +00:00
ld a , [ wWhichPokemon ]
2014-06-14 11:12:40 +00:00
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
2014-06-14 11:12:40 +00:00
ld bc , NUM_MOVES
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
jr .loadMovePPs
.copyStandardMoves
; for a wild mon, first copy default moves from the mon header
2015-08-31 02:38:41 +00:00
ld hl , wMonHMoves
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc de
ld a , [ hli ]
ld [ de ], a
inc de
ld a , [ hli ]
ld [ de ], a
inc de
ld a , [ hl ]
ld [ de ], a
dec de
dec de
dec de
xor a
2015-07-19 03:49:52 +00:00
ld [ wLearningMovesFromDayCare ], a
2014-08-09 05:39:13 +00:00
predef WriteMonMoves ; get moves based on current level
.loadMovePPs
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2015-07-20 00:52:26 +00:00
ld de , wEnemyMonPP - 1
2014-06-16 20:57:26 +00:00
predef LoadMovePPs
2015-08-31 02:38:41 +00:00
ld hl , wMonHBaseStats
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonBaseStats
2015-07-24 08:49:33 +00:00
ld b , NUM_STATS
2014-08-09 05:39:13 +00:00
.copyBaseStatsLoop
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc de
dec b
2014-08-09 05:39:13 +00:00
jr nz , .copyBaseStatsLoop
2015-08-31 02:38:41 +00:00
ld hl , wMonHCatchRate
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld [ de ], a
inc de
ld a , [ hl ] ; base exp
ld [ de ], a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies2 ]
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetMonName
2014-05-26 21:04:56 +00:00
ld hl , wcd6d
2014-06-14 11:12:40 +00:00
ld de , wEnemyMonNick
2015-08-11 04:51:20 +00:00
ld bc , NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies2 ]
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-06-16 20:57:26 +00:00
predef IndexToPokedex
2014-05-26 21:04:56 +00:00
ld a , [ wd11e ]
2014-05-22 22:13:20 +00:00
dec a
ld c , a
2015-07-20 03:45:34 +00:00
ld b , FLAG_SET
2014-08-09 05:39:13 +00:00
ld hl , wPokedexSeen
predef FlagActionPredef ; mark this mon as seen in the pokedex
ld hl , wEnemyMonLevel
ld de , wEnemyMonUnmodifiedLevel
2015-07-24 08:49:33 +00:00
ld bc , 1 + NUM_STATS * 2
2014-05-22 22:13:20 +00:00
call CopyData
2014-08-09 05:39:13 +00:00
ld a , $ 7 ; default stat mod
2015-07-24 08:49:33 +00:00
ld b , NUM_STAT_MODS ; number of stat mods
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatMods
.statModLoop
2014-05-22 22:13:20 +00:00
ld [ hli ], a
dec b
2014-08-09 05:39:13 +00:00
jr nz , .statModLoop
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; calls BattleTransition to show the battle transition animation and initializes some battle variables
2016-06-12 00:24:04 +00:00
DoBattleTransitionAndInitBattleVariables:
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
jr nz , .next
; link battle
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ wMenuJoypadPollCount ], a
callab Di sp layLinkBattleVersusTextBox
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-09-13 07:50:56 +00:00
ld [ wUpdateSpritesEnabled ], a
2014-05-22 22:13:20 +00:00
call Cl earScreen
2014-08-09 05:39:13 +00:00
.next
2014-05-22 22:13:20 +00:00
call DelayFrame
2014-06-16 20:57:26 +00:00
predef BattleTransition
2014-08-09 05:39:13 +00:00
callab LoadHudAndHpBarAndStatusTilePatterns
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
ld a , $ ff
2014-09-13 07:50:56 +00:00
ld [ wUpdateSpritesEnabled ], a
2014-05-23 22:34:35 +00:00
call Cl earSprites
2014-05-22 22:13:20 +00:00
call Cl earScreen
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-09-23 22:02:03 +00:00
ld [ hWY ], a
2014-08-09 05:39:13 +00:00
ld [ rWY ], a
2014-09-14 18:29:18 +00:00
ld [ hTilesetType ], a
2015-02-08 09:44:41 +00:00
ld hl , wPlayerStatsToDouble
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hli ], a
ld [ hl ], a
2015-08-31 02:38:41 +00:00
ld [ wPlayerDisabledMove ], a
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; swaps the level values of the BattleMon and EnemyMon structs
2016-06-12 00:24:04 +00:00
SwapPlayerAndEnemyLevels:
2014-05-22 22:13:20 +00:00
push bc
2014-08-09 05:39:13 +00:00
ld a , [ wBattleMonLevel ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wEnemyMonLevel ]
ld [ wBattleMonLevel ], a
2014-05-22 22:13:20 +00:00
ld a , b
2014-08-09 05:39:13 +00:00
ld [ wEnemyMonLevel ], a
2014-05-22 22:13:20 +00:00
pop bc
ret
2014-08-09 05:39:13 +00:00
; loads either red back pic or old man back pic
; also writes OAM data and loads tile patterns for the Red or Old Man back sprite's head
; (for use when scrolling the player sprite and enemy's silhouettes on screen)
2016-06-12 00:24:04 +00:00
LoadPlayerBackPic:
2015-08-31 02:38:41 +00:00
ld a , [ wBattleType ]
2014-08-09 05:39:13 +00:00
dec a ; is it the old man tutorial?
ld de , RedPicBack
jr nz , .next
ld de , OldManPic
.next
2014-05-22 22:13:20 +00:00
ld a , BANK ( RedPicBack )
call UncompressSpriteFromDE
2014-06-16 20:57:26 +00:00
predef ScaleSpriteByTwo
2014-05-22 22:13:20 +00:00
ld hl , wOAMBuffer
xor a
2015-07-18 15:17:29 +00:00
ld [ hOAMTile ], a ; initial tile number
2014-08-09 05:39:13 +00:00
ld b , $ 7 ; 7 columns
ld e , $ a0 ; X for the left-most column
.loop ; each loop iteration writes 3 OAM entries in a vertical column
ld c , $ 3 ; 3 tiles per column
ld d , $ 38 ; Y for the top of each column
.innerLoop ; each loop iteration writes 1 OAM entry in the column
ld [ hl ], d ; OAM Y
2014-05-22 22:13:20 +00:00
inc hl
2014-08-09 05:39:13 +00:00
ld [ hl ], e ; OAM X
ld a , $ 8 ; height of tile
add d ; increase Y by height of tile
2014-05-22 22:13:20 +00:00
ld d , a
inc hl
2015-07-18 15:17:29 +00:00
ld a , [ hOAMTile ]
2014-08-09 05:39:13 +00:00
ld [ hli ], a ; OAM tile number
inc a ; increment tile number
2015-07-18 15:17:29 +00:00
ld [ hOAMTile ], a
2014-05-22 22:13:20 +00:00
inc hl
dec c
2014-08-09 05:39:13 +00:00
jr nz , .innerLoop
2015-07-18 15:17:29 +00:00
ld a , [ hOAMTile ]
2014-08-09 05:39:13 +00:00
add $ 4 ; increase tile number by 4
2015-07-18 15:17:29 +00:00
ld [ hOAMTile ], a
2014-08-09 05:39:13 +00:00
ld a , $ 8 ; width of tile
add e ; increase X by width of tile
2014-05-22 22:13:20 +00:00
ld e , a
dec b
2014-08-09 05:39:13 +00:00
jr nz , .loop
2014-05-29 08:31:46 +00:00
ld de , vBackPic
2014-05-22 22:13:20 +00:00
call InterlaceMergeSpriteBuffers
ld a , $ a
ld [ $ 0 ], a
xor a
ld [ $ 4000 ], a
2014-05-29 08:31:46 +00:00
ld hl , vSprites
2015-08-31 03:15:32 +00:00
ld de , sS priteBuffer1
2014-05-22 22:13:20 +00:00
ld a , [ H_LOADEDROMBANK ]
ld b , a
2014-05-29 08:31:46 +00:00
ld c , 7 * 7
2014-05-22 22:13:20 +00:00
call CopyVideoData
xor a
ld [ $ 0 ], a
ld a , $ 31
2015-07-24 03:48:35 +00:00
ld [ hStartTileID ], a
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-07-03 19:37:53 +00:00
predef_jump CopyUncompressedPicToTilemap
2014-05-22 22:13:20 +00:00
2015-02-08 09:44:41 +00:00
; does nothing since no stats are ever selected (barring glitches)
2016-06-12 00:24:04 +00:00
DoubleOrHalveSelectedStats:
2015-02-08 09:44:41 +00:00
callab DoubleSelectedStats
2015-07-19 18:56:13 +00:00
jpab HalveSelectedStats
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ScrollTrainerPicAfterBattle:
2015-07-19 18:56:13 +00:00
jpab _ScrollTrainerPicAfterBattle
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ApplyBurnAndParalysisPenaltiesToPlayer:
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
jr ApplyBurnAndParalysisPenalties
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ApplyBurnAndParalysisPenaltiesToEnemy:
2014-05-22 22:13:20 +00:00
xor a
2016-06-12 00:24:04 +00:00
ApplyBurnAndParalysisPenalties:
2014-08-09 05:39:13 +00:00
ld [ H_WHOSETURN ], a
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
2016-06-12 00:24:04 +00:00
QuarterSpeedDueToParalysis:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .playerTurn
.enemyTurn ; quarter the player's speed
ld a , [ wBattleMonStatus ]
and 1 << PAR
ret z ; return if player not paralysed
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonSpeed + 1
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
ld b , a
ld a , [ hl ]
srl a
rr b
srl a
rr b
ld [ hli ], a
or b
2014-08-09 05:39:13 +00:00
jr nz , .storePlayerSpeed
ld b , 1 ; give the player a minimum of at least one speed point
.storePlayerSpeed
2014-05-22 22:13:20 +00:00
ld [ hl ], b
ret
2014-08-09 05:39:13 +00:00
.playerTurn ; quarter the enemy's speed
ld a , [ wEnemyMonStatus ]
and 1 << PAR
ret z ; return if enemy not paralysed
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonSpeed + 1
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
ld b , a
ld a , [ hl ]
srl a
rr b
srl a
rr b
ld [ hli ], a
or b
2014-08-09 05:39:13 +00:00
jr nz , .storeEnemySpeed
ld b , 1 ; give the enemy a minimum of at least one speed point
.storeEnemySpeed
2014-05-22 22:13:20 +00:00
ld [ hl ], b
ret
2016-06-12 00:24:04 +00:00
HalveAttackDueToBurn:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z , .playerTurn
.enemyTurn ; halve the player's attack
ld a , [ wBattleMonStatus ]
and 1 << BRN
ret z ; return if player not burnt
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonAttack + 1
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
ld b , a
ld a , [ hl ]
srl a
rr b
ld [ hli ], a
or b
2014-08-09 05:39:13 +00:00
jr nz , .storePlayerAttack
ld b , 1 ; give the player a minimum of at least one attack point
.storePlayerAttack
2014-05-22 22:13:20 +00:00
ld [ hl ], b
ret
2014-08-09 05:39:13 +00:00
.playerTurn ; halve the enemy's attack
ld a , [ wEnemyMonStatus ]
and 1 << BRN
ret z ; return if enemy not burnt
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonAttack + 1
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
ld b , a
ld a , [ hl ]
srl a
rr b
ld [ hli ], a
or b
2014-08-09 05:39:13 +00:00
jr nz , .storeEnemyAttack
ld b , 1 ; give the enemy a minimum of at least one attack point
.storeEnemyAttack
2014-05-22 22:13:20 +00:00
ld [ hl ], b
ret
2016-06-12 00:24:04 +00:00
CalculateModifiedStats:
2014-08-09 05:39:13 +00:00
ld c , 0
.loop
call CalculateModifiedStat
2014-05-22 22:13:20 +00:00
inc c
ld a , c
2015-07-24 08:49:33 +00:00
cp NUM_STATS - 1
2014-08-09 05:39:13 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; calculate modified stat for stat c (0 = attack, 1 = defense, 2 = speed, 3 = special)
2016-06-12 00:24:04 +00:00
CalculateModifiedStat:
2014-05-22 22:13:20 +00:00
push bc
push bc
2015-08-07 12:20:37 +00:00
ld a , [ wCalculateWhoseStats ]
2014-05-22 22:13:20 +00:00
and a
ld a , c
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonAttack
2014-08-09 05:39:13 +00:00
ld de , wPlayerMonUnmodifiedAttack
2015-08-07 12:20:37 +00:00
ld bc , wPlayerMonStatMods
2014-08-09 05:39:13 +00:00
jr z , .next
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonAttack
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonUnmodifiedAttack
ld bc , wEnemyMonStatMods
.next
2014-05-22 22:13:20 +00:00
add c
ld c , a
2014-08-09 05:39:13 +00:00
jr nc , .noCarry1
2014-05-22 22:13:20 +00:00
inc b
2014-08-09 05:39:13 +00:00
.noCarry1
2014-05-22 22:13:20 +00:00
ld a , [ bc ]
pop bc
ld b , a
push bc
sla c
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , c
add e
ld e , a
2014-08-09 05:39:13 +00:00
jr nc , .noCarry2
2014-05-22 22:13:20 +00:00
inc d
2014-08-09 05:39:13 +00:00
.noCarry2
2014-05-22 22:13:20 +00:00
pop bc
push hl
2014-08-09 05:39:13 +00:00
ld hl , StatModifierRatios
2014-05-22 22:13:20 +00:00
dec b
sla b
ld c , b
2014-08-09 05:39:13 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
add hl , bc
xor a
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND ], a
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2014-08-09 05:39:13 +00:00
ld [ H_MULTIPLIER ], a
2014-05-22 22:13:20 +00:00
call Multiply
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
ld [ H_DIVISOR ], a
2014-05-22 22:13:20 +00:00
ld b , $ 4
call Di vide
pop hl
2014-08-09 05:39:13 +00:00
ld a , [ H_DIVIDEND + 3 ]
sub 999 % $ 100
ld a , [ H_DIVIDEND + 2 ]
sbc 999 / $ 100
jp c , .storeNewStatValue
; cap the stat at 999
ld a , 999 / $ 100
ld [ H_DIVIDEND + 2 ], a
ld a , 999 % $ 100
ld [ H_DIVIDEND + 3 ], a
.storeNewStatValue
ld a , [ H_DIVIDEND + 2 ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ H_DIVIDEND + 3 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
or b
2014-08-09 05:39:13 +00:00
jr nz , .done
inc [ hl ] ; if the stat is 0, bump it up to 1
.done
2014-05-22 22:13:20 +00:00
pop bc
ret
2016-06-12 00:24:04 +00:00
ApplyBadgeStatBoosts:
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-08-09 05:39:13 +00:00
ret z ; return if link battle
2015-08-31 02:38:41 +00:00
ld a , [ wObtainedBadges ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonAttack
2014-05-22 22:13:20 +00:00
ld c , $ 4
2014-08-09 05:39:13 +00:00
; the boost is applied for badges whose bit position is even
; the order of boosts matches the order they are laid out in RAM
; Boulder (bit 0) - attack
; Thunder (bit 2) - defense
; Soul (bit 4) - speed
; Volcano (bit 6) - special
.loop
2014-05-22 22:13:20 +00:00
srl b
2014-08-09 05:39:13 +00:00
call c , .applyBoostToStat
2014-05-22 22:13:20 +00:00
inc hl
inc hl
srl b
dec c
2014-08-09 05:39:13 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
; multiply stat at hl by 1.125
; cap stat at 999
.applyBoostToStat
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld d , a
ld e , [ hl ]
srl d
rr e
srl d
rr e
srl d
rr e
ld a , [ hl ]
add e
ld [ hld ], a
ld a , [ hl ]
adc d
ld [ hli ], a
ld a , [ hld ]
2014-08-09 05:39:13 +00:00
sub 999 % $ 100
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2014-08-09 05:39:13 +00:00
sbc 999 / $ 100
2014-05-22 22:13:20 +00:00
ret c
2014-08-09 05:39:13 +00:00
ld a , 999 / $ 100
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2014-08-09 05:39:13 +00:00
ld a , 999 % $ 100
2014-05-22 22:13:20 +00:00
ld [ hld ], a
ret
2016-06-12 00:24:04 +00:00
LoadHudAndHpBarAndStatusTilePatterns:
2014-05-22 22:13:20 +00:00
call LoadHpBarAndStatusTilePatterns
2016-06-12 00:24:04 +00:00
LoadHudTilePatterns:
2014-08-09 05:39:13 +00:00
ld a , [ rLCDC ]
add a ; is LCD disabled?
jr c , .lcdEnabled
.lcdDisabled
ld hl , BattleHudTiles1
2014-05-29 08:31:46 +00:00
ld de , vChars2 + $ 6 d0
2015-08-10 04:56:20 +00:00
ld bc , BattleHudTiles1End - BattleHudTiles1
2014-05-22 22:13:20 +00:00
ld a , BANK ( BattleHudTiles1 )
call FarCopyDataDouble
2014-08-09 05:39:13 +00:00
ld hl , BattleHudTiles2
2014-05-29 08:31:46 +00:00
ld de , vChars2 + $ 730
2015-08-10 04:56:20 +00:00
ld bc , BattleHudTiles3End - BattleHudTiles2
2014-05-22 22:13:20 +00:00
ld a , BANK ( BattleHudTiles2 )
jp FarCopyDataDouble
2014-08-09 05:39:13 +00:00
.lcdEnabled
ld de , BattleHudTiles1
2014-05-29 08:31:46 +00:00
ld hl , vChars2 + $ 6 d0
2015-08-10 04:56:20 +00:00
lb bc , BANK ( BattleHudTiles1 ), ( BattleHudTiles1End - BattleHudTiles1 ) / $ 8
2014-05-22 22:13:20 +00:00
call CopyVideoDataDouble
2014-08-09 05:39:13 +00:00
ld de , BattleHudTiles2
2014-05-29 08:31:46 +00:00
ld hl , vChars2 + $ 730
2015-08-10 04:56:20 +00:00
lb bc , BANK ( BattleHudTiles2 ), ( BattleHudTiles3End - BattleHudTiles2 ) / $ 8
2014-05-22 22:13:20 +00:00
jp CopyVideoDataDouble
2016-06-12 00:24:04 +00:00
PrintEmptyString:
2014-08-09 05:39:13 +00:00
ld hl , .emptyString
2014-05-22 22:13:20 +00:00
jp PrintText
2014-08-09 05:39:13 +00:00
.emptyString
2014-05-22 22:13:20 +00:00
db "@"
2014-05-24 18:40:38 +00:00
BattleRandom:
; Link battles use a shared PRNG.
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2014-05-24 18:40:38 +00:00
jp nz , Random
2014-05-22 22:13:20 +00:00
push hl
push bc
2015-02-07 10:43:08 +00:00
ld a , [ wLinkBattleRandomNumberListIndex ]
2014-05-22 22:13:20 +00:00
ld c , a
2014-05-24 18:40:38 +00:00
ld b , 0
2015-02-07 10:43:08 +00:00
ld hl , wLinkBattleRandomNumberList
2014-05-22 22:13:20 +00:00
add hl , bc
inc a
2015-02-07 10:43:08 +00:00
ld [ wLinkBattleRandomNumberListIndex ], a
2014-05-24 18:40:38 +00:00
cp 9
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
pop bc
pop hl
ret c
2014-05-24 18:40:38 +00:00
2015-02-03 19:51:53 +00:00
; if we picked the last seed, we need to recalculate the nine seeds
2014-05-22 22:13:20 +00:00
push hl
push bc
push af
2015-06-11 22:41:33 +00:00
; point to seed 0 so we pick the first number the next time
2014-05-22 22:13:20 +00:00
xor a
2015-02-07 10:43:08 +00:00
ld [ wLinkBattleRandomNumberListIndex ], a
ld hl , wLinkBattleRandomNumberList
2014-05-24 18:40:38 +00:00
ld b , 9
.loop
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
ld c , a
2015-06-11 22:41:33 +00:00
; multiply by 5
2014-05-22 22:13:20 +00:00
add a
add a
add c
2015-06-11 22:41:33 +00:00
; add 1
2014-05-22 22:13:20 +00:00
inc a
ld [ hli ], a
dec b
2014-05-24 18:40:38 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
pop af
pop bc
pop hl
ret
2014-05-24 18:40:38 +00:00
2016-06-12 00:24:04 +00:00
HandleExplodingAnimation:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-07-03 19:37:53 +00:00
ld hl , wEnemyMonType1
2015-08-31 02:38:41 +00:00
ld de , wEnemyBattleStatus1
ld a , [ wPlayerMoveNum ]
2016-06-12 04:30:05 +00:00
jr z , .player
2015-07-03 19:37:53 +00:00
ld hl , wBattleMonType1
2015-08-31 02:38:41 +00:00
ld de , wEnemyBattleStatus1
ld a , [ wEnemyMoveNum ]
2016-06-12 04:30:05 +00:00
.player
2014-05-22 22:13:20 +00:00
cp SELFDESTRUCT
2016-06-12 04:30:05 +00:00
jr z , .isExplodingMove
2014-05-22 22:13:20 +00:00
cp EXPLOSION
ret nz
2016-06-12 04:30:05 +00:00
.isExplodingMove
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-02-03 19:51:53 +00:00
bit Invulnerable , a ; fly/dig
2014-05-22 22:13:20 +00:00
ret nz
ld a , [ hli ]
cp GHOST
ret z
ld a , [ hl ]
cp GHOST
ret z
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
ret nz
2015-01-20 19:21:16 +00:00
ld a , 5
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PlayMoveAnimation:
2015-08-31 02:38:41 +00:00
ld [ wAnimationID ], a
2014-05-22 22:13:20 +00:00
call Delay3
2014-06-16 20:25:46 +00:00
predef_jump MoveAnimation
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
InitBattle:
2015-08-31 02:38:41 +00:00
ld a , [ wCurOpponent ]
2014-05-22 22:13:20 +00:00
and a
2015-07-03 19:37:53 +00:00
jr z , DetermineWildOpponent
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
InitOpponent:
2015-08-31 02:38:41 +00:00
ld a , [ wCurOpponent ]
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonSpecies2 ], a
2015-07-03 19:37:53 +00:00
jr InitBattleCommon
2016-06-12 00:24:04 +00:00
DetermineWildOpponent:
2014-05-26 21:04:56 +00:00
ld a , [ wd732 ]
2014-05-22 22:13:20 +00:00
bit 1 , a
jr z , .asm_3ef2f
2014-05-25 17:51:53 +00:00
ld a , [ hJoyHeld ]
2014-09-13 07:50:56 +00:00
bit 1 , a ; B button pressed?
2014-05-22 22:13:20 +00:00
ret nz
.asm_3ef2f
2014-09-13 07:50:56 +00:00
ld a , [ wNumberOfNoRandomBattleStepsLeft ]
2014-05-22 22:13:20 +00:00
and a
ret nz
2015-02-08 00:24:16 +00:00
callab TryDoWildEncounter
2014-05-22 22:13:20 +00:00
ret nz
2016-06-12 00:24:04 +00:00
InitBattleCommon:
2014-09-13 07:50:56 +00:00
ld a , [ wMapPalOffset ]
2014-05-22 22:13:20 +00:00
push af
2015-07-15 02:46:52 +00:00
ld hl , wLetterPrintingDelayFlags
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
push af
res 1 , [ hl ]
2015-02-08 00:24:16 +00:00
callab InitBattleVariables
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonSpecies2 ]
2015-08-10 16:09:16 +00:00
sub 200
2014-05-22 22:13:20 +00:00
jp c , InitWildBattle
2015-08-31 02:38:41 +00:00
ld [ wTrainerClass ], a
2014-05-22 22:13:20 +00:00
call GetTrainerInformation
callab ReadTrainer
2014-08-09 05:39:13 +00:00
call DoBattleTransitionAndInitBattleVariables
2014-05-22 22:13:20 +00:00
call _LoadTrainerPic
xor a
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonSpecies2 ], a
2015-07-24 03:48:35 +00:00
ld [ hStartTileID ], a
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [ wAICount ], a
2015-07-18 20:52:03 +00:00
coord hl , 12 , 0
2015-07-03 19:37:53 +00:00
predef CopyUncompressedPicToTilemap
2014-05-22 22:13:20 +00:00
ld a , $ ff
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonPartyPos ], a
2014-05-22 22:13:20 +00:00
ld a , $ 2
2015-08-31 02:38:41 +00:00
ld [ wIsInBattle ], a
2015-08-14 07:36:06 +00:00
jp _InitBattleCommon
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
InitWildBattle:
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-08-31 02:38:41 +00:00
ld [ wIsInBattle ], a
2014-08-09 05:39:13 +00:00
call LoadEnemyMonData
call DoBattleTransitionAndInitBattleVariables
2015-08-31 02:38:41 +00:00
ld a , [ wCurOpponent ]
2014-05-22 22:13:20 +00:00
cp MAROWAK
jr z , .isGhost
call IsGhostBattle
jr nz , .isNoGhost
.isGhost
2015-08-31 02:38:41 +00:00
ld hl , wMonHSpriteDim
2014-05-22 22:13:20 +00:00
ld a , $ 66
ld [ hli ], a ; write sprite dimensions
2014-08-09 05:39:13 +00:00
ld bc , GhostPic
2014-05-22 22:13:20 +00:00
ld a , c
ld [ hli ], a ; write front sprite pointer
ld [ hl ], b
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonNick ; set name to "GHOST"
2014-05-22 22:13:20 +00:00
ld a , "G"
ld [ hli ], a
ld a , "H"
ld [ hli ], a
ld a , "O"
ld [ hli ], a
ld a , "S"
ld [ hli ], a
ld a , "T"
ld [ hli ], a
ld [ hl ], "@"
2014-05-26 21:04:56 +00:00
ld a , [ wcf91 ]
2014-05-22 22:13:20 +00:00
push af
ld a , MON_GHOST
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-05-29 08:31:46 +00:00
ld de , vFrontPic
2014-05-22 22:13:20 +00:00
call LoadMonFrontSprite ; load ghost sprite
pop af
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2014-05-22 22:13:20 +00:00
jr .spriteLoaded
.isNoGhost
2014-05-29 08:31:46 +00:00
ld de , vFrontPic
2014-05-22 22:13:20 +00:00
call LoadMonFrontSprite ; load mon sprite
.spriteLoaded
xor a
2015-08-31 02:38:41 +00:00
ld [ wTrainerClass ], a
2015-07-24 03:48:35 +00:00
ld [ hStartTileID ], a
2015-07-18 20:52:03 +00:00
coord hl , 12 , 0
2015-07-03 19:37:53 +00:00
predef CopyUncompressedPicToTilemap
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
; common code that executes after init battle code specific to trainer or wild battles
2016-06-12 00:24:04 +00:00
_InitBattleCommon:
2015-08-12 09:16:56 +00:00
ld b , SET_PAL_BATTLE_BLACK
call RunPaletteCommand
2014-08-09 05:39:13 +00:00
call SlidePlayerAndEnemySilhouettesOnScreen
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
ld hl , .emptyString
2014-05-22 22:13:20 +00:00
call PrintText
call SaveScreenTilesToBuffer1
call Cl earScreen
ld a , $ 98
2015-07-12 23:37:06 +00:00
ld [ H_AUTOBGTRANSFERDEST + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , $ 1
2014-08-09 05:39:13 +00:00
ld [ H_AUTOBGTRANSFERENABLED ], a
2014-05-22 22:13:20 +00:00
call Delay3
ld a , $ 9 c
2015-07-12 23:37:06 +00:00
ld [ H_AUTOBGTRANSFERDEST + 1 ], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2015-07-18 20:52:03 +00:00
coord hl , 9 , 7
2015-08-05 21:20:29 +00:00
lb bc , 5 , 10
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-07-18 20:52:03 +00:00
coord hl , 1 , 0
2015-08-05 21:20:29 +00:00
lb bc , 4 , 10
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2014-05-23 22:34:35 +00:00
call Cl earSprites
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-08-09 05:39:13 +00:00
dec a ; is it a wild battle?
call z , DrawEnemyHUDAndHPBar ; draw enemy HUD and HP bar if it's a wild battle
call StartBattle
callab EndOfBattle
2014-05-22 22:13:20 +00:00
pop af
2015-07-15 02:46:52 +00:00
ld [ wLetterPrintingDelayFlags ], a
2014-05-22 22:13:20 +00:00
pop af
2014-09-13 07:50:56 +00:00
ld [ wMapPalOffset ], a
2015-07-20 00:52:26 +00:00
ld a , [ wSavedTilesetType ]
2014-09-14 18:29:18 +00:00
ld [ hTilesetType ], a
2014-05-22 22:13:20 +00:00
scf
ret
2014-08-09 05:39:13 +00:00
.emptyString
2014-05-22 22:13:20 +00:00
db "@"
2016-06-12 00:24:04 +00:00
_LoadTrainerPic:
2014-05-26 21:04:56 +00:00
; wd033-wd034 contain pointer to pic
2015-07-03 19:37:53 +00:00
ld a , [ wTrainerPicPointer ]
2014-05-22 22:13:20 +00:00
ld e , a
2015-07-03 19:37:53 +00:00
ld a , [ wTrainerPicPointer + 1 ]
2014-05-22 22:13:20 +00:00
ld d , a ; de contains pointer to trainer pic
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
2014-05-22 22:13:20 +00:00
and a
ld a , Bank ( TrainerPics ) ; this is where all the trainer pics are (not counting Red's)
jr z , .loadSprite
ld a , Bank ( RedPicFront )
.loadSprite
call UncompressSpriteFromDE
2014-05-29 08:31:46 +00:00
ld de , vFrontPic
2014-05-22 22:13:20 +00:00
ld a , $ 77
ld c , a
jp LoadUncompressedSpriteData
2015-03-31 20:22:12 +00:00
; unreferenced
2016-06-12 00:24:04 +00:00
ResetCryModifiers:
2014-05-22 22:13:20 +00:00
xor a
2015-08-09 05:32:44 +00:00
ld [ wFrequencyModifier ], a
ld [ wTempoModifier ], a
2014-05-22 22:13:20 +00:00
jp PlaySound
2015-07-15 06:16:06 +00:00
; animates the mon "growing" out of the pokeball
2016-06-12 00:24:04 +00:00
AnimateSendingOutMon:
2014-05-26 21:04:56 +00:00
ld a , [ wPredefRegisters ]
2014-05-22 22:13:20 +00:00
ld h , a
2014-05-26 21:04:56 +00:00
ld a , [ wPredefRegisters + 1 ]
2014-05-22 22:13:20 +00:00
ld l , a
2015-07-24 03:48:35 +00:00
ld a , [ hStartTileID ]
ld [ hBaseTileID ], a
2014-05-22 22:13:20 +00:00
ld b , $ 4 c
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 03:48:35 +00:00
jr z , .notInBattle
2014-05-22 22:13:20 +00:00
add b
ld [ hl ], a
call Delay3
2015-07-24 03:48:35 +00:00
ld bc , - ( SCREEN_WIDTH * 2 + 1 )
2014-05-22 22:13:20 +00:00
add hl , bc
2015-07-24 03:48:35 +00:00
ld a , 1
2015-07-15 06:16:06 +00:00
ld [ wDownscaledMonSize ], a
2015-07-24 03:48:35 +00:00
lb bc , 3 , 3
2015-07-15 06:16:06 +00:00
predef CopyDownscaledMonTiles
2015-07-03 19:37:53 +00:00
ld c , 4
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-07-24 03:48:35 +00:00
ld bc , - ( SCREEN_WIDTH * 2 + 1 )
2014-05-22 22:13:20 +00:00
add hl , bc
xor a
2015-07-15 06:16:06 +00:00
ld [ wDownscaledMonSize ], a
2015-07-24 03:48:35 +00:00
lb bc , 5 , 5
2015-07-15 06:16:06 +00:00
predef CopyDownscaledMonTiles
2015-07-03 19:37:53 +00:00
ld c , 5
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-07-24 03:48:35 +00:00
ld bc , - ( SCREEN_WIDTH * 2 + 1 )
jr .next
.notInBattle
ld bc , - ( SCREEN_WIDTH * 6 + 3 )
.next
2014-05-22 22:13:20 +00:00
add hl , bc
2015-07-24 03:48:35 +00:00
ld a , [ hBaseTileID ]
2014-05-22 22:13:20 +00:00
add $ 31
2015-07-03 19:37:53 +00:00
jr CopyUncompressedPicToHL
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
CopyUncompressedPicToTilemap:
2014-05-26 21:04:56 +00:00
ld a , [ wPredefRegisters ]
2014-05-22 22:13:20 +00:00
ld h , a
2014-05-26 21:04:56 +00:00
ld a , [ wPredefRegisters + 1 ]
2014-05-22 22:13:20 +00:00
ld l , a
2015-07-24 03:48:35 +00:00
ld a , [ hStartTileID ]
2016-06-12 00:24:04 +00:00
CopyUncompressedPicToHL:
2015-07-24 03:48:35 +00:00
lb bc , 7 , 7
2015-07-14 07:16:19 +00:00
ld de , SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
push af
2015-08-31 02:38:41 +00:00
ld a , [ wSpriteFlipped ]
2014-05-22 22:13:20 +00:00
and a
2015-07-24 03:48:35 +00:00
jr nz , .flipped
2014-05-22 22:13:20 +00:00
pop af
2015-07-24 03:48:35 +00:00
.loop
2014-05-22 22:13:20 +00:00
push bc
push hl
2015-07-24 03:48:35 +00:00
.innerLoop
2014-05-22 22:13:20 +00:00
ld [ hl ], a
add hl , de
inc a
dec c
2015-07-24 03:48:35 +00:00
jr nz , .innerLoop
2014-05-22 22:13:20 +00:00
pop hl
inc hl
pop bc
dec b
2015-07-24 03:48:35 +00:00
jr nz , .loop
2014-05-22 22:13:20 +00:00
ret
2015-06-11 22:41:33 +00:00
2015-07-24 03:48:35 +00:00
.flipped
2014-05-22 22:13:20 +00:00
push bc
2015-07-24 03:48:35 +00:00
ld b , 0
2014-05-22 22:13:20 +00:00
dec c
add hl , bc
pop bc
pop af
2015-07-24 03:48:35 +00:00
.flippedLoop
2014-05-22 22:13:20 +00:00
push bc
push hl
2015-07-24 03:48:35 +00:00
.flippedInnerLoop
2014-05-22 22:13:20 +00:00
ld [ hl ], a
add hl , de
inc a
dec c
2015-07-24 03:48:35 +00:00
jr nz , .flippedInnerLoop
2014-05-22 22:13:20 +00:00
pop hl
dec hl
pop bc
dec b
2015-07-24 03:48:35 +00:00
jr nz , .flippedLoop
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
LoadMonBackPic:
2014-05-29 08:31:46 +00:00
; Assumes the monster's attributes have
; been loaded with GetMonHeader.
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonSpecies2 ]
2014-05-26 21:04:56 +00:00
ld [ wcf91 ], a
2015-07-18 20:52:03 +00:00
coord hl , 1 , 5
2015-08-05 21:20:29 +00:00
ld b , 7
ld c , 8
2014-05-22 22:13:20 +00:00
call Cl earScreenArea
2015-08-31 02:38:41 +00:00
ld hl , wMonHBackSprite - wMonHeader
2014-05-22 22:13:20 +00:00
call UncompressMonSprite
2014-06-16 20:57:26 +00:00
predef ScaleSpriteByTwo
2014-05-29 08:31:46 +00:00
ld de , vBackPic
2014-05-22 22:13:20 +00:00
call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
2014-05-29 08:31:46 +00:00
ld hl , vSprites
ld de , vBackPic
2014-05-22 22:13:20 +00:00
ld c , ( 2 * SP RITEBUFFERSIZE ) / 16 ; count of 16-byte chunks to be copied
ld a , [ H_LOADEDROMBANK ]
ld b , a
jp CopyVideoData
2016-06-12 00:24:04 +00:00
JumpMoveEffect:
2014-08-09 05:39:13 +00:00
call _JumpMoveEffect
2014-05-22 22:13:20 +00:00
ld b , $ 1
ret
2016-06-12 00:24:04 +00:00
_JumpMoveEffect:
2015-03-31 18:50:49 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2014-05-22 22:13:20 +00:00
jr z , .next1
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2014-05-22 22:13:20 +00:00
.next1
2015-03-31 18:50:49 +00:00
dec a ; subtract 1, there is no special effect for 00
add a ; x2, 16bit pointers
2014-05-22 22:13:20 +00:00
ld hl , MoveEffectPointerTable
ld b , 0
ld c , a
add hl , bc
ld a , [ hli ]
ld h , [ hl ]
ld l , a
2015-03-31 18:50:49 +00:00
jp [ hl ] ; jump to special effect handler
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MoveEffectPointerTable:
2014-05-22 22:13:20 +00:00
dw SleepEffect ; unused effect
dw PoisonEffect ; POISON_SIDE_EFFECT1
dw DrainHPEffect ; DRAIN_HP_EFFECT
dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT1
dw FreezeBurnParalyzeEffect ; FREEZE_SIDE_EFFECT
dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT1
dw ExplodeEffect ; EXPLODE_EFFECT
dw DrainHPEffect ; DREAM_EATER_EFFECT
dw $ 0000 ; MIRROR_MOVE_EFFECT
dw StatModifierUpEffect ; ATTACK_UP1_EFFECT
dw StatModifierUpEffect ; DEFENSE_UP1_EFFECT
dw StatModifierUpEffect ; SPEED_UP1_EFFECT
dw StatModifierUpEffect ; SPECIAL_UP1_EFFECT
dw StatModifierUpEffect ; ACCURACY_UP1_EFFECT
dw StatModifierUpEffect ; EVASION_UP1_EFFECT
dw PayDayEffect ; PAY_DAY_EFFECT
dw $ 0000 ; SWIFT_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN1_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN1_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN1_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN1_EFFECT
dw StatModifierDownEffect ; ACCURACY_DOWN1_EFFECT
dw StatModifierDownEffect ; EVASION_DOWN1_EFFECT
dw ConversionEffect ; CONVERSION_EFFECT
dw HazeEffect ; HAZE_EFFECT
dw BideEffect ; BIDE_EFFECT
dw ThrashPetalDanceEffect ; THRASH_PETAL_DANCE_EFFECT
dw SwitchAndTeleportEffect ; SWITCH_AND_TELEPORT_EFFECT
dw TwoToFiveAttacksEffect ; TWO_TO_FIVE_ATTACKS_EFFECT
dw TwoToFiveAttacksEffect ; unused effect
2015-01-31 17:26:05 +00:00
dw FlinchSideEffect ; FLINCH_SIDE_EFFECT1
2014-05-22 22:13:20 +00:00
dw SleepEffect ; SLEEP_EFFECT
dw PoisonEffect ; POISON_SIDE_EFFECT2
dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT2
dw FreezeBurnParalyzeEffect ; unused effect
dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT2
2015-01-31 17:26:05 +00:00
dw FlinchSideEffect ; FLINCH_SIDE_EFFECT2
2014-05-22 22:13:20 +00:00
dw OneHitKOEffect ; OHKO_EFFECT
dw Ch argeEffect ; CHARGE_EFFECT
dw $ 0000 ; SUPER_FANG_EFFECT
dw $ 0000 ; SPECIAL_DAMAGE_EFFECT
dw TrappingEffect ; TRAPPING_EFFECT
dw Ch argeEffect ; FLY_EFFECT
dw TwoToFiveAttacksEffect ; ATTACK_TWICE_EFFECT
dw $ 0000 ; JUMP_KICK_EFFECT
dw MistEffect ; MIST_EFFECT
dw FocusEnergyEffect ; FOCUS_ENERGY_EFFECT
dw RecoilEffect ; RECOIL_EFFECT
dw ConfusionEffect ; CONFUSION_EFFECT
dw StatModifierUpEffect ; ATTACK_UP2_EFFECT
dw StatModifierUpEffect ; DEFENSE_UP2_EFFECT
dw StatModifierUpEffect ; SPEED_UP2_EFFECT
dw StatModifierUpEffect ; SPECIAL_UP2_EFFECT
dw StatModifierUpEffect ; ACCURACY_UP2_EFFECT
dw StatModifierUpEffect ; EVASION_UP2_EFFECT
dw HealEffect ; HEAL_EFFECT
dw TransformEffect ; TRANSFORM_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN2_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN2_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN2_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN2_EFFECT
dw StatModifierDownEffect ; ACCURACY_DOWN2_EFFECT
dw StatModifierDownEffect ; EVASION_DOWN2_EFFECT
dw ReflectLightScreenEffect ; LIGHT_SCREEN_EFFECT
dw ReflectLightScreenEffect ; REFLECT_EFFECT
dw PoisonEffect ; POISON_EFFECT
dw ParalyzeEffect ; PARALYZE_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw ConfusionSideEffect ; CONFUSION_SIDE_EFFECT
dw TwoToFiveAttacksEffect ; TWINEEDLE_EFFECT
dw $ 0000 ; unused effect
dw SubstituteEffect ; SUBSTITUTE_EFFECT
dw HyperBeamEffect ; HYPER_BEAM_EFFECT
dw RageEffect ; RAGE_EFFECT
dw MimicEffect ; MIMIC_EFFECT
dw $ 0000 ; METRONOME_EFFECT
dw LeechSeedEffect ; LEECH_SEED_EFFECT
dw Sp lashEffect ; SPLASH_EFFECT
dw Di sableEffect ; DISABLE_EFFECT
2016-06-12 00:24:04 +00:00
SleepEffect:
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonStatus
2015-08-31 02:38:41 +00:00
ld bc , wEnemyBattleStatus2
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jp z , .sleepEffect
2014-08-09 05:39:13 +00:00
ld de , wBattleMonStatus
2015-08-31 02:38:41 +00:00
ld bc , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
2015-01-20 19:21:16 +00:00
.sleepEffect
2014-05-22 22:13:20 +00:00
ld a , [ bc ]
2015-02-03 19:51:53 +00:00
bit NeedsToRecharge , a ; does the target need to recharge? (hyper beam)
res NeedsToRecharge , a ; target no longer needs to recharge
2014-05-22 22:13:20 +00:00
ld [ bc ], a
2015-01-20 19:21:16 +00:00
jr nz , .setSleepCounter ; if the target had to recharge, all hit tests will be skipped
2015-01-31 17:26:05 +00:00
; including the event where the target already has another status
2014-05-22 22:13:20 +00:00
ld a , [ de ]
ld b , a
and $ 7
2015-01-20 19:21:16 +00:00
jr z , .notAlreadySleeping ; can't affect a mon that is already asleep
2014-05-22 22:13:20 +00:00
ld hl , Al readyAsleepText
jp PrintText
2015-01-20 19:21:16 +00:00
.notAlreadySleeping
2014-05-22 22:13:20 +00:00
ld a , b
and a
2015-01-20 19:21:16 +00:00
jr nz , .didntAffect ; can't affect a mon that is already statused
2014-05-22 22:13:20 +00:00
push de
2015-01-20 11:12:30 +00:00
call MoveHitTest ; apply accuracy tests
2014-05-22 22:13:20 +00:00
pop de
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr nz , .didntAffect
.setSleepCounter
2015-01-20 11:12:30 +00:00
; set target's sleep counter to a random number between 1 and 7
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-23 03:05:13 +00:00
and $ 7
2015-01-20 19:21:16 +00:00
jr z , .setSleepCounter
2014-05-22 22:13:20 +00:00
ld [ de ], a
2015-03-31 20:22:12 +00:00
call PlayCurrentMoveAnimation2
2014-05-22 22:13:20 +00:00
ld hl , FellAsleepText
jp PrintText
2015-01-20 19:21:16 +00:00
.didntAffect
2014-05-22 22:13:20 +00:00
jp PrintDidntAffectText
2016-06-12 00:24:04 +00:00
FellAsleepText:
2014-05-22 22:13:20 +00:00
TX_FAR _FellAsleepText
db "@"
2016-06-12 00:24:04 +00:00
AlreadyAsleepText:
2014-05-22 22:13:20 +00:00
TX_FAR _AlreadyAsleepText
db "@"
2016-06-12 00:24:04 +00:00
PoisonEffect:
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatus
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .poisonEffect
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonStatus
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveEffect
2015-01-20 19:21:16 +00:00
.poisonEffect
2014-05-22 22:13:20 +00:00
call Ch eckTargetSubstitute
2015-01-20 19:21:16 +00:00
jr nz , .noEffect ; can't posion a substitute target
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
ld b , a
and a
2015-01-20 19:21:16 +00:00
jr nz , .noEffect ; miss if target is already statused
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2015-01-20 19:21:16 +00:00
cp POISON ; can't posion a poison-type target
jr z , .noEffect
2014-05-22 22:13:20 +00:00
ld a , [ hld ]
2015-01-20 19:21:16 +00:00
cp POISON ; can't posion a poison-type target
jr z , .noEffect
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp POISON_SIDE_EFFECT1
ld b , $ 34 ; ~20% chance of poisoning
2015-01-20 19:21:16 +00:00
jr z , .sideEffectTest
2014-05-22 22:13:20 +00:00
cp POISON_SIDE_EFFECT2
ld b , $ 67 ; ~40% chance of poisoning
2015-01-20 19:21:16 +00:00
jr z , .sideEffectTest
2014-05-22 22:13:20 +00:00
push hl
push de
2015-01-20 11:12:30 +00:00
call MoveHitTest ; apply accuracy tests
2014-05-22 22:13:20 +00:00
pop de
pop hl
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr nz , .didntAffect
jr .inflictPoison
.sideEffectTest
2015-01-23 03:05:13 +00:00
call BattleRandom
2015-01-20 11:12:30 +00:00
cp b ; was side effect successful?
2014-05-22 22:13:20 +00:00
ret nc
2015-01-20 19:21:16 +00:00
.inflictPoison
2014-05-22 22:13:20 +00:00
dec hl
2015-01-20 11:12:30 +00:00
set 3 , [ hl ] ; mon is now poisoned
2014-05-22 22:13:20 +00:00
push de
dec de
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-09-17 19:37:47 +00:00
ld b , ANIM_C7
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus3
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-08-31 02:38:41 +00:00
ld de , wPlayerToxicCounter
2015-01-20 19:21:16 +00:00
jr nz , .ok
2014-09-17 19:37:47 +00:00
ld b , ANIM_A9
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus3
2016-06-12 04:30:05 +00:00
ld de , wEnemyToxicCounter
2015-01-20 19:21:16 +00:00
.ok
2014-09-17 19:37:47 +00:00
cp TOXIC
2015-01-20 19:21:16 +00:00
jr nz , .normalPoison ; done if move is not Toxic
2015-02-03 19:51:53 +00:00
set BadlyPoisoned , [ hl ] ; else set Toxic battstatus
2014-05-22 22:13:20 +00:00
xor a
ld [ de ], a
ld hl , BadlyPoisonedText
2016-06-12 04:30:05 +00:00
jr .continue
2015-01-20 19:21:16 +00:00
.normalPoison
2014-05-22 22:13:20 +00:00
ld hl , PoisonedText
2016-06-12 04:30:05 +00:00
.continue
2014-05-22 22:13:20 +00:00
pop de
ld a , [ de ]
cp POISON_EFFECT
2016-06-12 04:30:05 +00:00
jr z , .regularPoisonEffect
2014-05-22 22:13:20 +00:00
ld a , b
2015-03-31 20:22:12 +00:00
call PlayBattleAnimation2
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 04:30:05 +00:00
.regularPoisonEffect
2015-03-31 20:22:12 +00:00
call PlayCurrentMoveAnimation2
2014-05-22 22:13:20 +00:00
jp PrintText
2015-01-20 19:21:16 +00:00
.noEffect
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp POISON_EFFECT
ret nz
2015-01-20 19:21:16 +00:00
.didntAffect
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
jp PrintDidntAffectText
2016-06-12 00:24:04 +00:00
PoisonedText:
2014-05-22 22:13:20 +00:00
TX_FAR _PoisonedText
db "@"
2016-06-12 00:24:04 +00:00
BadlyPoisonedText:
2014-05-22 22:13:20 +00:00
TX_FAR _BadlyPoisonedText
db "@"
2016-06-12 00:24:04 +00:00
DrainHPEffect:
2015-07-19 18:56:13 +00:00
jpab DrainHPEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ExplodeEffect:
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonHP
2015-08-31 02:38:41 +00:00
ld de , wPlayerBattleStatus2
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .faintUser
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonHP
2015-08-31 02:38:41 +00:00
ld de , wEnemyBattleStatus2
2015-01-20 19:21:16 +00:00
.faintUser
2014-05-22 22:13:20 +00:00
xor a
ld [ hli ], a ; set the mon's HP to 0
ld [ hli ], a
inc hl
ld [ hl ], a ; set mon's status to 0
ld a , [ de ]
2015-02-03 19:51:53 +00:00
res Seeded , a ; clear mon's leech seed status
2014-05-22 22:13:20 +00:00
ld [ de ], a
ret
2016-06-12 00:24:04 +00:00
FreezeBurnParalyzeEffect:
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2015-01-20 11:12:30 +00:00
call Ch eckTargetSubstitute ; test bit 4 of d063/d068 flags [target has substitute flag]
ret nz ; return if they have a substitute, can't effect them
2015-03-31 18:50:49 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jp nz , opponentAttacker
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonStatus ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 11:12:30 +00:00
jp nz , Ch eckDefrost ; can't inflict status if opponent is already statused
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveType ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonType1 ]
2015-01-20 11:12:30 +00:00
cp b ; do target type 1 and move type match?
ret z ; return if they match (an ice move can't freeze an ice-type, body slam can't paralyze a normal-type, etc.)
2014-06-14 11:12:40 +00:00
ld a , [ wEnemyMonType2 ]
2015-01-20 11:12:30 +00:00
cp b ; do target type 2 and move type match?
ret z ; return if they match
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2015-01-20 19:21:16 +00:00
cp a , PARALYZE_SIDE_EFFECT1 + 1 ; 10% status effects are 04, 05, 06 so 07 will set carry for those
2015-01-20 11:12:30 +00:00
ld b , $ 1 a ; 0x1A/0x100 or 26/256 = 10.2%~ chance
jr c , .next1 ; branch ahead if this is a 10% chance effect..
ld b , $ 4 d ; else use 0x4D/0x100 or 77/256 = 30.1%~ chance
sub a , $ 1 e ; subtract $1E to map to equivalent 10% chance effects
2014-05-22 22:13:20 +00:00
.next1
2015-01-23 03:05:13 +00:00
push af
2015-01-20 11:12:30 +00:00
call BattleRandom ; get random 8bit value for probability test
cp b
2015-01-23 03:05:13 +00:00
pop bc
2015-01-20 11:12:30 +00:00
ret nc ; do nothing if random value is >= 1A or 4D [no status applied]
ld a , b ; what type of effect is this?
2014-05-22 22:13:20 +00:00
cp a , BURN_SIDE_EFFECT1
jr z , .burn
cp a , FREEZE_SIDE_EFFECT
jr z , .freeze
2015-01-23 03:05:13 +00:00
; .paralyze
2014-05-22 22:13:20 +00:00
ld a , 1 << PAR
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonStatus ], a
2015-01-20 11:12:30 +00:00
call QuarterSpeedDueToParalysis ; quarter speed of affected mon
2014-09-17 19:37:47 +00:00
ld a , ANIM_A9
2015-01-23 03:05:13 +00:00
call PlayBattleAnimation
2015-01-20 11:12:30 +00:00
jp PrintMayNotAttackText ; print paralysis text
2014-05-22 22:13:20 +00:00
.burn
ld a , 1 << BRN
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonStatus ], a
2015-01-20 11:12:30 +00:00
call HalveAttackDueToBurn ; halve attack of affected mon
2014-09-17 19:37:47 +00:00
ld a , ANIM_A9
2015-01-23 03:05:13 +00:00
call PlayBattleAnimation
2014-05-22 22:13:20 +00:00
ld hl , BurnedText
jp PrintText
.freeze
2015-01-31 17:26:05 +00:00
call Cl earHyperBeam ; resets hyper beam (recharge) condition from target
2014-05-22 22:13:20 +00:00
ld a , 1 << FRZ
2014-06-14 11:12:40 +00:00
ld [ wEnemyMonStatus ], a
2014-09-17 19:37:47 +00:00
ld a , ANIM_A9
2015-01-23 03:05:13 +00:00
call PlayBattleAnimation
2014-05-22 22:13:20 +00:00
ld hl , FrozenText
jp PrintText
2016-06-12 00:24:04 +00:00
opponentAttacker:
2015-01-20 11:12:30 +00:00
ld a , [ wBattleMonStatus ] ; mostly same as above with addresses swapped for opponent
2014-05-22 22:13:20 +00:00
and a
jp nz , Ch eckDefrost
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveType ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonType1 ]
2014-05-22 22:13:20 +00:00
cp b
ret z
2014-06-14 11:12:40 +00:00
ld a , [ wBattleMonType2 ]
2014-05-22 22:13:20 +00:00
cp b
ret z
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2015-02-03 19:51:53 +00:00
cp a , PARALYZE_SIDE_EFFECT1 + 1
2014-05-22 22:13:20 +00:00
ld b , $ 1 a
jr c , .next1
ld b , $ 4 d
sub a , $ 1 e
.next1
push af
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
pop bc
ret nc
ld a , b
cp a , BURN_SIDE_EFFECT1
jr z , .burn
cp a , FREEZE_SIDE_EFFECT
jr z , .freeze
ld a , 1 << PAR
2014-06-14 11:12:40 +00:00
ld [ wBattleMonStatus ], a
2014-08-09 05:39:13 +00:00
call QuarterSpeedDueToParalysis
2014-05-22 22:13:20 +00:00
jp PrintMayNotAttackText
.burn
ld a , 1 << BRN
2014-06-14 11:12:40 +00:00
ld [ wBattleMonStatus ], a
2014-08-09 05:39:13 +00:00
call HalveAttackDueToBurn
2014-05-22 22:13:20 +00:00
ld hl , BurnedText
jp PrintText
.freeze
2015-01-20 11:12:30 +00:00
; hyper beam bits aren't reseted for opponent's side
2014-05-22 22:13:20 +00:00
ld a , 1 << FRZ
2014-06-14 11:12:40 +00:00
ld [ wBattleMonStatus ], a
2014-05-22 22:13:20 +00:00
ld hl , FrozenText
jp PrintText
2016-06-12 00:24:04 +00:00
BurnedText:
2014-05-22 22:13:20 +00:00
TX_FAR _BurnedText
db "@"
2016-06-12 00:24:04 +00:00
FrozenText:
2014-05-22 22:13:20 +00:00
TX_FAR _FrozenText
db "@"
2016-06-12 00:24:04 +00:00
CheckDefrost:
2015-01-20 11:12:30 +00:00
; any fire-type move that has a chance inflict burn (all but Fire Spin) will defrost a frozen target
2016-07-28 03:33:48 +00:00
and a , 1 << FRZ ; are they frozen?
2015-01-20 11:12:30 +00:00
ret z ; return if so
2015-03-31 18:50:49 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr nz , .opponent
;player [attacker]
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveType ]
2014-05-22 22:13:20 +00:00
sub a , FIRE
2015-01-20 11:12:30 +00:00
ret nz ; return if type of move used isn't fire
2016-07-28 03:33:48 +00:00
ld [ wEnemyMonStatus ], a ; set opponent status to 00 ["defrost" a frozen monster]
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMon1Status
ld a , [ wEnemyMonPartyPos ]
ld bc , wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
xor a
2015-01-20 11:12:30 +00:00
ld [ hl ], a ; clear status in roster
2014-05-22 22:13:20 +00:00
ld hl , FireDefrostedText
jr .common
.opponent
2016-07-28 03:33:48 +00:00
ld a , [ wEnemyMoveType ] ; same as above with addresses swapped
2014-05-22 22:13:20 +00:00
sub a , FIRE
ret nz
2014-06-14 11:12:40 +00:00
ld [ wBattleMonStatus ], a
ld hl , wPartyMon1Status
2014-05-22 22:13:20 +00:00
ld a , [ wPlayerMonNumber ]
2014-06-14 11:12:40 +00:00
ld bc , wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
xor a
ld [ hl ], a
ld hl , FireDefrostedText
.common
jp PrintText
2016-06-12 00:24:04 +00:00
FireDefrostedText:
2014-05-22 22:13:20 +00:00
TX_FAR _FireDefrostedText
db "@"
2016-06-12 00:24:04 +00:00
StatModifierUpEffect:
2014-08-09 05:39:13 +00:00
ld hl , wPlayerMonStatMods
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .statModifierUpEffect
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatMods
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveEffect
2015-01-20 19:21:16 +00:00
.statModifierUpEffect
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-01-23 03:05:13 +00:00
sub ATTACK_UP1_EFFECT
2015-02-03 19:51:53 +00:00
cp EVASION_UP1_EFFECT + $ 3 - ATTACK_UP1_EFFECT ; covers all +1 effects
2015-01-20 19:21:16 +00:00
jr c , .incrementStatMod
2015-01-20 19:34:56 +00:00
sub ATTACK_UP2_EFFECT - ATTACK_UP1_EFFECT ; map +2 effects to equivalent +1 effect
2015-01-20 19:21:16 +00:00
.incrementStatMod
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld b , [ hl ]
2015-01-20 11:12:30 +00:00
inc b ; increment corresponding stat mod
2014-05-22 22:13:20 +00:00
ld a , $ d
2015-01-20 11:12:30 +00:00
cp b ; can't raise stat past +6 ($d or 13)
2015-02-03 19:51:53 +00:00
jp c , PrintNothingHappenedText
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-01-20 19:34:56 +00:00
cp ATTACK_UP1_EFFECT + $ 8 ; is it a +2 effect?
2015-01-20 19:21:16 +00:00
jr c , .ok
2015-01-20 11:12:30 +00:00
inc b ; if so, increment stat mod again
2014-05-22 22:13:20 +00:00
ld a , $ d
2015-01-20 11:12:30 +00:00
cp b ; unless it's already +6
2015-01-20 19:21:16 +00:00
jr nc , .ok
2014-05-22 22:13:20 +00:00
ld b , a
2015-01-20 19:21:16 +00:00
.ok
2014-05-22 22:13:20 +00:00
ld [ hl ], b
ld a , c
cp $ 4
2015-01-20 19:21:16 +00:00
jr nc , UpdateStatDone ; jump if mod affected is evasion/accuracy
2014-05-22 22:13:20 +00:00
push hl
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonAttack + 1
2015-02-03 19:51:53 +00:00
ld de , wPlayerMonUnmodifiedAttack
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .pointToStats
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonAttack + 1
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonUnmodifiedAttack
2015-01-20 19:21:16 +00:00
.pointToStats
2014-05-22 22:13:20 +00:00
push bc
sla c
ld b , $ 0
2015-01-20 11:12:30 +00:00
add hl , bc ; hl = modified stat
2014-05-22 22:13:20 +00:00
ld a , c
add e
ld e , a
2015-01-20 19:21:16 +00:00
jr nc , .checkIf999
2015-01-20 11:12:30 +00:00
inc d ; de = unmodified (original) stat
2015-01-20 19:21:16 +00:00
.checkIf999
2014-05-22 22:13:20 +00:00
pop bc
ld a , [ hld ]
2015-02-03 19:51:53 +00:00
sub 999 % $ 100 ; check if stat is already 999
2015-01-20 19:21:16 +00:00
jr nz , .recalculateStat
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
2015-02-03 19:51:53 +00:00
sbc 999 / $ 100
2015-03-31 20:22:12 +00:00
jp z , RestoreOriginalStatModifier
2015-01-20 19:21:16 +00:00
.recalculateStat ; recalculate affected stat
2015-01-31 17:26:05 +00:00
; paralysis and burn penalties, as well as badge boosts are ignored
2014-05-22 22:13:20 +00:00
push hl
push bc
2014-08-09 05:39:13 +00:00
ld hl , StatModifierRatios
2014-05-22 22:13:20 +00:00
dec b
sla b
ld c , b
ld b , $ 0
add hl , bc
pop bc
xor a
2015-06-11 22:41:33 +00:00
ld [ H_MULTIPLICAND ], a
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2015-06-11 22:41:33 +00:00
ld [ H_MULTIPLIER ], a
2014-05-22 22:13:20 +00:00
call Multiply
ld a , [ hl ]
2015-06-11 22:41:33 +00:00
ld [ H_DIVISOR ], a
2014-05-22 22:13:20 +00:00
ld b , $ 4
call Di vide
pop hl
2015-01-23 03:05:13 +00:00
; cap at 999
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
sub 999 % $ 100
ld a , [ H_PRODUCT + 2 ]
sbc 999 / $ 100
2015-01-20 19:21:16 +00:00
jp c , UpdateStat
2014-05-22 22:13:20 +00:00
ld a , 999 / $ 100
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , 999 % $ 100
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
UpdateStat:
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
pop hl
2016-06-12 00:24:04 +00:00
UpdateStatDone:
2014-05-22 22:13:20 +00:00
ld b , c
inc b
2015-07-03 19:37:53 +00:00
call PrintStatText
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
ld de , wPlayerMoveNum
2015-07-12 22:51:04 +00:00
ld bc , wPlayerMonMinimized
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .asm_3f4e6
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
ld de , wEnemyMoveNum
2015-07-12 22:51:04 +00:00
ld bc , wEnemyMonMinimized
2014-05-22 22:13:20 +00:00
.asm_3f4e6
ld a , [ de ]
cp MINIMIZE
jr nz , .asm_3f4f9
2015-07-12 22:51:04 +00:00
; if a substitute is up, slide off the substitute and show the mon pic before
; playing the minimize animation
bit HasSubstituteUp , [ hl ]
2014-05-22 22:13:20 +00:00
push af
push bc
2015-07-12 22:51:04 +00:00
ld hl , HideSubstituteShowMonAnim
ld b , BANK ( HideSubstituteShowMonAnim )
2014-05-22 22:13:20 +00:00
push de
2015-07-12 22:51:04 +00:00
call nz , Bankswitch
2014-05-22 22:13:20 +00:00
pop de
.asm_3f4f9
2015-02-08 00:24:16 +00:00
call PlayCurrentMoveAnimation
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp MINIMIZE
2015-01-20 19:21:16 +00:00
jr nz , .applyBadgeBoostsAndStatusPenalties
2014-05-22 22:13:20 +00:00
pop bc
ld a , $ 1
ld [ bc ], a
2015-07-12 22:51:04 +00:00
ld hl , ReshowSubstituteAnim
ld b , BANK ( ReshowSubstituteAnim )
2014-05-22 22:13:20 +00:00
pop af
call nz , Bankswitch
2015-01-20 19:21:16 +00:00
.applyBadgeBoostsAndStatusPenalties
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 11:12:30 +00:00
call z , ApplyBadgeStatBoosts ; whenever the player uses a stat-up move, badge boosts get reapplied again to every stat,
2015-01-31 17:26:05 +00:00
; even to those not affected by the stat-up move (will be boosted further)
2014-05-22 22:13:20 +00:00
ld hl , MonsStatsRoseText
call PrintText
2015-01-20 11:12:30 +00:00
2015-01-23 03:05:13 +00:00
; these shouldn't be here
2015-01-20 11:12:30 +00:00
call QuarterSpeedDueToParalysis ; apply speed penalty to the player whose turn is not, if it's paralyzed
jp HalveAttackDueToBurn ; apply attack penalty to the player whose turn is not, if it's burned
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
RestoreOriginalStatModifier:
2014-05-22 22:13:20 +00:00
pop hl
dec [ hl ]
2016-06-12 00:24:04 +00:00
PrintNothingHappenedText:
2014-05-22 22:13:20 +00:00
ld hl , NothingHappenedText
jp PrintText
2016-06-12 00:24:04 +00:00
MonsStatsRoseText:
2014-05-22 22:13:20 +00:00
TX_FAR _MonsStatsRoseText
2015-07-03 19:58:50 +00:00
TX_ASM
2014-05-22 22:13:20 +00:00
ld hl , GreatlyRoseText
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2016-06-12 04:30:05 +00:00
jr z , .playerTurn
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2016-06-12 04:30:05 +00:00
.playerTurn
2014-05-22 22:13:20 +00:00
cp ATTACK_DOWN1_EFFECT
ret nc
ld hl , RoseText
ret
2016-06-12 00:24:04 +00:00
GreatlyRoseText:
2016-07-18 06:17:03 +00:00
TX_DELAY
2014-05-22 22:13:20 +00:00
TX_FAR _GreatlyRoseText
2016-06-12 04:30:05 +00:00
; fallthrough
2016-06-12 00:24:04 +00:00
RoseText:
2014-05-22 22:13:20 +00:00
TX_FAR _RoseText
db "@"
2016-06-12 00:24:04 +00:00
StatModifierDownEffect:
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonStatMods
2015-08-31 02:38:41 +00:00
ld de , wPlayerMoveEffect
ld bc , wEnemyBattleStatus1
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .statModifierDownEffect
2014-08-09 05:39:13 +00:00
ld hl , wPlayerMonStatMods
2015-08-31 02:38:41 +00:00
ld de , wEnemyMoveEffect
ld bc , wPlayerBattleStatus1
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-01-20 19:21:16 +00:00
jr z , .statModifierDownEffect
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-02-03 19:51:53 +00:00
cp $ 40 ; 1/4 chance to miss by in regular battle
2015-01-20 19:21:16 +00:00
jp c , MoveMissed
.statModifierDownEffect
2015-01-20 11:12:30 +00:00
call Ch eckTargetSubstitute ; can't hit through substitute
2015-01-20 19:21:16 +00:00
jp nz , MoveMissed
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp ATTACK_DOWN_SIDE_EFFECT
2015-01-20 19:21:16 +00:00
jr c , .nonSideEffect
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-20 11:12:30 +00:00
cp $ 55 ; 85/256 chance for side effects
2015-01-20 19:21:16 +00:00
jp nc , CantLowerAnymore
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-01-20 11:12:30 +00:00
sub ATTACK_DOWN_SIDE_EFFECT ; map each stat to 0-3
2015-01-20 19:21:16 +00:00
jr .decrementStatMod
.nonSideEffect ; non-side effects only
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
2015-01-20 11:12:30 +00:00
call MoveHitTest ; apply accuracy tests
2014-05-22 22:13:20 +00:00
pop bc
pop de
pop hl
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jp nz , MoveMissed
2014-05-22 22:13:20 +00:00
ld a , [ bc ]
2015-02-03 19:51:53 +00:00
bit Invulnerable , a ; fly/dig
2015-01-20 19:21:16 +00:00
jp nz , MoveMissed
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-01-23 03:05:13 +00:00
sub ATTACK_DOWN1_EFFECT
2015-02-03 19:51:53 +00:00
cp EVASION_DOWN1_EFFECT + $ 3 - ATTACK_DOWN1_EFFECT ; covers al -1 effects
2015-01-20 19:21:16 +00:00
jr c , .decrementStatMod
2015-02-03 19:51:53 +00:00
sub ATTACK_DOWN2_EFFECT - ATTACK_DOWN1_EFFECT ; map -2 effects to corresponding -1 effect
2015-01-20 19:21:16 +00:00
.decrementStatMod
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld b , [ hl ]
2015-01-20 11:12:30 +00:00
dec b ; dec corresponding stat mod
2015-01-20 19:21:16 +00:00
jp z , CantLowerAnymore ; if stat mod is 1 (-6), can't lower anymore
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-02-03 19:51:53 +00:00
cp ATTACK_DOWN2_EFFECT - $ 16 ; $24
2015-01-20 19:21:16 +00:00
jr c , .ok
2015-02-03 19:51:53 +00:00
cp EVASION_DOWN2_EFFECT + $ 5 ; $44
2015-01-20 19:21:16 +00:00
jr nc , .ok
2015-01-20 11:12:30 +00:00
dec b ; stat down 2 effects only (dec mod again)
2015-01-20 19:21:16 +00:00
jr nz , .ok
2015-01-20 11:12:30 +00:00
inc b ; increment mod to 1 (-6) if it would become 0 (-7)
2015-01-20 19:21:16 +00:00
.ok
2015-01-23 03:05:13 +00:00
ld [ hl ], b ; save modified mod
2014-05-22 22:13:20 +00:00
ld a , c
2015-01-23 03:05:13 +00:00
cp $ 4
2015-02-03 19:51:53 +00:00
jr nc , UpdateLoweredStatDone ; jump for evasion/accuracy
2014-05-22 22:13:20 +00:00
push hl
push de
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonAttack + 1
2014-08-09 05:39:13 +00:00
ld de , wEnemyMonUnmodifiedAttack
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .pointToStat
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonAttack + 1
2015-02-03 19:51:53 +00:00
ld de , wPlayerMonUnmodifiedAttack
2015-01-20 19:21:16 +00:00
.pointToStat
2014-05-22 22:13:20 +00:00
push bc
sla c
ld b , $ 0
2015-01-20 11:12:30 +00:00
add hl , bc ; hl = modified stat
2014-05-22 22:13:20 +00:00
ld a , c
add e
ld e , a
2016-06-12 04:30:05 +00:00
jr nc , .noCarry
2015-01-20 11:12:30 +00:00
inc d ; de = unmodified stat
2016-06-12 04:30:05 +00:00
.noCarry
2014-05-22 22:13:20 +00:00
pop bc
ld a , [ hld ]
2015-01-20 11:12:30 +00:00
sub $ 1 ; can't lower stat below 1 (-6)
2015-01-20 19:21:16 +00:00
jr nz , .recalculateStat
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
and a
2015-07-03 19:37:53 +00:00
jp z , CantLowerAnymore_Pop
2015-01-20 19:21:16 +00:00
.recalculateStat
2015-01-20 11:12:30 +00:00
; recalculate affected stat
; paralysis and burn penalties, as well as badge boosts are ignored
2014-05-22 22:13:20 +00:00
push hl
push bc
2014-08-09 05:39:13 +00:00
ld hl , StatModifierRatios
2014-05-22 22:13:20 +00:00
dec b
sla b
ld c , b
ld b , $ 0
add hl , bc
pop bc
xor a
2015-06-11 22:41:33 +00:00
ld [ H_MULTIPLICAND ], a
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
inc de
ld a , [ de ]
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
2015-06-11 22:41:33 +00:00
ld [ H_MULTIPLIER ], a
2014-05-22 22:13:20 +00:00
call Multiply
ld a , [ hl ]
2015-06-11 22:41:33 +00:00
ld [ H_DIVISOR ], a
2014-05-22 22:13:20 +00:00
ld b , $ 4
call Di vide
pop hl
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
or b
2015-02-03 19:51:53 +00:00
jp nz , UpdateLoweredStat
ld [ H_MULTIPLICAND + 1 ], a
2014-05-22 22:13:20 +00:00
ld a , $ 1
2015-02-03 19:51:53 +00:00
ld [ H_MULTIPLICAND + 2 ], a
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
UpdateLoweredStat:
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 2 ]
2014-05-22 22:13:20 +00:00
ld [ hli ], a
2015-02-03 19:51:53 +00:00
ld a , [ H_PRODUCT + 3 ]
2014-05-22 22:13:20 +00:00
ld [ hl ], a
pop de
pop hl
2016-06-12 00:24:04 +00:00
UpdateLoweredStatDone:
2014-05-22 22:13:20 +00:00
ld b , c
inc b
push de
2015-07-03 19:37:53 +00:00
call PrintStatText
2014-05-22 22:13:20 +00:00
pop de
ld a , [ de ]
cp $ 44
2015-01-20 19:21:16 +00:00
jr nc , .ApplyBadgeBoostsAndStatusPenalties
2015-03-31 20:22:12 +00:00
call PlayCurrentMoveAnimation2
2015-01-20 19:21:16 +00:00
.ApplyBadgeBoostsAndStatusPenalties
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 11:12:30 +00:00
call nz , ApplyBadgeStatBoosts ; whenever the player uses a stat-down move, badge boosts get reapplied again to every stat,
2015-01-31 17:26:05 +00:00
; even to those not affected by the stat-up move (will be boosted further)
2014-05-22 22:13:20 +00:00
ld hl , MonsStatsFellText
call PrintText
2015-01-23 03:05:13 +00:00
; These where probably added given that a stat-down move affecting speed or attack will override
2015-01-20 11:12:30 +00:00
; the stat penalties from paralysis and burn respectively.
2015-01-23 03:05:13 +00:00
; But they are always called regardless of the stat affected by the stat-down move.
2014-08-09 05:39:13 +00:00
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
CantLowerAnymore_Pop:
2014-05-22 22:13:20 +00:00
pop de
pop hl
inc [ hl ]
2016-06-12 00:24:04 +00:00
CantLowerAnymore:
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp ATTACK_DOWN_SIDE_EFFECT
ret nc
ld hl , NothingHappenedText
jp PrintText
2016-06-12 00:24:04 +00:00
MoveMissed:
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp $ 44
ret nc
2015-03-31 18:50:49 +00:00
jp ConditionalPrintButItFailed
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MonsStatsFellText:
2014-05-22 22:13:20 +00:00
TX_FAR _MonsStatsFellText
2015-07-03 19:58:50 +00:00
TX_ASM
2014-05-22 22:13:20 +00:00
ld hl , FellText
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveEffect ]
2016-06-12 04:30:05 +00:00
jr z , .playerTurn
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveEffect ]
2016-06-12 04:30:05 +00:00
.playerTurn
; check if the move's effect decreases a stat by 2
cp BIDE_EFFECT
2014-05-22 22:13:20 +00:00
ret c
2016-06-12 04:30:05 +00:00
cp ATTACK_DOWN_SIDE_EFFECT
2014-05-22 22:13:20 +00:00
ret nc
ld hl , GreatlyFellText
ret
2016-06-12 00:24:04 +00:00
GreatlyFellText:
2016-07-18 06:17:03 +00:00
TX_DELAY
2014-05-22 22:13:20 +00:00
TX_FAR _GreatlyFellText
2016-06-12 04:30:05 +00:00
; fallthrough
2016-06-12 00:24:04 +00:00
FellText:
2014-05-22 22:13:20 +00:00
TX_FAR _FellText
db "@"
2016-06-12 00:24:04 +00:00
PrintStatText:
2014-05-22 22:13:20 +00:00
ld hl , StatsTextStrings
2015-08-05 21:20:29 +00:00
ld c , "@"
2016-06-12 04:30:05 +00:00
.findStatName_outer
2014-05-22 22:13:20 +00:00
dec b
2016-06-12 04:30:05 +00:00
jr z , .foundStatName
.findStatName_inner
2014-05-22 22:13:20 +00:00
ld a , [ hli ]
cp c
2016-06-12 04:30:05 +00:00
jr z , .findStatName_outer
jr .findStatName_inner
.foundStatName
2014-05-26 21:04:56 +00:00
ld de , wcf4b
2014-05-22 22:13:20 +00:00
ld bc , $ a
jp CopyData
2016-06-12 00:24:04 +00:00
StatsTextStrings:
2014-05-22 22:13:20 +00:00
db "ATTACK@"
db "DEFENSE@"
db "SPEED@"
db "SPECIAL@"
db "ACCURACY@"
db "EVADE@"
2016-06-12 00:24:04 +00:00
StatModifierRatios:
2014-05-22 22:13:20 +00:00
; first byte is numerator, second byte is denominator
db 25 , 100 ; 0.25
db 28 , 100 ; 0.28
db 33 , 100 ; 0.33
db 40 , 100 ; 0.40
db 50 , 100 ; 0.50
db 66 , 100 ; 0.66
db 1 , 1 ; 1.00
db 15 , 10 ; 1.50
db 2 , 1 ; 2.00
db 25 , 10 ; 2.50
db 3 , 1 ; 3.00
db 35 , 10 ; 3.50
db 4 , 1 ; 4.00
2016-06-12 00:24:04 +00:00
BideEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2015-02-07 10:43:08 +00:00
ld de , wPlayerBideAccumulatedDamage
2014-08-09 05:39:13 +00:00
ld bc , wPlayerNumAttacksLeft
2014-05-22 22:13:20 +00:00
ld a , [ H_WHOSETURN ]
and a
2015-01-20 19:21:16 +00:00
jr z , .bideEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2015-02-07 10:43:08 +00:00
ld de , wEnemyBideAccumulatedDamage
2014-08-09 05:39:13 +00:00
ld bc , wEnemyNumAttacksLeft
2015-01-20 19:21:16 +00:00
.bideEffect
2015-02-03 19:51:53 +00:00
set StoringEnergy , [ hl ] ; mon is now using bide
2014-05-22 22:13:20 +00:00
xor a
ld [ de ], a
inc de
ld [ de ], a
2015-08-31 02:38:41 +00:00
ld [ wPlayerMoveEffect ], a
ld [ wEnemyMoveEffect ], a
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 1
inc a
inc a
2015-01-20 11:12:30 +00:00
ld [ bc ], a ; set Bide counter to 2 or 3 at random
2014-05-22 22:13:20 +00:00
ld a , [ H_WHOSETURN ]
2014-09-17 19:37:47 +00:00
add XSTATITEM_ANIM
2015-03-31 20:22:12 +00:00
jp PlayBattleAnimation2
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ThrashPetalDanceEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wPlayerNumAttacksLeft
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .thrashPetalDanceEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wEnemyNumAttacksLeft
2015-01-20 19:21:16 +00:00
.thrashPetalDanceEffect
2015-02-03 19:51:53 +00:00
set ThrashingAbout , [ hl ] ; mon is now using thrash/petal dance
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-23 03:05:13 +00:00
and $ 1
2014-05-22 22:13:20 +00:00
inc a
inc a
2015-01-20 11:12:30 +00:00
ld [ de ], a ; set thrash/petal dance counter to 2 or 3 at random
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-09-17 19:37:47 +00:00
add ANIM_B0
2015-03-31 20:22:12 +00:00
jp PlayBattleAnimation2
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SwitchAndTeleportEffect:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr nz , .handleEnemy
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
2016-06-12 04:30:05 +00:00
jr nz , .notWildBattle1
2015-08-31 02:38:41 +00:00
ld a , [ wCurEnemyLVL ]
2014-05-22 22:13:20 +00:00
ld b , a
2014-08-09 05:39:13 +00:00
ld a , [ wBattleMonLevel ]
2016-06-12 04:30:05 +00:00
cp b ; is the player's level greater than the enemy's level?
jr nc , .playerMoveWasSuccessful ; if so, teleport will always succeed
2014-05-22 22:13:20 +00:00
add b
ld c , a
2016-06-12 04:30:05 +00:00
inc c ; c = sum of player level and enemy level
.rejectionSampleLoop1
2014-05-24 18:40:38 +00:00
call BattleRandom
2016-06-12 04:30:05 +00:00
cp c ; get a random number between 0 and c
jr nc , .rejectionSampleLoop1
2014-05-22 22:13:20 +00:00
srl b
2016-10-17 05:30:32 +00:00
srl b ; b = enemyLevel / 4
cp b ; is rand[0, playerLevel + enemyLevel) >= (enemyLevel / 4)?
2016-06-12 04:30:05 +00:00
jr nc , .playerMoveWasSuccessful ; if so, allow teleporting
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz , PrintDidntAffectText
jp PrintButItFailedText_
2016-06-12 04:30:05 +00:00
.playerMoveWasSuccessful
2014-05-22 22:13:20 +00:00
call ReadPlayerMonCurHPAndStatus
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ wEscapedFromBattle ], a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2016-06-12 04:30:05 +00:00
jr .playAnimAndPrintText
.notWildBattle1
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
ld hl , IsUnaffectedText
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz , PrintText
jp PrintButItFailedText_
2016-06-12 04:30:05 +00:00
.handleEnemy
2015-08-31 02:38:41 +00:00
ld a , [ wIsInBattle ]
2014-05-22 22:13:20 +00:00
dec a
2016-06-12 04:30:05 +00:00
jr nz , .notWildBattle2
2014-08-09 05:39:13 +00:00
ld a , [ wBattleMonLevel ]
2014-05-22 22:13:20 +00:00
ld b , a
2015-08-31 02:38:41 +00:00
ld a , [ wCurEnemyLVL ]
2014-05-22 22:13:20 +00:00
cp b
2016-06-12 04:30:05 +00:00
jr nc , .enemyMoveWasSuccessful
2014-05-22 22:13:20 +00:00
add b
ld c , a
inc c
2016-06-12 04:30:05 +00:00
.rejectionSampleLoop2
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp c
2016-06-12 04:30:05 +00:00
jr nc , .rejectionSampleLoop2
2014-05-22 22:13:20 +00:00
srl b
srl b
cp b
2016-06-12 04:30:05 +00:00
jr nc , .enemyMoveWasSuccessful
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz , PrintDidntAffectText
jp PrintButItFailedText_
2016-06-12 04:30:05 +00:00
.enemyMoveWasSuccessful
2014-05-22 22:13:20 +00:00
call ReadPlayerMonCurHPAndStatus
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [ wEscapedFromBattle ], a
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2016-06-12 04:30:05 +00:00
jr .playAnimAndPrintText
.notWildBattle2
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
ld hl , IsUnaffectedText
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz , PrintText
2015-03-31 18:50:49 +00:00
jp ConditionalPrintButItFailed
2016-06-12 04:30:05 +00:00
.playAnimAndPrintText
2014-05-22 22:13:20 +00:00
push af
2015-01-23 03:05:13 +00:00
call PlayBattleAnimation
2015-07-03 19:37:53 +00:00
ld c , 20
2014-05-22 22:13:20 +00:00
call DelayFrames
pop af
2014-08-09 05:39:13 +00:00
ld hl , RanFromBattleText
2014-05-22 22:13:20 +00:00
cp TELEPORT
2016-06-12 04:30:05 +00:00
jr z , .printText
2014-08-09 05:39:13 +00:00
ld hl , RanAwayScaredText
2014-05-22 22:13:20 +00:00
cp ROAR
2016-06-12 04:30:05 +00:00
jr z , .printText
2014-08-09 05:39:13 +00:00
ld hl , WasBlownAwayText
2016-06-12 04:30:05 +00:00
.printText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
RanFromBattleText:
2014-05-22 22:13:20 +00:00
TX_FAR _RanFromBattleText
db "@"
2016-06-12 00:24:04 +00:00
RanAwayScaredText:
2014-05-22 22:13:20 +00:00
TX_FAR _RanAwayScaredText
db "@"
2016-06-12 00:24:04 +00:00
WasBlownAwayText:
2014-05-22 22:13:20 +00:00
TX_FAR _WasBlownAwayText
db "@"
2016-06-12 00:24:04 +00:00
TwoToFiveAttacksEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wPlayerNumAttacksLeft
2015-02-07 10:43:08 +00:00
ld bc , wPlayerNumHits
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .twoToFiveAttacksEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wEnemyNumAttacksLeft
2015-02-07 10:43:08 +00:00
ld bc , wEnemyNumHits
2015-01-20 19:21:16 +00:00
.twoToFiveAttacksEffect
2015-02-03 19:51:53 +00:00
bit AttackingMultipleTimes , [ hl ] ; is mon attacking multiple times?
2014-05-22 22:13:20 +00:00
ret nz
2015-02-03 19:51:53 +00:00
set AttackingMultipleTimes , [ hl ] ; mon is now attacking multiple times
2015-08-31 02:38:41 +00:00
ld hl , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-20 19:21:16 +00:00
jr z , .setNumberOfHits
2015-08-31 02:38:41 +00:00
ld hl , wEnemyMoveEffect
2015-01-20 19:21:16 +00:00
.setNumberOfHits
2014-05-22 22:13:20 +00:00
ld a , [ hl ]
cp TWINEEDLE_EFFECT
2015-01-20 19:21:16 +00:00
jr z , .twineedle
2014-05-22 22:13:20 +00:00
cp ATTACK_TWICE_EFFECT
2015-01-20 19:21:16 +00:00
ld a , $ 2 ; number of hits it's always 2 for ATTACK_TWICE_EFFECT
jr z , .saveNumberOfHits
2015-01-23 03:05:13 +00:00
; for TWO_TO_FIVE_ATTACKS_EFFECT 3/8 chance for 2 and 3 hits, and 1/8 chance for 4 and 5 hits
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-01-23 03:05:13 +00:00
and $ 3
cp $ 2
2016-06-12 04:30:05 +00:00
jr c , .gotNumHits
; if the number of hits was greater than 2, re-roll again for a lower chance
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
2016-06-12 04:30:05 +00:00
.gotNumHits
2014-05-22 22:13:20 +00:00
inc a
inc a
2015-01-20 19:21:16 +00:00
.saveNumberOfHits
2014-05-22 22:13:20 +00:00
ld [ de ], a
ld [ bc ], a
ret
2015-01-20 19:21:16 +00:00
.twineedle
ld a , POISON_SIDE_EFFECT1
ld [ hl ], a ; set Twineedle's effect to poison effect
jr .saveNumberOfHits
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FlinchSideEffect:
2014-05-22 22:13:20 +00:00
call Ch eckTargetSubstitute
ret nz
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
ld de , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr z , .flinchSideEffect
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
ld de , wEnemyMoveEffect
2015-01-31 17:26:05 +00:00
.flinchSideEffect
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp FLINCH_SIDE_EFFECT1
ld b , $ 1 a ; ~10% chance of flinch
2015-01-31 17:26:05 +00:00
jr z , .gotEffectChance
2014-05-22 22:13:20 +00:00
ld b , $ 4 d ; ~30% chance of flinch
2015-01-31 17:26:05 +00:00
.gotEffectChance
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
ret nc
2015-02-03 19:51:53 +00:00
set Flinched , [ hl ] ; set mon's status to flinching
2015-01-20 19:21:16 +00:00
call Cl earHyperBeam
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
OneHitKOEffect:
2015-07-19 18:56:13 +00:00
jpab OneHitKOEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ChargeEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
ld de , wPlayerMoveEffect
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-09-17 19:37:47 +00:00
ld b , XSTATITEM_ANIM
2015-01-31 17:26:05 +00:00
jr z , .chargeEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
ld de , wEnemyMoveEffect
2014-09-17 19:37:47 +00:00
ld b , ANIM_AF
2015-01-31 17:26:05 +00:00
.chargeEffect
2015-02-03 19:51:53 +00:00
set Ch argingUp , [ hl ]
2014-05-22 22:13:20 +00:00
ld a , [ de ]
dec de ; de contains enemy or player MOVENUM
cp FLY_EFFECT
2015-01-31 17:26:05 +00:00
jr nz , .notFly
2015-02-03 19:51:53 +00:00
set Invulnerable , [ hl ] ; mon is now invulnerable to typical attacks (fly/dig)
2015-01-31 17:26:05 +00:00
ld b , TELEPORT ; load Teleport's animation
.notFly
2014-05-22 22:13:20 +00:00
ld a , [ de ]
cp DI G
2015-01-31 17:26:05 +00:00
jr nz , .notDigOrFly
2015-02-03 19:51:53 +00:00
set Invulnerable , [ hl ] ; mon is now invulnerable to typical attacks (fly/dig)
2014-09-17 19:37:47 +00:00
ld b , ANIM_C0
2015-01-31 17:26:05 +00:00
.notDigOrFly
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-05-22 22:13:20 +00:00
ld a , b
2015-01-23 03:05:13 +00:00
call PlayBattleAnimation
2014-05-22 22:13:20 +00:00
ld a , [ de ]
2015-07-16 03:04:58 +00:00
ld [ wChargeMoveNum ], a
2014-08-09 05:39:13 +00:00
ld hl , Ch argeMoveEffectText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
ChargeMoveEffectText:
2014-05-22 22:13:20 +00:00
TX_FAR _ChargeMoveEffectText
2015-07-03 19:58:50 +00:00
TX_ASM
2015-07-16 03:04:58 +00:00
ld a , [ wChargeMoveNum ]
2014-05-22 22:13:20 +00:00
cp RAZOR_WIND
2014-08-09 05:39:13 +00:00
ld hl , MadeWhirlwindText
2016-06-12 04:30:05 +00:00
jr z , .gotText
2014-05-22 22:13:20 +00:00
cp SOLARBEAM
2014-08-09 05:39:13 +00:00
ld hl , TookInSunlightText
2016-06-12 04:30:05 +00:00
jr z , .gotText
2014-05-22 22:13:20 +00:00
cp SKULL_BASH
2014-08-09 05:39:13 +00:00
ld hl , LoweredItsHeadText
2016-06-12 04:30:05 +00:00
jr z , .gotText
2014-05-22 22:13:20 +00:00
cp SKY_ATTACK
2014-08-09 05:39:13 +00:00
ld hl , SkyAttackGlowingText
2016-06-12 04:30:05 +00:00
jr z , .gotText
2014-05-22 22:13:20 +00:00
cp FLY
2014-08-09 05:39:13 +00:00
ld hl , FlewUpHighText
2016-06-12 04:30:05 +00:00
jr z , .gotText
2014-05-22 22:13:20 +00:00
cp DI G
2014-08-09 05:39:13 +00:00
ld hl , DugAHoleText
2016-06-12 04:30:05 +00:00
.gotText
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
MadeWhirlwindText:
2014-05-22 22:13:20 +00:00
TX_FAR _MadeWhirlwindText
db "@"
2016-06-12 00:24:04 +00:00
TookInSunlightText:
2014-05-22 22:13:20 +00:00
TX_FAR _TookInSunlightText
db "@"
2016-06-12 00:24:04 +00:00
LoweredItsHeadText:
2014-05-22 22:13:20 +00:00
TX_FAR _LoweredItsHeadText
db "@"
2016-06-12 00:24:04 +00:00
SkyAttackGlowingText:
2014-05-22 22:13:20 +00:00
TX_FAR _SkyAttackGlowingText
db "@"
2016-06-12 00:24:04 +00:00
FlewUpHighText:
2014-05-22 22:13:20 +00:00
TX_FAR _FlewUpHighText
db "@"
2016-06-12 00:24:04 +00:00
DugAHoleText:
2014-05-22 22:13:20 +00:00
TX_FAR _DugAHoleText
db "@"
2016-06-12 00:24:04 +00:00
TrappingEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wPlayerNumAttacksLeft
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr z , .trappingEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
2014-08-09 05:39:13 +00:00
ld de , wEnemyNumAttacksLeft
2015-01-31 17:26:05 +00:00
.trappingEffect
2015-02-03 19:51:53 +00:00
bit UsingTrappingMove , [ hl ]
2014-05-22 22:13:20 +00:00
ret nz
2015-06-11 22:41:33 +00:00
call Cl earHyperBeam ; since this effect is called before testing whether the move will hit,
; the target won't need to recharge even if the trapping move missed
2015-02-03 19:51:53 +00:00
set UsingTrappingMove , [ hl ] ; mon is now using a trapping move
2015-01-31 17:26:05 +00:00
call BattleRandom ; 3/8 chance for 2 and 3 attacks, and 1/8 chance for 4 and 5 attacks
2014-05-22 22:13:20 +00:00
and $ 3
cp $ 2
2015-01-31 17:26:05 +00:00
jr c , .setTrappingCounter
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
2015-01-31 17:26:05 +00:00
.setTrappingCounter
2014-05-22 22:13:20 +00:00
inc a
ld [ de ], a
ret
2016-06-12 00:24:04 +00:00
MistEffect:
2015-07-19 18:56:13 +00:00
jpab MistEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FocusEnergyEffect:
2015-07-19 18:56:13 +00:00
jpab FocusEnergyEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
RecoilEffect:
2015-07-19 18:56:13 +00:00
jpab RecoilEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ConfusionSideEffect:
2014-05-24 18:40:38 +00:00
call BattleRandom
2016-06-12 04:30:05 +00:00
cp $ 19 ; ~10% chance
2014-05-22 22:13:20 +00:00
ret nc
2015-01-31 17:26:05 +00:00
jr ConfusionSideEffectSuccess
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ConfusionEffect:
2014-05-22 22:13:20 +00:00
call Ch eckTargetSubstitute
2015-01-31 17:26:05 +00:00
jr nz , ConfusionEffectFailed
2014-05-22 22:13:20 +00:00
call MoveHitTest
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr nz , ConfusionEffectFailed
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ConfusionSideEffectSuccess:
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus1
ld bc , wEnemyConfusedCounter
ld a , [ wPlayerMoveEffect ]
2015-01-31 17:26:05 +00:00
jr z , .confuseTarget
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus1
ld bc , wPlayerConfusedCounter
ld a , [ wEnemyMoveEffect ]
2015-01-31 17:26:05 +00:00
.confuseTarget
2015-02-03 19:51:53 +00:00
bit Confused , [ hl ] ; is mon confused?
2015-01-31 17:26:05 +00:00
jr nz , ConfusionEffectFailed
2015-02-03 19:51:53 +00:00
set Confused , [ hl ] ; mon is now confused
2014-05-22 22:13:20 +00:00
push af
2014-05-24 18:40:38 +00:00
call BattleRandom
2015-06-11 22:41:33 +00:00
and $ 3
2014-05-22 22:13:20 +00:00
inc a
inc a
2015-01-31 17:26:05 +00:00
ld [ bc ], a ; confusion status will last 2-5 turns
2014-05-22 22:13:20 +00:00
pop af
cp CONFUSION_SIDE_EFFECT
2015-03-31 20:22:12 +00:00
call nz , PlayCurrentMoveAnimation2
2014-08-09 05:39:13 +00:00
ld hl , BecameConfusedText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
BecameConfusedText:
2014-05-22 22:13:20 +00:00
TX_FAR _BecameConfusedText
db "@"
2016-06-12 00:24:04 +00:00
ConfusionEffectFailed:
2014-05-22 22:13:20 +00:00
cp CONFUSION_SIDE_EFFECT
ret z
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-03-31 18:50:49 +00:00
jp ConditionalPrintButItFailed
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ParalyzeEffect:
2015-07-19 18:56:13 +00:00
jpab ParalyzeEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SubstituteEffect:
2015-07-19 18:56:13 +00:00
jpab SubstituteEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
HyperBeamEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-01-31 17:26:05 +00:00
jr z , .hyperBeamEffect
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2015-01-31 17:26:05 +00:00
.hyperBeamEffect
2015-02-03 19:51:53 +00:00
set NeedsToRecharge , [ hl ] ; mon now needs to recharge
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
ClearHyperBeam:
2014-05-22 22:13:20 +00:00
push hl
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr z , .playerTurn
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2016-06-12 04:30:05 +00:00
.playerTurn
2015-02-03 19:51:53 +00:00
res NeedsToRecharge , [ hl ] ; mon no longer needs to recharge
2014-05-22 22:13:20 +00:00
pop hl
ret
2016-06-12 00:24:04 +00:00
RageEffect:
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
ld a , [ H_WHOSETURN ]
and a
jr z , .player
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2014-05-22 22:13:20 +00:00
.player
2015-02-03 19:51:53 +00:00
set UsingRage , [ hl ] ; mon is now in "rage" mode
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
MimicEffect:
2015-07-03 19:37:53 +00:00
ld c , 50
2014-05-22 22:13:20 +00:00
call DelayFrames
call MoveHitTest
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2016-06-12 04:30:05 +00:00
jr nz , .mimicMissed
2014-05-22 22:13:20 +00:00
ld a , [ H_WHOSETURN ]
and a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerBattleStatus1 ]
2016-06-12 04:30:05 +00:00
jr nz , .enemyTurn
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2016-06-12 04:30:05 +00:00
jr nz , .letPlayerChooseMove
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus1 ]
2016-06-12 04:30:05 +00:00
.enemyTurn
2015-02-03 19:51:53 +00:00
bit Invulnerable , a
2016-06-12 04:30:05 +00:00
jr nz , .mimicMissed
.getRandomMove
2014-05-22 22:13:20 +00:00
push hl
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
ld c , a
ld b , $ 0
add hl , bc
ld a , [ hl ]
pop hl
and a
2016-06-12 04:30:05 +00:00
jr z , .getRandomMove
2014-05-22 22:13:20 +00:00
ld d , a
ld a , [ H_WHOSETURN ]
and a
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2014-05-22 22:13:20 +00:00
ld a , [ wPlayerMoveListIndex ]
2016-06-12 04:30:05 +00:00
jr z , .playerTurn
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2014-05-22 22:13:20 +00:00
ld a , [ wEnemyMoveListIndex ]
2016-06-12 04:30:05 +00:00
jr .playerTurn
.letPlayerChooseMove
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyBattleStatus1 ]
2015-02-03 19:51:53 +00:00
bit Invulnerable , a
2016-06-12 04:30:05 +00:00
jr nz , .mimicMissed
2014-05-22 22:13:20 +00:00
ld a , [ wCurrentMenuItem ]
push af
ld a , $ 1
ld [ wMoveMenuType ], a
call MoveSelectionMenu
call LoadScreenTilesFromBuffer1
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2014-05-22 22:13:20 +00:00
ld a , [ wCurrentMenuItem ]
ld c , a
ld b , $ 0
add hl , bc
ld d , [ hl ]
pop af
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2016-06-12 04:30:05 +00:00
.playerTurn
2014-05-22 22:13:20 +00:00
ld c , a
ld b , $ 0
add hl , bc
ld a , d
ld [ hl ], a
2014-05-26 21:04:56 +00:00
ld [ wd11e ], a
2014-05-22 22:13:20 +00:00
call GetMoveName
2015-02-08 00:24:16 +00:00
call PlayCurrentMoveAnimation
2014-05-22 22:13:20 +00:00
ld hl , MimicLearnedMoveText
jp PrintText
2016-06-12 04:30:05 +00:00
.mimicMissed
2014-05-22 22:13:20 +00:00
jp PrintButItFailedText_
2016-06-12 00:24:04 +00:00
MimicLearnedMoveText:
2014-05-22 22:13:20 +00:00
TX_FAR _MimicLearnedMoveText
db "@"
2016-06-12 00:24:04 +00:00
LeechSeedEffect:
2015-07-19 18:56:13 +00:00
jpab LeechSeedEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SplashEffect:
2015-02-08 00:24:16 +00:00
call PlayCurrentMoveAnimation
2014-05-22 22:13:20 +00:00
jp PrintNoEffectText
2016-06-12 00:24:04 +00:00
DisableEffect:
2014-05-22 22:13:20 +00:00
call MoveHitTest
2015-08-31 02:38:41 +00:00
ld a , [ wMoveMissed ]
2014-05-22 22:13:20 +00:00
and a
2015-04-08 23:17:56 +00:00
jr nz , .moveMissed
2015-08-31 02:38:41 +00:00
ld de , wEnemyDisabledMove
2014-06-14 11:12:40 +00:00
ld hl , wEnemyMonMoves
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-04-08 23:17:56 +00:00
jr z , .disableEffect
2015-08-31 02:38:41 +00:00
ld de , wPlayerDisabledMove
2014-06-14 11:12:40 +00:00
ld hl , wBattleMonMoves
2015-04-08 23:17:56 +00:00
.disableEffect
; no effect if target already has a move disabled
2014-05-22 22:13:20 +00:00
ld a , [ de ]
and a
2015-04-08 23:17:56 +00:00
jr nz , .moveMissed
.pickMoveToDisable
2014-05-22 22:13:20 +00:00
push hl
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 3
ld c , a
ld b , $ 0
add hl , bc
ld a , [ hl ]
pop hl
and a
2015-04-08 23:17:56 +00:00
jr z , .pickMoveToDisable ; loop until a non-00 move slot is found
ld [ wd11e ], a ; store move number
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
ld hl , wBattleMonPP
2015-06-11 22:41:33 +00:00
jr nz , .enemyTurn
2015-02-07 10:43:08 +00:00
ld a , [ wLinkState ]
cp LINK_STATE_BATTLING
2015-04-08 23:17:56 +00:00
pop hl ; wEnemyMonMoves
jr nz , .playerTurnNotLinkBattle
2015-06-11 22:41:33 +00:00
; .playerTurnLinkBattle
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld hl , wEnemyMonPP
2015-04-08 23:17:56 +00:00
.enemyTurn
2014-05-22 22:13:20 +00:00
push hl
ld a , [ hli ]
or [ hl ]
inc hl
or [ hl ]
inc hl
or [ hl ]
and $ 3 f
2015-04-08 23:17:56 +00:00
pop hl ; wBattleMonPP or wEnemyMonPP
jr z , .moveMissedPopHL ; nothing to do if all moves have no PP left
2014-05-22 22:13:20 +00:00
add hl , bc
ld a , [ hl ]
pop hl
and a
2015-04-08 23:17:56 +00:00
jr z , .pickMoveToDisable ; pick another move if this one had 0 PP
.playerTurnNotLinkBattle
; non-link battle enemies have unlimited PP so the previous checks aren't needed
2014-05-24 18:40:38 +00:00
call BattleRandom
2014-05-22 22:13:20 +00:00
and $ 7
2015-04-08 23:17:56 +00:00
inc a ; 1-8 turns disabled
inc c ; move 1-4 will be disabled
2015-06-11 22:41:33 +00:00
swap c
2015-08-31 02:38:41 +00:00
add c ; map disabled move to high nibble of wEnemyDisabledMove / wPlayerDisabledMove
2014-05-22 22:13:20 +00:00
ld [ de ], a
2015-03-31 20:22:12 +00:00
call PlayCurrentMoveAnimation2
2015-04-08 23:17:56 +00:00
ld hl , wPlayerDisabledMoveNumber
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-04-08 23:17:56 +00:00
jr nz , .printDisableText
inc hl ; wEnemyDisabledMoveNumber
.printDisableText
ld a , [ wd11e ] ; move number
2015-06-11 22:41:33 +00:00
ld [ hl ], a
2014-05-22 22:13:20 +00:00
call GetMoveName
2014-08-09 05:39:13 +00:00
ld hl , MoveWasDisabledText
2014-05-22 22:13:20 +00:00
jp PrintText
2015-04-08 23:17:56 +00:00
.moveMissedPopHL
2014-05-22 22:13:20 +00:00
pop hl
2015-04-08 23:17:56 +00:00
.moveMissed
2014-05-22 22:13:20 +00:00
jp PrintButItFailedText_
2016-06-12 00:24:04 +00:00
MoveWasDisabledText:
2014-05-22 22:13:20 +00:00
TX_FAR _MoveWasDisabledText
db "@"
2016-06-12 00:24:04 +00:00
PayDayEffect:
2015-07-19 18:56:13 +00:00
jpab PayDayEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ConversionEffect:
2015-07-19 18:56:13 +00:00
jpab ConversionEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
HazeEffect:
2015-07-19 18:56:13 +00:00
jpab HazeEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
HealEffect:
2015-07-19 18:56:13 +00:00
jpab HealEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
TransformEffect:
2015-07-19 18:56:13 +00:00
jpab TransformEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ReflectLightScreenEffect:
2015-07-19 18:56:13 +00:00
jpab ReflectLightScreenEffect_
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
NothingHappenedText:
2014-05-22 22:13:20 +00:00
TX_FAR _NothingHappenedText
db "@"
2016-06-12 00:24:04 +00:00
PrintNoEffectText:
2014-05-22 22:13:20 +00:00
ld hl , NoEffectText
jp PrintText
2016-06-12 00:24:04 +00:00
NoEffectText:
2014-05-22 22:13:20 +00:00
TX_FAR _NoEffectText
db "@"
2016-06-12 00:24:04 +00:00
ConditionalPrintButItFailed:
2015-03-31 18:28:42 +00:00
ld a , [ wMoveDidntMiss ]
2014-05-22 22:13:20 +00:00
and a
2015-03-31 18:50:49 +00:00
ret nz ; return if the side effect failed, yet the attack was successful
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PrintButItFailedText_:
2014-05-22 22:13:20 +00:00
ld hl , ButItFailedText
jp PrintText
2016-06-12 00:24:04 +00:00
ButItFailedText:
2014-05-22 22:13:20 +00:00
TX_FAR _ButItFailedText
db "@"
2016-06-12 00:24:04 +00:00
PrintDidntAffectText:
2014-05-22 22:13:20 +00:00
ld hl , Di dntAffectText
jp PrintText
2016-06-12 00:24:04 +00:00
DidntAffectText:
2014-05-22 22:13:20 +00:00
TX_FAR _DidntAffectText
db "@"
2016-06-12 00:24:04 +00:00
IsUnaffectedText:
2014-05-22 22:13:20 +00:00
TX_FAR _IsUnaffectedText
db "@"
2016-06-12 00:24:04 +00:00
PrintMayNotAttackText:
2014-08-09 05:39:13 +00:00
ld hl , ParalyzedMayNotAttackText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
ParalyzedMayNotAttackText:
2014-05-22 22:13:20 +00:00
TX_FAR _ParalyzedMayNotAttackText
db "@"
2016-06-12 00:24:04 +00:00
CheckTargetSubstitute:
2014-05-22 22:13:20 +00:00
push hl
2015-08-31 02:38:41 +00:00
ld hl , wEnemyBattleStatus2
2015-06-11 22:41:33 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
jr z , .next1
2015-08-31 02:38:41 +00:00
ld hl , wPlayerBattleStatus2
2014-05-22 22:13:20 +00:00
.next1
2015-06-11 22:41:33 +00:00
bit HasSubstituteUp , [ hl ]
2014-05-22 22:13:20 +00:00
pop hl
ret
2016-06-12 00:24:04 +00:00
PlayCurrentMoveAnimation2:
2015-03-31 19:09:43 +00:00
; animation at MOVENUM will be played unless MOVENUM is 0
2015-03-31 20:22:12 +00:00
; plays wAnimationType 3 or 6
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2015-03-31 20:22:12 +00:00
jr z , .notEnemyTurn
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2015-03-31 20:22:12 +00:00
.notEnemyTurn
2014-05-22 22:13:20 +00:00
and a
ret z
2016-06-12 00:24:04 +00:00
PlayBattleAnimation2:
2015-03-31 20:22:12 +00:00
; play animation ID at a and animation type 6 or 3
2015-08-31 02:38:41 +00:00
ld [ wAnimationID ], a
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
ld a , $ 6
2015-03-31 19:09:43 +00:00
jr z , .storeAnimationType
2014-05-22 22:13:20 +00:00
ld a , $ 3
2015-03-31 19:09:43 +00:00
.storeAnimationType
ld [ wAnimationType ], a
jp PlayBattleAnimationGotID
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PlayCurrentMoveAnimation:
2015-03-31 20:22:12 +00:00
; animation at MOVENUM will be played unless MOVENUM is 0
; resets wAnimationType
2014-05-22 22:13:20 +00:00
xor a
2015-03-31 19:09:43 +00:00
ld [ wAnimationType ], a
2014-08-09 05:39:13 +00:00
ld a , [ H_WHOSETURN ]
2014-05-22 22:13:20 +00:00
and a
2015-08-31 02:38:41 +00:00
ld a , [ wPlayerMoveNum ]
2015-02-08 00:24:16 +00:00
jr z , .notEnemyTurn
2015-08-31 02:38:41 +00:00
ld a , [ wEnemyMoveNum ]
2015-02-08 00:24:16 +00:00
.notEnemyTurn
2014-05-22 22:13:20 +00:00
and a
ret z
2016-06-12 00:24:04 +00:00
PlayBattleAnimation:
2015-03-31 20:22:12 +00:00
; play animation ID at a and predefined animation type
2015-08-31 02:38:41 +00:00
ld [ wAnimationID ], a
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PlayBattleAnimationGotID:
2015-08-31 02:38:41 +00:00
; play animation at wAnimationID
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
2014-06-16 20:57:26 +00:00
predef MoveAnimation
2014-05-22 22:13:20 +00:00
pop bc
pop de
pop hl
ret