pokered/engine/battle/core.asm

8595 lines
169 KiB
NASM
Raw Normal View History

2014-05-22 22:13:20 +00:00
BattleCore:
; These are move effects (second value from the Moves table in bank $E).
EffectsArray1: ; 3c000 (f:4000)
db CONVERSION_EFFECT
db HAZE_EFFECT
db SWITCH_AND_TELEPORT_EFFECT
db MIST_EFFECT
db FOCUS_ENERGY_EFFECT
db CONFUSION_EFFECT
db HEAL_EFFECT
db TRANSFORM_EFFECT
db LIGHT_SCREEN_EFFECT
db REFLECT_EFFECT
db POISON_EFFECT
db PARALYZE_EFFECT
db SUBSTITUTE_EFFECT
db MIMIC_EFFECT
db LEECH_SEED_EFFECT
db SPLASH_EFFECT
db -1
EffectsArray2: ; 3c011 (f:4011)
; moves that do damage but not through normal calculations
; e.g., Super Fang, Psywave
db SUPER_FANG_EFFECT
db SPECIAL_DAMAGE_EFFECT
db -1
EffectsArray3: ; 3c014 (f:4014)
; non-damaging, stataffecting or statuscausing moves?
; e.g., Meditate, Bide, Hypnosis
db $01
db ATTACK_UP1_EFFECT
db DEFENSE_UP1_EFFECT
db SPEED_UP1_EFFECT
db SPECIAL_UP1_EFFECT
db ACCURACY_UP1_EFFECT
db EVASION_UP1_EFFECT
db ATTACK_DOWN1_EFFECT
db DEFENSE_DOWN1_EFFECT
db SPEED_DOWN1_EFFECT
db SPECIAL_DOWN1_EFFECT
db ACCURACY_DOWN1_EFFECT
db EVASION_DOWN1_EFFECT
db BIDE_EFFECT
db SLEEP_EFFECT
db ATTACK_UP2_EFFECT
db DEFENSE_UP2_EFFECT
db SPEED_UP2_EFFECT
db SPECIAL_UP2_EFFECT
db ACCURACY_UP2_EFFECT
db EVASION_UP2_EFFECT
db ATTACK_DOWN2_EFFECT
db DEFENSE_DOWN2_EFFECT
db SPEED_DOWN2_EFFECT
db SPECIAL_DOWN2_EFFECT
db ACCURACY_DOWN2_EFFECT
db EVASION_DOWN2_EFFECT
db -1
EffectsArray4: ; 3c030 (f:4030)
; Attacks that aren't finished after they faint the opponent.
db DRAIN_HP_EFFECT
db EXPLODE_EFFECT
db DREAM_EATER_EFFECT
db PAY_DAY_EFFECT
db TWO_TO_FIVE_ATTACKS_EFFECT
db $1E
db ATTACK_TWICE_EFFECT
db RECOIL_EFFECT
db TWINEEDLE_EFFECT
db RAGE_EFFECT
db -1
EffectsArray5: ; 3c03b (f:403b)
db DRAIN_HP_EFFECT
db EXPLODE_EFFECT
db DREAM_EATER_EFFECT
db PAY_DAY_EFFECT
db SWIFT_EFFECT
db TWO_TO_FIVE_ATTACKS_EFFECT
db $1E
db CHARGE_EFFECT
db SUPER_FANG_EFFECT
db SPECIAL_DAMAGE_EFFECT
db FLY_EFFECT
db ATTACK_TWICE_EFFECT
db JUMP_KICK_EFFECT
db RECOIL_EFFECT
; fallthrough to Next EffectsArray
EffectsArray5B: ; 3c049 (f:4049)
; moves that prevent the player from switching moves?
db THRASH_PETAL_DANCE_EFFECT
db TRAPPING_EFFECT
db -1
2014-08-09 05:39:13 +00:00
SlidePlayerAndEnemySilhouettesOnScreen: ; 3c04c (f:404c)
call LoadPlayerBackPic
ld a, $1 ; the usual text box at the bottom of the screen
ld [wd125], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID
hlCoord 1, 5
2014-05-22 22:13:20 +00:00
ld bc, $307
call ClearScreenArea
call DisableLCD
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
2014-05-22 22:13:20 +00:00
ld a, $7f
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
2014-05-22 22:13:20 +00:00
ld hl, wTileMap
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-08-09 05:39:13 +00:00
ld [hVBlankWY], a
ld [rWY], a
2014-05-22 22:13:20 +00:00
xor a
ld [$ffd7], a
2014-08-09 05:39:13 +00:00
ld [hVBlankSCY], 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-08-09 05:39:13 +00:00
ld [hVBlankSCX], 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-08-09 05:39:13 +00:00
ld [hVBlankSCX], 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
ld [$ffe1], a
hlCoord 1, 5
predef Func_3f0c6
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [hVBlankWY], a
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
ld b, $1
call GoPAL_SET
2014-05-23 22:34:35 +00:00
call HideSprites
2014-05-22 22:13:20 +00:00
ld hl, PrintBeginningBattleText
ld b, BANK(PrintBeginningBattleText)
jp Bankswitch
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
SlidePlayerHeadLeft: ; 3c0ff (f:40ff)
2014-05-22 22:13:20 +00:00
push bc
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
2014-08-09 05:39:13 +00:00
SetScrollXForSlidingPlayerBodyLeft: ; 3c110 (f:4110)
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
2014-08-09 05:39:13 +00:00
StartBattle: ; 3c11e (f:411e)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [wPartyGainExpFlags], a
ld [wPartyFoughtCurrentEnemyFlags], a
ld [wcd6a], a
2014-05-22 22:13:20 +00:00
inc a
ld [wd11d], 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
ld [wcc3e], a
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
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
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
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
and a ; is it a normal battle?
jp z, .playerSendOutFirstMon ; if so, send out player mon
; safari zone battle
.displaySafariZoneBattleMenu
call DisplayBattleMenu
ret c ; return if the player ran from battle
ld a, [wcd6a]
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?
ld a, [W_NUMSAFARIBALLS]
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
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
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
ld [wcf91], a
ld [wBattleMonSpecies2], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
hlCoord 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
ld b, $1
push bc
2014-08-09 05:39:13 +00:00
ld hl, wPartyGainExpFlags
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
ld hl, wPartyFoughtCurrentEnemyFlags
2014-05-22 22:13:20 +00:00
pop bc
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
EnemyRan: ; 3c202 (f:4202)
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
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
ld a, (SFX_08_44 - SFX_Headers_08) / 3
call PlaySoundWaitForCurrent
xor a
2014-08-09 05:39:13 +00:00
ld [H_WHOSETURN], a
2014-05-22 22:13:20 +00:00
ld hl, AnimationSlideEnemyMonOut
ld b, BANK(AnimationSlideEnemyMonOut)
jp Bankswitch
WildRanText: ; 3c229 (f:4229)
TX_FAR _WildRanText
db "@"
EnemyRanText: ; 3c22e (f:422e)
TX_FAR _EnemyRanText
db "@"
MainInBattleLoop: ; 3c233 (f:4233)
call ReadPlayerMonCurHPAndStatus
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
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
ld [wd11d], a
ld a, [W_PLAYERBATTSTATUS2]
2014-08-09 05:39:13 +00:00
and %01100000 ; check if the player is using Rage or needs to recharge
jr nz, .selectEnemyMove
; the player is not using Rage and doesn't need to recharge
ld hl, W_ENEMYBATTSTATUS1
2014-08-09 05:39:13 +00:00
res 3, [hl] ; reset flinch bit
ld hl, W_PLAYERBATTSTATUS1
2014-08-09 05:39:13 +00:00
res 3, [hl] ; reset flinch bit
2014-05-22 22:13:20 +00:00
ld a, [hl]
2014-08-09 05:39:13 +00:00
and %00010010 ; check if the player is thrashing about or charging for an attack
jr nz, .selectEnemyMove ; if so, jump
; the player is neither thrashing about nor charging for an attack
call DisplayBattleMenu ; show battle menu
ret c ; return if player ran from battle
ld a, [wEscapedFromBattle]
and a
ret nz ; return if pokedoll was used to escape from battle
ld a, [wBattleMonStatus]
2014-08-09 05:39:13 +00:00
and (1 << FRZ) | SLP ; is mon frozen or asleep?
jr nz, .selectEnemyMove ; if so, jump
ld a, [W_PLAYERBATTSTATUS1]
2014-08-09 05:39:13 +00:00
and %00100001 ; check player is using Bide or using a multi-turn attack like wrap
jr nz, .selectEnemyMove ; if so, jump
ld a, [W_ENEMYBATTSTATUS1]
2014-08-09 05:39:13 +00:00
bit 5, a ; check if enemy is using a multi-turn attack like wrap
jr z, .selectPlayerMove ; if not, jump
; enemy is using a mult-turn attack like wrap, so player is trapped and cannot select a move
2014-05-22 22:13:20 +00:00
ld a, $ff
ld [wPlayerSelectedMove], a
2014-08-09 05:39:13 +00:00
jr .selectEnemyMove
.selectPlayerMove
ld a, [wcd6a]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr nz, .selectEnemyMove
ld [wMoveMenuType], a
2014-05-22 22:13:20 +00:00
inc a
ld [W_ANIMATIONID], 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
ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .noLinkBattle
2014-08-09 05:39:13 +00:00
; link battle
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
cp $f
2014-08-09 05:39:13 +00:00
jp z, EnemyRan
2014-05-22 22:13:20 +00:00
cp $e
jr z, .noLinkBattle
cp $d
jr z, .noLinkBattle
sub $4
jr c, .noLinkBattle
2014-08-09 05:39:13 +00:00
; the link battle enemy has switched mons
ld a, [W_PLAYERBATTSTATUS1]
2014-08-09 05:39:13 +00:00
bit 5, a ; check if using multi-turn move like Wrap
jr z, .asm_3c2dd
ld a, [wPlayerMoveListIndex]
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]
2014-08-09 05:39:13 +00:00
cp METRONOME
jr nz, .asm_3c2dd
2014-05-22 22:13:20 +00:00
ld [wPlayerSelectedMove], a
.asm_3c2dd
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
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
2014-05-22 22:13:20 +00:00
.speedEqual
ld a, [$ffaa]
cp $2
jr z, .invertOutcome
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $80
jr c, .playerMovesFirst
jr .enemyMovesFirst
.invertOutcome
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
jp z, HandlePlayerMonFainted
.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 CheckNumAttacksLeft
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 CheckNumAttacksLeft
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
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
ld [wcc5b], 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
2014-08-09 05:39:13 +00:00
ld de, W_PLAYERBATTSTATUS2
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .playersTurn2
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYBATTSTATUS2
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
ld [wcc5b], 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
2014-05-22 22:13:20 +00:00
ld c, $14
call DelayFrames
xor a
ret
HurtByPoisonText: ; 3c42e (f:442e)
TX_FAR _HurtByPoisonText
db "@"
HurtByBurnText: ; 3c433 (f:4433)
TX_FAR _HurtByBurnText
db "@"
HurtByLeechSeedText: ; 3c438 (f:4438)
TX_FAR _HurtByLeechSeedText
db "@"
; decreases the mon's current HP by 1/16 of the Max HP (multiplied by number of toxic ticks if active)
; note that the toxic ticks are considered even if the damage is not poison (hence the Leech Seed glitch)
; hl: HP pointer
; bc (out): total damage
HandlePoisonBurnLeechSeed_DecreaseOwnHP: ; 3c43d (f:443d)
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
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS3
ld de, W_PLAYERTOXICCOUNTER
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, W_ENEMYBATTSTATUS3
ld de, W_ENEMYTOXICCOUNTER
2014-05-22 22:13:20 +00:00
.playersTurn
bit 0, [hl]
jr z, .noToxic
ld a, [de] ; increment toxic counter
inc a
ld [de], a
ld hl, $0000
.toxicTicksLoop
add hl, bc
dec a
jr nz, .toxicTicksLoop
ld b, h ; bc = damage * toxic counter
ld c, l
.noToxic
pop hl
inc hl
ld a, [hl] ; subtract total damage from current HP
ld [wHPBarOldHP], a
sub c
ld [hld], a
ld [wHPBarNewHP], a
ld a, [hl]
ld [wHPBarOldHP+1], a
sbc b
ld [hl], a
ld [wHPBarNewHP+1], a
jr nc, .noOverkill
xor a ; overkill: zero HP
ld [hli], a
ld [hl], a
ld [wHPBarNewHP], a
ld [wHPBarNewHP+1], a
.noOverkill
call UpdateCurMonHPBar
pop hl
ret
; adds bc to enemy HP
HandlePoisonBurnLeechSeed_IncreaseEnemyHP: ; 3c4a3 (f:44a3)
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
ld de, $fff2
add hl, de ; skip back fomr max hp to current hp
ld a, [hl]
ld [wHPBarOldHP], a ; add bc to current HP
add c
ld [hld], a
ld [wHPBarNewHP], a
ld a, [hl]
ld [wHPBarOldHP+1], a
adc b
ld [hli], a
ld [wHPBarNewHP+1], a
ld a, [wHPBarMaxHP]
ld c, a
ld a, [hld]
sub c
ld a, [wHPBarMaxHP+1]
ld b, a
ld a, [hl]
sbc b
jr c, .noOverfullHeal
ld a, b ; overfull heal, set HP to max HP
ld [hli], a
ld [wHPBarNewHP+1], a
ld a, c
ld [hl], a
ld [wHPBarNewHP], a
.noOverfullHeal
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
UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
hlCoord 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
hlCoord 2, 2 ; tile pointer to enemy HP bar
2014-05-22 22:13:20 +00:00
xor a
.playersTurn
push bc
2014-08-09 05:39:13 +00:00
ld [wListMenuID], a
predef UpdateHPBar2
2014-05-22 22:13:20 +00:00
pop bc
ret
2014-08-09 05:39:13 +00:00
CheckNumAttacksLeft: ; 3c50f (f:450f)
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
ld hl, W_PLAYERBATTSTATUS1
res 5, [hl] ; player not using multi-turn attack like wrap any more
.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
ld hl, W_ENEMYBATTSTATUS1
res 5, [hl] ; enemy not using multi-turn attack like wrap any more
2014-05-22 22:13:20 +00:00
ret
HandleEnemyMonFainted: ; 3c525 (f:4525)
xor a
ld [wccf0], a
2014-05-22 22:13:20 +00:00
call FaintEnemyPokemon
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
ld a, [W_ISINBATTLE]
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 ChooseNextMon
.skipReplacingBattleMon
2014-05-22 22:13:20 +00:00
ld a, $1
ld [wcd6a], a
2014-08-09 05:39:13 +00:00
call ReplaceFaintedEnemyMon
jp z, EnemyRan
2014-05-22 22:13:20 +00:00
xor a
ld [wcd6a], a
2014-05-22 22:13:20 +00:00
jp MainInBattleLoop
FaintEnemyPokemon ; 0x3c567
call ReadPlayerMonCurHPAndStatus
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
2014-05-22 22:13:20 +00:00
dec a
jr z, .wild
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
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 2, [hl]
xor a
2014-08-09 05:39:13 +00:00
ld [W_NUMHITS], a
ld hl, wd065 ; 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
2014-08-09 05:39:13 +00:00
ld [W_ENEMYDISABLEDMOVE], a
ld [wccef], a
ld [wccf3], a
ld hl, wccf1
2014-05-22 22:13:20 +00:00
ld [hli], a
ld [hl], a
hlCoord 12, 5
deCoord 12, 6
2014-08-09 05:39:13 +00:00
call SlideDownFaintedMonPic
2014-05-22 22:13:20 +00:00
ld hl, wTileMap
ld bc, $40b
call ClearScreenArea
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
2014-05-22 22:13:20 +00:00
dec a
jr z, .wild_win
xor a
ld [wc0f1], a
ld [wc0f2], a
2014-05-22 22:13:20 +00:00
ld a, (SFX_08_48 - SFX_Headers_08) / 3 ; SFX_FALL?
call PlaySoundWaitForCurrent
.sfxwait
ld a, [wc02a]
2014-05-22 22:13:20 +00:00
cp (SFX_08_48 - SFX_Headers_08) / 3
jr z, .sfxwait
ld a, (SFX_08_43 - SFX_Headers_08) / 3 ; SFX_DROP
call PlaySound
call WaitForSoundToFinish
jr .sfxplayed
.wild_win
call Func_3c643
ld a, MUSIC_DEFEATED_WILD_MON
call PlayBattleVictoryMusic
.sfxplayed
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
ld a, [wccf0]
2014-05-22 22:13:20 +00:00
and a
jr nz, .playermonnotfaint
2014-08-09 05:39:13 +00:00
call RemoveFaintedPlayerMon
2014-05-22 22:13:20 +00:00
.playermonnotfaint
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
2014-05-22 22:13:20 +00:00
ld b, EXP__ALL
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
ld [wcc5b], 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
ld [wcc5b], 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
2014-05-22 22:13:20 +00:00
ld hl, GainExperience
ld b, BANK(GainExperience)
jp Bankswitch
EnemyMonFaintedText: ; 0x3c63e
TX_FAR _EnemyMonFaintedText
db "@"
Func_3c643: ; 3c643 (f:4643)
xor a
ld [wd083], a
ld [wc02a], a
2014-05-22 22:13:20 +00:00
inc a
ld [wccf6], a
2014-05-22 22:13:20 +00:00
ret
AnyEnemyPokemonAliveCheck: ; 3c64f (f:464f)
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
2014-05-22 22:13:20 +00:00
ld de, $2c
.asm_3c65a
or [hl]
inc hl
or [hl]
dec hl
add hl, de
dec b
jr nz, .asm_3c65a
and a
ret
2014-08-09 05:39:13 +00:00
; stores whether enemy ran in Z flag
ReplaceFaintedEnemyMon: ; 3c664 (f:4664)
ld hl, wcf1e
2014-05-22 22:13:20 +00:00
ld e, $30
call GetBattleHealthBarColor
callab DrawEnemyPokeballs
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr nz, .asm_3c687
2014-08-09 05:39:13 +00:00
; link battle
call LinkBattleExchangeData
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
cp $f
ret z
call LoadScreenTilesFromBuffer1
.asm_3c687
call EnemySendOut
xor a
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVENUM], a
ld [wcd6a], a
ld [wccd5], a
2014-08-09 05:39:13 +00:00
inc a ; reset Z flag
2014-05-22 22:13:20 +00:00
ret
TrainerBattleVictory: ; 3c696 (f:4696)
call Func_3c643
ld b, MUSIC_DEFEATED_GYM_LEADER
2014-08-09 05:39:13 +00:00
ld a, [W_GYMLEADERNO]
2014-05-22 22:13:20 +00:00
and a
jr nz, .gymleader
ld b, MUSIC_DEFEATED_TRAINER
.gymleader
2014-08-09 05:39:13 +00:00
ld a, [W_TRAINERCLASS]
2014-05-22 22:13:20 +00:00
cp SONY3 ; final battle against rival
jr nz, .notrival
ld b, MUSIC_DEFEATED_GYM_LEADER
ld hl, W_FLAGS_D733
set 1, [hl]
.notrival
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
ld a, b
call nz, PlayBattleVictoryMusic
ld hl, TrainerDefeatedText
call PrintText
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
ret z
call ScrollTrainerPicAfterBattle
ld c, $28
call DelayFrames
call Func_3381
ld hl, MoneyForWinningText
call PrintText
2014-08-09 05:39:13 +00:00
ld de, wPlayerMoney + 2
ld hl, wd07b
2014-05-22 22:13:20 +00:00
ld c, $3
predef_jump AddBCDPredef
2014-05-22 22:13:20 +00:00
MoneyForWinningText: ; 3c6e4 (f:46e4)
TX_FAR _MoneyForWinningText
db "@"
TrainerDefeatedText: ; 3c6e9 (f:46e9)
TX_FAR _TrainerDefeatedText
db "@"
PlayBattleVictoryMusic: ; 3c6ee (f:46ee)
push af
ld a, $ff
ld [wc0ee], a
2014-05-22 22:13:20 +00:00
call PlaySoundWaitForCurrent
ld c, BANK(Music_DefeatedTrainer)
pop af
call PlayMusic
jp Delay3
HandlePlayerMonFainted: ; 3c700 (f:4700)
ld a, $1
ld [wccf0], a
2014-08-09 05:39:13 +00:00
call RemoveFaintedPlayerMon
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
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
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 ChooseNextMon
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
ld [wcd6a], 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
ld [wcd6a], 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
RemoveFaintedPlayerMon: ; 3c741 (f:4741)
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
2014-05-22 22:13:20 +00:00
ld b, $0
2014-08-09 05:39:13 +00:00
predef FlagActionPredef ; clear gain exp flag for fainted mon
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 2, [hl] ; reset "attacking multiple times" flag
ld a, [wd083]
2014-05-22 22:13:20 +00:00
bit 7, a ; skip sound flag (red bar (?))
jr z, .skipWaitForSound
ld a, $ff
ld [wd083], a
2014-05-22 22:13:20 +00:00
call WaitForSoundToFinish
.skipWaitForSound
ld hl, wcd05
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
hlCoord 9, 7
2014-05-22 22:13:20 +00:00
ld bc, $50b
call ClearScreenArea
hlCoord 1, 10
deCoord 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
ld a, [wccf0]
2014-05-22 22:13:20 +00:00
and a
ret z
ld a, [wBattleMonSpecies]
2014-05-22 22:13:20 +00:00
call PlayCry
ld hl, PlayerMonFaintedText
jp PrintText
PlayerMonFaintedText: ; 3c796 (f:4796)
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
DoUseNextMonDialogue: ; 3c79b (f:479b)
call PrintEmptyString
2014-05-22 22:13:20 +00:00
call SaveScreenTilesToBuffer1
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
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
hlCoord 13, 9
2014-05-22 22:13:20 +00:00
ld bc, $a0e
2014-08-09 05:39:13 +00:00
ld a, $14 ; yes/no text box
ld [wd125], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID
ld a, [wd12e]
2014-08-09 05:39:13 +00:00
cp $2 ; did the player choose NO?
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?
ld hl, wPartyMon1Speed
ld de, wEnemyMonSpeed
2014-08-09 05:39:13 +00:00
jp TryRunningFromBattle
2014-05-22 22:13:20 +00:00
UseNextMonText: ; 3c7d3 (f:47d3)
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
ChooseNextMon: ; 3c7d8 (f:47d8)
2014-05-22 22:13:20 +00:00
ld a, $2
ld [wd07d], a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
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
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr nz, .asm_3c7fa
inc a
ld [wcd6a], a
2014-08-09 05:39:13 +00:00
call LinkBattleExchangeData
2014-05-22 22:13:20 +00:00
.asm_3c7fa
xor a
ld [wcd6a], a
2014-05-23 22:34:35 +00:00
call ClearSprites
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
2014-05-22 22:13:20 +00:00
ld b, $1
push bc
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
ld hl, wPartyFoughtCurrentEnemyFlags
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
call GoPAL_SET_CF1C
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)
HandlePlayerBlackOut: ; 3c837 (f:4837)
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr z, .notSony1Battle
2014-08-09 05:39:13 +00:00
ld a, [W_CUROPPONENT]
2014-05-22 22:13:20 +00:00
cp $c8 + SONY1
jr nz, .notSony1Battle
ld hl, wTileMap ; sony 1 battle
ld bc, $815
call ClearScreenArea
call ScrollTrainerPicAfterBattle
ld c, $28
call DelayFrames
ld hl, Sony1WinText
call PrintText
ld a, [W_CURMAP]
cp OAKS_LAB
ret z ; starter battle in oak's lab: don't black out
.notSony1Battle
ld b, $0
call GoPAL_SET
ld hl, PlayerBlackedOutText2
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr nz, .noLinkBattle
ld hl, LinkBattleLostText
.noLinkBattle
call PrintText
ld a, [wd732]
2014-05-22 22:13:20 +00:00
res 5, a
ld [wd732], a
2014-05-22 22:13:20 +00:00
call ClearScreen
scf
ret
Sony1WinText: ; 3c884 (f:4884)
TX_FAR _Sony1WinText
db "@"
PlayerBlackedOutText2: ; 3c889 (f:4889)
TX_FAR _PlayerBlackedOutText2
db "@"
LinkBattleLostText: ; 3c88e (f:488e)
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
SlideDownFaintedMonPic: ; 3c893 (f:4893)
ld a, [wd730]
2014-05-22 22:13:20 +00:00
push af
set 6, a
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
2014-08-09 05:39:13 +00:00
ld bc, -20
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
ld bc, 20
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
ld [wd730], a
2014-05-22 22:13:20 +00:00
ret
SevenSpacesText: ; 3c8d7 (f:48d7)
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
SlideTrainerPicOffScreen: ; 3c8df (f:48df)
ld [$FF8B], 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
2014-08-09 05:39:13 +00:00
ld a, [$FF8B]
2014-05-22 22:13:20 +00:00
ld c, a
2014-08-09 05:39:13 +00:00
.columnLoop
ld a, [$FF8B]
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
2014-05-22 22:13:20 +00:00
EnemySendOut: ; 3c90e (f:490e)
2014-08-09 05:39:13 +00:00
ld hl,wPartyGainExpFlags
2014-05-22 22:13:20 +00:00
xor a
ld [hl],a
ld a,[wPlayerMonNumber]
2014-05-22 22:13:20 +00:00
ld c,a
ld b,1
push bc
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
predef FlagActionPredef
2014-08-09 05:39:13 +00:00
; don't change wPartyGainExpFlags or wPartyFoughtCurrentEnemyFlags
EnemySendOutFirstMon: ; 3c92a (f:492a)
2014-05-22 22:13:20 +00:00
xor a
ld hl,wd065
2014-05-22 22:13:20 +00:00
ld [hli],a
ld [hli],a
ld [hli],a
ld [hli],a
ld [hl],a
ld [W_ENEMYDISABLEDMOVE],a
ld [wccef],a
ld [wccf3],a
ld hl,wccf1
2014-05-22 22:13:20 +00:00
ld [hli],a
ld [hl],a
dec a
ld [wAICount],a
ld hl,W_PLAYERBATTSTATUS1
res 5,[hl]
hlCoord 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
ld a,[W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp 4
jr nz,.next
ld a,[wcc3e]
2014-05-22 22:13:20 +00:00
sub 4
ld [wWhichPokemon],a
jr .next3
.next
ld b,$FF
.next2
inc b
ld a,[wEnemyMonPartyPos]
2014-05-22 22:13:20 +00:00
cp b
jr z,.next2
ld hl,wEnemyMon1
2014-05-22 22:13:20 +00:00
ld a,b
ld [wWhichPokemon],a
push bc
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]
ld hl,wEnemyMon1Level
ld bc,wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a,[hl]
ld [W_CURENEMYLVL],a
2014-05-22 22:13:20 +00:00
ld a,[wWhichPokemon]
inc a
ld hl,wEnemyPartyCount
2014-05-22 22:13:20 +00:00
ld c,a
ld b,0
add hl,bc
ld a,[hl]
ld [wEnemyMonSpecies2],a
ld [wcf91],a
2014-08-09 05:39:13 +00:00
call LoadEnemyMonData
ld hl,wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld [wcce3],a
2014-05-22 22:13:20 +00:00
ld a,[hl]
ld [wcce4],a
2014-05-22 22:13:20 +00:00
ld a,1
ld [wCurrentMenuItem],a
ld a,[wd11d]
2014-05-22 22:13:20 +00:00
dec a
jr z,.next4
ld a,[wPartyCount]
2014-05-22 22:13:20 +00:00
dec a
jr z,.next4
ld a,[W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp 4
jr z,.next4
ld a,[W_OPTIONS]
2014-05-22 22:13:20 +00:00
bit 6,a
jr nz,.next4
ld hl, TrainerAboutToUseText
call PrintText
hlCoord 0, 7
2014-05-22 22:13:20 +00:00
ld bc,$0801
ld a,$14
ld [wd125],a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID
ld a,[wCurrentMenuItem]
2014-05-22 22:13:20 +00:00
and a
jr nz,.next4
ld a,2
ld [wd07d],a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
.next9
ld a,1
ld [wCurrentMenuItem],a
2014-05-22 22:13:20 +00:00
jr c,.next7
ld hl,wPlayerMonNumber
2014-05-22 22:13:20 +00:00
ld a,[wWhichPokemon]
cp [hl]
jr nz,.next6
ld hl,AlreadyOutText
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
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 ClearSprites
2014-05-22 22:13:20 +00:00
ld hl,wTileMap
ld bc,$040B
call ClearScreenArea
ld b,1
call GoPAL_SET
call GBPalNormal
ld hl,TrainerSentOutText
call PrintText
ld a,[wEnemyMonSpecies2]
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
ld a,$CF
ld [$FFE1],a
hlCoord 15, 6
predef Func_3f073
ld a,[wEnemyMonSpecies2]
2014-05-22 22:13:20 +00:00
call PlayCry
2014-08-09 05:39:13 +00:00
call DrawEnemyHUDAndHPBar
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
TrainerAboutToUseText: ; 3ca79 (f:4a79)
TX_FAR _TrainerAboutToUseText
db "@"
TrainerSentOutText: ; 3ca7e (f:4a7e)
TX_FAR _TrainerSentOutText
db "@"
; tests if the player has any pokemon that are not fainted
; sets d = 0 if all fainted, d != 0 if some mons are still alive
AnyPartyAlive: ; 3ca83 (f:4a83)
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
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
HasMonFainted: ; 3ca97 (f:4a97)
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
ld a, [wd11d]
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
NoWillText: ; 3cab4 (f:4ab4)
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
TryRunningFromBattle: ; 3cab9 (f:4ab9)
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
ld a, [W_BATTLETYPE]
2014-05-22 22:13:20 +00:00
cp $2
2014-08-09 05:39:13 +00:00
jp z, .canEscape ; jump if it's a safari battle
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
2014-08-09 05:39:13 +00:00
jp z, .canEscape
ld a, [W_ISINBATTLE]
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]
ld [$ff8d], a
inc de
ld a, [de]
ld [$ff8e], a
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
ld de, H_MULTIPLICAND + 1
2014-05-22 22:13:20 +00:00
ld hl, $ff8d
ld c, $2
call StringCmp
2014-08-09 05:39:13 +00:00
jr nc, .canEscape ; jump if player speed greater than enemy speed
xor a
ld [H_MULTIPLICAND], a
ld a, 32
ld [H_MULTIPLIER], a
call Multiply ; multiply player speed by 32
ld a, [H_PRODUCT + 2]
ld [H_DIVIDEND], a
ld a, [H_PRODUCT + 3]
ld [H_DIVIDEND + 1], a
2014-05-22 22:13:20 +00:00
ld a, [$ff8d]
ld b, a
ld a, [$ff8e]
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 Divide ; divide (player speed * 32) by ((enemy speed / 4) % 256)
ld a, [H_QUOTIENT + 2]
and a ; is the quotient greater than 256?
jr nz, .canEscape ; if so, the player can escape
ld a, [wNumRunAttempts]
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
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
2014-08-09 05:39:13 +00:00
jr nc, .canEscape ; if the random value was less than or equal to the quotient plus 30 times the number of attempts, the player can escape
; can't escape
2014-05-22 22:13:20 +00:00
ld a, $1
ld [wcd6a], a
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
ld a, $1
ld [wd11f], 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
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
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
ld [wcd6a], a
2014-05-22 22:13:20 +00:00
ld a, $f
2014-08-09 05:39:13 +00:00
ld [wPlayerMoveListIndex], a
call LinkBattleExchangeData
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
cp $f
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
2014-05-22 22:13:20 +00:00
ld a, (SFX_08_44 - SFX_Headers_08) / 3
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
CantEscapeText: ; 3cb97 (f:4b97)
TX_FAR _CantEscapeText
db "@"
NoRunningText: ; 3cb9c (f:4b9c)
TX_FAR _NoRunningText
db "@"
GotAwayText: ; 3cba1 (f:4ba1)
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
LoadBattleMonFromParty: ; 3cba6 (f:4ba6)
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
ld bc, $2c
2014-08-09 05:39:13 +00:00
ld hl, wPartyMon1Species
2014-05-22 22:13:20 +00:00
call AddNTimes
ld de, wBattleMonSpecies
2014-05-22 22:13:20 +00:00
ld bc, $c
call CopyData
ld bc, $f
add hl, bc
ld de, wBattleMonDVs
2014-05-22 22:13:20 +00:00
ld bc, $2
call CopyData
2014-08-09 05:39:13 +00:00
ld de, wBattleMonPP
2014-05-22 22:13:20 +00:00
ld bc, $4
call CopyData
2014-08-09 05:39:13 +00:00
ld de, wBattleMonLevel
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
ld a, [wBattleMonSpecies2]
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
ld de, wBattleMonNick
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
2014-08-09 05:39:13 +00:00
ld hl, wBattleMonLevel
ld de, wPlayerMonUnmodifiedLevel ; block of memory used for unmodified stats
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
2014-08-09 05:39:13 +00:00
call ApplyBurnAndParalysisPenaltiesToPlayer
call ApplyBadgeStatBoosts
ld a, $7 ; default stat modifier
2014-05-22 22:13:20 +00:00
ld b, $8
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
LoadEnemyMonFromParty: ; 3cc13 (f:4c13)
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
ld bc, $2c
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMons
2014-05-22 22:13:20 +00:00
call AddNTimes
ld de, wEnemyMonSpecies
2014-05-22 22:13:20 +00:00
ld bc, $c
call CopyData
ld bc, $f
add hl, bc
ld de, wEnemyMonDVs
2014-05-22 22:13:20 +00:00
ld bc, $2
call CopyData
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonPP
2014-05-22 22:13:20 +00:00
ld bc, $4
call CopyData
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonLevel
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
ld hl, wEnemyMonNicks
2014-08-09 05:39:13 +00:00
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
call SkipFixedLengthTextEntries
ld de, wEnemyMonNick
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonLevel
ld de, wEnemyMonUnmodifiedLevel ; block of memory used for unmodified stats
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
2014-08-09 05:39:13 +00:00
call ApplyBurnAndParalysisPenaltiesToEnemy
2014-05-22 22:13:20 +00:00
ld hl, W_MONHBASESTATS
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonBaseStats
2014-05-22 22:13:20 +00:00
ld b, $5
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
2014-05-22 22:13:20 +00:00
ld b, $8
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]
ld [wEnemyMonPartyPos], a
2014-05-22 22:13:20 +00:00
ret
2014-08-09 05:39:13 +00:00
SendOutMon: ; 3cc91 (f:4c91)
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
predef LoadMonBackPic
2014-05-22 22:13:20 +00:00
xor a
ld [$ffe1], a
ld hl, wcc2d
2014-05-22 22:13:20 +00:00
ld [hli], a
ld [hl], a
ld [wcc5b], a
ld [wd05b], a
2014-08-09 05:39:13 +00:00
ld [W_PLAYERMOVENUM], a
ld hl, wccf1
2014-05-22 22:13:20 +00:00
ld [hli], a
ld [hl], a
ld hl, wd060
2014-05-22 22:13:20 +00:00
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
2014-08-09 05:39:13 +00:00
ld [W_PLAYERDISABLEDMOVE], a
ld [wccee], a
ld [wccf7], a
2014-05-22 22:13:20 +00:00
ld b, $1
call GoPAL_SET
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 5, [hl]
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
hlCoord 4, 11
predef Func_3f073
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
2014-08-09 05:39:13 +00:00
; show 2 stages of the player getting smaller before disappearing
AnimateRetreatingPlayerMon: ; 3ccfa (f:4cfa)
hlCoord 1, 5
2014-05-22 22:13:20 +00:00
ld bc, $707
call ClearScreenArea
hlCoord 3, 7
2014-05-22 22:13:20 +00:00
ld bc, $505
xor a
ld [wcd6c], a
2014-08-09 05:39:13 +00:00
ld [H_DOWNARROWBLINKCNT1], a
predef Func_79aba
2014-05-22 22:13:20 +00:00
ld c, $4
call DelayFrames
2014-08-09 05:39:13 +00:00
call .clearScreenArea
hlCoord 4, 9
2014-05-22 22:13:20 +00:00
ld bc, $303
ld a, $1
ld [wcd6c], a
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [H_DOWNARROWBLINKCNT1], a
predef Func_79aba
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, $4c
Coorda 5, 11
2014-08-09 05:39:13 +00:00
.clearScreenArea
hlCoord 1, 5
2014-05-22 22:13:20 +00:00
ld bc, $707
jp ClearScreenArea
; reads player's current mon's HP into wBattleMonHP
2014-05-22 22:13:20 +00:00
ReadPlayerMonCurHPAndStatus: ; 3cd43 (f:4d43)
2014-08-09 05:39:13 +00:00
ld a, [wPlayerMonNumber]
ld hl, wPartyMon1HP
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
2014-08-09 05:39:13 +00:00
DrawHUDsAndHPBars: ; 3cd5a (f:4d5a)
call DrawPlayerHUDAndHPBar
jp DrawEnemyHUDAndHPBar
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
DrawPlayerHUDAndHPBar: ; 3cd60 (f:4d60)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [H_AUTOBGTRANSFERENABLED], a
hlCoord 9, 7
2014-05-22 22:13:20 +00:00
ld bc, $50b
call ClearScreenArea
callab PlacePlayerHUDTiles
hlCoord 18, 9
2014-05-22 22:13:20 +00:00
ld [hl], $73
ld de, wBattleMonNick
hlCoord 10, 7
2014-08-09 05:39:13 +00:00
call CenterMonName
2014-05-22 22:13:20 +00:00
call PlaceString
ld hl, wBattleMonSpecies
ld de, wcf98
2014-05-22 22:13:20 +00:00
ld bc, $c
call CopyData
2014-08-09 05:39:13 +00:00
ld hl, wBattleMonLevel
ld de, wcfb9
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
hlCoord 14, 8
2014-05-22 22:13:20 +00:00
push hl
inc hl
ld de, wcf9c
2014-05-22 22:13:20 +00:00
call PrintStatusConditionNotFainted
pop hl
jr nz, .asm_3cdae
call PrintLevel
.asm_3cdae
ld a, [wcf98]
ld [wcf91], a
hlCoord 10, 9
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
ld hl, wcf1d
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]
jr z, .asm_3cdd9
ld a, [wccf6]
2014-05-22 22:13:20 +00:00
and a
ret nz
ld a, [wcf1d]
2014-05-22 22:13:20 +00:00
cp $2
jr z, .asm_3cde6
.asm_3cdd9
ld hl, wd083
2014-05-22 22:13:20 +00:00
bit 7, [hl]
ld [hl], $0
ret z
xor a
ld [wc02a], a
2014-05-22 22:13:20 +00:00
ret
.asm_3cde6
ld hl, wd083
2014-05-22 22:13:20 +00:00
set 7, [hl]
ret
2014-08-09 05:39:13 +00:00
DrawEnemyHUDAndHPBar: ; 3cdec (f:4dec)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [H_AUTOBGTRANSFERENABLED], a
2014-05-22 22:13:20 +00:00
ld hl, wTileMap
ld bc, $40c
call ClearScreenArea
callab PlaceEnemyHUDTiles
ld de, wEnemyMonNick
hlCoord 1, 0
2014-08-09 05:39:13 +00:00
call CenterMonName
2014-05-22 22:13:20 +00:00
call PlaceString
hlCoord 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]
ld [wcfb9], 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 Divide ; 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
2014-08-09 05:39:13 +00:00
ld [wListMenuID], a
hlCoord 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
ld hl, wcf1e
2014-05-22 22:13:20 +00:00
GetBattleHealthBarColor: ; 3ce90 (f:4e90)
ld b, [hl]
call GetHealthBarColor
ld a, [hl]
cp b
ret z
ld b, $1
jp GoPAL_SET
2014-08-09 05:39:13 +00:00
; center's mon's name on the battle screen
; if the name is 1 or 2 letters long, it is printed 2 spaces more to the right than usual (i.e. for names longer than 4 letters)
; if the name is 3 or 4 letters long, it is printed 1 space more to the right than usual (i.e. for names longer than 4 letters)
CenterMonName: ; 3ce9c (f:4e9c)
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]
cp $50
2014-08-09 05:39:13 +00:00
jr z, .done
2014-05-22 22:13:20 +00:00
inc de
ld a, [de]
cp $50
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
2014-08-09 05:39:13 +00:00
DisplayBattleMenu: ; 3ceb3 (f:4eb3)
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1 ; restore saved screen
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
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
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
2014-05-22 22:13:20 +00:00
cp $2 ; safari
ld a, $b ; safari menu id
jr nz, .menuselected
ld a, $1b ; regular menu id
.menuselected
ld [wd125], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
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
ld de, W_GRASSRATE
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData ; temporarily save the player name in unused space,
; which is supposed to get overwritten when entering a
; map with wild pokémon. due to an oversight, the data
; may not get overwritten (cinnabar) and the infamous
; missingno. glitch can show up.
2014-08-09 05:39:13 +00:00
ld hl, .oldManName
ld de, wPlayerName
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
; the following simulates the keystrokes by drawing menus on screen
hlCoord 9, 14
2014-05-22 22:13:20 +00:00
ld [hl], "▶"
ld c, $50
call DelayFrames
ld [hl], $7f
hlCoord 9, 16
2014-05-22 22:13:20 +00:00
ld [hl], "▶"
ld c, $32
call DelayFrames
ld [hl], $ec
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
ld a, [wcc2d]
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
ld a, [W_BATTLETYPE]
2014-05-22 22:13:20 +00:00
cp $2
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
Coorda 13, 14
Coorda 13, 16
hlCoord 7, 14
2014-08-09 05:39:13 +00:00
ld de, W_NUMSAFARIBALLS
2014-05-22 22:13:20 +00:00
ld bc, $102
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
ld a, [W_BATTLETYPE]
2014-05-22 22:13:20 +00:00
cp $2
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
hlCoord 7, 14
2014-08-09 05:39:13 +00:00
ld de, W_NUMSAFARIBALLS
2014-05-22 22:13:20 +00:00
ld bc, $102
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
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
cp $2 ; is it a Safari battle?
ld a, [wCurrentMenuItem]
ld [wcc2d], a
2014-08-09 05:39:13 +00:00
jr z, .handleMenuSelection
; not Safari battle
; swap the IDs of the item menu and party menu (this is probably because they swapped the positions of these menu items in first generation English versions)
cp $1 ; was the item menu selected?
jr nz, .notItemMenu
; item menu was selected
inc a ; increment a to 2
jr .handleMenuSelection
.notItemMenu
cp $2 ; was the party menu selected?
jr nz, .handleMenuSelection
; party menu selected
dec a ; decrement a to 1
.handleMenuSelection
and a
jr nz, .upperLeftMenuItemWasNotSelected
; the upper left menu item was selected
ld a, [W_BATTLETYPE]
2014-05-22 22:13:20 +00:00
cp $2
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
ld [wcf91], a
2014-08-09 05:39:13 +00:00
jr .useItem
.upperLeftMenuItemWasNotSelected ; a menu item other than the upper left item was selected
2014-05-22 22:13:20 +00:00
cp $2
2014-08-09 05:39:13 +00:00
jp nz, .partyMenuOrRockOrRunWasSelected
; either the bag (normal battle) or bait (safari battle) was selected
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
2014-08-09 05:39:13 +00:00
jr nz, .notLinkBattle
; can't use items in link battles
ld hl, .itemsCantBeUsedHereText
2014-05-22 22:13:20 +00:00
call PrintText
2014-08-09 05:39:13 +00:00
jp DisplayBattleMenu
.notLinkBattle
call SaveScreenTilesToBuffer2
ld a, [W_BATTLETYPE]
cp $2 ; is it a safari battle?
jr nz, .bagWasSelected
; bait was selected
2014-05-22 22:13:20 +00:00
ld a, SAFARI_BAIT
ld [wcf91], a
2014-08-09 05:39:13 +00:00
jr .useItem
.bagWasSelected
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
and a ; is it a normal battle?
jr nz, .next
; normal battle
call DrawHUDsAndHPBars
.next
ld a, [W_BATTLETYPE]
dec a ; is it the old man tutorial?
jr nz, .getPlayerBagPointer ; no, it is a normal battle
ld hl, .oldManItemList
2014-05-22 22:13:20 +00:00
ld a, l
ld [wcf8b], a
2014-05-22 22:13:20 +00:00
ld a, h
ld [wcf8c], a
2014-08-09 05:39:13 +00:00
jr .displayBagMenu
.oldManItemList
2014-05-22 22:13:20 +00:00
db $01, POKE_BALL, 50, $ff
2014-08-09 05:39:13 +00:00
.getPlayerBagPointer ; get the pointer to player's bag when in a normal battle
ld hl, wNumBagItems
2014-05-22 22:13:20 +00:00
ld a, l
ld [wcf8b], a
2014-05-22 22:13:20 +00:00
ld a, h
ld [wcf8c], a
2014-08-09 05:39:13 +00:00
.displayBagMenu
2014-05-22 22:13:20 +00:00
xor a
ld [wcf93], a
2014-08-09 05:39:13 +00:00
ld a, ITEMLISTMENU
ld [wListMenuID], a
ld a, [wcc2c]
2014-08-09 05:39:13 +00:00
ld [wCurrentMenuItem], a
2014-05-22 22:13:20 +00:00
call DisplayListMenuID
2014-08-09 05:39:13 +00:00
ld a, [wCurrentMenuItem]
ld [wcc2c], a
2014-05-22 22:13:20 +00:00
ld a, $0
ld [wcc37], a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap], a
jp c, DisplayBattleMenu ; go back to battle menu if an item was not selected
.useItem ; either use an item from the bag or use a safari zone item
ld a, [wcf91]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetItemName
call CopyStringToCF4B ; copy name
xor a
ld [wd152], 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 ClearSprites
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [wCurrentMenuItem], a
ld a, [W_BATTLETYPE]
cp $2 ; is it a safari battle?
jr z, .checkIfMonCaptured
ld a, [wcd6a]
2014-08-09 05:39:13 +00:00
and a ; was the item used successfully?
jp z, .bagWasSelected ; if not, go back to the bag menu
ld a, [W_PLAYERBATTSTATUS1]
bit 5, a ; is the player using a multi-turn move like wrap?
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
ld hl, W_PLAYERBATTSTATUS1
res 5, [hl] ; not using multi-turn move any more
.checkIfMonCaptured
ld a, [wd11c]
2014-08-09 05:39:13 +00:00
and a ; was the enemy mon captured with a ball?
jr nz, .returnAfterCapturingMon
ld a, [W_BATTLETYPE]
cp $2 ; is it a safari battle?
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-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-08-09 05:39:13 +00:00
.returnAfterCapturingMon
2014-05-22 22:13:20 +00:00
call GBPalNormal
xor a
ld [wd11c], 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-08-09 05:39:13 +00:00
.itemsCantBeUsedHereText
2014-05-22 22:13:20 +00:00
TX_FAR _ItemsCantBeUsedHereText
db "@"
2014-08-09 05:39:13 +00:00
.partyMenuOrRockOrRunWasSelected
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
2014-08-09 05:39:13 +00:00
ld a, [W_BATTLETYPE]
cp $2 ; is it a safari battle?
jr nz, .partyMenuWasSelected
; safari battle
2014-05-22 22:13:20 +00:00
ld a, SAFARI_ROCK
ld [wcf91], a
2014-08-09 05:39:13 +00:00
jp .useItem
.partyMenuWasSelected
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
xor a
ld [wd07d], a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap], a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
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 ClearSprites
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
call GoPAL_SET_CF1C
call GBPalNormal
2014-08-09 05:39:13 +00:00
jp DisplayBattleMenu
.partyMonDeselected
hlCoord 11, 11
2014-05-22 22:13:20 +00:00
ld bc, $81
ld a, $7f
call FillMemory
xor a
ld [wd07d], a
2014-05-22 22:13:20 +00:00
call GoBackToPartyMenu
2014-08-09 05:39:13 +00:00
jr .checkIfPartyMonWasSelected
.partyMonWasSelected
ld a, $c ; switch/stats/cancel menu
ld [wd125], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID
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
2014-05-22 22:13:20 +00:00
xor a
ld [wcc49], a
2014-08-09 05:39:13 +00:00
ld hl, wPartyMon1
2014-05-23 22:34:35 +00:00
call ClearSprites
2014-08-09 05:39:13 +00:00
; display the two status screens
predef StatusScreen
predef StatusScreen2
2014-08-09 05:39:13 +00:00
; now we need to reload the enemy mon pic
ld a, [W_ENEMYBATTSTATUS2]
bit 4, 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
ld a, [wccf3]
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
ld a, [wEnemyMonSpecies]
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, AlreadyOutText
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
ld [wcd6a], a
2014-05-22 22:13:20 +00:00
call GBPalWhiteOut
2014-05-23 22:34:35 +00:00
call ClearSprites
2014-08-09 05:39:13 +00:00
call LoadHudTilePatterns
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
call GoPAL_SET_CF1C
call GBPalNormal
2014-08-09 05:39:13 +00:00
; fall through to SwitchPlayerMon
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
SwitchPlayerMon: ; 3d1ba (f:51ba)
2014-05-22 22:13:20 +00:00
callab RetreatMon
ld c, $32
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
ld b, $1
push bc
2014-08-09 05:39:13 +00:00
ld hl, wPartyGainExpFlags
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
pop bc
2014-08-09 05:39:13 +00:00
ld hl, wPartyFoughtCurrentEnemyFlags
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
AlreadyOutText: ; 3d1f5 (f:51f5)
TX_FAR _AlreadyOutText
db "@"
2014-08-09 05:39:13 +00:00
BattleMenu_RunWasSelected: ; 3d1fa (f:51fa)
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1
ld a, $3
2014-08-09 05:39:13 +00:00
ld [wCurrentMenuItem], a
ld hl, wBattleMonSpeed
ld de, wEnemyMonSpeed
2014-08-09 05:39:13 +00:00
call TryRunningFromBattle
2014-05-22 22:13:20 +00:00
ld a, $0
ld [wd11f], a
2014-05-22 22:13:20 +00:00
ret c
ld a, [wcd6a]
2014-05-22 22:13:20 +00:00
and a
ret nz
2014-08-09 05:39:13 +00:00
jp DisplayBattleMenu
2014-05-22 22:13:20 +00:00
MoveSelectionMenu: ; 3d219 (f:5219)
ld a, [wMoveMenuType]
dec a
jr z, .mimicmenu
dec a
jr z, .relearnmenu
jr .regularmenu
.loadmoves
ld de, wd0dc
2014-05-22 22:13:20 +00:00
ld bc, $4
call CopyData
callab Func_39b87
ret
.writemoves
ld de, wd0e1
2014-05-22 22:13:20 +00:00
ld a, [$fff6]
set 2, a
ld [$fff6], a
call PlaceString
ld a, [$fff6]
res 2, a
ld [$fff6], a
ret
.regularmenu
call Func_3d3f5
ret z
ld hl, wBattleMonMoves
2014-05-22 22:13:20 +00:00
call .loadmoves
hlCoord 4, 12
2014-05-22 22:13:20 +00:00
ld b, $4
ld c, $e
di
call TextBoxBorder
hlCoord 4, 12
2014-05-22 22:13:20 +00:00
ld [hl], $7a
hlCoord 10, 12
2014-05-22 22:13:20 +00:00
ld [hl], $7e
ei
hlCoord 6, 13
2014-05-22 22:13:20 +00:00
call .writemoves
ld b, $5
ld a, $c
jr .menuset
.mimicmenu
ld hl, wEnemyMonMoves
2014-05-22 22:13:20 +00:00
call .loadmoves
hlCoord 0, 7
2014-05-22 22:13:20 +00:00
ld b, $4
ld c, $e
call TextBoxBorder
hlCoord 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
2014-05-22 22:13:20 +00:00
ld bc, $2c
call AddNTimes
call .loadmoves
hlCoord 4, 7
2014-05-22 22:13:20 +00:00
ld b, $4
ld c, $e
call TextBoxBorder
hlCoord 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
2014-05-22 22:13:20 +00:00
ld [hli], a
ld a, b
2014-08-09 05:39:13 +00:00
ld [hli], a
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
2014-08-09 05:39:13 +00:00
ld [hli], a
2014-05-22 22:13:20 +00:00
inc hl ; wTileBehindCursor untouched
ld a, [wcd6c]
2014-05-22 22:13:20 +00:00
inc a
inc a
2014-08-09 05:39:13 +00:00
ld [hli], a
2014-05-22 22:13:20 +00:00
ld a, [wMoveMenuType]
dec a
ld b, $c1 ; can't use B
jr z, .matchedkeyspicked
dec a
ld b, $c3
jr z, .matchedkeyspicked
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr z, .matchedkeyspicked
ld a, [W_FLAGS_D733]
bit 0, a
ld b, $c7
jr z, .matchedkeyspicked
ld b, $ff
.matchedkeyspicked
ld a, b
2014-08-09 05:39:13 +00:00
ld [hli], a
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
2014-05-22 22:13:20 +00:00
Func_3d2fe: ; 3d2fe (f:52fe)
ld a, [wMoveMenuType]
and a
jr z, .battleselect
dec a
jr nz, .select
hlCoord 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
ld a, [W_FLAGS_D733]
bit 0, a
jr nz, .select
call Func_3d4b6
2014-08-09 05:39:13 +00:00
ld a, [wMenuItemToSwap]
2014-05-22 22:13:20 +00:00
and a
jr z, .select
hlCoord 5, 13
2014-05-22 22:13:20 +00:00
dec a
ld bc, $14
call AddNTimes
ld [hl], $ec
.select
ld hl, $fff6
set 1, [hl]
call HandleMenuInput
ld hl, $fff6
res 1, [hl]
bit 6, a
jp nz, Func_3d3c9 ; up
bit 7, a
jp nz, Func_3d3dd ; down
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
jr nz, .nob
pop af
ret
.nob
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 $3f
jr z, .nopp
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERDISABLEDMOVE]
2014-05-22 22:13:20 +00:00
swap a
and $f
dec a
cp c
jr z, .disabled
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERBATTSTATUS3]
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]
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
.nopp
ld hl, MoveNoPPText
.print
call PrintText
call LoadScreenTilesFromBuffer1
jp MoveSelectionMenu
MoveNoPPText: ; 3d3ae (f:53ae)
TX_FAR _MoveNoPPText
db "@"
MoveDisabledText: ; 3d3b3 (f:53b3)
TX_FAR _MoveDisabledText
db "@"
WhichTechniqueString: ; 3d3b8 (f:53b8)
db "WHICH TECHNIQUE?@"
Func_3d3c9: ; 3d3c9 (f:53c9)
2014-08-09 05:39:13 +00:00
ld a, [wCurrentMenuItem]
2014-05-22 22:13:20 +00:00
and a
jp nz, Func_3d2fe
call EraseMenuCursor
ld a, [wcd6c]
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [wCurrentMenuItem], a
2014-05-22 22:13:20 +00:00
jp Func_3d2fe
Func_3d3dd: ; 3d3dd (f:53dd)
2014-08-09 05:39:13 +00:00
ld a, [wCurrentMenuItem]
2014-05-22 22:13:20 +00:00
ld b, a
ld a, [wcd6c]
2014-05-22 22:13:20 +00:00
inc a
inc a
cp b
jp nz, Func_3d2fe
call EraseMenuCursor
ld a, $1
2014-08-09 05:39:13 +00:00
ld [wCurrentMenuItem], a
2014-05-22 22:13:20 +00:00
jp Func_3d2fe
Func_3d3f5: ; 3d3f5 (f:53f5)
2014-08-09 05:39:13 +00:00
ld a, STRUGGLE
ld [wPlayerSelectedMove], a
ld a, [W_PLAYERDISABLEDMOVE]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
ld hl, wBattleMonPP
2014-05-22 22:13:20 +00:00
jr nz, .asm_3d40e
ld a, [hli]
or [hl]
inc hl
or [hl]
inc hl
or [hl]
and $3f
ret nz
jr .asm_3d423
.asm_3d40e
swap a
and $f
ld b, a
ld d, $5
xor a
.asm_3d416
dec d
jr z, .asm_3d421
ld c, [hl]
inc hl
dec b
jr z, .asm_3d416
or c
jr .asm_3d416
.asm_3d421
and a
ret nz
.asm_3d423
ld hl, NoMovesLeftText
call PrintText
ld c, $3c
call DelayFrames
xor a
ret
NoMovesLeftText: ; 3d430 (f:5430)
TX_FAR _NoMovesLeftText
db "@"
2014-08-09 05:39:13 +00:00
SwapMovesInMenu: ; 3d435 (f:5435)
ld a, [wMenuItemToSwap]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z, .noMenuItemSelected
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
ld hl, W_PLAYERDISABLEDMOVE
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
ld bc, $15
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
Func_3d4b6: ; 3d4b6 (f:54b6)
xor a
2014-08-09 05:39:13 +00:00
ld [H_AUTOBGTRANSFERENABLED], a
hlCoord 0, 8
2014-05-22 22:13:20 +00:00
ld b, $3
ld c, $9
call TextBoxBorder
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERDISABLEDMOVE]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3d4df
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
jr nz, .asm_3d4df
hlCoord 1, 10
2014-05-22 22:13:20 +00:00
ld de, DisabledText
call PlaceString
jr .asm_3d54e
.asm_3d4df
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
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
ld b, $0
add hl, bc
ld a, [hl]
2014-08-09 05:39:13 +00:00
ld [wPlayerSelectedMove], a
ld a, [wPlayerMonNumber]
ld [wWhichPokemon], a
2014-05-22 22:13:20 +00:00
ld a, $4
ld [wcc49], 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 $3f
ld [wcd6d], a
hlCoord 1, 9
2014-05-22 22:13:20 +00:00
ld de, TypeText
call PlaceString
hlCoord 7, 11
2014-05-22 22:13:20 +00:00
ld [hl], "/"
hlCoord 5, 9
2014-05-22 22:13:20 +00:00
ld [hl], "/"
hlCoord 5, 11
ld de, wcd6d
2014-05-22 22:13:20 +00:00
ld bc, $102
call PrintNumber
hlCoord 8, 11
ld de, wd11e
2014-05-22 22:13:20 +00:00
ld bc, $102
call PrintNumber
call GetCurrentMove
hlCoord 2, 10
predef Func_27d98
2014-05-22 22:13:20 +00:00
.asm_3d54e
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
DisabledText: ; 3d555 (f:5555)
db "disabled!@"
TypeText: ; 3d55f (f:555f)
db "TYPE@"
SelectEnemyMove: ; 3d564 (f:5564)
ld a, [W_ISLINKBATTLE]
sub $4
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
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
cp $e
jp z, .asm_3d601
cp $d
jr z, .unableToMove
cp $4
ret nc
ld [wEnemyMoveListIndex], a
2014-05-22 22:13:20 +00:00
ld c, a
ld hl, wEnemyMonMoves
2014-05-22 22:13:20 +00:00
ld b, $0
add hl, bc
ld a, [hl]
jr .done
.noLinkBattle
ld a, [W_ENEMYBATTSTATUS2]
and $60 ; need to recharge or using rage
ret nz
ld hl, W_ENEMYBATTSTATUS1
ld a, [hl]
and $12 ; using multi-turn move or bide
ret nz
ld a, [wEnemyMonStatus]
2014-05-22 22:13:20 +00:00
and SLP | 1 << FRZ ; sleeping or frozen
ret nz
ld a, [W_ENEMYBATTSTATUS1]
and $21 ; using fly/dig or thrash/petal dance
ret nz
ld a, [W_PLAYERBATTSTATUS1]
bit 5, a ; caught in player's multi-turn move (e.g. wrap)
jr z, .notCaughtInWrap
.unableToMove
ld a, $ff
jr .done
.notCaughtInWrap
ld hl, wEnemyMonMoves+1 ; 2nd enemy move
2014-05-22 22:13:20 +00:00
ld a, [hld]
and a
jr nz, .atLeastTwoMovesAvailable
ld a, [W_ENEMYDISABLEDMOVE]
and a
ld a, STRUGGLE ; struggle if the only move is disabled
jr nz, .done
.atLeastTwoMovesAvailable
ld a, [W_ISINBATTLE]
dec a
jr z, .chooseRandomMove ; wild encounter
callab AIEnemyTrainerChooseMoves
.chooseRandomMove
push hl
call BattleRandom
2014-05-22 22:13:20 +00:00
ld b, $1
cp $3f ; select move 1 in [0,3e] (63/256 chance)
jr c, .moveChosen
inc hl
inc b
cp $7f ; select move 1 in [3f,7e] (64/256 chance)
jr c, .moveChosen
inc hl
inc b
cp $be ; select move 1 in [7f,bd] (63/256 chance)
jr c, .moveChosen
inc hl
inc b ; select move 4 in [be,ff] (66/256 chance)
.moveChosen
ld a, b
dec a
ld [wEnemyMoveListIndex], a
ld a, [W_ENEMYDISABLEDMOVE]
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
.asm_3d601
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
LinkBattleExchangeData: ; 3d605 (f:5605)
2014-05-22 22:13:20 +00:00
ld a, $ff
ld [wcc3e], a
2014-08-09 05:39:13 +00:00
ld a, [wPlayerMoveListIndex]
cp $f ; is the player running from battle?
2014-05-22 22:13:20 +00:00
jr z, .asm_3d630
ld a, [wcd6a]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3d629
2014-08-09 05:39:13 +00:00
ld a, [wPlayerSelectedMove]
cp STRUGGLE
2014-05-22 22:13:20 +00:00
ld b, $e
jr z, .asm_3d62f
dec b
inc a
jr z, .asm_3d62f
2014-08-09 05:39:13 +00:00
ld a, [wPlayerMoveListIndex]
2014-05-22 22:13:20 +00:00
jr .asm_3d630
.asm_3d629
2014-08-09 05:39:13 +00:00
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
add $4
ld b, a
.asm_3d62f
ld a, b
.asm_3d630
ld [wcc42], a
2014-05-22 22:13:20 +00:00
callab PrintWaitingText
.asm_3d63b
call Func_22c3
call DelayFrame
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
inc a
jr z, .asm_3d63b
ld b, $a
.asm_3d649
call DelayFrame
call Func_22c3
dec b
jr nz, .asm_3d649
ld b, $a
.asm_3d654
call DelayFrame
call Func_22ed
dec b
jr nz, .asm_3d654
ret
2014-08-09 05:39:13 +00:00
ExecutePlayerMove: ; 3d65e (f:565e)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld [H_WHOSETURN], a
ld a, [wPlayerSelectedMove]
2014-05-22 22:13:20 +00:00
inc a
jp z, Func_3d80a
xor a
2014-08-09 05:39:13 +00:00
ld [W_MOVEMISSED], a
ld [wcced], a
ld [wccf4], a
2014-05-22 22:13:20 +00:00
ld a, $a
ld [wd05b], a
ld a, [wcd6a]
2014-05-22 22:13:20 +00:00
and a
jp nz, Func_3d80a
call PrintGhostText
jp z, Func_3d80a
2014-08-09 05:39:13 +00:00
call CheckPlayerStatusConditions
2014-05-22 22:13:20 +00:00
jr nz, .asm_3d68a
jp [hl]
.asm_3d68a
call GetCurrentMove
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
2014-05-22 22:13:20 +00:00
bit 4, [hl]
jr nz, asm_3d6a9
2014-08-09 05:39:13 +00:00
call CheckForDisobedience
2014-05-22 22:13:20 +00:00
jp z, Func_3d80a
Func_3d69a: ; 3d69a (f:569a)
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp CHARGE_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
2014-05-22 22:13:20 +00:00
jr asm_3d6b0
; in-battle stuff
asm_3d6a9: ; 3d6a9 (f:56a9)
ld hl,W_PLAYERBATTSTATUS1
res 4,[hl]
res 6,[hl]
asm_3d6b0: ; 3d6b0 (f:56b0)
call PrintMonName1Text
ld hl,DecrementPP
ld de,wPlayerSelectedMove ; pointer to the move just used
2014-05-22 22:13:20 +00:00
ld b,BANK(DecrementPP)
call Bankswitch
ld a,[W_PLAYERMOVEEFFECT] ; effect of the move just used
ld hl,EffectsArray1
ld de,1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c,JumpMoveEffect
2014-05-22 22:13:20 +00:00
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray5B
ld de,1
call IsInArray
2014-08-09 05:39:13 +00:00
call c,JumpMoveEffect
2014-05-22 22:13:20 +00:00
asm_3d6dc: ; 3d6dc (f:56dc)
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray2
ld de,1
call IsInArray
jp c,.asm_3d702
call CriticalHitTest
call HandleCounterMove
jr z,asm_3d705
2014-08-09 05:39:13 +00:00
call GetDamageVarsForPlayerAttack
2014-05-22 22:13:20 +00:00
call CalculateDamage
jp z,asm_3d74b
call AdjustDamageForMoveType
2014-08-09 05:39:13 +00:00
call RandomizeDamage
2014-05-22 22:13:20 +00:00
.asm_3d702
call MoveHitTest
asm_3d705
ld a,[W_MOVEMISSED]
and a
jr z,asm_3d714
ld a,[W_PLAYERMOVEEFFECT]
sub a,7
jr z,asm_3d71e
2014-08-09 05:39:13 +00:00
jr asm_3d74b
2014-05-22 22:13:20 +00:00
asm_3d714
ld a,[W_PLAYERMOVEEFFECT]
and a
ld a,4
jr z,asm_3d71e
ld a,5
asm_3d71e
push af
ld a,[W_PLAYERBATTSTATUS2]
bit 4,a
ld hl,Func_79747
ld b,BANK(Func_79747)
call nz,Bankswitch
pop af
ld [wcc5b],a
2014-05-22 22:13:20 +00:00
ld a,[W_PLAYERMOVENUM]
call PlayMoveAnimation
call Func_3eed3
2014-08-09 05:39:13 +00:00
call DrawPlayerHUDAndHPBar
2014-05-22 22:13:20 +00:00
ld a,[W_PLAYERBATTSTATUS2]
bit 4,a
ld hl,Func_79771
ld b,BANK(Func_79771)
call nz,Bankswitch
jr asm_3d766
asm_3d74b
ld c,$1E
call DelayFrames
ld a,[W_PLAYERMOVEEFFECT]
cp a,FLY_EFFECT
jr z,.next5
cp a,CHARGE_EFFECT
jr z,.next5
jr asm_3d766
.next5
xor a
ld [wcc5b],a
2014-05-22 22:13:20 +00:00
ld a,STATUS_AFFECTED_ANIM
call PlayMoveAnimation
asm_3d766
ld a,[W_PLAYERMOVEEFFECT]
cp a,MIRROR_MOVE_EFFECT
2014-08-09 05:39:13 +00:00
jr nz,.next6
2014-05-22 22:13:20 +00:00
call MirrorMoveCopyMove
jp z,Func_3d80a
xor a
ld [wcced],a
2014-05-22 22:13:20 +00:00
jp Func_3d69a
.next6
cp a,METRONOME_EFFECT
2014-08-09 05:39:13 +00:00
jr nz,.next7
2014-05-22 22:13:20 +00:00
call MetronomePickMove
jp Func_3d69a
.next7
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray3
ld de,1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c,JumpMoveEffect
2014-05-22 22:13:20 +00:00
ld a,[W_MOVEMISSED]
and a
2014-08-09 05:39:13 +00:00
jr z,.next8
2014-05-22 22:13:20 +00:00
call PrintMoveFailureText
ld a,[W_PLAYERMOVEEFFECT]
cp a,EXPLODE_EFFECT
2014-08-09 05:39:13 +00:00
jr z,.next9
2014-05-22 22:13:20 +00:00
jp Func_3d80a
.next8
call ApplyAttackToEnemyPokemon
2014-08-09 05:39:13 +00:00
call PrintCriticalOHKOText
2014-05-22 22:13:20 +00:00
callab DisplayEffectiveness
ld a,1
ld [wccf4],a
2014-05-22 22:13:20 +00:00
.next9
ld a,[W_PLAYERMOVEEFFECT]
ld hl,EffectsArray4
ld de,1
call IsInArray
2014-08-09 05:39:13 +00:00
call c,JumpMoveEffect
ld hl,wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld b,[hl]
or b
ret z
call HandleBuildingRage
ld hl,W_PLAYERBATTSTATUS1
bit 2,[hl]
2014-08-09 05:39:13 +00:00
jr z,.next10
ld a,[wPlayerNumAttacksLeft]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [wPlayerNumAttacksLeft],a
2014-05-22 22:13:20 +00:00
jp nz,asm_3d714
res 2,[hl]
ld hl,MultiHitText
call PrintText
xor a
ld [W_NUMHITS],a ; reset
.next10
ld a,[W_PLAYERMOVEEFFECT]
and a
jp z,Func_3d80a
ld hl,EffectsArray5
ld de,1
call IsInArray
2014-08-09 05:39:13 +00:00
call nc,JumpMoveEffect
2014-05-22 22:13:20 +00:00
jp Func_3d80a
MultiHitText: ; 3d805 (f:5805)
TX_FAR _MultiHitText
db "@"
Func_3d80a: ; 3d80a (f:580a)
xor a
ld [wcd6a],a
2014-05-22 22:13:20 +00:00
ld b,1
ret
PrintGhostText: ; 3d811 (f:5811)
; print the ghost battle messages
call IsGhostBattle
ret nz
ld a,[H_WHOSETURN]
and a
jr nz,.Ghost
ld a,[wBattleMonStatus] ; players 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 ; ghosts turn
ld hl,GetOutText
call PrintText
xor a
ret
ScaredText: ; 3d830 (f:5830)
TX_FAR _ScaredText
db "@"
GetOutText: ; 3d835 (f:5835)
TX_FAR _GetOutText
db "@"
IsGhostBattle: ; 3d83a (f:583a)
ld a,[W_ISINBATTLE]
dec a
ret nz
ld a,[W_CURMAP]
cp a,POKEMONTOWER_1
jr c,.next
cp a,LAVENDER_HOUSE_1
jr nc,.next
ld b,SILPH_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
CheckPlayerStatusConditions: ; 3d854 (f:5854)
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
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
; 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
ld [wcc5b],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
ld [wccf1],a
2014-05-22 22:13:20 +00:00
ld hl,Func_3d80a
2014-08-09 05:39:13 +00:00
jp .CannotUseMove
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
ld [wccf1],a
2014-05-22 22:13:20 +00:00
ld hl,Func_3d80a
2014-08-09 05:39:13 +00:00
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
.HeldInPlaceCheck
ld a,[W_ENEMYBATTSTATUS1]
bit 5,a
2014-08-09 05:39:13 +00:00
jp z,.FlinchedCheck
2014-05-22 22:13:20 +00:00
ld hl,CantMoveText
call PrintText
ld hl,Func_3d80a
2014-08-09 05:39:13 +00:00
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.FlinchedCheck
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
bit 3,[hl]
2014-08-09 05:39:13 +00:00
jp z,.HyperBeamCheck
2014-05-22 22:13:20 +00:00
res 3,[hl]
ld hl,FlinchedText
call PrintText
ld hl,Func_3d80a
2014-08-09 05:39:13 +00:00
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.HyperBeamCheck
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS2
bit 5,[hl]
2014-08-09 05:39:13 +00:00
jr z,.AnyMoveDisabledCheck
2014-05-22 22:13:20 +00:00
res 5,[hl]
ld hl,MustRechargeText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl,Func_3d80a
jp .CannotUseMove
.AnyMoveDisabledCheck
ld hl,W_PLAYERDISABLEDMOVE
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
and a,$F
2014-08-09 05:39:13 +00:00
jr nz,.ConfusedCheck
2014-05-22 22:13:20 +00:00
ld [hl],a
ld [wccee],a
2014-05-22 22:13:20 +00:00
ld hl,DisabledNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
.ConfusedCheck
2014-05-22 22:13:20 +00:00
ld a,[W_PLAYERBATTSTATUS1]
add a
2014-08-09 05:39:13 +00:00
jr nc,.TriedToUseDisabledMoveCheck
ld hl,wd06b
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
jr nz,.IsConfused
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
res 7,[hl]
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
ld [wcc5b],a
2014-05-22 22:13:20 +00:00
ld a,CONF_ANIM - 1
call PlayMoveAnimation
call BattleRandom
2014-05-22 22:13:20 +00:00
cp a,$80
2014-08-09 05:39:13 +00:00
jr c,.TriedToUseDisabledMoveCheck
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
ld a,[hl]
and a,$80 ; confused
ld [hl],a
call PrintHurtItselfText
2014-08-09 05:39:13 +00:00
jr .MonHurtItselfOrFullyParalysed
.TriedToUseDisabledMoveCheck
ld a,[wccee]
2014-05-22 22:13:20 +00:00
and a
2014-08-09 05:39:13 +00:00
jr z,.ParalysisCheck
ld hl,wPlayerSelectedMove
2014-05-22 22:13:20 +00:00
cp [hl]
jr nz,.ParalysisCheck
call PrintMoveIsDisabledText
2014-08-09 05:39:13 +00:00
ld hl,Func_3d80a
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
.ParalysisCheck
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
call BattleRandom
2014-05-22 22:13:20 +00:00
cp a,$3F
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
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
ld a,[hl]
2014-08-09 05:39:13 +00:00
and a,$CC ; clear bide, thrashing, charging up, and multi-turn moves such as warp
2014-05-22 22:13:20 +00:00
ld [hl],a
ld a,[W_PLAYERMOVEEFFECT]
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,CHARGE_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
ld [wcc5b],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
ld hl,Func_3d80a
jp .CannotUseMove
.BideCheck
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
2014-08-09 05:39:13 +00:00
bit 0,[hl] ; is mon using bide?
jr z,.ThrashingAboutCheck
2014-05-22 22:13:20 +00:00
xor a
ld [W_PLAYERMOVENUM],a
ld hl,W_DAMAGE
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld b,a
ld c,[hl]
ld hl,wd075
2014-05-22 22:13:20 +00:00
ld a,[hl]
add c
ld [hld],a
ld a,[hl]
adc b
ld [hl],a
2014-08-09 05:39:13 +00:00
ld hl,wPlayerNumAttacksLeft
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
jr z,.UnleashEnergy
ld hl,Func_3d80a
jp .CannotUseMove
.UnleashEnergy
2014-05-22 22:13:20 +00:00
ld hl,W_PLAYERBATTSTATUS1
2014-08-09 05:39:13 +00:00
res 0,[hl] ; not using bide any more
2014-05-22 22:13:20 +00:00
ld hl,UnleashedEnergyText
call PrintText
ld a,1
ld [W_PLAYERMOVEPOWER],a
ld hl,wd075
2014-05-22 22:13:20 +00:00
ld a,[hld]
add a
ld b,a
ld [wd0d8],a
2014-05-22 22:13:20 +00:00
ld a,[hl]
rl a
ld [W_DAMAGE],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
ld [W_MOVEMISSED],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
ld [W_PLAYERMOVENUM],a
2014-08-09 05:39:13 +00:00
ld hl,asm_3d705
jp .CannotUseMove
.ThrashingAboutCheck
bit 1,[hl] ; is mon using thrash or petal dance?
jr z,.MultiturnMoveCheck
2014-05-22 22:13:20 +00:00
ld a,THRASH
ld [W_PLAYERMOVENUM],a
ld hl,ThrashingAboutText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl,wPlayerNumAttacksLeft
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
ld hl,asm_3d6dc
jp nz,.CannotUseMove
2014-05-22 22:13:20 +00:00
push hl
ld hl,W_PLAYERBATTSTATUS1
res 1,[hl]
set 7,[hl]
call BattleRandom
2014-05-22 22:13:20 +00:00
and a,3
inc a
inc a
ld [wd06b],a
2014-05-22 22:13:20 +00:00
pop hl
2014-08-09 05:39:13 +00:00
jp .CannotUseMove
.MultiturnMoveCheck
bit 5,[hl] ; is mon using multi-turn move?
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]
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld [wPlayerNumAttacksLeft],a
ld hl,asm_3d714
jp nz,.CannotUseMove
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.RageCheck
ld a, [W_PLAYERBATTSTATUS2]
bit 6, a ; is mon using rage?
jp z, .CanUseMove
2014-05-22 22:13:20 +00:00
ld a, RAGE
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B
xor a
2014-08-09 05:39:13 +00:00
ld [W_PLAYERMOVEEFFECT], a
ld hl, asm_3d6b0
jp .CannotUseMove
2014-05-22 22:13:20 +00:00
2014-08-09 05:39:13 +00:00
.CannotUseMove
2014-05-22 22:13:20 +00:00
xor a
ret
2014-08-09 05:39:13 +00:00
.CanUseMove
2014-05-22 22:13:20 +00:00
ld a, $1
and a
ret
FastAsleepText: ; 3da3d (f:5a3d)
TX_FAR _FastAsleepText
db "@"
WokeUpText: ; 3da42 (f:5a42)
TX_FAR _WokeUpText
db "@"
IsFrozenText: ; 3da47 (f:5a47)
TX_FAR _IsFrozenText
db "@"
FullyParalyzedText: ; 3da4c (f:5a4c)
TX_FAR _FullyParalyzedText
db "@"
FlinchedText: ; 3da51 (f:5a51)
TX_FAR _FlinchedText
db "@"
MustRechargeText: ; 3da56 (f:5a56)
TX_FAR _MustRechargeText
db "@"
DisabledNoMoreText: ; 3da5b (f:5a5b)
TX_FAR _DisabledNoMoreText
db "@"
IsConfusedText: ; 3da60 (f:5a60)
TX_FAR _IsConfusedText
db "@"
HurtItselfText: ; 3da65 (f:5a65)
TX_FAR _HurtItselfText
db "@"
ConfusedNoMoreText: ; 3da6a (f:5a6a)
TX_FAR _ConfusedNoMoreText
db "@"
SavingEnergyText: ; 3da6f (f:5a6f)
TX_FAR _SavingEnergyText
db "@"
UnleashedEnergyText: ; 3da74 (f:5a74)
TX_FAR _UnleashedEnergyText
db "@"
ThrashingAboutText: ; 3da79 (f:5a79)
TX_FAR _ThrashingAboutText
db "@"
AttackContinuesText: ; 3da7e (f:5a7e)
TX_FAR _AttackContinuesText
db "@"
CantMoveText: ; 3da83 (f:5a83)
TX_FAR _CantMoveText
db "@"
PrintMoveIsDisabledText: ; 3da88 (f:5a88)
2014-08-09 05:39:13 +00:00
ld hl, wPlayerSelectedMove
ld de, W_PLAYERBATTSTATUS1
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3da97
inc hl
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
.asm_3da97
ld a, [de]
res 4, a
ld [de], a
ld a, [hl]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMoveName
ld hl, MoveIsDisabledText
jp PrintText
MoveIsDisabledText: ; 3daa8 (f:5aa8)
TX_FAR _MoveIsDisabledText
db "@"
PrintHurtItselfText: ; 3daad (f:5aad)
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
ld a, [wBattleMonDefense]
2014-05-22 22:13:20 +00:00
ld [hli], a
ld a, [wBattleMonDefense + 1]
2014-05-22 22:13:20 +00:00
ld [hl], a
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERMOVEEFFECT
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
2014-05-22 22:13:20 +00:00
ld a, $28
ld [hli], a
xor a
ld [hl], a
2014-08-09 05:39:13 +00:00
call GetDamageVarsForPlayerAttack
2014-05-22 22:13:20 +00:00
call CalculateDamage
pop af
pop hl
ld [hl], a
ld hl, wEnemyMonDefense + 1
2014-05-22 22:13:20 +00:00
pop af
ld [hld], a
pop af
ld [hl], a
xor a
ld [wcc5b], 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
PrintMonName1Text: ; 3daf5 (f:5af5)
ld hl, MonName1Text
jp PrintText
MonName1Text: ; 3dafb (f:5afb)
TX_FAR _MonName1Text
db $08 ; asm
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 a, [W_PLAYERMOVENUM]
ld hl, wccf1
2014-05-22 22:13:20 +00:00
jr z, .asm_3db11
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
ld hl, wccf2
2014-05-22 22:13:20 +00:00
.asm_3db11
ld [hl], a
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call Func_3db85
ld a, [wcced]
2014-05-22 22:13:20 +00:00
and a
ld hl, Used2Text
ret nz
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
cp DOUBLESLAP
ld hl, Used2Text
ret c
ld hl, Used1Text
ret
Used1Text: ; 3db2d (f:5b2d)
TX_FAR _Used1Text
db $08 ; asm
jr PrintInsteadText
Used2Text: ; 3db34 (f:5b34)
TX_FAR _Used2Text
db $08 ; asm
PrintInsteadText: ; 3db39 (f:5b39)
ld a, [wcced]
2014-05-22 22:13:20 +00:00
and a
jr z, PrintCF4BText
ld hl, InsteadText
ret
InsteadText: ; 3db43 (f:5b43)
TX_FAR _InsteadText
db $08 ; asm
PrintCF4BText: ; 3db48 (f:5b48)
ld hl, CF4BText
ret
CF4BText: ; 3db4c (f:5b4c)
TX_FAR _CF4BText
db $08 ; asm
ld hl, ExclamationPointPointerTable
ld a, [wd11e]
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
ExclamationPointPointerTable: ; 3db62 (f:5b62)
dw ExclamationPoint1Text
dw ExclamationPoint2Text
dw ExclamationPoint3Text
dw ExclamationPoint4Text
dw ExclamationPoint5Text
ExclamationPoint1Text: ; 3db6c (f:5b6c)
TX_FAR _ExclamationPoint1Text
db "@"
ExclamationPoint2Text: ; 3db71 (f:5b71)
TX_FAR _ExclamationPoint2Text
db "@"
ExclamationPoint3Text: ; 3db76 (f:5b76)
TX_FAR _ExclamationPoint3Text
db "@"
ExclamationPoint4Text: ; 3db7b (f:5b7b)
TX_FAR _ExclamationPoint4Text
db "@"
ExclamationPoint5Text: ; 3db80 (f:5b80)
TX_FAR _ExclamationPoint5Text
db "@"
Func_3db85: ; 3db85 (f:5b85)
push bc
ld a, [wd11e] ; move number
2014-05-22 22:13:20 +00:00
ld c, a
ld b, $0
2014-08-09 05:39:13 +00:00
ld hl, UnknownMovesList_3dba3
2014-05-22 22:13:20 +00:00
.asm_3db8f
ld a, [hli]
cp $ff
jr z, .asm_3db9d
cp c
jr z, .asm_3db9d
and a
jr nz, .asm_3db8f
inc b
jr .asm_3db8f
.asm_3db9d
ld a, b
ld [wd11e], a
2014-05-22 22:13:20 +00:00
pop bc
ret
UnknownMovesList_3dba3: ; 3dba3 (f:5ba3)
db SWORDS_DANCE, GROWTH
db $00
db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
db $00
db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
db $00
db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN
db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS
db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE
db $00
db $FF ; terminator
PrintMoveFailureText: ; 3dbe2 (f:5be2)
2014-08-09 05:39:13 +00:00
ld de, W_PLAYERMOVEEFFECT
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
ld de, W_ENEMYMOVEEFFECT
.playersTurn
ld hl, DoesntAffectMonText
ld a, [wd05b]
2014-05-22 22:13:20 +00:00
and $7f
jr z, .asm_3dc04
2014-08-09 05:39:13 +00:00
ld hl, AttackMissedText
ld a, [wCriticalHitOrOHKO]
2014-05-22 22:13:20 +00:00
cp $ff
jr nz, .asm_3dc04
2014-08-09 05:39:13 +00:00
ld hl, UnaffectedText
2014-05-22 22:13:20 +00:00
.asm_3dc04
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
; if you get here, the mon used hi jump kick and missed
2014-08-09 05:39:13 +00:00
ld hl, W_DAMAGE
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
jr nz, .asm_3dc2a
inc a
ld [hl], a
.asm_3dc2a
2014-08-09 05:39:13 +00:00
ld hl, KeptGoingAndCrashedText
2014-05-22 22:13:20 +00:00
call PrintText
ld b, $4
predef Func_48125
2014-08-09 05:39:13 +00:00
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3dc3f
jp ApplyDamageToPlayerPokemon
.asm_3dc3f
jp ApplyDamageToEnemyPokemon
AttackMissedText: ; 3dc42 (f:5c42)
TX_FAR _AttackMissedText
db "@"
KeptGoingAndCrashedText: ; 3dc47 (f:5c47)
TX_FAR _KeptGoingAndCrashedText
db "@"
UnaffectedText: ; 3dc4c (f:5c4c)
TX_FAR _UnaffectedText
db "@"
PrintDoesntAffectText: ; 3dc51 (f:5c51)
2014-08-09 05:39:13 +00:00
ld hl, DoesntAffectMonText
2014-05-22 22:13:20 +00:00
jp PrintText
DoesntAffectMonText: ; 3dc57 (f:5c57)
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
PrintCriticalOHKOText: ; 3dc5c (f:5c5c)
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
2014-05-22 22:13:20 +00:00
ld c, $14
jp DelayFrames
CriticalOHKOTextPointers: ; 3dc7a (f:5c7a)
dw CriticalHitText
dw OHKOText
CriticalHitText: ; 3dc7e (f:5c7e)
TX_FAR _CriticalHitText
db "@"
OHKOText: ; 3dc83 (f:5c83)
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
CheckForDisobedience: ; 3dc88 (f:5c88)
2014-05-22 22:13:20 +00:00
xor a
ld [wcced], a
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
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?
ld hl, W_OBTAINEDBADGES
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
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
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
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
call PrintHurtItselfText
2014-08-09 05:39:13 +00:00
jp .cannotUseMove
.monNaps
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
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
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
ld a, [wccee]
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 $3f
ld b, a
ld a, [hli]
and $3f
add b
ld b, a
ld a, [hli]
and $3f
add b
ld b, a
ld a, [hl]
and $3f
add b
pop hl
push af
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 $3f
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
ld [wcced], 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
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
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
LoafingAroundText: ; 3ddb6 (f:5db6)
TX_FAR _LoafingAroundText
db "@"
BeganToNapText: ; 3ddbb (f:5dbb)
TX_FAR _BeganToNapText
db "@"
WontObeyText: ; 3ddc0 (f:5dc0)
TX_FAR _WontObeyText
db "@"
TurnedAwayText: ; 3ddc5 (f:5dc5)
TX_FAR _TurnedAwayText
db "@"
IgnoredOrdersText: ; 3ddca (f:5dca)
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
GetDamageVarsForPlayerAttack: ; 3ddcf (f:5dcf)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
2014-05-22 22:13:20 +00:00
ldi [hl], a
ld [hl], a
ld hl, W_PLAYERMOVEPOWER
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
ld a, [hl] ; a = [W_PLAYERMOVETYPE]
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
ld a, [W_ENEMYBATTSTATUS3]
bit 2, a ; check for Reflect
jr z, .physicalAttackCritCheck
; if the enemy has used Reflect, double the enemy's defense
sla c
2014-05-22 22:13:20 +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
2014-05-22 22:13:20 +00:00
ld a, [$ff97]
ld b, a
ld a, [$ff98]
ld c, a
push bc
ld hl, wPartyMon1Attack
2014-05-22 22:13:20 +00:00
ld a, [wPlayerMonNumber]
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
ld a, [W_ENEMYBATTSTATUS3]
bit 1, a ; check for Light Screen
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
2014-08-09 05:39:13 +00:00
.specialAttackCritCheck
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
2014-05-22 22:13:20 +00:00
ld a, [$ff97]
ld b, a
ld a, [$ff98]
ld c, a
push bc
ld hl, wPartyMon1Special
2014-05-22 22:13:20 +00:00
ld a, [wPlayerMonNumber]
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
; bc /= 4 (scale enemy's defensive stat)
srl b
2014-05-22 22:13:20 +00:00
rr c
srl b
rr c
2014-08-09 05:39:13 +00:00
; hl /= 4 (scale player's offensive stat)
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
ld b, l ; b = player's offensive stat (possibly scaled) (c already contains enemy's defensive stat (possibly scaled))
ld a, [wBattleMonLevel]
ld e, a ; e = level
ld a, [wCriticalHitOrOHKO]
and a ; check for critical hit
jr z, .done
sla e ; double level if it was a critical hit
.done
ld a, 1
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
GetDamageVarsForEnemyAttack: ; 3de75 (f:5e75)
ld hl, W_DAMAGE ; damage to eventually inflict, initialise to zero
2014-05-22 22:13:20 +00:00
xor a
ld [hli], a
ld [hl], a
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYMOVEPOWER
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
ld a, [hl] ; a = [W_ENEMYMOVETYPE]
cp FIRE ; types >= FIRE are all special
jr nc, .specialAttack
.physicalAttack
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
ld a, [W_PLAYERBATTSTATUS3]
bit 2, a ; check for Reflect
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
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
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
2014-05-22 22:13:20 +00:00
ld hl, $ff97
pop bc
2014-08-09 05:39:13 +00:00
jr .scaleStats
.specialAttack
ld hl, wBattleMonSpecial
2014-05-22 22:13:20 +00:00
ld a, [hli]
ld b, a
ld c, [hl]
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERBATTSTATUS3]
bit 1, a ; check for Light Screen
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
2014-08-09 05:39:13 +00:00
rl b
.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
2014-05-22 22:13:20 +00:00
ld hl, $ff97
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
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
ld b, l ; b = enemy's offensive stat (possibly scaled) (c already contains player's defensive stat (possibly scaled))
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)
GetEnemyMonStat: ; 3df1c (f:5f1c)
2014-05-22 22:13:20 +00:00
push de
push bc
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr nz, .asm_3df40
ld hl, wEnemyMon1Stats
2014-05-22 22:13:20 +00:00
dec c
sla c
ld b, $0
add hl, bc
ld a, [wEnemyMonPartyPos]
ld bc, wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a, [hli]
ld [$ff97], a
ld a, [hl]
ld [$ff98], a
pop bc
pop de
ret
.asm_3df40
2014-08-09 05:39:13 +00:00
ld a, [wEnemyMonLevel]
ld [W_CURENEMYLVL], a
ld a, [wEnemyMonSpecies]
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
ld hl, wEnemyMonDVs
ld de, wcfaf
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
ld hl, wcfa4
2014-05-22 22:13:20 +00:00
call CalcStat
pop de
ret
2014-08-09 05:39:13 +00:00
CalculateDamage: ; 3df65 (f:5f65)
2014-05-22 22:13:20 +00:00
; input:
; b: attack
; c: opponent defense
; d: base power
; e: level
ld a, [$fff3] ; whose turn?
and a
ld a, [W_PLAYERMOVEEFFECT]
jr z, .effect
ld a, [W_ENEMYMOVEEFFECT]
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, $1e
jr z, .skipbp
; Calculate OHKO damage based on remaining HP.
cp a, OHKO_EFFECT
jp z, Func_3e016
; Don't calculate damage for moves that don't do any.
ld a, d ; base power
and a
ret z
.skipbp
xor a
ld hl, H_DIVIDEND
ldi [hl], a
ldi [hl], a
ld [hl], a
; Multiply level by 2
ld a, e ; level
add a
jr nc, .nc
push af
ld a, 1
ld [hl], a
pop af
.nc
inc hl
ldi [hl], a
; Divide by 5
ld a, 5
ldd [hl], a
push bc
ld b, 4
call Divide
pop bc
; Add 2
inc [hl]
inc [hl]
inc hl ; multiplier
; Multiply by attack base power
ld [hl], d
call Multiply
; Multiply by attack stat
ld [hl], b
call Multiply
; Divide by defender's defense stat
ld [hl], c
ld b, 4
call Divide
; Divide by 50
ld [hl], 50
ld b, 4
call Divide
ld hl, W_DAMAGE
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
ld a, 997 / $100
ld [hli], a
ld a, 997 % $100
ld [hld], a
.asm_3e00a
inc hl
ld a, [hl]
add 2
ld [hld], a
jr nc, .done
inc [hl]
.done
ld a, 1
and a
ret
Func_3e016: ; 3e016 (f:6016)
2014-08-09 05:39:13 +00:00
call JumpMoveEffect
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
dec a
ret
UnusedHighCriticalMoves: ; 3e01e (f:601e)
db KARATE_CHOP
db RAZOR_LEAF
db CRABHAMMER
db SLASH
db $FF
; 3e023
; determines if attack is a critical hit
; azure heights claims "the fastest pokémon (who are,not coincidentally,
; among the most popular) tend to CH about 20 to 25% of the time."
CriticalHitTest: ; 3e023 (f:6023)
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
ld a, [wEnemyMonSpecies]
2014-05-22 22:13:20 +00:00
jr nz, .asm_3e032
ld a, [wBattleMonSpecies]
2014-05-22 22:13:20 +00:00
.asm_3e032
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
ld a, [W_MONHBASESPEED]
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
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERMOVEPOWER
ld de, W_PLAYERBATTSTATUS2
2014-05-22 22:13:20 +00:00
jr z, .calcCriticalHitProbability
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYMOVEPOWER
ld de, W_ENEMYBATTSTATUS2
2014-05-22 22:13:20 +00:00
.calcCriticalHitProbability ; 0x3e04f
ld a, [hld] ; read base power from RAM
and a
ret z ; do nothing if zero
dec hl
ld c, [hl] ; read move id
ld a, [de]
bit 2, a ; test for focus energy
jr nz, .focusEnergyUsed ; bug: using focus energy causes a shift to the right instead of left,
; resulting in 1/4 the usual crit chance
sla b ; (effective (base speed/2)*2)
jr nc, .noFocusEnergyUsed
ld b, $ff ; cap at 255/256
jr .noFocusEnergyUsed
.focusEnergyUsed
srl b
.noFocusEnergyUsed
ld hl, HighCriticalMoves ; table of high critical hit moves
.Loop
ld a, [hli] ; read move from move table
cp c ; does it match the move about to be used?
jr z, .HighCritical ; if so, the move about to be used is a high critical hit ratio move
inc a ; move on to the next move, FF terminates loop
jr nz, .Loop ; check the next move in HighCriticalMoves
srl b ; /2 for regular move (effective (base speed / 2))
jr .SkipHighCritical ; continue as a normal move
.HighCritical
sla b ; *2 for high critical hit moves
jr nc, .noCarry
ld b, $ff ; cap at 255/256
.noCarry
sla b ; *4 for high critical move (effective (base speed/2)*8))
jr nc, .SkipHighCritical
ld b, $ff
.SkipHighCritical
call BattleRandom ; generates a random value, in "a"
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
2014-08-09 05:39:13 +00:00
ld [wCriticalHitOrOHKO], a ; set critical hit flag
2014-05-22 22:13:20 +00:00
ret
; high critical hit moves
HighCriticalMoves: ; 3e08e (f:608e)
db KARATE_CHOP
db RAZOR_LEAF
db CRABHAMMER
db SLASH
db $FF
; function to determine if Counter hits and if so, how much damage it does
HandleCounterMove: ; 3e093 (f:6093)
ld a,[H_WHOSETURN] ; whose turn
and a
; player's turn
ld hl,wEnemySelectedMove
ld de,W_ENEMYMOVEPOWER
ld a,[wPlayerSelectedMove]
jr z,.next
; enemy's turn
ld hl,wPlayerSelectedMove
ld de,W_PLAYERMOVEPOWER
ld a,[wEnemySelectedMove]
.next
cp a,COUNTER
ret nz ; return if not using Counter
ld a,$01
ld [W_MOVEMISSED],a ; initialize the move missed variable to true (it is set to false below if the move hits)
ld a,[hl]
cp a,COUNTER
ret z ; if the target also used Counter, miss
ld a,[de]
and a
ret z ; if the move the target used has 0 power, miss
; check if the move the target used was Normal or Fighting type
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
ld hl,W_DAMAGE
ld a,[hli]
or [hl]
ret z ; Counter misses if the target did no damage to the Counter user
; double the damage that the target did to the Counter user
ld a,[hl]
add a
ldd [hl],a
ld a,[hl]
adc a
ld [hl],a
jr nc,.noCarry
; damage is capped at 0xFFFF
ld a,$ff
ld [hli],a
ld [hl],a
.noCarry
xor a
ld [W_MOVEMISSED],a
call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
xor a
ret
ApplyAttackToEnemyPokemon: ; 3e0df (f:60df)
ld a,[W_PLAYERMOVEEFFECT]
cp a,OHKO_EFFECT
jr z,ApplyDamageToEnemyPokemon
cp a,SUPER_FANG_EFFECT
jr z,.superFangEffect
cp a,SPECIAL_DAMAGE_EFFECT
jr z,.specialDamage
ld a,[W_PLAYERMOVEPOWER]
and a
jp z,ApplyAttackToEnemyPokemonDone
jr ApplyDamageToEnemyPokemon
.superFangEffect
; set the damage to half the target's HP
ld hl,wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld de,W_DAMAGE
ld a,[hli]
srl a
ld [de],a
inc de
ld b,a
ld a,[hl]
rr a
ld [de],a
or b
jr nz,ApplyDamageToEnemyPokemon
; make sure Super Fang's damage is always at least 1
ld a,$01
ld [de],a
jr ApplyDamageToEnemyPokemon
.specialDamage
ld hl,wBattleMonLevel
2014-05-22 22:13:20 +00:00
ld a,[hl]
ld b,a
ld a,[W_PLAYERMOVENUM]
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 = level * 1.5
; loop until a random number in the range [1, b) is found
.loop
call BattleRandom
2014-05-22 22:13:20 +00:00
and a
jr z,.loop
cp b
jr nc,.loop
ld b,a
.storeDamage
ld hl,W_DAMAGE
xor a
ld [hli],a
ld a,b
ld [hl],a
ApplyDamageToEnemyPokemon: ; 3e142 (f:6142)
ld hl,W_DAMAGE
ld a,[hli]
ld b,a
ld a,[hl]
or b
jr z,ApplyAttackToEnemyPokemonDone ; we're done if damage is 0
ld a,[W_ENEMYBATTSTATUS2]
bit 4,a ; does the enemy have a substitute?
jp nz,AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP
ld a,[hld]
ld b,a
ld a,[wEnemyMonHP + 1]
2014-05-22 22:13:20 +00:00
ld [wHPBarOldHP],a
sub b
ld [wEnemyMonHP + 1],a
2014-05-22 22:13:20 +00:00
ld a,[hl]
ld b,a
ld a,[wEnemyMonHP]
2014-05-22 22:13:20 +00:00
ld [wHPBarOldHP+1],a
sbc b
ld [wEnemyMonHP],a
2014-05-22 22:13:20 +00:00
jr nc,.animateHpBar
; if more damage was done than the current HP, zero the HP and set the damage
; equal to how much HP the pokemon had before the attack
ld a,[wHPBarOldHP+1]
ld [hli],a
ld a,[wHPBarOldHP]
ld [hl],a
xor a
ld hl,wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld [hli],a
ld [hl],a
.animateHpBar
ld hl,wEnemyMonMaxHP
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld [wHPBarMaxHP+1],a
ld a,[hl]
ld [wHPBarMaxHP],a
ld hl,wEnemyMonHP
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld [wHPBarNewHP+1],a
ld a,[hl]
ld [wHPBarNewHP],a
hlCoord 2, 2
2014-05-22 22:13:20 +00:00
xor a
ld [wListMenuID],a
predef UpdateHPBar2 ; animate the HP bar shortening
2014-05-22 22:13:20 +00:00
ApplyAttackToEnemyPokemonDone: ; 3e19d (f:619d)
2014-08-09 05:39:13 +00:00
jp DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
ApplyAttackToPlayerPokemon: ; 3e1a0 (f:61a0)
ld a,[W_ENEMYMOVEEFFECT]
cp a,OHKO_EFFECT
jr z,ApplyDamageToPlayerPokemon
cp a,SUPER_FANG_EFFECT
jr z,.superFangEffect
cp a,SPECIAL_DAMAGE_EFFECT
jr z,.specialDamage
ld a,[W_ENEMYMOVEPOWER]
and a
jp z,ApplyAttackToPlayerPokemonDone
jr ApplyDamageToPlayerPokemon
.superFangEffect
; set the damage to half the target's HP
ld hl,wBattleMonHP
2014-05-22 22:13:20 +00:00
ld de,W_DAMAGE
ld a,[hli]
srl a
ld [de],a
inc de
ld b,a
ld a,[hl]
rr a
ld [de],a
or b
jr nz,ApplyDamageToPlayerPokemon
; make sure Super Fang's damage is always at least 1
ld a,$01
ld [de],a
jr ApplyDamageToPlayerPokemon
.specialDamage
ld hl,wEnemyMonLevel
2014-05-22 22:13:20 +00:00
ld a,[hl]
ld b,a
ld a,[W_ENEMYMOVENUM]
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
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
jr nc,.loop
ld b,a
.storeDamage
ld hl,W_DAMAGE
xor a
ld [hli],a
ld a,b
ld [hl],a
ApplyDamageToPlayerPokemon: ; 3e200 (f:6200)
ld hl,W_DAMAGE
ld a,[hli]
ld b,a
ld a,[hl]
or b
jr z,ApplyAttackToPlayerPokemonDone ; we're done if damage is 0
ld a,[W_PLAYERBATTSTATUS2]
bit 4,a ; does the player have a substitute?
jp nz,AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP and the new HP at wHPBarNewHP
ld a,[hld]
ld b,a
ld a,[wBattleMonHP + 1]
2014-05-22 22:13:20 +00:00
ld [wHPBarOldHP],a
sub b
ld [wBattleMonHP + 1],a
2014-05-22 22:13:20 +00:00
ld [wHPBarNewHP],a
ld b,[hl]
ld a,[wBattleMonHP]
2014-05-22 22:13:20 +00:00
ld [wHPBarOldHP+1],a
sbc b
ld [wBattleMonHP],a
2014-05-22 22:13:20 +00:00
ld [wHPBarNewHP+1],a
jr nc,.animateHpBar
; if more damage was done than the current HP, zero the HP and set the damage
; equal to how much HP the pokemon had before the attack
ld a,[wHPBarOldHP+1]
ld [hli],a
ld a,[wHPBarOldHP]
ld [hl],a
xor a
ld hl,wBattleMonHP
2014-05-22 22:13:20 +00:00
ld [hli],a
ld [hl],a
ld hl,wHPBarNewHP
ld [hli],a
ld [hl],a
.animateHpBar
ld hl,wBattleMonMaxHP
2014-05-22 22:13:20 +00:00
ld a,[hli]
ld [wHPBarMaxHP+1],a
ld a,[hl]
ld [wHPBarMaxHP],a
hlCoord 10, 9
2014-05-22 22:13:20 +00:00
ld a,$01
ld [wListMenuID],a
predef UpdateHPBar2 ; animate the HP bar shortening
2014-05-22 22:13:20 +00:00
ApplyAttackToPlayerPokemonDone
2014-08-09 05:39:13 +00:00
jp DrawHUDsAndHPBars
2014-05-22 22:13:20 +00:00
AttackSubstitute: ; 3e25e (f:625e)
ld hl,SubstituteTookDamageText
call PrintText
; values for player turn
ld de,wEnemySubstituteHP
ld bc,W_ENEMYBATTSTATUS2
ld a,[H_WHOSETURN]
and a
jr z,.applyDamageToSubstitute
; values for enemy turn
ld de,wPlayerSubstituteHP
ld bc,W_PLAYERBATTSTATUS2
.applyDamageToSubstitute
ld hl,W_DAMAGE
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
ld h,b
ld l,c
res 4,[hl] ; unset the substitute bit
ld hl,SubstituteBrokeText
call PrintText
; flip whose turn it is for the next function call
ld a,[H_WHOSETURN]
xor a,$01
ld [H_WHOSETURN],a
callab Func_79747 ; animate the substitute breaking
; flip the turn back to the way it was
ld a,[H_WHOSETURN]
xor a,$01
ld [H_WHOSETURN],a
ld hl,W_PLAYERMOVEEFFECT ; value for player's turn
and a
jr z,.nullifyEffect
ld hl,W_ENEMYMOVEEFFECT ; value for enemy's turn
.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
SubstituteTookDamageText: ; 3e2ac (f:62ac)
TX_FAR _SubstituteTookDamageText
db "@"
SubstituteBrokeText: ; 3e2b1 (f:62b1)
TX_FAR _SubstituteBrokeText
db "@"
; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
HandleBuildingRage: ; 3e2b6 (f:62b6)
; values for the player turn
ld hl,W_ENEMYBATTSTATUS2
ld de,wEnemyMonStatMods
ld bc,W_ENEMYMOVENUM
ld a,[H_WHOSETURN]
and a
jr z,.next
; values for the enemy turn
ld hl,W_PLAYERBATTSTATUS2
ld de,wPlayerMonStatMods
ld bc,W_PLAYERMOVENUM
.next
bit 6,[hl] ; is the pokemon being attacked under the effect of Rage?
ret z ; return if not
ld a,[de]
cp a,$0d ; 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
; change the target pokemon's move to $00 and the effect to the one
; that causes the attack modifier to go up one stage
ld h,b
ld l,c
ld [hl],$00 ; null move number
inc hl
ld [hl],ATTACK_UP1_EFFECT
push hl
ld hl,BuildingRageText
call PrintText
call StatModifierUpEffect ; stat modifier raising function
pop hl
xor a
ldd [hl],a ; null move effect
ld a,RAGE
ld [hl],a ; restore the target pokemon's move number to Rage
ld a,[H_WHOSETURN]
xor a,$01 ; flip turn back to the way it was
ld [H_WHOSETURN],a
ret
BuildingRageText: ; 3e2f8 (f:62f8)
TX_FAR _BuildingRageText
db "@"
; copy last move for Mirror Move
; sets zero flag on failure and unsets zero flag on success
MirrorMoveCopyMove: ; 3e2fd (f:62fd)
ld a,[H_WHOSETURN]
and a
; values for player turn
ld a,[wccf2]
2014-05-22 22:13:20 +00:00
ld hl,wPlayerSelectedMove
ld de,W_PLAYERMOVENUM
jr z,.next
; values for enemy turn
ld a,[wccf1]
2014-05-22 22:13:20 +00:00
ld de,W_ENEMYMOVENUM
ld hl,wEnemySelectedMove
.next
ld [hl],a
cp a,MIRROR_MOVE ; did the target pokemon also use Mirror Move?
jr z,.mirrorMoveFailed
and a ; null move?
jr nz,ReloadMoveData
.mirrorMoveFailed
; Mirror Move fails on itself and null moves
ld hl,MirrorMoveFailedText
call PrintText
xor a
ret
MirrorMoveFailedText: ; 3e324 (f:6324)
TX_FAR _MirrorMoveFailedText
db "@"
; function used to reload move data for moves like Mirror Move and Metronome
ReloadMoveData: ; 3e329 (f:6329)
ld [wd11e],a
2014-05-22 22:13:20 +00:00
dec a
ld hl,Moves
ld bc,$0006
call AddNTimes
ld a,BANK(Moves)
call FarCopyData ; copy the move's stats
call IncrementMovePP
; the follow two function calls are used to reload the move name
call GetMoveName
call CopyStringToCF4B
ld a,$01
and a
ret
; function that picks a random move for metronome
MetronomePickMove: ; 3e348 (f:6348)
xor a
ld [wcc5b],a
2014-05-22 22:13:20 +00:00
ld a,METRONOME
call PlayMoveAnimation ; play Metronome's animation
; values for player turn
ld de,W_PLAYERMOVENUM
ld hl,wPlayerSelectedMove
ld a,[H_WHOSETURN]
and a
jr z,.pickMoveLoop
; values for enemy turn
ld de,W_ENEMYMOVENUM
ld hl,wEnemySelectedMove
; loop to pick a random number in the range [1, $a5) to be the move used by Metronome
.pickMoveLoop
call BattleRandom
2014-05-22 22:13:20 +00:00
and a
jr z,.pickMoveLoop
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
IncrementMovePP: ; 3e373 (f:6373)
ld a,[H_WHOSETURN]
and a
; values for player turn
ld hl,wBattleMonPP
ld de,wPartyMon1PP
2014-05-22 22:13:20 +00:00
ld a,[wPlayerMoveListIndex]
jr z,.next
; values for enemy turn
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
jr z,.next2
ld a,[wEnemyMonPartyPos] ; value for enemy turn
2014-05-22 22:13:20 +00:00
.next2
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
AdjustDamageForMoveType: ; 3e3a5 (f:63a5)
; values for player turn
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
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
ld a,[W_PLAYERMOVETYPE]
ld [wd11e],a
2014-05-22 22:13:20 +00:00
ld a,[H_WHOSETURN]
and a
jr z,.next
; values for enemy turn
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
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
ld a,[W_ENEMYMOVETYPE]
ld [wd11e],a
2014-05-22 22:13:20 +00:00
.next
ld a,[wd11e] ; move type
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
ld hl,W_DAMAGE + 1
ld a,[hld]
ld h,[hl]
ld l,a ; hl = damage
ld b,h
ld c,l ; bc = damage
srl b
rr c ; bc = floor(0.5 * damage)
add hl,bc ; hl = floor(1.5 * damage)
; store damage
ld a,h
ld [W_DAMAGE],a
ld a,l
ld [W_DAMAGE + 1],a
ld hl,wd05b
2014-05-22 22:13:20 +00:00
set 7,[hl]
.skipSameTypeAttackBonus
ld a,[wd11e]
2014-05-22 22:13:20 +00:00
ld b,a ; b = move type
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
ld a,[wd05b]
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
ld [wd05b],a
2014-05-22 22:13:20 +00:00
xor a
ld [H_MULTIPLICAND],a
ld hl,W_DAMAGE
ld a,[hli]
ld [H_MULTIPLICAND + 1],a
ld a,[hld]
ld [H_MULTIPLICAND + 2],a
call Multiply
ld a,10
ld [H_DIVISOR],a
ld b,$04
call Divide
ld a,[H_QUOTIENT + 2]
ld [hli],a
ld b,a
ld a,[H_QUOTIENT + 3]
ld [hl],a
or b ; is damage 0?
jr nz,.skipTypeImmunity
.typeImmunity
; if damage is 0, make the move miss
inc a
ld [W_MOVEMISSED],a
.skipTypeImmunity
pop bc
pop hl
.nextTypePair
inc hl
inc hl
jp .loop
.done
ret
; function to tell how effective the type of an enemy attack is on the player's current pokemon
; this doesn't take into account the effects that dual types can have
; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
; the result is stored in [wd11e]
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
AIGetTypeEffectiveness: ; 3e449 (f:6449)
ld a,[W_ENEMYMOVETYPE]
ld d,a ; d = type of enemy move
ld hl,wBattleMonType
2014-05-22 22:13:20 +00:00
ld b,[hl] ; b = type 1 of player's pokemon
inc hl
ld c,[hl] ; c = type 2 of player's pokemon
ld a,$10
ld [wd11e],a ; initialize [wd11e] to neutral effectiveness
2014-05-22 22:13:20 +00:00
ld hl,TypeEffects
.loop
ld a,[hli]
cp a,$ff
ret z
cp d ; match the type of the move
jr nz,.nextTypePair1
ld a,[hli]
cp b ; match with type 1 of pokemon
jr z,.done
cp c ; or match with type 2 of pokemon
jr z,.done
jr .nextTypePair2
.nextTypePair1
inc hl
.nextTypePair2
inc hl
jr .loop
.done
ld a,[hl]
ld [wd11e],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
MoveHitTest: ; 3e56b (f:656b)
; player's turn
ld hl,W_ENEMYBATTSTATUS1
ld de,W_PLAYERMOVEEFFECT
ld bc,wEnemyMonStatus
2014-05-22 22:13:20 +00:00
ld a,[H_WHOSETURN]
and a
jr z,.dreamEaterCheck
; enemy's turn
ld hl,W_PLAYERBATTSTATUS1
ld de,W_ENEMYMOVEEFFECT
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]
and a,$07 ; is the target pokemon sleeping?
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 CheckTargetSubstitute ; substitute check (note that this overwrites a)
jr z,.checkForDigOrFlyStatus
; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
; since $7b79 overwrites a with either $00 or $01, it never works.
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
bit 6,[hl]
jp nz,.moveMissed
ld a,[H_WHOSETURN]
and a
jr nz,.enemyTurn
.playerTurn
; this checks if the move effect is disallowed by mist
ld a,[W_PLAYERMOVEEFFECT]
cp a,ATTACK_DOWN1_EFFECT
jr c,.skipEnemyMistCheck
cp a,BIDE_EFFECT
jr c,.enemyMistCheck
cp a,$3a
jr c,.skipEnemyMistCheck
cp a,POISON_EFFECT
jr c,.enemyMistCheck
jr .skipEnemyMistCheck
.enemyMistCheck
; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
; i.e. the following moves
; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
; FLASH, CONVERSION, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
; the moves that are marked with an asterisk are not affected since this
; function is not called when those moves are used
; XXX are there are any others like those three?
ld a,[W_ENEMYBATTSTATUS2]
bit 1,a ; is mon protected by mist?
jp nz,.moveMissed
.skipEnemyMistCheck
ld a,[W_PLAYERBATTSTATUS2]
bit 0,a ; is the player using X Accuracy?
ret nz ; if so, always hit regardless of accuracy/evasion
jr .calcHitChance
.enemyTurn
ld a,[W_ENEMYMOVEEFFECT]
cp a,ATTACK_DOWN1_EFFECT
jr c,.skipPlayerMistCheck
cp a,BIDE_EFFECT
jr c,.playerMistCheck
cp a,$3a
jr c,.skipPlayerMistCheck
cp a,POISON_EFFECT
jr c,.playerMistCheck
jr .skipPlayerMistCheck
.playerMistCheck
; similar to enemy mist check
ld a,[W_PLAYERBATTSTATUS2]
bit 1,a ; is mon protected by mist?
jp nz,.moveMissed
.skipPlayerMistCheck
ld a,[W_ENEMYBATTSTATUS2]
bit 0,a ; is the enemy using X Accuracy?
ret nz ; if so, always hit regardless of accuracy/evasion
.calcHitChance
call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
ld a,[W_PLAYERMOVEACCURACY]
ld b,a
ld a,[H_WHOSETURN]
and a
jr z,.doAccuracyCheck
ld a,[W_ENEMYMOVEACCURACY]
ld b,a
.doAccuracyCheck
; if the random number generated is greater than or equal to the scaled accuracy, the move misses
; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
jr nc,.moveMissed
ret
.moveMissed
xor a
ld hl,W_DAMAGE ; zero the damage
ld [hli],a
ld [hl],a
inc a
ld [W_MOVEMISSED],a
ld a,[H_WHOSETURN]
and a
jr z,.playerTurn2
.enemyTurn2
ld hl,W_ENEMYBATTSTATUS1
res 5,[hl] ; end multi-turn attack e.g. wrap
ret
.playerTurn2
ld hl,W_PLAYERBATTSTATUS1
res 5,[hl] ; end multi-turn attack e.g. wrap
ret
; values for player turn
CalcHitChance: ; 3e624 (f:6624)
ld hl,W_PLAYERMOVEACCURACY
ld a,[H_WHOSETURN]
and a
ld a,[wPlayerMonAccuracyMod]
ld b,a
ld a,[wEnemyMonEvasionMod]
ld c,a
jr z,.next
; values for enemy turn
ld hl,W_ENEMYMOVEACCURACY
ld a,[wEnemyMonAccuracyMod]
ld b,a
ld a,[wPlayerMonEvasionMod]
ld c,a
.next
ld a,$0e
sub c
ld c,a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion decreases the hit chance instead of increasing the hit chance)
; zero the high bytes of the multiplicand
xor a
ld [H_MULTIPLICAND],a
ld [H_MULTIPLICAND + 1],a
ld a,[hl]
ld [H_MULTIPLICAND + 2],a ; set multiplicand to move accuracy
push hl
ld d,$02 ; loop has two iterations
; loop to do the calculations, the first iteration multiplies by the accuracy ratio and the second iteration multiplies by the evasion ratio
.loop
push bc
ld hl, StatModifierRatios ; $76cb ; stat modifier ratios
dec b
sla b
ld c,b
ld b,$00
add hl,bc ; hl = address of stat modifier ratio
pop bc
ld a,[hli]
ld [H_MULTIPLIER],a ; set multiplier to the numerator of the ratio
call Multiply
ld a,[hl]
ld [H_DIVISOR],a ; set divisor to the the denominator of the ratio (the dividend is the product of the previous multiplication)
ld b,$04 ; number of bytes in the dividend
call Divide
ld a,[H_QUOTIENT + 3]
ld b,a
ld a,[H_QUOTIENT + 2]
or b
jp nz,.nextCalculation
; make sure the result is always at least one
ld [H_QUOTIENT + 2],a
ld a,$01
ld [H_QUOTIENT + 3],a
.nextCalculation
ld b,c
dec d
jr nz,.loop
ld a,[H_QUOTIENT + 2]
and a ; is the calculated hit chance over 0xFF?
ld a,[H_QUOTIENT + 3]
jr z,.storeAccuracy
; if calculated hit chance over 0xFF
ld a,$ff ; set the hit chance to 0xFF
.storeAccuracy
pop hl
ld [hl],a ; store the hit chance in the move accuracy variable
ret
2014-08-09 05:39:13 +00:00
; multiplies damage by a random percentage from ~85% to 100%
RandomizeDamage: ; 3e687 (f:6687)
ld hl, W_DAMAGE
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
2014-05-22 22:13:20 +00:00
ret c
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
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 Divide ; divide the result by 255
; store the modified damage
ld a, [H_QUOTIENT + 2]
ld hl, W_DAMAGE
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
2014-08-09 05:39:13 +00:00
ExecuteEnemyMove: ; 3e6bc (f:66bc)
ld a, [wEnemySelectedMove]
2014-05-22 22:13:20 +00:00
inc a
jp z, Func_3e88c
call PrintGhostText
jp z, Func_3e88c
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr nz, .asm_3e6dc
ld b, $1
ld a, [wcc3e]
2014-05-22 22:13:20 +00:00
cp $e
jr z, .asm_3e6dc
cp $4
ret nc
.asm_3e6dc
ld hl, wccd5
2014-05-22 22:13:20 +00:00
inc [hl]
xor a
2014-08-09 05:39:13 +00:00
ld [W_MOVEMISSED], a
ld [wccf4], a
2014-05-22 22:13:20 +00:00
ld a, $a
ld [wd05b], a
2014-08-09 05:39:13 +00:00
call CheckEnemyStatusConditions
jr nz, .canUseMove
2014-05-22 22:13:20 +00:00
jp [hl]
2014-08-09 05:39:13 +00:00
.canUseMove
ld hl, W_ENEMYBATTSTATUS1
bit 4, [hl] ; is the enemy charging up for attack?
jr nz, asm_3e70b ; if so, jump
2014-05-22 22:13:20 +00:00
call GetCurrentMove
Func_3e6fc: ; 3e6fc (f:66fc)
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp CHARGE_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
2014-05-22 22:13:20 +00:00
jr asm_3e72b
asm_3e70b: ; 3e70b (f:670b)
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 4, [hl] ; no longer charging up for attack
2014-08-09 05:39:13 +00:00
res 6, [hl] ; no longer invulnerable to typical attacks
ld a, [W_ENEMYMOVENUM]
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
ld a, $2c
ld [wPredefBank], a
2014-05-22 22:13:20 +00:00
ld a, MOVE_NAME
ld [W_LISTTYPE], a
call GetName
ld de, wcd6d
2014-05-22 22:13:20 +00:00
call CopyStringToCF4B
asm_3e72b: ; 3e72b (f:672b)
xor a
ld [wcced], a
2014-05-22 22:13:20 +00:00
call PrintMonName1Text
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
ld hl, EffectsArray1
2014-05-22 22:13:20 +00:00
ld de, $1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c, JumpMoveEffect
ld a, [W_ENEMYMOVEEFFECT]
ld hl, EffectsArray5B
2014-05-22 22:13:20 +00:00
ld de, $1
call IsInArray
2014-08-09 05:39:13 +00:00
call c, JumpMoveEffect
2014-05-22 22:13:20 +00:00
asm_3e750: ; 3e750 (f:6750)
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
ld a, [W_ENEMYMOVEEFFECT]
ld hl, EffectsArray2
2014-05-22 22:13:20 +00:00
ld de, $1
call IsInArray
jp c, Func_3e77f
call CriticalHitTest
call HandleCounterMove
jr z, asm_3e782
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
call GetDamageVarsForEnemyAttack
call SwapPlayerAndEnemyLevels
call CalculateDamage
2014-05-22 22:13:20 +00:00
jp z, Func_3e7d1
call AdjustDamageForMoveType
2014-08-09 05:39:13 +00:00
call RandomizeDamage
2014-05-22 22:13:20 +00:00
Func_3e77f: ; 3e77f (f:677f)
call MoveHitTest
asm_3e782: ; 3e782 (f:6782)
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3e791
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp EXPLODE_EFFECT
jr z, asm_3e7a0
jr Func_3e7d1
.asm_3e791
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2014-05-22 22:13:20 +00:00
Func_3e794: ; 3e794 (f:6794)
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
and a
ld a, $1
jr z, asm_3e7a4
ld a, $2
jr asm_3e7a4
asm_3e7a0: ; 3e7a0 (f:67a0)
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2014-05-22 22:13:20 +00:00
xor a
asm_3e7a4: ; 3e7a4 (f:67a4)
push af
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYBATTSTATUS2]
2014-05-22 22:13:20 +00:00
bit 4, a ; does mon have a substitute?
ld hl, Func_79747
ld b, BANK(Func_79747)
call nz, Bankswitch
pop af
ld [wcc5b], a
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
call PlayMoveAnimation
call Func_3eed3
2014-08-09 05:39:13 +00:00
call DrawEnemyHUDAndHPBar
ld a, [W_ENEMYBATTSTATUS2]
2014-05-22 22:13:20 +00:00
bit 4, a ; does mon have a substitute?
ld hl, Func_79771
ld b, BANK(Func_79771)
call nz, Bankswitch ; slide the substitute's sprite out
jr asm_3e7ef
Func_3e7d1: ; 3e7d1 (f:67d1)
2014-08-09 05:39:13 +00:00
call SwapPlayerAndEnemyLevels
2014-05-22 22:13:20 +00:00
ld c, $1e
call DelayFrames
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp FLY_EFFECT
jr z, .asm_3e7e6
cp CHARGE_EFFECT
jr z, .asm_3e7e6
jr asm_3e7ef
.asm_3e7e6
xor a
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
ld a,STATUS_AFFECTED_ANIM
call PlayMoveAnimation
asm_3e7ef: ; 3e7ef (f:67ef)
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp MIRROR_MOVE_EFFECT
jr nz, .notMirrorMoveEffect
call MirrorMoveCopyMove
jp z, Func_3e88c
jp Func_3e6fc
.notMirrorMoveEffect
cp METRONOME_EFFECT
jr nz, .notMetronomeEffect
call MetronomePickMove
jp Func_3e6fc
.notMetronomeEffect
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
ld hl, EffectsArray3
2014-05-22 22:13:20 +00:00
ld de, $1
call IsInArray
2014-08-09 05:39:13 +00:00
jp c, JumpMoveEffect
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3e82b
call PrintMoveFailureText
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
cp EXPLODE_EFFECT
jr z, .asm_3e83e
jp Func_3e88c
.asm_3e82b
call ApplyAttackToPlayerPokemon
2014-08-09 05:39:13 +00:00
call PrintCriticalOHKOText
2014-05-22 22:13:20 +00:00
callab DisplayEffectiveness
2014-08-09 05:39:13 +00:00
ld a, 1
ld [wccf4], a
2014-05-22 22:13:20 +00:00
.asm_3e83e
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
ld hl, EffectsArray4
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
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
bit 2, [hl] ; is mon hitting multiple times? (example: double kick)
jr z, .asm_3e873
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
jp nz, Func_3e794
res 2, [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
ld [wcd05], a
2014-05-22 22:13:20 +00:00
.asm_3e873
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
and a
jr z, Func_3e88c
2014-08-09 05:39:13 +00:00
ld hl, EffectsArray5
2014-05-22 22:13:20 +00:00
ld de, $1
call IsInArray
2014-08-09 05:39:13 +00:00
call nc, JumpMoveEffect
2014-05-22 22:13:20 +00:00
jr Func_3e88c
HitXTimesText: ; 3e887 (f:6887)
TX_FAR _HitXTimesText
db "@"
Func_3e88c: ; 3e88c (f:688c)
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
CheckEnemyStatusConditions: ; 3e88f (f:688f)
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
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
ld a,SLP_ANIM
call PlayMoveAnimation
2014-08-09 05:39:13 +00:00
jr .next1
.wokeUp
2014-05-22 22:13:20 +00:00
ld hl, WokeUpText
call PrintText
2014-08-09 05:39:13 +00:00
.next1
2014-05-22 22:13:20 +00:00
xor a
ld [wccf2], a
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfFrozen
bit FRZ, [hl]
jr z, .checkIfTrapped
2014-05-22 22:13:20 +00:00
ld hl, IsFrozenText
call PrintText
xor a
ld [wccf2], a
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfTrapped
ld a, [W_PLAYERBATTSTATUS1]
bit 5, a ; is the player using a multi-turn attack like warp
jp z, .checkIfFlinched
2014-05-22 22:13:20 +00:00
ld hl, CantMoveText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfFlinched
ld hl, W_ENEMYBATTSTATUS1
bit 3, [hl] ; check if enemy mon flinched
jp z, .checkIfMustRecharge
2014-05-22 22:13:20 +00:00
res 3, [hl]
ld hl, FlinchedText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfMustRecharge
ld hl, W_ENEMYBATTSTATUS2
bit 5, [hl] ; check if enemy mon has to recharge after using a move
jr z, .checkIfAnyMoveDisabled
2014-05-22 22:13:20 +00:00
res 5, [hl]
ld hl, MustRechargeText
call PrintText
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfAnyMoveDisabled
ld hl, W_ENEMYDISABLEDMOVE
2014-05-22 22:13:20 +00:00
ld a, [hl]
and a
2014-08-09 05:39:13 +00:00
jr z, .checkIfConfused
2014-05-22 22:13:20 +00:00
dec a
ld [hl], a
and $f
2014-08-09 05:39:13 +00:00
jr nz, .checkIfConfused
2014-05-22 22:13:20 +00:00
ld [hl], a
ld [wccef], a
2014-05-22 22:13:20 +00:00
ld hl, DisabledNoMoreText
call PrintText
2014-08-09 05:39:13 +00:00
.checkIfConfused
ld a, [W_ENEMYBATTSTATUS1]
add a ; check if enemy mon is confused
jp nc, .checkIfTriedToUseDisabledMove
ld hl, wd070
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
jr nz, .isConfused
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 7, [hl]
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
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
ld a,CONF_ANIM
call PlayMoveAnimation
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $80
2014-08-09 05:39:13 +00:00
jr c, .checkIfTriedToUseDisabledMove
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
ld a, [hl]
and $80
ld [hl], a
ld hl, HurtItselfText
call PrintText
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
ld a, [wEnemyMonDefense + 1]
2014-05-22 22:13:20 +00:00
ld [hl], a
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYMOVEEFFECT
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
2014-05-22 22:13:20 +00:00
ld a, $28
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
ld hl, wBattleMonDefense + 1
2014-05-22 22:13:20 +00:00
pop af
ld [hld], a
pop af
ld [hl], a
xor a
ld [wcc5b], 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
ld a, [wccef]
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
2014-08-09 05:39:13 +00:00
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfParalysed
ld hl, wEnemyMonStatus
bit PAR, [hl]
jr z, .checkIfUsingBide
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $3f
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
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
ld a, [hl]
2014-08-09 05:39:13 +00:00
and $cc ; clear bide, thrashing, charging up, and multi-turn moves such as warp
2014-05-22 22:13:20 +00:00
ld [hl], a
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
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 CHARGE_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
ld [wcc5b], 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
ld hl, Func_3e88c
jp .cannotUseMove
.checkIfUsingBide
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
bit 0, [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
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVENUM], a
ld hl, W_DAMAGE
2014-05-22 22:13:20 +00:00
ld a, [hli]
ld b, a
ld c, [hl]
ld hl, wcd06
2014-05-22 22:13:20 +00:00
ld a, [hl]
add c
ld [hld], a
ld a, [hl]
adc b
ld [hl], a
2014-08-09 05:39:13 +00:00
ld hl, wEnemyNumAttacksLeft
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
jr z, .unleashEnergy
ld hl, Func_3e88c
jp .cannotUseMove
.unleashEnergy
ld hl, W_ENEMYBATTSTATUS1
res 0, [hl] ; not using bide any more
2014-05-22 22:13:20 +00:00
ld hl, UnleashedEnergyText
call PrintText
ld a, $1
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVEPOWER], a
ld hl, wcd06
2014-05-22 22:13:20 +00:00
ld a, [hld]
add a
ld b, a
ld [wd0d8], a
2014-05-22 22:13:20 +00:00
ld a, [hl]
rl a
2014-08-09 05:39:13 +00:00
ld [W_DAMAGE], a
2014-05-22 22:13:20 +00:00
or b
2014-08-09 05:39:13 +00:00
jr nz, .next2
2014-05-22 22:13:20 +00:00
ld a, $1
2014-08-09 05:39:13 +00:00
ld [W_MOVEMISSED], a
.next2
2014-05-22 22:13:20 +00:00
xor a
ld [hli], a
ld [hl], a
ld a, BIDE
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVENUM], a
call SwapPlayerAndEnemyLevels
ld hl, asm_3e782
jp .cannotUseMove
.checkIfThrashingAbout
2014-05-22 22:13:20 +00:00
bit 1, [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
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVENUM], 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
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
ld hl, asm_3e750
jp nz, .cannotUseMove
2014-05-22 22:13:20 +00:00
push hl
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
2014-05-22 22:13:20 +00:00
res 1, [hl] ; mon is no longer using thrash or petal dance
set 7, [hl] ; mon is now confused
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
inc a
inc a
ld [wd070], a
2014-05-22 22:13:20 +00:00
pop hl
2014-08-09 05:39:13 +00:00
jp .cannotUseMove
.checkIfUsingMultiturnMove
2014-05-22 22:13:20 +00:00
bit 5, [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
2014-05-22 22:13:20 +00:00
dec [hl]
2014-08-09 05:39:13 +00:00
ld hl, Func_3e794
jp nz, .cannotUseMove
jp .cannotUseMove
.checkIfUsingRage
ld a, [W_ENEMYBATTSTATUS2]
2014-05-22 22:13:20 +00:00
bit 6, a ; is mon using rage?
2014-08-09 05:39:13 +00:00
jp z, .canUseMove
2014-05-22 22:13:20 +00:00
ld a, RAGE
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B
xor a
2014-08-09 05:39:13 +00:00
ld [W_ENEMYMOVEEFFECT], a
ld hl, asm_3e72b
jp .cannotUseMove
.cannotUseMove
xor a ; set Z flag
2014-05-22 22:13:20 +00:00
ret
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
GetCurrentMove: ; 3eabe (f:6abe)
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
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYMOVENUM
ld a, [wEnemySelectedMove]
2014-05-22 22:13:20 +00:00
jr .selected
.player
2014-08-09 05:39:13 +00:00
ld de, W_PLAYERMOVENUM
2014-05-22 22:13:20 +00:00
ld a, [W_FLAGS_D733]
bit 0, a
ld a, [wccd9]
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
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
dec a
2014-08-09 05:39:13 +00:00
ld hl, Moves
2014-05-22 22:13:20 +00:00
ld bc, $6
call AddNTimes
ld a, BANK(Moves)
call FarCopyData
ld a, $2c
ld [wPredefBank], a
2014-05-22 22:13:20 +00:00
ld a, $2
ld [W_LISTTYPE], a ; list type 2 = move name
call GetName
ld de, wcd6d
2014-05-22 22:13:20 +00:00
jp CopyStringToCF4B
2014-08-09 05:39:13 +00:00
LoadEnemyMonData: ; 3eb01 (f:6b01)
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
2014-08-09 05:39:13 +00:00
jp z, LoadEnemyMonFromParty
ld a, [wEnemyMonSpecies2]
ld [wEnemyMonSpecies], a
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
call GetMonHeader
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYBATTSTATUS3]
bit 3, a ; is enemy mon transformed?
ld hl, wcceb ; copied DVs from when it used Transform
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
ld a, [W_ISINBATTLE]
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
call BattleRandom
2014-05-22 22:13:20 +00:00
ld b, a
call BattleRandom
2014-08-09 05:39:13 +00:00
.storeDVs
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
ld a, [W_CURENEMYLVL]
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
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
cp $2 ; is it a trainer battle?
jr z, .copyHPAndStatusFromPartyData
ld a, [W_ENEMYBATTSTATUS3]
bit 3, a ; is enemy mon transformed?
jr nz, .copyTypes ; if transformed, jump
; if it's a wild mon and not transformed, init the current HP to max HP and the status to 0
ld a, [wEnemyMonMaxHP]
2014-05-22 22:13:20 +00:00
ld [hli], a
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]
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]
ld [wEnemyMonHP + 1], a
2014-08-09 05:39:13 +00:00
ld a, [wWhichPokemon]
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
2014-05-22 22:13:20 +00:00
ld hl, W_MONHTYPES
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
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
cp $2 ; is it a trainer battle?
jr nz, .copyStandardMoves
; if it's a trainer battle, copy moves from enemy party data
ld hl, wEnemyMon1Moves
2014-08-09 05:39:13 +00:00
ld a, [wWhichPokemon]
ld bc, wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
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
2014-05-22 22:13:20 +00:00
ld hl, W_MONHMOVES
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
dec de
dec de
dec de
xor a
ld [wHPBarMaxHP], a
2014-08-09 05:39:13 +00:00
predef WriteMonMoves ; get moves based on current level
.loadMovePPs
ld hl, wEnemyMonMoves
ld de, wEnemyMonSpecial + 1
predef LoadMovePPs
2014-05-22 22:13:20 +00:00
ld hl, W_MONHBASESTATS
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonBaseStats
2014-05-22 22:13:20 +00:00
ld b, $5
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
2014-05-22 22:13:20 +00:00
ld hl, W_MONHCATCHRATE
ld a, [hli]
ld [de], a
inc de
ld a, [hl] ; base exp
ld [de], a
ld a, [wEnemyMonSpecies2]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMonName
ld hl, wcd6d
ld de, wEnemyMonNick
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
ld a, [wEnemyMonSpecies2]
ld [wd11e], a
predef IndexToPokedex
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
dec a
ld c, a
ld b, $1
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
2014-05-22 22:13:20 +00:00
ld bc, $b
call CopyData
2014-08-09 05:39:13 +00:00
ld a, $7 ; default stat mod
ld b, $8 ; number of stat mods
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
DoBattleTransitionAndInitBattleVariables: ; 3ec32 (f:6c32)
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
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 DisplayLinkBattleVersusTextBox
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 ClearScreen
2014-08-09 05:39:13 +00:00
.next
2014-05-22 22:13:20 +00:00
call DelayFrame
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 ClearSprites
2014-05-22 22:13:20 +00:00
call ClearScreen
xor a
2014-08-09 05:39:13 +00:00
ld [H_AUTOBGTRANSFERENABLED], a
ld [hVBlankWY], a
ld [rWY], a
2014-05-22 22:13:20 +00:00
ld [$ffd7], a
ld hl, wd060
2014-05-22 22:13:20 +00:00
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hl], a
2014-08-09 05:39:13 +00:00
ld [W_PLAYERDISABLEDMOVE], 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
SwapPlayerAndEnemyLevels: ; 3ec81 (f:6c81)
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)
LoadPlayerBackPic: ; 3ec92 (f:6c92)
ld a, [W_BATTLETYPE]
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
predef ScaleSpriteByTwo
2014-05-22 22:13:20 +00:00
ld hl, wOAMBuffer
xor a
2014-08-09 05:39:13 +00:00
ld [$FF8B], a ; initial tile number
ld b, $7 ; 7 columns
ld e, $a0 ; X for the left-most column
.loop ; each loop iteration writes 3 OAM entries in a vertical column
ld c, $3 ; 3 tiles per column
ld d, $38 ; Y for the top of each column
.innerLoop ; each loop iteration writes 1 OAM entry in the column
ld [hl], d ; OAM Y
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
2014-08-09 05:39:13 +00:00
ld a, [$FF8B]
ld [hli], a ; OAM tile number
inc a ; increment tile number
ld [$FF8B], a
2014-05-22 22:13:20 +00:00
inc hl
dec c
2014-08-09 05:39:13 +00:00
jr nz, .innerLoop
ld a, [$FF8B]
add $4 ; increase tile number by 4
ld [$FF8B], a
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
2014-05-22 22:13:20 +00:00
ld de, S_SPRITEBUFFER1
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
ld [$ffe1], a
hlCoord 1, 5
predef_jump Func_3f0c6
2014-05-22 22:13:20 +00:00
Func_3ed02: ; 3ed02 (f:6d02)
callab Func_39680
ld hl, Func_396a7
ld b, BANK(Func_396a7)
jp Bankswitch
ScrollTrainerPicAfterBattle: ; 3ed12 (f:6d12)
ld hl, _ScrollTrainerPicAfterBattle
ld b, BANK(_ScrollTrainerPicAfterBattle)
jp Bankswitch
2014-08-09 05:39:13 +00:00
ApplyBurnAndParalysisPenaltiesToPlayer: ; 3ed1a (f:6d1a)
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
2014-08-09 05:39:13 +00:00
ApplyBurnAndParalysisPenaltiesToEnemy: ; 3ed1e (f:6d1e)
2014-05-22 22:13:20 +00:00
xor a
2014-08-09 05:39:13 +00:00
ApplyBurnAndParalysisPenalties: ; 3ed1f (f:6d1f)
ld [H_WHOSETURN], a
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
QuarterSpeedDueToParalysis: ; 3ed27 (f:6d27)
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
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
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
2014-08-09 05:39:13 +00:00
HalveAttackDueToBurn: ; 3ed64 (f:6d64)
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
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
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
2014-08-09 05:39:13 +00:00
CalculateModifiedStats: ; 3ed99 (f:6d99)
ld c, 0
.loop
call CalculateModifiedStat
2014-05-22 22:13:20 +00:00
inc c
ld a, c
2014-08-09 05:39:13 +00:00
cp 4
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)
CalculateModifiedStat: ; 3eda5 (f:6da5)
2014-05-22 22:13:20 +00:00
push bc
push bc
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
and a
ld a, c
ld hl, wBattleMonAttack
2014-08-09 05:39:13 +00:00
ld de, wPlayerMonUnmodifiedAttack
ld bc, wPlayerMonAttackMod
jr z, .next
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 Divide
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
2014-08-09 05:39:13 +00:00
ApplyBadgeStatBoosts: ; 3ee19 (f:6e19)
2014-05-22 22:13:20 +00:00
ld a, [W_ISLINKBATTLE]
cp $4
2014-08-09 05:39:13 +00:00
ret z ; return if link battle
2014-05-22 22:13:20 +00:00
ld a, [W_OBTAINEDBADGES]
ld b, a
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
2014-08-09 05:39:13 +00:00
LoadHudAndHpBarAndStatusTilePatterns: ; 3ee58 (f:6e58)
2014-05-22 22:13:20 +00:00
call LoadHpBarAndStatusTilePatterns
2014-08-09 05:39:13 +00:00
LoadHudTilePatterns: ; 3ee5b (f:6e5b)
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 + $6d0
2014-05-22 22:13:20 +00:00
ld bc, $18
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
2014-05-22 22:13:20 +00:00
ld bc, $30
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 + $6d0
2014-05-22 22:13:20 +00:00
ld bc, (BANK(BattleHudTiles1) << 8) + $03
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
2014-05-22 22:13:20 +00:00
ld bc, (BANK(BattleHudTiles2) << 8) + $06
jp CopyVideoDataDouble
2014-08-09 05:39:13 +00:00
PrintEmptyString: ; 3ee94 (f:6e94)
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 "@"
BattleRandom:
; Link battles use a shared PRNG.
2014-05-22 22:13:20 +00:00
ld a, [W_ISLINKBATTLE]
cp $4
jp nz, Random
2014-05-22 22:13:20 +00:00
push hl
push bc
ld a, [wccde]
2014-05-22 22:13:20 +00:00
ld c, a
ld b, 0
ld hl, wd148
2014-05-22 22:13:20 +00:00
add hl, bc
inc a
ld [wccde], a
cp 9
2014-05-22 22:13:20 +00:00
ld a, [hl]
pop bc
pop hl
ret c
2014-05-22 22:13:20 +00:00
push hl
push bc
push af
2014-05-22 22:13:20 +00:00
xor a
ld [wccde], a
ld hl, wd148
ld b, 9
.loop
2014-05-22 22:13:20 +00:00
ld a, [hl]
ld c, a
add a
add a
add c
inc a
ld [hli], a
dec b
jr nz, .loop
2014-05-22 22:13:20 +00:00
pop af
pop bc
pop hl
ret
2014-05-22 22:13:20 +00:00
Func_3eed3: ; 3eed3 (f:6ed3)
2014-08-09 05:39:13 +00:00
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
ld hl, wEnemyMonType1 ; wcfea (aliases: wEnemyMonType)
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYBATTSTATUS1
ld a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
jr z, .asm_3eeea
ld hl, wBattleMonType1 ; wd019 (aliases: wBattleMonType)
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYBATTSTATUS1
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
.asm_3eeea
cp SELFDESTRUCT
jr z, .asm_3eef1
cp EXPLOSION
ret nz
.asm_3eef1
ld a, [de]
bit 6, a ; fly/dig
ret nz
ld a, [hli]
cp GHOST
ret z
ld a, [hl]
cp GHOST
ret z
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
ret nz
ld a, MEGA_PUNCH
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
PlayMoveAnimation: ; 3ef07 (f:6f07)
ld [W_ANIMATIONID],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
InitBattle: ; 3ef12 (f:6f12)
2014-08-09 05:39:13 +00:00
ld a, [W_CUROPPONENT]
2014-05-22 22:13:20 +00:00
and a
jr z, asm_3ef23
InitOpponent: ; 3ef18 (f:6f18)
2014-08-09 05:39:13 +00:00
ld a, [W_CUROPPONENT]
ld [wcf91], a
ld [wEnemyMonSpecies2], a
2014-05-22 22:13:20 +00:00
jr asm_3ef3d
asm_3ef23: ; 3ef23 (f:6f23)
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
callab Func_13870
ret nz
asm_3ef3d: ; 3ef3d (f:6f3d)
2014-09-13 07:50:56 +00:00
ld a, [wMapPalOffset]
2014-05-22 22:13:20 +00:00
push af
ld hl, wd358
2014-05-22 22:13:20 +00:00
ld a, [hl]
push af
res 1, [hl]
callab Func_525af
ld a, [wEnemyMonSpecies2]
2014-05-22 22:13:20 +00:00
sub $c8
jp c, InitWildBattle
2014-08-09 05:39:13 +00:00
ld [W_TRAINERCLASS], 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
ld [wEnemyMonSpecies2], a
2014-05-22 22:13:20 +00:00
ld [$ffe1], a
dec a
2014-08-09 05:39:13 +00:00
ld [wAICount], a
hlCoord 12, 0
predef Func_3f0c6
2014-05-22 22:13:20 +00:00
ld a, $ff
ld [wEnemyMonPartyPos], a
2014-05-22 22:13:20 +00:00
ld a, $2
2014-08-09 05:39:13 +00:00
ld [W_ISINBATTLE], a
jp InitBattle_Common
2014-05-22 22:13:20 +00:00
InitWildBattle: ; 3ef8b (f:6f8b)
ld a, $1
2014-08-09 05:39:13 +00:00
ld [W_ISINBATTLE], a
call LoadEnemyMonData
call DoBattleTransitionAndInitBattleVariables
ld a, [W_CUROPPONENT]
2014-05-22 22:13:20 +00:00
cp MAROWAK
jr z, .isGhost
call IsGhostBattle
jr nz, .isNoGhost
.isGhost
ld hl, W_MONHSPRITEDIM
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
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], "@"
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
ld a, MON_GHOST
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
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
2014-08-09 05:39:13 +00:00
ld [W_TRAINERCLASS], a
2014-05-22 22:13:20 +00:00
ld [$ffe1], a
hlCoord 12, 0
predef Func_3f0c6
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
InitBattle_Common: ; 3efeb (f:6feb)
2014-05-22 22:13:20 +00:00
ld b, $0
call GoPAL_SET
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 ClearScreen
ld a, $98
ld [$ffbd], a
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, $9c
ld [$ffbd], a
call LoadScreenTilesFromBuffer1
hlCoord 9, 7
2014-05-22 22:13:20 +00:00
ld bc, $50a
call ClearScreenArea
hlCoord 1, 0
2014-05-22 22:13:20 +00:00
ld bc, $40a
call ClearScreenArea
2014-05-23 22:34:35 +00:00
call ClearSprites
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
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
ld [wd358], a
2014-05-22 22:13:20 +00:00
pop af
2014-09-13 07:50:56 +00:00
ld [wMapPalOffset], a
ld a, [wd0d4]
2014-05-22 22:13:20 +00:00
ld [$ffd7], a
scf
ret
2014-08-09 05:39:13 +00:00
.emptyString
2014-05-22 22:13:20 +00:00
db "@"
_LoadTrainerPic: ; 3f04b (f:704b)
; wd033-wd034 contain pointer to pic
ld a, [wd033]
2014-05-22 22:13:20 +00:00
ld e, a
ld a, [wd034]
2014-05-22 22:13:20 +00:00
ld d, a ; de contains pointer to trainer pic
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
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
Func_3f069: ; 3f069 (f:7069)
xor a
ld [wc0f1], a
ld [wc0f2], a
2014-05-22 22:13:20 +00:00
jp PlaySound
Func_3f073: ; 3f073 (f:7073)
ld a, [wPredefRegisters]
2014-05-22 22:13:20 +00:00
ld h, a
ld a, [wPredefRegisters + 1]
2014-05-22 22:13:20 +00:00
ld l, a
ld a, [$ffe1]
2014-08-09 05:39:13 +00:00
ld [H_DOWNARROWBLINKCNT1], a
2014-05-22 22:13:20 +00:00
ld b, $4c
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f0bc
add b
ld [hl], a
call Delay3
2014-08-09 05:39:13 +00:00
ld bc, -41
2014-05-22 22:13:20 +00:00
add hl, bc
ld a, $1
ld [wcd6c], a
2014-05-22 22:13:20 +00:00
ld bc, $303
predef Func_79aba
2014-05-22 22:13:20 +00:00
ld c, $4
call DelayFrames
2014-08-09 05:39:13 +00:00
ld bc, -41
2014-05-22 22:13:20 +00:00
add hl, bc
xor a
ld [wcd6c], a
2014-05-22 22:13:20 +00:00
ld bc, $505
predef Func_79aba
2014-05-22 22:13:20 +00:00
ld c, $5
call DelayFrames
2014-08-09 05:39:13 +00:00
ld bc, -41
2014-05-22 22:13:20 +00:00
jr .asm_3f0bf
.asm_3f0bc
2014-08-09 05:39:13 +00:00
ld bc, -123
2014-05-22 22:13:20 +00:00
.asm_3f0bf
add hl, bc
2014-08-09 05:39:13 +00:00
ld a, [H_DOWNARROWBLINKCNT1]
2014-05-22 22:13:20 +00:00
add $31
jr asm_3f0d0
Func_3f0c6: ; 3f0c6 (f:70c6)
ld a, [wPredefRegisters]
2014-05-22 22:13:20 +00:00
ld h, a
ld a, [wPredefRegisters + 1]
2014-05-22 22:13:20 +00:00
ld l, a
ld a, [$ffe1]
asm_3f0d0: ; 3f0d0 (f:70d0)
ld bc, $707
ld de, $14
push af
ld a, [W_SPRITEFLIPPED]
and a
jr nz, .asm_3f0ed
pop af
.asm_3f0de
push bc
push hl
.asm_3f0e0
ld [hl], a
add hl, de
inc a
dec c
jr nz, .asm_3f0e0
pop hl
inc hl
pop bc
dec b
jr nz, .asm_3f0de
ret
.asm_3f0ed
push bc
ld b, $0
dec c
add hl, bc
pop bc
pop af
.asm_3f0f4
push bc
push hl
.asm_3f0f6
ld [hl], a
add hl, de
inc a
dec c
jr nz, .asm_3f0f6
pop hl
dec hl
pop bc
dec b
jr nz, .asm_3f0f4
ret
LoadMonBackPic:
2014-05-29 08:31:46 +00:00
; Assumes the monster's attributes have
; been loaded with GetMonHeader.
ld a, [wBattleMonSpecies2]
ld [wcf91], a
hlCoord 1, 5
2014-05-22 22:13:20 +00:00
ld b, $7
ld c, $8
call ClearScreenArea
ld hl, W_MONHBACKSPRITE - W_MONHEADER
call UncompressMonSprite
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*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
ld a, [H_LOADEDROMBANK]
ld b, a
jp CopyVideoData
2014-08-09 05:39:13 +00:00
JumpMoveEffect: ; 3f132 (f:7132)
call _JumpMoveEffect
2014-05-22 22:13:20 +00:00
ld b, $1
ret
2014-08-09 05:39:13 +00:00
_JumpMoveEffect: ; 3f138 (f:7138)
2014-05-22 22:13:20 +00:00
ld a, [$fff3] ;whose turn?
and a
ld a, [W_PLAYERMOVEEFFECT]
jr z, .next1
ld a, [W_ENEMYMOVEEFFECT]
.next1
dec a ;subtract 1, there is no special effect for 00
add a ;x2, 16bit pointers
ld hl, MoveEffectPointerTable
ld b, 0
ld c, a
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
jp [hl] ;jump to special effect handler
MoveEffectPointerTable: ; 3f150 (f:7150)
dw SleepEffect ; unused effect
dw PoisonEffect ; POISON_SIDE_EFFECT1
dw DrainHPEffect ; DRAIN_HP_EFFECT
dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT1
dw FreezeBurnParalyzeEffect ; FREEZE_SIDE_EFFECT
dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT1
dw ExplodeEffect ; EXPLODE_EFFECT
dw DrainHPEffect ; DREAM_EATER_EFFECT
dw $0000 ; MIRROR_MOVE_EFFECT
dw StatModifierUpEffect ; ATTACK_UP1_EFFECT
dw StatModifierUpEffect ; DEFENSE_UP1_EFFECT
dw StatModifierUpEffect ; SPEED_UP1_EFFECT
dw StatModifierUpEffect ; SPECIAL_UP1_EFFECT
dw StatModifierUpEffect ; ACCURACY_UP1_EFFECT
dw StatModifierUpEffect ; EVASION_UP1_EFFECT
dw PayDayEffect ; PAY_DAY_EFFECT
dw $0000 ; SWIFT_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN1_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN1_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN1_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN1_EFFECT
dw StatModifierDownEffect ; ACCURACY_DOWN1_EFFECT
dw StatModifierDownEffect ; EVASION_DOWN1_EFFECT
dw ConversionEffect ; CONVERSION_EFFECT
dw HazeEffect ; HAZE_EFFECT
dw BideEffect ; BIDE_EFFECT
dw ThrashPetalDanceEffect ; THRASH_PETAL_DANCE_EFFECT
dw SwitchAndTeleportEffect ; SWITCH_AND_TELEPORT_EFFECT
dw TwoToFiveAttacksEffect ; TWO_TO_FIVE_ATTACKS_EFFECT
dw TwoToFiveAttacksEffect ; unused effect
dw FlichSideEffect ; FLINCH_SIDE_EFFECT1
dw SleepEffect ; SLEEP_EFFECT
dw PoisonEffect ; POISON_SIDE_EFFECT2
dw FreezeBurnParalyzeEffect ; BURN_SIDE_EFFECT2
dw FreezeBurnParalyzeEffect ; unused effect
dw FreezeBurnParalyzeEffect ; PARALYZE_SIDE_EFFECT2
dw FlichSideEffect ; FLINCH_SIDE_EFFECT2
dw OneHitKOEffect ; OHKO_EFFECT
dw ChargeEffect ; CHARGE_EFFECT
dw $0000 ; SUPER_FANG_EFFECT
dw $0000 ; SPECIAL_DAMAGE_EFFECT
dw TrappingEffect ; TRAPPING_EFFECT
dw ChargeEffect ; FLY_EFFECT
dw TwoToFiveAttacksEffect ; ATTACK_TWICE_EFFECT
dw $0000 ; JUMP_KICK_EFFECT
dw MistEffect ; MIST_EFFECT
dw FocusEnergyEffect ; FOCUS_ENERGY_EFFECT
dw RecoilEffect ; RECOIL_EFFECT
dw ConfusionEffect ; CONFUSION_EFFECT
dw StatModifierUpEffect ; ATTACK_UP2_EFFECT
dw StatModifierUpEffect ; DEFENSE_UP2_EFFECT
dw StatModifierUpEffect ; SPEED_UP2_EFFECT
dw StatModifierUpEffect ; SPECIAL_UP2_EFFECT
dw StatModifierUpEffect ; ACCURACY_UP2_EFFECT
dw StatModifierUpEffect ; EVASION_UP2_EFFECT
dw HealEffect ; HEAL_EFFECT
dw TransformEffect ; TRANSFORM_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN2_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN2_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN2_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN2_EFFECT
dw StatModifierDownEffect ; ACCURACY_DOWN2_EFFECT
dw StatModifierDownEffect ; EVASION_DOWN2_EFFECT
dw ReflectLightScreenEffect ; LIGHT_SCREEN_EFFECT
dw ReflectLightScreenEffect ; REFLECT_EFFECT
dw PoisonEffect ; POISON_EFFECT
dw ParalyzeEffect ; PARALYZE_EFFECT
dw StatModifierDownEffect ; ATTACK_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; DEFENSE_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; SPEED_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; SPECIAL_DOWN_SIDE_EFFECT
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw StatModifierDownEffect ; unused effect
dw ConfusionSideEffect ; CONFUSION_SIDE_EFFECT
dw TwoToFiveAttacksEffect ; TWINEEDLE_EFFECT
dw $0000 ; unused effect
dw SubstituteEffect ; SUBSTITUTE_EFFECT
dw HyperBeamEffect ; HYPER_BEAM_EFFECT
dw RageEffect ; RAGE_EFFECT
dw MimicEffect ; MIMIC_EFFECT
dw $0000 ; METRONOME_EFFECT
dw LeechSeedEffect ; LEECH_SEED_EFFECT
dw SplashEffect ; SPLASH_EFFECT
dw DisableEffect ; DISABLE_EFFECT
SleepEffect: ; 3f1fc (f:71fc)
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonStatus
ld bc, W_ENEMYBATTSTATUS2
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jp z, .asm_3f20e
2014-08-09 05:39:13 +00:00
ld de, wBattleMonStatus
ld bc, W_PLAYERBATTSTATUS2
2014-05-22 22:13:20 +00:00
.asm_3f20e
ld a, [bc]
bit 5, a ; does the mon need to recharge? (hyper beam)
res 5, a ; mon no longer needs to recharge
ld [bc], a
jr nz, .asm_3f231
ld a, [de]
ld b, a
and $7
jr z, .asm_3f222
ld hl, AlreadyAsleepText
jp PrintText
.asm_3f222
ld a, b
and a
jr nz, .asm_3f242
push de
call MoveHitTest
pop de
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3f242
.asm_3f231
call BattleRandom
2014-05-22 22:13:20 +00:00
and $7
jr z, .asm_3f231
ld [de], a
call Func_3fb89
ld hl, FellAsleepText
jp PrintText
.asm_3f242
jp PrintDidntAffectText
FellAsleepText: ; 3f245 (f:7245)
TX_FAR _FellAsleepText
db "@"
AlreadyAsleepText: ; 3f24a (f:724a)
TX_FAR _AlreadyAsleepText
db "@"
PoisonEffect: ; 3f24f (f:724f)
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonStatus
ld de, W_PLAYERMOVEEFFECT
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f260
2014-08-09 05:39:13 +00:00
ld hl, wBattleMonStatus
ld de, W_ENEMYMOVEEFFECT
2014-05-22 22:13:20 +00:00
.asm_3f260
call CheckTargetSubstitute
jr nz, .asm_3f2d3
ld a, [hli]
ld b, a
and a
jr nz, .asm_3f2d3
ld a, [hli]
cp $3
jr z, .asm_3f2d3
ld a, [hld]
cp $3
jr z, .asm_3f2d3
ld a, [de]
cp POISON_SIDE_EFFECT1
ld b, $34 ; ~20% chance of poisoning
jr z, .asm_3f290
cp POISON_SIDE_EFFECT2
ld b, $67 ; ~40% chance of poisoning
jr z, .asm_3f290
push hl
push de
call MoveHitTest
pop de
pop hl
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3f2d7
jr .asm_3f295
.asm_3f290
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
ret nc
.asm_3f295
dec hl
set 3, [hl]
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
ld b, $c7
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS3
2014-05-22 22:13:20 +00:00
ld a, [de]
2014-08-09 05:39:13 +00:00
ld de, W_PLAYERTOXICCOUNTER
2014-05-22 22:13:20 +00:00
jr nz, .asm_3f2b0
ld b, $a9
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS3
ld de, W_ENEMYTOXICCOUNTER
2014-05-22 22:13:20 +00:00
.asm_3f2b0
cp $5c
jr nz, .asm_3f2bd
set 0, [hl]
xor a
ld [de], a
ld hl, BadlyPoisonedText
jr .asm_3f2c0
.asm_3f2bd
ld hl, PoisonedText
.asm_3f2c0
pop de
ld a, [de]
cp POISON_EFFECT
jr z, .asm_3f2cd
ld a, b
call Func_3fb96
jp PrintText
.asm_3f2cd
call Func_3fb89
jp PrintText
.asm_3f2d3
ld a, [de]
cp POISON_EFFECT
ret nz
.asm_3f2d7
ld c, $32
call DelayFrames
jp PrintDidntAffectText
PoisonedText: ; 3f2df (f:72df)
TX_FAR _PoisonedText
db "@"
BadlyPoisonedText: ; 3f2e4 (f:72e4)
TX_FAR _BadlyPoisonedText
db "@"
DrainHPEffect: ; 3f2e9 (f:72e9)
ld hl, DrainHPEffect_
ld b, BANK(DrainHPEffect_)
jp Bankswitch
ExplodeEffect: ; 3f2f1 (f:72f1)
2014-08-09 05:39:13 +00:00
ld hl, wBattleMonHP
ld de, W_PLAYERBATTSTATUS2
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f302
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonHP
ld de, W_ENEMYBATTSTATUS2
2014-05-22 22:13:20 +00:00
.asm_3f302
xor a
ld [hli], a ; set the mon's HP to 0
ld [hli], a
inc hl
ld [hl], a ; set mon's status to 0
ld a, [de]
res 7, a ; clear mon's leech seed status
ld [de], a
ret
FreezeBurnParalyzeEffect: ; 3f30c (f:730c)
xor a
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
call CheckTargetSubstitute ;test bit 4 of d063/d068 flags [target has substitute flag]
ret nz ;return if they have a substitute, can't effect them
ld a, [$fff3] ;whose turn?
and a
jp nz, opponentAttacker
ld a, [wEnemyMonStatus]
2014-05-22 22:13:20 +00:00
and a
jp nz, CheckDefrost
;opponent has no existing status
ld a, [W_PLAYERMOVETYPE]
ld b, a
ld a, [wEnemyMonType1]
2014-05-22 22:13:20 +00:00
cp b
ret z ;return if they match [can't freeze an ice type etc.]
ld a, [wEnemyMonType2]
2014-05-22 22:13:20 +00:00
cp b
ret z ;return..
ld a, [W_PLAYERMOVEEFFECT]
cp a, 7 ;10% status effects are 04, 05, 06 so 07 will set carry for those
ld b, $1a ;[1A-1]/100 or [26-1]/256 = 9.8%~ chance
jr c, .next1 ;branch ahead if this is a 10% chance effect..
ld b, $4d ;..or use [4D-1]/100 or [76-1]/256 = 29.7%~ chance
sub a, $1e ;subtract $1E to map to equivalent 10% chance effects
.next1
push af ;push effect...
call BattleRandom ;get random 8bit value for probability test
2014-05-22 22:13:20 +00:00
cp b ;success?
pop bc ;...pop effect into C
ret nc ;do nothing if random value is >= 1A or 4D [no status applied]
;the test passed
ld a, b ;what type of effect is this?
cp a, BURN_SIDE_EFFECT1
jr z, .burn
cp a, FREEZE_SIDE_EFFECT
jr z, .freeze
ld a, 1 << PAR
ld [wEnemyMonStatus], a
2014-08-09 05:39:13 +00:00
call QuarterSpeedDueToParalysis ;quarter speed of affected monster
2014-05-22 22:13:20 +00:00
ld a, $a9
call Func_3fbb9 ;animation
jp PrintMayNotAttackText ;print paralysis text
.burn
ld a, 1 << BRN
ld [wEnemyMonStatus], a
2014-08-09 05:39:13 +00:00
call HalveAttackDueToBurn
2014-05-22 22:13:20 +00:00
ld a, $a9
call Func_3fbb9 ;animation
ld hl, BurnedText
jp PrintText
.freeze
call Func_3f9cf ;resets bit 5 of the D063/D068 flags
ld a, 1 << FRZ
ld [wEnemyMonStatus], a
2014-05-22 22:13:20 +00:00
ld a, $a9
call Func_3fbb9 ;animation
ld hl, FrozenText
jp PrintText
opponentAttacker: ; 3f382 (f:7382)
ld a, [wBattleMonStatus] ;this appears to the same as above with addresses swapped for opponent
2014-05-22 22:13:20 +00:00
and a
jp nz, CheckDefrost
ld a, [W_ENEMYMOVETYPE]
ld b, a
ld a, [wBattleMonType1]
2014-05-22 22:13:20 +00:00
cp b
ret z
ld a, [wBattleMonType2]
2014-05-22 22:13:20 +00:00
cp b
ret z
ld a, [W_ENEMYMOVEEFFECT]
cp a, 7
ld b, $1a
jr c, .next1
ld b, $4d
sub a, $1e
.next1
push af
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
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
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
ld a, 1 << FRZ
ld [wBattleMonStatus], a
2014-05-22 22:13:20 +00:00
ld hl, FrozenText
jp PrintText
BurnedText: ; 3f3d8 (f:73d8)
TX_FAR _BurnedText
db "@"
FrozenText: ; 3f3dd (f:73dd)
TX_FAR _FrozenText
db "@"
CheckDefrost: ; 3f3e2 (f:73e2)
and a, 1 << FRZ ;are they frozen?
ret z ;return if so
;not frozen
ld a, [$fff3] ;whose turn?
and a
jr nz, .opponent
;player [attacker]
ld a, [W_PLAYERMOVETYPE]
sub a, FIRE
ret nz ;return if it isn't fire
;type is fire
ld [wEnemyMonStatus], a ;set opponent status to 00 ["defrost" a frozen monster]
ld hl, wEnemyMon1Status
ld a, [wEnemyMonPartyPos]
ld bc, wEnemyMon2 - wEnemyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
xor a
ld [hl], a ;clear status in roster
ld hl, FireDefrostedText
jr .common
.opponent
ld a, [W_ENEMYMOVETYPE] ;same as above with addresses swapped
sub a, FIRE
ret nz
ld [wBattleMonStatus], a
ld hl, wPartyMon1Status
2014-05-22 22:13:20 +00:00
ld a, [wPlayerMonNumber]
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
FireDefrostedText: ; 3f423 (f:7423)
TX_FAR _FireDefrostedText
db "@"
StatModifierUpEffect: ; 3f428 (f:7428)
2014-08-09 05:39:13 +00:00
ld hl, wPlayerMonStatMods
ld de, W_PLAYERMOVEEFFECT
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f439
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonStatMods
ld de, W_ENEMYMOVEEFFECT
2014-05-22 22:13:20 +00:00
.asm_3f439
ld a, [de]
sub $a
cp $8
jr c, .asm_3f442
sub $28
.asm_3f442
ld c, a
ld b, $0
add hl, bc
ld b, [hl]
inc b
ld a, $d
cp b
jp c, Func_3f522
ld a, [de]
cp $12
jr c, .asm_3f45a
inc b
ld a, $d
cp b
jr nc, .asm_3f45a
ld b, a
.asm_3f45a
ld [hl], b
ld a, c
cp $4
jr nc, asm_3f4ca
push hl
ld hl, wBattleMonAttack + 1
ld de, wcd12
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_3f472
ld hl, wEnemyMonAttack + 1
2014-08-09 05:39:13 +00:00
ld de, wEnemyMonUnmodifiedAttack
2014-05-22 22:13:20 +00:00
.asm_3f472
push bc
sla c
ld b, $0
add hl, bc
ld a, c
add e
ld e, a
jr nc, .asm_3f47e
inc d
.asm_3f47e
pop bc
ld a, [hld]
sub $e7
jr nz, .asm_3f48a
ld a, [hl]
sbc $3
jp z, Func_3f520
.asm_3f48a
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
ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
ld a, [de]
ld [$ff97], a
inc de
ld a, [de]
ld [$ff98], a
ld a, [hli]
ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
call Multiply
ld a, [hl]
ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
ld b, $4
call Divide
pop hl
ld a, [$ff98]
sub $e7
ld a, [$ff97]
sbc $3
jp c, Func_3f4c3
ld a, 999 / $100
ld [$ff97], a
ld a, 999 % $100
ld [$ff98], a
Func_3f4c3: ; 3f4c3 (f:74c3)
ld a, [$ff97]
ld [hli], a
ld a, [$ff98]
ld [hl], a
pop hl
asm_3f4ca: ; 3f4ca (f:74ca)
ld b, c
inc b
call Func_3f688
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS2
ld de, W_PLAYERMOVENUM
ld bc, wccf7
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
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS2
ld de, W_ENEMYMOVENUM
ld bc, wccf3
2014-05-22 22:13:20 +00:00
.asm_3f4e6
ld a, [de]
cp MINIMIZE
jr nz, .asm_3f4f9
bit 4, [hl]
push af
push bc
ld hl, Func_79747
ld b, BANK(Func_79747)
push de
call nz, Bankswitch
pop de
.asm_3f4f9
call Func_3fba8
ld a, [de]
cp MINIMIZE
jr nz, .asm_3f50e
pop bc
ld a, $1
ld [bc], a
ld hl, Func_79771
ld b, BANK(Func_79771)
pop af
call nz, Bankswitch
.asm_3f50e
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
call z, ApplyBadgeStatBoosts
2014-05-22 22:13:20 +00:00
ld hl, MonsStatsRoseText
call PrintText
2014-08-09 05:39:13 +00:00
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
2014-05-22 22:13:20 +00:00
Func_3f520: ; 3f520 (f:7520)
pop hl
dec [hl]
Func_3f522: ; 3f522 (f:7522)
ld hl, NothingHappenedText
jp PrintText
MonsStatsRoseText: ; 3f528 (f:7528)
TX_FAR _MonsStatsRoseText
db $08 ; asm
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
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVEEFFECT]
2014-05-22 22:13:20 +00:00
jr z, .asm_3f53b
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
.asm_3f53b
cp ATTACK_DOWN1_EFFECT
ret nc
ld hl, RoseText
ret
GreatlyRoseText: ; 3f542 (f:7542)
db $0a
TX_FAR _GreatlyRoseText
RoseText: ; 3f547 (f:7547)
TX_FAR _RoseText
db "@"
StatModifierDownEffect: ; 3f54c (f:754c)
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonStatMods
ld de, W_PLAYERMOVEEFFECT
ld bc, W_ENEMYBATTSTATUS1
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f572
2014-08-09 05:39:13 +00:00
ld hl, wPlayerMonStatMods
ld de, W_ENEMYMOVEEFFECT
ld bc, W_PLAYERBATTSTATUS1
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
jr z, .asm_3f572
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $40
jp c, Func_3f65a
.asm_3f572
call CheckTargetSubstitute
jp nz, Func_3f65a
ld a, [de]
cp ATTACK_DOWN_SIDE_EFFECT
jr c, .asm_3f58a
call BattleRandom
2014-05-22 22:13:20 +00:00
cp SPLASH_EFFECT
jp nc, Func_3f650
ld a, [de]
sub ATTACK_DOWN_SIDE_EFFECT
jr .asm_3f5a9
.asm_3f58a
push hl
push de
push bc
call MoveHitTest
pop bc
pop de
pop hl
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jp nz, Func_3f65a
ld a, [bc]
bit 6, a
jp nz, Func_3f65a
ld a, [de]
sub $12
cp $8
jr c, .asm_3f5a9
sub $28
.asm_3f5a9
ld c, a
ld b, $0
add hl, bc
ld b, [hl]
dec b
jp z, Func_3f650
ld a, [de]
cp $24
jr c, .asm_3f5bf
cp $44
jr nc, .asm_3f5bf
dec b
jr nz, .asm_3f5bf
inc b
.asm_3f5bf
ld [hl], b
ld a, c
cp $4
jr nc, asm_3f62c
push hl
push de
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
jr z, .asm_3f5d8
ld hl, wBattleMonAttack + 1
ld de, wcd12
2014-05-22 22:13:20 +00:00
.asm_3f5d8
push bc
sla c
ld b, $0
add hl, bc
ld a, c
add e
ld e, a
jr nc, .asm_3f5e4
inc d
.asm_3f5e4
pop bc
ld a, [hld]
sub $1
jr nz, .asm_3f5ef
ld a, [hl]
and a
jp z, Func_3f64d
.asm_3f5ef
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
ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
ld a, [de]
ld [$ff97], a
inc de
ld a, [de]
ld [$ff98], a
ld a, [hli]
ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
call Multiply
ld a, [hl]
ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
ld b, $4
call Divide
pop hl
ld a, [$ff98]
ld b, a
ld a, [$ff97]
or b
jp nz, Func_3f624
ld [$ff97], a
ld a, $1
ld [$ff98], a
Func_3f624: ; 3f624 (f:7624)
ld a, [$ff97]
ld [hli], a
ld a, [$ff98]
ld [hl], a
pop de
pop hl
asm_3f62c: ; 3f62c (f:762c)
ld b, c
inc b
push de
call Func_3f688
pop de
ld a, [de]
cp $44
jr nc, .asm_3f63b
call Func_3fb89
.asm_3f63b
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
call nz, ApplyBadgeStatBoosts
2014-05-22 22:13:20 +00:00
ld hl, MonsStatsFellText
call PrintText
2014-08-09 05:39:13 +00:00
call QuarterSpeedDueToParalysis
jp HalveAttackDueToBurn
2014-05-22 22:13:20 +00:00
Func_3f64d: ; 3f64d (f:764d)
pop de
pop hl
inc [hl]
Func_3f650: ; 3f650 (f:7650)
ld a, [de]
cp ATTACK_DOWN_SIDE_EFFECT
ret nc
ld hl, NothingHappenedText
jp PrintText
Func_3f65a: ; 3f65a (f:765a)
ld a, [de]
cp $44
ret nc
jp Func_3fb4e
MonsStatsFellText: ; 3f661 (f:7661)
TX_FAR _MonsStatsFellText
db $08 ; asm
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
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVEEFFECT]
2014-05-22 22:13:20 +00:00
jr z, .asm_3f674
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
.asm_3f674
cp $1a
ret c
cp $44
ret nc
ld hl, GreatlyFellText
ret
GreatlyFellText: ; 3f67e (f:767e)
db $0a
TX_FAR _GreatlyFellText
FellText: ; 3f683 (f:7683)
TX_FAR _FellText
db "@"
Func_3f688: ; 3f688 (f:7688)
ld hl, StatsTextStrings
ld c, $50
.asm_3f68d
dec b
jr z, .asm_3f696
.asm_3f690
ld a, [hli]
cp c
jr z, .asm_3f68d
jr .asm_3f690
.asm_3f696
ld de, wcf4b
2014-05-22 22:13:20 +00:00
ld bc, $a
jp CopyData
StatsTextStrings: ; 3f69f (f:769f)
db "ATTACK@"
db "DEFENSE@"
db "SPEED@"
db "SPECIAL@"
db "ACCURACY@"
db "EVADE@"
StatModifierRatios: ; 3f6cb (f:76cb)
; first byte is numerator, second byte is denominator
db 25, 100 ; 0.25
db 28, 100 ; 0.28
db 33, 100 ; 0.33
db 40, 100 ; 0.40
db 50, 100 ; 0.50
db 66, 100 ; 0.66
db 1, 1 ; 1.00
db 15, 10 ; 1.50
db 2, 1 ; 2.00
db 25, 10 ; 2.50
db 3, 1 ; 3.00
db 35, 10 ; 3.50
db 4, 1 ; 4.00
BideEffect: ; 3f6e5 (f:76e5)
ld hl, W_PLAYERBATTSTATUS1
ld de, W_NUMHITS
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
jr z, .asm_3f6fc
ld hl, W_ENEMYBATTSTATUS1
ld de, wcd05
2014-08-09 05:39:13 +00:00
ld bc, wEnemyNumAttacksLeft
2014-05-22 22:13:20 +00:00
.asm_3f6fc
set 0, [hl] ; mon is now using bide
xor a
ld [de], a
inc de
ld [de], a
ld [W_PLAYERMOVEEFFECT], a
ld [W_ENEMYMOVEEFFECT], a
call BattleRandom
2014-05-22 22:13:20 +00:00
and $1
inc a
inc a
ld [bc], a
ld a, [H_WHOSETURN]
add $ae
jp Func_3fb96
ThrashPetalDanceEffect: ; 3f717 (f:7717)
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld de, wPlayerNumAttacksLeft
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f728
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
ld de, wEnemyNumAttacksLeft
2014-05-22 22:13:20 +00:00
.asm_3f728
set 1, [hl] ; mon is now using thrash/petal dance
call BattleRandom
2014-05-22 22:13:20 +00:00
and $1
inc a
inc a
ld [de], a
2014-08-09 05:39:13 +00:00
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
add $b0
jp Func_3fb96
SwitchAndTeleportEffect: ; 3f739 (f:7739)
2014-08-09 05:39:13 +00:00
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3f791
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
2014-05-22 22:13:20 +00:00
dec a
jr nz, .asm_3f77e
2014-08-09 05:39:13 +00:00
ld a, [W_CURENEMYLVL]
2014-05-22 22:13:20 +00:00
ld b, a
2014-08-09 05:39:13 +00:00
ld a, [wBattleMonLevel]
2014-05-22 22:13:20 +00:00
cp b
jr nc, .asm_3f76e
add b
ld c, a
inc c
.asm_3f751
call BattleRandom
2014-05-22 22:13:20 +00:00
cp c
jr nc, .asm_3f751
srl b
srl b
cp b
jr nc, .asm_3f76e
ld c, $32
call DelayFrames
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
.asm_3f76e
call ReadPlayerMonCurHPAndStatus
xor a
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [wEscapedFromBattle], a
ld a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
jr .asm_3f7e4
.asm_3f77e
ld c, $32
call DelayFrames
ld hl, IsUnaffectedText
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz, PrintText
jp PrintButItFailedText_
.asm_3f791
2014-08-09 05:39:13 +00:00
ld a, [W_ISINBATTLE]
2014-05-22 22:13:20 +00:00
dec a
jr nz, .asm_3f7d1
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, [W_CURENEMYLVL]
2014-05-22 22:13:20 +00:00
cp b
jr nc, .asm_3f7c1
add b
ld c, a
inc c
.asm_3f7a4
call BattleRandom
2014-05-22 22:13:20 +00:00
cp c
jr nc, .asm_3f7a4
srl b
srl b
cp b
jr nc, .asm_3f7c1
ld c, $32
call DelayFrames
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz, PrintDidntAffectText
jp PrintButItFailedText_
.asm_3f7c1
call ReadPlayerMonCurHPAndStatus
xor a
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
inc a
2014-08-09 05:39:13 +00:00
ld [wEscapedFromBattle], a
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
jr .asm_3f7e4
.asm_3f7d1
ld c, $32
call DelayFrames
ld hl, IsUnaffectedText
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
cp TELEPORT
jp nz, PrintText
jp Func_3fb4e
.asm_3f7e4
push af
call Func_3fbb9
ld c, $14
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
jr z, .asm_3f7ff
2014-08-09 05:39:13 +00:00
ld hl, RanAwayScaredText
2014-05-22 22:13:20 +00:00
cp ROAR
jr z, .asm_3f7ff
2014-08-09 05:39:13 +00:00
ld hl, WasBlownAwayText
2014-05-22 22:13:20 +00:00
.asm_3f7ff
jp PrintText
RanFromBattleText: ; 3f802 (f:7802)
TX_FAR _RanFromBattleText
db "@"
RanAwayScaredText: ; 3f807 (f:7807)
TX_FAR _RanAwayScaredText
db "@"
WasBlownAwayText: ; 3f80c (f:780c)
TX_FAR _WasBlownAwayText
db "@"
TwoToFiveAttacksEffect: ; 3f811 (f:7811)
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld de, wPlayerNumAttacksLeft
ld bc, W_NUMHITS
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f828
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
ld de, wEnemyNumAttacksLeft
ld bc, wcd05
2014-05-22 22:13:20 +00:00
.asm_3f828
bit 2, [hl] ; is mon attacking multiple times?
ret nz
set 2, [hl] ; mon is now attacking multiple times
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERMOVEEFFECT
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f838
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYMOVEEFFECT
2014-05-22 22:13:20 +00:00
.asm_3f838
ld a, [hl]
cp TWINEEDLE_EFFECT
jr z, .asm_3f856
cp ATTACK_TWICE_EFFECT
ld a, $2
jr z, .asm_3f853
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
cp $2
jr c, .asm_3f851
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
.asm_3f851
inc a
inc a
.asm_3f853
ld [de], a
ld [bc], a
ret
.asm_3f856
ld a, $2
ld [hl], a
jr .asm_3f853
FlichSideEffect: ; 3f85b (f:785b)
call CheckTargetSubstitute
ret nz
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
ld de, W_PLAYERMOVEEFFECT
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f870
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld de, W_ENEMYMOVEEFFECT
2014-05-22 22:13:20 +00:00
.asm_3f870
ld a, [de]
cp FLINCH_SIDE_EFFECT1
ld b, $1a ; ~10% chance of flinch
jr z, .asm_3f879
ld b, $4d ; ~30% chance of flinch
.asm_3f879
call BattleRandom
2014-05-22 22:13:20 +00:00
cp b
ret nc
set 3, [hl] ; set mon's status to flinching
call Func_3f9cf
ret
OneHitKOEffect: ; 3f884 (f:7884)
ld hl, OneHitKOEffect_
ld b, BANK(OneHitKOEffect_)
jp Bankswitch
ChargeEffect: ; 3f88c (f:788c)
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld de, W_PLAYERMOVEEFFECT
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
ld b, $ae
jr z, .asm_3f8a1
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
ld de, W_ENEMYMOVEEFFECT
2014-05-22 22:13:20 +00:00
ld b, $af
.asm_3f8a1
set 4, [hl]
ld a, [de]
dec de ; de contains enemy or player MOVENUM
cp FLY_EFFECT
jr nz, .asm_3f8ad
set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
ld b, $64
.asm_3f8ad
ld a, [de]
cp DIG
jr nz, .asm_3f8b6
set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
ld b, $c0
.asm_3f8b6
xor a
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
ld a, b
call Func_3fbb9
ld a, [de]
2014-08-09 05:39:13 +00:00
ld [wWhichTrade], a
ld hl, ChargeMoveEffectText
2014-05-22 22:13:20 +00:00
jp PrintText
ChargeMoveEffectText: ; 3f8c8 (f:78c8)
TX_FAR _ChargeMoveEffectText
db $08 ; asm
2014-08-09 05:39:13 +00:00
ld a, [wWhichTrade]
2014-05-22 22:13:20 +00:00
cp RAZOR_WIND
2014-08-09 05:39:13 +00:00
ld hl, MadeWhirlwindText
2014-05-22 22:13:20 +00:00
jr z, .asm_3f8f8
cp SOLARBEAM
2014-08-09 05:39:13 +00:00
ld hl, TookInSunlightText
2014-05-22 22:13:20 +00:00
jr z, .asm_3f8f8
cp SKULL_BASH
2014-08-09 05:39:13 +00:00
ld hl, LoweredItsHeadText
2014-05-22 22:13:20 +00:00
jr z, .asm_3f8f8
cp SKY_ATTACK
2014-08-09 05:39:13 +00:00
ld hl, SkyAttackGlowingText
2014-05-22 22:13:20 +00:00
jr z, .asm_3f8f8
cp FLY
2014-08-09 05:39:13 +00:00
ld hl, FlewUpHighText
2014-05-22 22:13:20 +00:00
jr z, .asm_3f8f8
cp DIG
2014-08-09 05:39:13 +00:00
ld hl, DugAHoleText
2014-05-22 22:13:20 +00:00
.asm_3f8f8
ret
MadeWhirlwindText: ; 3f8f9 (f:78f9)
TX_FAR _MadeWhirlwindText
db "@"
TookInSunlightText: ; 3f8fe (f:78fe)
TX_FAR _TookInSunlightText
db "@"
LoweredItsHeadText: ; 3f903 (f:7903)
TX_FAR _LoweredItsHeadText
db "@"
SkyAttackGlowingText: ; 3f908 (f:7908)
TX_FAR _SkyAttackGlowingText
db "@"
FlewUpHighText: ; 3f90d (f:790d)
TX_FAR _FlewUpHighText
db "@"
DugAHoleText: ; 3f912 (f:7912)
TX_FAR _DugAHoleText
db "@"
TrappingEffect: ; 3f917 (f:7917)
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld de, wPlayerNumAttacksLeft
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f928
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS1
ld de, wEnemyNumAttacksLeft
2014-05-22 22:13:20 +00:00
.asm_3f928
bit 5, [hl]
ret nz
call Func_3f9cf
set 5, [hl]
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
cp $2
jr c, .asm_3f93e
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
.asm_3f93e
inc a
ld [de], a
ret
MistEffect: ; 3f941 (f:7941)
ld hl, MistEffect_
ld b, BANK(MistEffect_)
jp Bankswitch
FocusEnergyEffect: ; 3f949 (f:7949)
ld hl, FocusEnergyEffect_
ld b, BANK(FocusEnergyEffect_)
jp Bankswitch
RecoilEffect: ; 3f951 (f:7951)
ld hl, RecoilEffect_
ld b, BANK(RecoilEffect_)
jp Bankswitch
ConfusionSideEffect: ; 3f959 (f:7959)
call BattleRandom
2014-05-22 22:13:20 +00:00
cp $19
ret nc
jr Func_3f96f
ConfusionEffect: ; 3f961 (f:7961)
call CheckTargetSubstitute
jr nz, Func_3f9a6
call MoveHitTest
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr nz, Func_3f9a6
Func_3f96f: ; 3f96f (f:796f)
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, W_ENEMYBATTSTATUS1
ld bc, wd070
2014-08-09 05:39:13 +00:00
ld a, [W_PLAYERMOVEEFFECT]
2014-05-22 22:13:20 +00:00
jr z, .asm_3f986
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS1
ld bc, wd06b
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVEEFFECT]
2014-05-22 22:13:20 +00:00
.asm_3f986
bit 7, [hl] ; is mon confused?
jr nz, Func_3f9a6
set 7, [hl] ; mon is now confused
push af
call BattleRandom
2014-05-22 22:13:20 +00:00
and $3
inc a
inc a
ld [bc], a
pop af
cp CONFUSION_SIDE_EFFECT
call nz, Func_3fb89
2014-08-09 05:39:13 +00:00
ld hl, BecameConfusedText
2014-05-22 22:13:20 +00:00
jp PrintText
BecameConfusedText: ; 3f9a1 (f:79a1)
TX_FAR _BecameConfusedText
db "@"
Func_3f9a6: ; 3f9a6 (f:79a6)
cp CONFUSION_SIDE_EFFECT
ret z
ld c, $32
call DelayFrames
jp Func_3fb4e
ParalyzeEffect: ; 3f9b1 (f:79b1)
ld hl, ParalyzeEffect_
ld b, BANK(ParalyzeEffect_)
jp Bankswitch
SubstituteEffect: ; 3f9b9 (f:79b9)
ld hl, SubstituteEffectHandler
ld b, BANK(SubstituteEffectHandler)
jp Bankswitch
HyperBeamEffect: ; 3f9c1 (f:79c1)
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS2
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f9cc
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS2
2014-05-22 22:13:20 +00:00
.asm_3f9cc
set 5, [hl] ; mon now needs to recharge
ret
Func_3f9cf: ; 3f9cf (f:79cf)
push hl
2014-08-09 05:39:13 +00:00
ld hl, W_ENEMYBATTSTATUS2
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr z, .asm_3f9db
2014-08-09 05:39:13 +00:00
ld hl, W_PLAYERBATTSTATUS2
2014-05-22 22:13:20 +00:00
.asm_3f9db
res 5, [hl] ; mon no longer needs to recharge
pop hl
ret
RageEffect: ; 3f9df (f:79df)
ld hl, W_PLAYERBATTSTATUS2
ld a, [H_WHOSETURN]
and a
jr z, .player
ld hl, W_ENEMYBATTSTATUS2
.player
set 6, [hl] ; mon is now in "rage" mode
ret
MimicEffect: ; 3f9ed (f:79ed)
ld c, $32
call DelayFrames
call MoveHitTest
ld a, [W_MOVEMISSED]
and a
jr nz, .asm_3fa74
ld a, [H_WHOSETURN]
and a
ld hl, wBattleMonMoves
2014-05-22 22:13:20 +00:00
ld a, [W_PLAYERBATTSTATUS1]
jr nz, .asm_3fa13
ld a, [W_ISLINKBATTLE]
cp $4
jr nz, .asm_3fa3a
ld hl, wEnemyMonMoves
2014-05-22 22:13:20 +00:00
ld a, [W_ENEMYBATTSTATUS1]
.asm_3fa13
bit 6, a
jr nz, .asm_3fa74
.asm_3fa17
push hl
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
jr z, .asm_3fa17
ld d, a
ld a, [H_WHOSETURN]
and a
ld hl, wBattleMonMoves
2014-05-22 22:13:20 +00:00
ld a, [wPlayerMoveListIndex]
jr z, .asm_3fa5f
ld hl, wEnemyMonMoves
2014-05-22 22:13:20 +00:00
ld a, [wEnemyMoveListIndex]
jr .asm_3fa5f
.asm_3fa3a
ld a, [W_ENEMYBATTSTATUS1]
bit 6, a
jr nz, .asm_3fa74
ld a, [wCurrentMenuItem]
push af
ld a, $1
ld [wMoveMenuType], a
call MoveSelectionMenu
call LoadScreenTilesFromBuffer1
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
ld hl, wBattleMonMoves
2014-05-22 22:13:20 +00:00
.asm_3fa5f
ld c, a
ld b, $0
add hl, bc
ld a, d
ld [hl], a
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call Func_3fba8
ld hl, MimicLearnedMoveText
jp PrintText
.asm_3fa74
jp PrintButItFailedText_
MimicLearnedMoveText: ; 3fa77 (f:7a77)
TX_FAR _MimicLearnedMoveText
db "@"
LeechSeedEffect: ; 3fa7c (f:7a7c)
ld hl, LeechSeedEffect_
ld b, BANK(LeechSeedEffect_)
jp Bankswitch
SplashEffect: ; 3fa84 (f:7a84)
call Func_3fba8
jp PrintNoEffectText
DisableEffect: ; 3fa8a (f:7a8a)
call MoveHitTest
2014-08-09 05:39:13 +00:00
ld a, [W_MOVEMISSED]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3fb06
2014-08-09 05:39:13 +00:00
ld de, W_ENEMYDISABLEDMOVE
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
jr z, .asm_3faa4
2014-08-09 05:39:13 +00:00
ld de, W_PLAYERDISABLEDMOVE
ld hl, wBattleMonMoves
2014-05-22 22:13:20 +00:00
.asm_3faa4
ld a, [de]
and a
jr nz, .asm_3fb06
.asm_3faa8
push hl
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
jr z, .asm_3faa8
ld [wd11e], a
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
2014-05-22 22:13:20 +00:00
jr nz, .asm_3facf
2014-08-09 05:39:13 +00:00
ld a, [W_ISLINKBATTLE]
2014-05-22 22:13:20 +00:00
cp $4
pop hl
jr nz, .asm_3fae1
push hl
2014-08-09 05:39:13 +00:00
ld hl, wEnemyMonPP
2014-05-22 22:13:20 +00:00
.asm_3facf
push hl
ld a, [hli]
or [hl]
inc hl
or [hl]
inc hl
or [hl]
and $3f
pop hl
jr z, .asm_3fb05
add hl, bc
ld a, [hl]
pop hl
and a
jr z, .asm_3faa8
.asm_3fae1
call BattleRandom
2014-05-22 22:13:20 +00:00
and $7
inc a
inc c
swap c
add c
ld [de], a
call Func_3fb89
ld hl, wccee
2014-08-09 05:39:13 +00:00
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
jr nz, .asm_3faf8
inc hl
.asm_3faf8
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
ld [hl], a
call GetMoveName
2014-08-09 05:39:13 +00:00
ld hl, MoveWasDisabledText
2014-05-22 22:13:20 +00:00
jp PrintText
.asm_3fb05
pop hl
.asm_3fb06
jp PrintButItFailedText_
MoveWasDisabledText: ; 3fb09 (f:7b09)
TX_FAR _MoveWasDisabledText
db "@"
PayDayEffect: ; 3fb0e (f:7b0e)
ld hl, PayDayEffect_
ld b, BANK(PayDayEffect_)
jp Bankswitch
ConversionEffect: ; 3fb16 (f:7b16)
ld hl, ConversionEffect_
ld b, BANK(ConversionEffect_)
jp Bankswitch
HazeEffect: ; 3fb1e (f:7b1e)
ld hl, HazeEffect_
ld b, BANK(HazeEffect_)
jp Bankswitch
HealEffect: ; 3fb26 (f:7b26)
ld hl, HealEffect_
ld b, BANK(HealEffect_)
jp Bankswitch
TransformEffect: ; 3fb2e (f:7b2e)
ld hl, TransformEffect_
ld b, BANK(TransformEffect_)
jp Bankswitch
ReflectLightScreenEffect: ; 3fb36 (f:7b36)
ld hl, ReflectLightScreenEffect_
ld b, BANK(ReflectLightScreenEffect_)
jp Bankswitch
NothingHappenedText: ; 3fb3e (f:7b3e)
TX_FAR _NothingHappenedText
db "@"
PrintNoEffectText: ; 3fb43 (f:7b43)
ld hl, NoEffectText
jp PrintText
NoEffectText: ; 3fb49 (f:7b49)
TX_FAR _NoEffectText
db "@"
Func_3fb4e: ; 3fb4e (f:7b4e)
ld a, [wccf4]
2014-05-22 22:13:20 +00:00
and a
ret nz
PrintButItFailedText_: ; 3fb53 (f:7b53)
ld hl, ButItFailedText
jp PrintText
ButItFailedText: ; 3fb59 (f:7b59)
TX_FAR _ButItFailedText
db "@"
PrintDidntAffectText: ; 3fb5e (f:7b5e)
ld hl, DidntAffectText
jp PrintText
DidntAffectText: ; 3fb64 (f:7b64)
TX_FAR _DidntAffectText
db "@"
IsUnaffectedText: ; 3fb69 (f:7b69)
TX_FAR _IsUnaffectedText
db "@"
PrintMayNotAttackText: ; 3fb6e (f:7b6e)
2014-08-09 05:39:13 +00:00
ld hl, ParalyzedMayNotAttackText
2014-05-22 22:13:20 +00:00
jp PrintText
ParalyzedMayNotAttackText: ; 3fb74 (f:7b74)
TX_FAR _ParalyzedMayNotAttackText
db "@"
CheckTargetSubstitute: ; 3fb79 (f:7b79)
push hl
ld hl, W_ENEMYBATTSTATUS2
2014-05-22 22:13:20 +00:00
ld a, [$fff3] ;whose turn?
and a
jr z, .next1
ld hl, W_PLAYERBATTSTATUS2
2014-05-22 22:13:20 +00:00
.next1
bit 4, [hl] ;test bit 4 in d063/d068 flags
pop hl
ret
Func_3fb89: ; 3fb89 (f:7b89)
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 a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
jr z, .asm_3fb94
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
.asm_3fb94
and a
ret z
Func_3fb96: ; 3fb96 (f:7b96)
2014-08-09 05:39:13 +00:00
ld [W_ANIMATIONID], a
ld a, [H_WHOSETURN]
2014-05-22 22:13:20 +00:00
and a
ld a, $6
jr z, .asm_3fba2
ld a, $3
.asm_3fba2
ld [wcc5b], a
2014-05-22 22:13:20 +00:00
jp Func_3fbbc
Func_3fba8: ; 3fba8 (f:7ba8)
xor a
ld [wcc5b], a
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 a, [W_PLAYERMOVENUM]
2014-05-22 22:13:20 +00:00
jr z, .asm_3fbb7
2014-08-09 05:39:13 +00:00
ld a, [W_ENEMYMOVENUM]
2014-05-22 22:13:20 +00:00
.asm_3fbb7
and a
ret z
Func_3fbb9: ; 3fbb9 (f:7bb9)
2014-08-09 05:39:13 +00:00
ld [W_ANIMATIONID], a
2014-05-22 22:13:20 +00:00
Func_3fbbc: ; 3fbbc (f:7bbc)
push hl
push de
push bc
predef MoveAnimation
2014-05-22 22:13:20 +00:00
pop bc
pop de
pop hl
ret