pokered/engine/items/item_effects.asm

2987 lines
62 KiB
NASM
Raw Normal View History

UseItem_::
ld a, 1
ld [wActionResultOrTookBattleTurn], a ; initialise to success value
ld a, [wcf91] ;contains item_ID
2020-07-06 02:52:27 +00:00
cp HM01
jp nc, ItemUseTMHM
ld hl, ItemUsePtrTable
2014-05-22 22:13:20 +00:00
dec a
add a
ld c, a
ld b, 0
add hl, bc
ld a, [hli]
ld h, [hl]
ld l, a
jp hl
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUsePtrTable:
2014-05-22 22:13:20 +00:00
dw ItemUseBall ; MASTER_BALL
dw ItemUseBall ; ULTRA_BALL
dw ItemUseBall ; GREAT_BALL
dw ItemUseBall ; POKE_BALL
dw ItemUseTownMap ; TOWN_MAP
dw ItemUseBicycle ; BICYCLE
dw ItemUseSurfboard ; out-of-battle Surf effect
dw ItemUseBall ; SAFARI_BALL
dw ItemUsePokedex ; POKEDEX
dw ItemUseEvoStone ; MOON_STONE
dw ItemUseMedicine ; ANTIDOTE
dw ItemUseMedicine ; BURN_HEAL
dw ItemUseMedicine ; ICE_HEAL
dw ItemUseMedicine ; AWAKENING
dw ItemUseMedicine ; PARLYZ_HEAL
dw ItemUseMedicine ; FULL_RESTORE
dw ItemUseMedicine ; MAX_POTION
dw ItemUseMedicine ; HYPER_POTION
dw ItemUseMedicine ; SUPER_POTION
dw ItemUseMedicine ; POTION
dw ItemUseBait ; BOULDERBADGE
dw ItemUseRock ; CASCADEBADGE
dw UnusableItem ; THUNDERBADGE
dw UnusableItem ; RAINBOWBADGE
dw UnusableItem ; SOULBADGE
dw UnusableItem ; MARSHBADGE
dw UnusableItem ; VOLCANOBADGE
dw UnusableItem ; EARTHBADGE
dw ItemUseEscapeRope ; ESCAPE_ROPE
dw ItemUseRepel ; REPEL
dw UnusableItem ; OLD_AMBER
dw ItemUseEvoStone ; FIRE_STONE
dw ItemUseEvoStone ; THUNDER_STONE
dw ItemUseEvoStone ; WATER_STONE
dw ItemUseVitamin ; HP_UP
dw ItemUseVitamin ; PROTEIN
dw ItemUseVitamin ; IRON
dw ItemUseVitamin ; CARBOS
dw ItemUseVitamin ; CALCIUM
dw ItemUseVitamin ; RARE_CANDY
dw UnusableItem ; DOME_FOSSIL
dw UnusableItem ; HELIX_FOSSIL
dw UnusableItem ; SECRET_KEY
dw UnusableItem
dw UnusableItem ; BIKE_VOUCHER
dw ItemUseXAccuracy ; X_ACCURACY
dw ItemUseEvoStone ; LEAF_STONE
dw ItemUseCardKey ; CARD_KEY
dw UnusableItem ; NUGGET
dw UnusableItem ; ??? PP_UP
dw ItemUsePokedoll ; POKE_DOLL
dw ItemUseMedicine ; FULL_HEAL
dw ItemUseMedicine ; REVIVE
dw ItemUseMedicine ; MAX_REVIVE
2015-12-15 04:09:30 +00:00
dw ItemUseGuardSpec ; GUARD_SPEC
2014-05-22 22:13:20 +00:00
dw ItemUseSuperRepel ; SUPER_REPL
dw ItemUseMaxRepel ; MAX_REPEL
dw ItemUseDireHit ; DIRE_HIT
dw UnusableItem ; COIN
dw ItemUseMedicine ; FRESH_WATER
dw ItemUseMedicine ; SODA_POP
dw ItemUseMedicine ; LEMONADE
2015-12-15 04:09:30 +00:00
dw UnusableItem ; S_S_TICKET
2014-05-22 22:13:20 +00:00
dw UnusableItem ; GOLD_TEETH
dw ItemUseXStat ; X_ATTACK
dw ItemUseXStat ; X_DEFEND
dw ItemUseXStat ; X_SPEED
dw ItemUseXStat ; X_SPECIAL
dw ItemUseCoinCase ; COIN_CASE
dw ItemUseOaksParcel ; OAKS_PARCEL
dw ItemUseItemfinder ; ITEMFINDER
dw UnusableItem ; SILPH_SCOPE
dw ItemUsePokeflute ; POKE_FLUTE
dw UnusableItem ; LIFT_KEY
2015-12-15 04:09:30 +00:00
dw UnusableItem ; EXP_ALL
2015-08-05 14:33:32 +00:00
dw ItemUseOldRod ; OLD_ROD
dw ItemUseGoodRod ; GOOD_ROD
dw ItemUseSuperRod ; SUPER_ROD
2014-05-22 22:13:20 +00:00
dw ItemUsePPUp ; PP_UP (real one)
dw ItemUsePPRestore ; ETHER
dw ItemUsePPRestore ; MAX_ETHER
dw ItemUsePPRestore ; ELIXER
dw ItemUsePPRestore ; MAX_ELIXER
2016-06-12 00:24:04 +00:00
ItemUseBall:
2015-08-30 06:21:54 +00:00
; Balls can't be used out of battle.
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp z, ItemUseNotTime
2015-08-30 06:21:54 +00:00
; Balls can't catch trainers' Pokémon.
2014-05-22 22:13:20 +00:00
dec a
jp nz, ThrowBallAtTrainerMon
2015-08-30 06:21:54 +00:00
; If this is for the old man battle, skip checking if the party & box are full.
ld a, [wBattleType]
2014-05-22 22:13:20 +00:00
dec a
jr z, .canUseBall
2015-08-30 06:21:54 +00:00
ld a, [wPartyCount] ; is party full?
cp PARTY_LENGTH
jr nz, .canUseBall
ld a, [wNumInBox] ; is box full?
cp MONS_PER_BOX
jp z, BoxFullCannotThrowBall
2015-08-30 06:21:54 +00:00
.canUseBall
2014-05-22 22:13:20 +00:00
xor a
ld [wCapturedMonSpecies], a
2015-08-30 06:21:54 +00:00
ld a, [wBattleType]
cp BATTLE_TYPE_SAFARI
jr nz, .skipSafariZoneCode
2015-08-30 06:21:54 +00:00
2014-05-22 22:13:20 +00:00
.safariZone
ld hl, wNumSafariBalls
2015-08-30 06:21:54 +00:00
dec [hl] ; remove a Safari Ball
.skipSafariZoneCode
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2015-08-30 06:21:54 +00:00
ld a, $43 ; successful capture value
ld [wPokeBallAnimData], a
2015-08-30 06:21:54 +00:00
call LoadScreenTilesFromBuffer1
ld hl, ItemUseText00
2014-05-22 22:13:20 +00:00
call PrintText
2015-08-30 06:21:54 +00:00
; If the player is fighting an unidentified ghost, set the value that indicates
; the Pokémon can't be caught and skip the capture calculations.
2014-05-22 22:13:20 +00:00
callab IsGhostBattle
ld b, $10 ; can't be caught value
jp z, .setAnimData
2015-08-30 06:21:54 +00:00
ld a, [wBattleType]
2014-05-22 22:13:20 +00:00
dec a
jr nz, .notOldManBattle
2015-08-30 06:21:54 +00:00
2014-05-22 22:13:20 +00:00
.oldManBattle
ld hl, wGrassRate
ld de, wPlayerName
ld bc, NAME_LENGTH
2015-08-30 06:21:54 +00:00
call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno. glitch)
jp .captured
.notOldManBattle
2015-08-30 06:21:54 +00:00
; If the player is fighting the ghost Marowak, set the value that indicates the
; Pokémon can't be caught and skip the capture calculations.
ld a, [wCurMap]
cp POKEMON_TOWER_6F
jr nz, .loop
ld a, [wEnemyMonSpecies2]
cp MAROWAK
ld b, $10 ; can't be caught value
jp z, .setAnimData
2015-08-30 06:21:54 +00:00
; Get the first random number. Let it be called Rand1.
; Rand1 must be within a certain range according the kind of ball being thrown.
; The ranges are as follows.
; Poké Ball: [0, 255]
; Great Ball: [0, 200]
; Ultra/Safari Ball: [0, 150]
; Loop until an acceptable number is found.
.loop
call Random
ld b, a
2015-08-30 06:21:54 +00:00
; Get the item ID.
ld hl, wcf91
ld a, [hl]
2015-08-30 06:21:54 +00:00
; The Master Ball always succeeds.
cp MASTER_BALL
jp z, .captured
2015-08-30 06:21:54 +00:00
; Anything will do for the basic Poké Ball.
cp POKE_BALL
jr z, .checkForAilments
2015-08-30 06:21:54 +00:00
; If it's a Great/Ultra/Safari Ball and Rand1 is greater than 200, try again.
ld a, 200
2014-05-22 22:13:20 +00:00
cp b
jr c, .loop
2015-08-30 06:21:54 +00:00
; Less than or equal to 200 is good enough for a Great Ball.
ld a, [hl]
cp GREAT_BALL
jr z, .checkForAilments
2015-08-30 06:21:54 +00:00
; If it's an Ultra/Safari Ball and Rand1 is greater than 150, try again.
ld a, 150
2014-05-22 22:13:20 +00:00
cp b
jr c, .loop
2015-08-30 06:21:54 +00:00
.checkForAilments
2015-08-30 06:21:54 +00:00
; Pokémon can be caught more easily with a status ailment.
; Depending on the status ailment, a certain value will be subtracted from
; Rand1. Let this value be called Status.
; The larger Status is, the more easily the Pokémon can be caught.
; no status ailment: Status = 0
; Burn/Paralysis/Poison: Status = 12
; Freeze/Sleep: Status = 25
; If Status is greater than Rand1, the Pokémon will be caught for sure.
ld a, [wEnemyMonStatus]
2014-05-22 22:13:20 +00:00
and a
jr z, .skipAilmentValueSubtraction ; no ailments
and 1 << FRZ | SLP
ld c, 12
jr z, .notFrozenOrAsleep
ld c, 25
.notFrozenOrAsleep
ld a, b
2014-05-22 22:13:20 +00:00
sub c
jp c, .captured
ld b, a
2015-08-30 06:21:54 +00:00
.skipAilmentValueSubtraction
2016-07-28 03:33:48 +00:00
push bc ; save (Rand1 - Status)
2015-08-30 06:21:54 +00:00
; Calculate MaxHP * 255.
2014-05-22 22:13:20 +00:00
xor a
ldh [hMultiplicand], a
ld hl, wEnemyMonMaxHP
ld a, [hli]
ldh [hMultiplicand + 1], a
ld a, [hl]
ldh [hMultiplicand + 2], a
ld a, 255
ldh [hMultiplier], a
2015-08-30 06:21:54 +00:00
call Multiply
; Determine BallFactor. It's 8 for Great Balls and 12 for the others.
ld a, [wcf91]
cp GREAT_BALL
ld a, 12
jr nz, .skip1
ld a, 8
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip1
2015-08-30 06:21:54 +00:00
; Note that the results of all division operations are floored.
; Calculate (MaxHP * 255) / BallFactor.
ldh [hDivisor], a
ld b, 4 ; number of bytes in dividend
2014-05-22 22:13:20 +00:00
call Divide
2015-08-30 06:21:54 +00:00
; Divide the enemy's current HP by 4. HP is not supposed to exceed 999 so
; the result should fit in a. If the division results in a quotient of 0,
; change it to 1.
ld hl, wEnemyMonHP
ld a, [hli]
ld b, a
ld a, [hl]
2014-05-22 22:13:20 +00:00
srl b
rr a
srl b
2015-08-30 06:21:54 +00:00
rr a
2014-05-22 22:13:20 +00:00
and a
jr nz, .skip2
2014-05-22 22:13:20 +00:00
inc a
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip2
2015-08-30 06:21:54 +00:00
; Let W = ((MaxHP * 255) / BallFactor) / max(HP / 4, 1). Calculate W.
ldh [hDivisor], a
ld b, 4
2015-08-30 06:21:54 +00:00
call Divide
2020-07-03 23:59:41 +00:00
; If W > 255, store 255 in [hQuotient + 3].
; Let X = min(W, 255) = [hQuotient + 3].
ldh a, [hQuotient + 2]
2014-05-22 22:13:20 +00:00
and a
jr z, .skip3
ld a, 255
ldh [hQuotient + 3], a
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip3
2015-08-30 06:21:54 +00:00
pop bc ; b = Rand1 - Status
; If Rand1 - Status > CatchRate, the ball fails to capture the Pokémon.
2018-03-24 18:41:54 +00:00
ld a, [wEnemyMonActualCatchRate]
2014-05-22 22:13:20 +00:00
cp b
jr c, .failedToCapture
2015-08-30 06:21:54 +00:00
; If W > 255, the ball captures the Pokémon.
ldh a, [hQuotient + 2]
2014-05-22 22:13:20 +00:00
and a
jr nz, .captured
2015-08-30 06:21:54 +00:00
call Random ; Let this random number be called Rand2.
; If Rand2 > X, the ball fails to capture the Pokémon.
ld b, a
ldh a, [hQuotient + 3]
2014-05-22 22:13:20 +00:00
cp b
jr c, .failedToCapture
2015-08-30 06:21:54 +00:00
.captured
jr .skipShakeCalculations
.failedToCapture
ldh a, [hQuotient + 3]
ld [wPokeBallCaptureCalcTemp], a ; Save X.
2015-08-30 06:21:54 +00:00
; Calculate CatchRate * 100.
2014-05-22 22:13:20 +00:00
xor a
ldh [hMultiplicand], a
ldh [hMultiplicand + 1], a
2018-03-24 18:41:54 +00:00
ld a, [wEnemyMonActualCatchRate]
ldh [hMultiplicand + 2], a
ld a, 100
ldh [hMultiplier], a
2015-08-30 06:21:54 +00:00
call Multiply
; Determine BallFactor2.
; Poké Ball: BallFactor2 = 255
; Great Ball: BallFactor2 = 200
; Ultra/Safari Ball: BallFactor2 = 150
ld a, [wcf91]
ld b, 255
cp POKE_BALL
jr z, .skip4
ld b, 200
cp GREAT_BALL
jr z, .skip4
ld b, 150
cp ULTRA_BALL
jr z, .skip4
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip4
2015-08-30 06:21:54 +00:00
; Let Y = (CatchRate * 100) / BallFactor2. Calculate Y.
ld a, b
ldh [hDivisor], a
ld b, 4
2014-05-22 22:13:20 +00:00
call Divide
2015-08-30 06:21:54 +00:00
; If Y > 255, there are 3 shakes.
; Note that this shouldn't be possible.
; The maximum value of Y is (255 * 100) / 150 = 170.
ldh a, [hQuotient + 2]
2014-05-22 22:13:20 +00:00
and a
ld b, $63 ; 3 shakes
jr nz, .setAnimData
2015-08-30 06:21:54 +00:00
; Calculate X * Y.
ld a, [wPokeBallCaptureCalcTemp]
ldh [hMultiplier], a
2014-05-22 22:13:20 +00:00
call Multiply
2015-08-30 06:21:54 +00:00
; Calculate (X * Y) / 255.
ld a, 255
ldh [hDivisor], a
ld b, 4
2014-05-22 22:13:20 +00:00
call Divide
2015-08-30 06:21:54 +00:00
; Determine Status2.
; no status ailment: Status2 = 0
; Burn/Paralysis/Poison: Status2 = 5
; Freeze/Sleep: Status2 = 10
ld a, [wEnemyMonStatus]
2014-05-22 22:13:20 +00:00
and a
jr z, .skip5
and 1 << FRZ | SLP
ld b, 5
jr z, .addAilmentValue
ld b, 10
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.addAilmentValue
2015-08-30 06:21:54 +00:00
; If the Pokémon has a status ailment, add Status2.
ldh a, [hQuotient + 3]
2014-05-22 22:13:20 +00:00
add b
ldh [hQuotient + 3], a
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip5
2015-08-30 06:21:54 +00:00
; Finally determine the number of shakes.
2020-07-03 23:59:41 +00:00
; Let Z = ((X * Y) / 255) + Status2 = [hQuotient + 3].
2015-08-30 06:21:54 +00:00
; The number of shakes depend on the range Z is in.
; 0 ≤ Z < 10: 0 shakes (the ball misses)
; 10 ≤ Z < 30: 1 shake
; 30 ≤ Z < 70: 2 shakes
; 70 ≤ Z: 3 shakes
ldh a, [hQuotient + 3]
cp 10
ld b, $20
jr c, .setAnimData
cp 30
ld b, $61
jr c, .setAnimData
cp 70
ld b, $62
jr c, .setAnimData
ld b, $63
2015-08-30 06:21:54 +00:00
.setAnimData
ld a, b
ld [wPokeBallAnimData], a
2015-08-30 06:21:54 +00:00
.skipShakeCalculations
ld c, 20
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-08-30 06:21:54 +00:00
; Do the animation.
ld a, TOSS_ANIM
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
xor a
ldh [hWhoseTurn], a
ld [wAnimationType], a
ld [wDamageMultipliers], a
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
predef MoveAnimation
2014-05-22 22:13:20 +00:00
pop af
ld [wcf91], a
2014-05-22 22:13:20 +00:00
pop af
ld [wWhichPokemon], a
2015-08-30 06:21:54 +00:00
; Determine the message to display from the animation.
ld a, [wPokeBallAnimData]
cp $10
ld hl, ItemUseBallText00
jp z, .printMessage
cp $20
ld hl, ItemUseBallText01
jp z, .printMessage
cp $61
ld hl, ItemUseBallText02
jp z, .printMessage
cp $62
ld hl, ItemUseBallText03
jp z, .printMessage
cp $63
ld hl, ItemUseBallText04
jp z, .printMessage
2015-08-30 06:21:54 +00:00
; Save current HP.
ld hl, wEnemyMonHP
ld a, [hli]
2014-05-22 22:13:20 +00:00
push af
ld a, [hli]
2015-08-30 06:21:54 +00:00
push af
; Save status ailment.
2014-05-22 22:13:20 +00:00
inc hl
ld a, [hl]
2015-08-30 06:21:54 +00:00
push af
2014-05-22 22:13:20 +00:00
push hl
2015-08-30 06:21:54 +00:00
; If the Pokémon is transformed, the Pokémon is assumed to be a Ditto.
; This is a bug because a wild Pokémon could have used Transform via
; Mirror Move even though the only wild Pokémon that knows Transform is Ditto.
ld hl, wEnemyBattleStatus3
bit TRANSFORMED, [hl]
jr z, .notTransformed
ld a, DITTO
ld [wEnemyMonSpecies2], a
2015-08-30 07:15:59 +00:00
jr .skip6
2015-08-30 06:21:54 +00:00
.notTransformed
; If the Pokémon is not transformed, set the transformed bit and copy the
; DVs to wTransformedEnemyMonOriginalDVs so that LoadEnemyMonData won't generate
; new DVs.
set TRANSFORMED, [hl]
ld hl, wTransformedEnemyMonOriginalDVs
ld a, [wEnemyMonDVs]
ld [hli], a
ld a, [wEnemyMonDVs + 1]
ld [hl], a
2015-08-30 06:21:54 +00:00
2015-08-30 07:15:59 +00:00
.skip6
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
ld a, [wEnemyMonSpecies2]
ld [wcf91], a
ld a, [wEnemyMonLevel]
ld [wCurEnemyLVL], a
2014-08-09 05:39:13 +00:00
callab LoadEnemyMonData
2014-05-22 22:13:20 +00:00
pop af
ld [wcf91], a
2014-05-22 22:13:20 +00:00
pop hl
pop af
ld [hld], a
2014-05-22 22:13:20 +00:00
dec hl
pop af
ld [hld], a
2014-05-22 22:13:20 +00:00
pop af
ld [hl], a
ld a, [wEnemyMonSpecies]
ld [wCapturedMonSpecies], a
ld [wcf91], a
ld [wd11e], a
ld a, [wBattleType]
2015-08-30 06:21:54 +00:00
dec a ; is this the old man battle?
jr z, .oldManCaughtMon ; if so, don't give the player the caught Pokémon
2015-08-30 06:21:54 +00:00
ld hl, ItemUseBallText05
2014-05-22 22:13:20 +00:00
call PrintText
2015-08-30 06:21:54 +00:00
; Add the caught Pokémon to the Pokédex.
predef IndexToPokedex
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
dec a
ld c, a
ld b, FLAG_TEST
ld hl, wPokedexOwned
predef FlagActionPredef
ld a, c
2014-05-22 22:13:20 +00:00
push af
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
dec a
ld c, a
ld b, FLAG_SET
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
pop af
2015-08-30 06:21:54 +00:00
and a ; was the Pokémon already in the Pokédex?
jr nz, .skipShowingPokedexData ; if so, don't show the Pokédex data
2015-08-30 06:21:54 +00:00
ld hl, ItemUseBallText06
2014-05-22 22:13:20 +00:00
call PrintText
2014-05-23 22:34:35 +00:00
call ClearSprites
ld a, [wEnemyMonSpecies]
ld [wd11e], a
predef ShowPokedexData
2015-08-30 06:21:54 +00:00
.skipShowingPokedexData
ld a, [wPartyCount]
cp PARTY_LENGTH ; is party full?
jr z, .sendToBox
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2014-05-23 22:34:35 +00:00
call ClearSprites
2015-08-30 06:21:54 +00:00
call AddPartyMon
jr .done
.sendToBox
2014-05-23 22:34:35 +00:00
call ClearSprites
2015-02-08 06:18:42 +00:00
call SendNewMonToBox
ld hl, ItemUseBallText07
2015-07-21 17:36:03 +00:00
CheckEvent EVENT_MET_BILL
jr nz, .printTransferredToPCText
ld hl, ItemUseBallText08
2015-08-30 06:21:54 +00:00
.printTransferredToPCText
2014-05-22 22:13:20 +00:00
call PrintText
2015-08-30 06:21:54 +00:00
jr .done
.oldManCaughtMon
ld hl, ItemUseBallText05
2015-08-30 06:21:54 +00:00
.printMessage
2014-05-22 22:13:20 +00:00
call PrintText
2014-05-23 22:34:35 +00:00
call ClearSprites
2015-08-30 06:21:54 +00:00
.done
ld a, [wBattleType]
2015-08-30 06:21:54 +00:00
and a ; is this the old man battle?
ret nz ; if so, don't remove a ball from the bag
; Remove a ball from the bag.
ld hl, wNumBagItems
2014-05-22 22:13:20 +00:00
inc a
ld [wItemQuantity], a
jp RemoveItemFromInventory
2015-08-30 06:21:54 +00:00
2016-06-12 00:24:04 +00:00
ItemUseBallText00:
2014-05-22 22:13:20 +00:00
;"It dodged the thrown ball!"
;"This pokemon can't be caught"
text_far _ItemUseBallText00
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText01:
2014-05-22 22:13:20 +00:00
;"You missed the pokemon!"
text_far _ItemUseBallText01
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText02:
2014-05-22 22:13:20 +00:00
;"Darn! The pokemon broke free!"
text_far _ItemUseBallText02
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText03:
2014-05-22 22:13:20 +00:00
;"Aww! It appeared to be caught!"
text_far _ItemUseBallText03
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText04:
2014-05-22 22:13:20 +00:00
;"Shoot! It was so close too!"
text_far _ItemUseBallText04
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText05:
2014-05-22 22:13:20 +00:00
;"All right! {MonName} was caught!"
;play sound
text_far _ItemUseBallText05
sound_caught_mon
text_promptbutton
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText07:
2014-05-22 22:13:20 +00:00
;"X was transferred to Bill's PC"
text_far _ItemUseBallText07
text_end
2016-06-12 00:24:04 +00:00
ItemUseBallText08:
2014-05-22 22:13:20 +00:00
;"X was transferred to someone's PC"
text_far _ItemUseBallText08
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseBallText06:
2014-05-22 22:13:20 +00:00
;"New DEX data will be added..."
;play sound
text_far _ItemUseBallText06
sound_dex_page_added
text_promptbutton
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseTownMap:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
2015-07-19 18:56:13 +00:00
jpba DisplayTownMap
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseBicycle:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
ld a, [wWalkBikeSurfState]
ld [wWalkBikeSurfStateCopy], a
cp 2 ; is the player surfing?
jp z, ItemUseNotTime
2014-05-22 22:13:20 +00:00
dec a ; is player already bicycling?
jr nz, .tryToGetOnBike
2014-05-22 22:13:20 +00:00
.getOffBike
call ItemUseReloadOverworldData
xor a
ld [wWalkBikeSurfState], a ; change player state to walking
call PlayDefaultMusic ; play walking music
ld hl, GotOffBicycleText
2014-05-22 22:13:20 +00:00
jr .printText
.tryToGetOnBike
call IsBikeRidingAllowed
jp nc, NoCyclingAllowedHere
2014-05-22 22:13:20 +00:00
call ItemUseReloadOverworldData
xor a ; no keys pressed
ldh [hJoyHeld], a ; current joypad state
2014-05-22 22:13:20 +00:00
inc a
ld [wWalkBikeSurfState], a ; change player state to bicycling
ld hl, GotOnBicycleText
call PlayDefaultMusic ; play bike riding music
2014-05-22 22:13:20 +00:00
.printText
jp PrintText
; used for Surf out-of-battle effect
2016-06-12 00:24:04 +00:00
ItemUseSurfboard:
ld a, [wWalkBikeSurfState]
ld [wWalkBikeSurfStateCopy], a
cp 2 ; is the player already surfing?
jr z, .tryToStopSurfing
2014-05-22 22:13:20 +00:00
.tryToSurf
call IsNextTileShoreOrWater
jp c, SurfingAttemptFailed
ld hl, TilePairCollisionsWater
2014-05-22 22:13:20 +00:00
call CheckForTilePairCollisions
jp c, SurfingAttemptFailed
2014-05-22 22:13:20 +00:00
.surf
call .makePlayerMoveForward
ld hl, wd730
set 7, [hl]
ld a, 2
ld [wWalkBikeSurfState], a ; change player state to surfing
call PlayDefaultMusic ; play surfing music
ld hl, SurfingGotOnText
2014-05-22 22:13:20 +00:00
jp PrintText
.tryToStopSurfing
xor a
ldh [hSpriteIndexOrTextID], a
ld d, 16 ; talking range in pixels (normal range)
2014-05-22 22:13:20 +00:00
call IsSpriteInFrontOfPlayer2
res 7, [hl]
ldh a, [hSpriteIndexOrTextID]
2014-05-22 22:13:20 +00:00
and a ; is there a sprite in the way?
jr nz, .cannotStopSurfing
ld hl, TilePairCollisionsWater
2014-05-22 22:13:20 +00:00
call CheckForTilePairCollisions
jr c, .cannotStopSurfing
ld hl, wTilesetCollisionPtr ; pointer to list of passable tiles
ld a, [hli]
ld h, [hl]
ld l, a ; hl now points to passable tiles
ld a, [wTileInFrontOfPlayer] ; tile in front of the player
ld b, a
2014-05-22 22:13:20 +00:00
.passableTileLoop
ld a, [hli]
2014-05-22 22:13:20 +00:00
cp b
jr z, .stopSurfing
cp $ff
jr nz, .passableTileLoop
2014-05-22 22:13:20 +00:00
.cannotStopSurfing
ld hl, SurfingNoPlaceToGetOffText
2014-05-22 22:13:20 +00:00
jp PrintText
.stopSurfing
call .makePlayerMoveForward
ld hl, wd730
set 7, [hl]
2014-05-22 22:13:20 +00:00
xor a
ld [wWalkBikeSurfState], a ; change player state to walking
2014-05-22 22:13:20 +00:00
dec a
ld [wJoyIgnore], a
call PlayDefaultMusic ; play walking music
2014-05-22 22:13:20 +00:00
jp LoadWalkingPlayerSpriteGraphics
; uses a simulated button press to make the player move forward
.makePlayerMoveForward
ld a, [wPlayerDirection] ; direction the player is going
bit PLAYER_DIR_BIT_UP, a
ld b, D_UP
jr nz, .storeSimulatedButtonPress
bit PLAYER_DIR_BIT_DOWN, a
ld b, D_DOWN
jr nz, .storeSimulatedButtonPress
bit PLAYER_DIR_BIT_LEFT, a
ld b, D_LEFT
jr nz, .storeSimulatedButtonPress
ld b, D_RIGHT
2014-05-22 22:13:20 +00:00
.storeSimulatedButtonPress
ld a, b
ld [wSimulatedJoypadStatesEnd], a
2014-05-22 22:13:20 +00:00
xor a
ld [wWastedByteCD39], a
2014-05-22 22:13:20 +00:00
inc a
ld [wSimulatedJoypadStatesIndex], a
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
SurfingGotOnText:
text_far _SurfingGotOnText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SurfingNoPlaceToGetOffText:
text_far _SurfingNoPlaceToGetOffText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUsePokedex:
predef_jump ShowPokedexMenu
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseEvoStone:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
ld [wEvoStoneItemID], a
2014-05-22 22:13:20 +00:00
push af
ld a, EVO_STONE_PARTY_MENU
ld [wPartyMenuTypeOrMessageID], a
ld a, $ff
ld [wUpdateSpritesEnabled], a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
pop bc
jr c, .canceledItemUse
ld a, b
ld [wcf91], a
ld a, $01
ld [wForceEvolution], a
ld a, SFX_HEAL_AILMENT
call PlaySoundWaitForCurrent
call WaitForSoundToFinish
2014-08-09 05:39:13 +00:00
callab TryEvolvingMon ; try to evolve pokemon
ld a, [wEvolutionOccurred]
2014-05-22 22:13:20 +00:00
and a
jr z, .noEffect
2014-05-22 22:13:20 +00:00
pop af
ld [wWhichPokemon], a
ld hl, wNumBagItems
ld a, 1 ; remove 1 stone
ld [wItemQuantity], a
2014-05-22 22:13:20 +00:00
jp RemoveItemFromInventory
.noEffect
call ItemUseNoEffect
.canceledItemUse
xor a
ld [wActionResultOrTookBattleTurn], a ; item not used
2014-05-22 22:13:20 +00:00
pop af
ret
2016-06-12 00:24:04 +00:00
ItemUseVitamin:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseMedicine:
ld a, [wPartyCount]
2014-05-22 22:13:20 +00:00
and a
jp z, .emptyParty
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
ld a, USE_ITEM_PARTY_MENU
ld [wPartyMenuTypeOrMessageID], a
ld a, $ff
ld [wUpdateSpritesEnabled], a
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Softboiled?
jr z, .notUsingSoftboiled
2014-05-22 22:13:20 +00:00
; if using softboiled
call GoBackToPartyMenu
jr .getPartyMonDataAddress
.emptyParty
ld hl, .emptyPartyText
2014-05-22 22:13:20 +00:00
xor a
ld [wActionResultOrTookBattleTurn], a ; item use failed
2014-05-22 22:13:20 +00:00
jp PrintText
.emptyPartyText
text "You don't have"
line "any #MON!"
prompt
.notUsingSoftboiled
call DisplayPartyMenu
.getPartyMonDataAddress
jp c, .canceledItemUse
ld hl, wPartyMons
ld bc, wPartyMon2 - wPartyMon1
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a, [wWhichPokemon]
ld [wUsedItemOnWhichPokemon], a
ld d, a
ld a, [wcf91]
ld e, a
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
pop af
ld [wcf91], a
2014-05-22 22:13:20 +00:00
pop af
ld [wWhichPokemon], a
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Softboiled?
jr z, .checkItemType
2014-05-22 22:13:20 +00:00
; if using softboiled
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
cp d ; is the pokemon trying to use softboiled on itself?
jr z, ItemUseMedicine ; if so, force another choice
2014-05-22 22:13:20 +00:00
.checkItemType
ld a, [wcf91]
cp REVIVE
jr nc, .healHP ; if it's a Revive or Max Revive
cp FULL_HEAL
jr z, .cureStatusAilment ; if it's a Full Heal
cp HP_UP
jp nc, .useVitamin ; if it's a vitamin or Rare Candy
cp FULL_RESTORE
jr nc, .healHP ; if it's a Full Restore or one of the potions
2017-06-24 20:01:43 +00:00
; fall through if it's one of the status-specific healing items
2014-05-22 22:13:20 +00:00
.cureStatusAilment
ld bc, wPartyMon1Status - wPartyMon1
add hl, bc ; hl now points to status
ld a, [wcf91]
2015-08-05 21:20:29 +00:00
lb bc, ANTIDOTE_MSG, 1 << PSN
cp ANTIDOTE
jr z, .checkMonStatus
2015-08-05 21:20:29 +00:00
lb bc, BURN_HEAL_MSG, 1 << BRN
cp BURN_HEAL
jr z, .checkMonStatus
2015-08-05 21:20:29 +00:00
lb bc, ICE_HEAL_MSG, 1 << FRZ
cp ICE_HEAL
jr z, .checkMonStatus
2015-08-05 21:20:29 +00:00
lb bc, AWAKENING_MSG, SLP
cp AWAKENING
jr z, .checkMonStatus
2015-08-05 21:20:29 +00:00
lb bc, PARALYZ_HEAL_MSG, 1 << PAR
cp PARLYZ_HEAL
jr z, .checkMonStatus
2015-08-05 21:20:29 +00:00
lb bc, FULL_HEAL_MSG, $ff ; Full Heal
2014-05-22 22:13:20 +00:00
.checkMonStatus
ld a, [hl] ; pokemon's status
2014-05-22 22:13:20 +00:00
and c ; does the pokemon have a status ailment the item can cure?
jp z, .healingItemNoEffect
2014-05-22 22:13:20 +00:00
; if the pokemon has a status the item can heal
xor a
ld [hl], a ; remove the status ailment in the party data
ld a, b
ld [wPartyMenuTypeOrMessageID], a ; the message to display for the item used
ld a, [wPlayerMonNumber]
2014-05-22 22:13:20 +00:00
cp d ; is pokemon the item was used on active in battle?
jp nz, .doneHealing
2014-05-22 22:13:20 +00:00
; if it is active in battle
xor a
ld [wBattleMonStatus], a ; remove the status ailment in the in-battle pokemon data
2014-05-22 22:13:20 +00:00
push hl
ld hl, wPlayerBattleStatus3
res BADLY_POISONED, [hl] ; heal Toxic status
2014-05-22 22:13:20 +00:00
pop hl
ld bc, wPartyMon1Stats - wPartyMon1Status
add hl, bc ; hl now points to party stats
ld de, wBattleMonStats
ld bc, NUM_STATS * 2
2014-05-22 22:13:20 +00:00
call CopyData ; copy party stats to in-battle stat data
2015-02-08 09:44:41 +00:00
predef DoubleOrHalveSelectedStats
2014-05-22 22:13:20 +00:00
jp .doneHealing
.healHP
inc hl ; hl = address of current HP
ld a, [hli]
ld b, a
ld [wHPBarOldHP+1], a
ld a, [hl]
ld c, a
ld [wHPBarOldHP], a ; current HP stored at wHPBarOldHP (2 bytes, big-endian)
2014-05-22 22:13:20 +00:00
or b
jr nz, .notFainted
2014-05-22 22:13:20 +00:00
.fainted
ld a, [wcf91]
cp REVIVE
jr z, .updateInBattleFaintedData
cp MAX_REVIVE
jr z, .updateInBattleFaintedData
2014-05-22 22:13:20 +00:00
jp .healingItemNoEffect
.updateInBattleFaintedData
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr z, .compareCurrentHPToMaxHP
2014-05-22 22:13:20 +00:00
push hl
push de
push bc
ld a, [wUsedItemOnWhichPokemon]
ld c, a
ld hl, wPartyFoughtCurrentEnemyFlags
ld b, FLAG_TEST
predef FlagActionPredef
ld a, c
2014-05-22 22:13:20 +00:00
and a
jr z, .next
ld a, [wUsedItemOnWhichPokemon]
ld c, a
ld hl, wPartyGainExpFlags
ld b, FLAG_SET
predef FlagActionPredef
2014-05-22 22:13:20 +00:00
.next
pop bc
pop de
pop hl
jr .compareCurrentHPToMaxHP
.notFainted
ld a, [wcf91]
cp REVIVE
jp z, .healingItemNoEffect
cp MAX_REVIVE
jp z, .healingItemNoEffect
2014-05-22 22:13:20 +00:00
.compareCurrentHPToMaxHP
push hl
push bc
ld bc, wPartyMon1MaxHP - (wPartyMon1HP + 1)
add hl, bc ; hl now points to max HP
2014-05-22 22:13:20 +00:00
pop bc
ld a, [hli]
2014-05-22 22:13:20 +00:00
cp b
jr nz, .skipComparingLSB ; no need to compare the LSB's if the MSB's don't match
ld a, [hl]
2014-05-22 22:13:20 +00:00
cp c
.skipComparingLSB
pop hl
jr nz, .notFullHP
2014-05-22 22:13:20 +00:00
.fullHP ; if the pokemon's current HP equals its max HP
ld a, [wcf91]
cp FULL_RESTORE
jp nz, .healingItemNoEffect
2014-05-22 22:13:20 +00:00
inc hl
inc hl
ld a, [hld] ; status ailment
2014-05-22 22:13:20 +00:00
and a ; does the pokemon have a status ailment?
jp z, .healingItemNoEffect
ld a, FULL_HEAL
ld [wcf91], a
2014-05-22 22:13:20 +00:00
dec hl
dec hl
dec hl
jp .cureStatusAilment
.notFullHP ; if the pokemon's current HP doesn't equal its max HP
xor a
ld [wLowHealthAlarm], a ;disable low health alarm
ld [wChannelSoundIDs + Ch5], a
2014-05-22 22:13:20 +00:00
push hl
push de
ld bc, wPartyMon1MaxHP - (wPartyMon1HP + 1)
add hl, bc ; hl now points to max HP
ld a, [hli]
ld [wHPBarMaxHP+1], a
ld a, [hl]
ld [wHPBarMaxHP], a ; max HP stored at wHPBarMaxHP (2 bytes, big-endian)
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Softboiled?
jp z, .notUsingSoftboiled2
2014-05-22 22:13:20 +00:00
; if using softboiled
ld hl, wHPBarMaxHP
ld a, [hli]
2014-05-22 22:13:20 +00:00
push af
ld a, [hli]
2014-05-22 22:13:20 +00:00
push af
ld a, [hli]
2014-05-22 22:13:20 +00:00
push af
ld a, [hl]
2014-05-22 22:13:20 +00:00
push af
ld hl, wPartyMon1MaxHP
ld a, [wWhichPokemon]
ld bc, wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld a, [hli]
ld [wHPBarMaxHP + 1], a
ldh [hDividend], a
ld a, [hl]
ld [wHPBarMaxHP], a
ldh [hDividend + 1], a
ld a, 5
ldh [hDivisor], a
ld b, 2 ; number of bytes
2014-05-22 22:13:20 +00:00
call Divide ; get 1/5 of max HP of pokemon that used Softboiled
ld bc, (wPartyMon1HP + 1) - (wPartyMon1MaxHP + 1)
add hl, bc ; hl now points to LSB of current HP of pokemon that used Softboiled
2014-05-22 22:13:20 +00:00
; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
ldh a, [hQuotient + 3]
2014-05-22 22:13:20 +00:00
push af
ld b, a
ld a, [hl]
ld [wHPBarOldHP], a
2014-05-22 22:13:20 +00:00
sub b
ld [hld], a
ld [wHPBarNewHP], a
ldh a, [hQuotient + 2]
ld b, a
ld a, [hl]
ld [wHPBarOldHP+1], a
2014-05-22 22:13:20 +00:00
sbc b
ld [hl], a
ld [wHPBarNewHP+1], a
2015-07-18 20:52:03 +00:00
coord hl, 4, 1
ld a, [wWhichPokemon]
ld bc, 2 * SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
ld a, SFX_HEAL_HP
call PlaySoundWaitForCurrent
ldh a, [hFlagsFFF6]
set 0, a
ldh [hFlagsFFF6], a
ld a, $02
ld [wHPBarType], a
predef UpdateHPBar2 ; animate HP bar decrease of pokemon that used Softboiled
ldh a, [hFlagsFFF6]
res 0, a
ldh [hFlagsFFF6], a
2014-05-22 22:13:20 +00:00
pop af
ld b, a ; store heal amount (1/5 of max HP)
ld hl, wHPBarOldHP + 1
2014-05-22 22:13:20 +00:00
pop af
ld [hld], a
2014-05-22 22:13:20 +00:00
pop af
ld [hld], a
2014-05-22 22:13:20 +00:00
pop af
ld [hld], a
2014-05-22 22:13:20 +00:00
pop af
ld [hl], a
2014-05-22 22:13:20 +00:00
jr .addHealAmount
.notUsingSoftboiled2
ld a, [wcf91]
cp SODA_POP
ld b, 60 ; Soda Pop heal amount
jr z, .addHealAmount
ld b, 80 ; Lemonade heal amount
jr nc, .addHealAmount
cp FRESH_WATER
ld b, 50 ; Fresh Water heal amount
jr z, .addHealAmount
cp SUPER_POTION
ld b, 200 ; Hyper Potion heal amount
jr c, .addHealAmount
ld b, 50 ; Super Potion heal amount
jr z, .addHealAmount
ld b, 20 ; Potion heal amount
2014-05-22 22:13:20 +00:00
.addHealAmount
pop de
pop hl
ld a, [hl]
2014-05-22 22:13:20 +00:00
add b
ld [hld], a
ld [wHPBarNewHP], a
ld a, [hl]
ld [wHPBarNewHP+1], a
jr nc, .noCarry
2014-05-22 22:13:20 +00:00
inc [hl]
ld a, [hl]
ld [wHPBarNewHP + 1], a
2014-05-22 22:13:20 +00:00
.noCarry
push de
inc hl
ld d, h
ld e, l ; de now points to current HP
ld hl, (wPartyMon1MaxHP + 1) - (wPartyMon1HP + 1)
add hl, de ; hl now points to max HP
ld a, [wcf91]
cp REVIVE
jr z, .setCurrentHPToHalfMaxHP
ld a, [hld]
ld b, a
ld a, [de]
2014-05-22 22:13:20 +00:00
sub b
dec de
ld b, [hl]
ld a, [de]
2014-05-22 22:13:20 +00:00
sbc b
jr nc, .setCurrentHPToMaxHp ; if current HP exceeds max HP after healing
ld a, [wcf91]
cp HYPER_POTION
jr c, .setCurrentHPToMaxHp ; if using a Full Restore or Max Potion
cp MAX_REVIVE
jr z, .setCurrentHPToMaxHp ; if using a Max Revive
2014-05-22 22:13:20 +00:00
jr .updateInBattleData
.setCurrentHPToHalfMaxHP
dec hl
dec de
ld a, [hli]
2014-05-22 22:13:20 +00:00
srl a
ld [de], a
ld [wHPBarNewHP+1], a
ld a, [hl]
2014-05-22 22:13:20 +00:00
rr a
inc de
ld [de], a
ld [wHPBarNewHP], a
2014-05-22 22:13:20 +00:00
dec de
jr .doneHealingPartyHP
.setCurrentHPToMaxHp
ld a, [hli]
ld [de], a
ld [wHPBarNewHP+1], a
2014-05-22 22:13:20 +00:00
inc de
ld a, [hl]
ld [de], a
ld [wHPBarNewHP], a
2014-05-22 22:13:20 +00:00
dec de
.doneHealingPartyHP ; done updating the pokemon's current HP in the party data structure
ld a, [wcf91]
cp FULL_RESTORE
jr nz, .updateInBattleData
ld bc, wPartyMon1Status - (wPartyMon1MaxHP + 1)
add hl, bc
2014-05-22 22:13:20 +00:00
xor a
ld [hl], a ; remove the status ailment in the party data
2014-05-22 22:13:20 +00:00
.updateInBattleData
ld h, d
ld l, e
2014-05-22 22:13:20 +00:00
pop de
ld a, [wPlayerMonNumber]
2014-05-22 22:13:20 +00:00
cp d ; is pokemon the item was used on active in battle?
jr nz, .calculateHPBarCoords
2014-05-22 22:13:20 +00:00
; copy party HP to in-battle HP
ld a, [hli]
ld [wBattleMonHP], a
ld a, [hld]
ld [wBattleMonHP + 1], a
ld a, [wcf91]
cp FULL_RESTORE
jr nz, .calculateHPBarCoords
2014-05-22 22:13:20 +00:00
xor a
ld [wBattleMonStatus], a ; remove the status ailment in the in-battle pokemon data
2014-05-22 22:13:20 +00:00
.calculateHPBarCoords
ld hl, wOAMBuffer + $90
ld bc, 2 * SCREEN_WIDTH
2014-05-22 22:13:20 +00:00
inc d
.calculateHPBarCoordsLoop
add hl, bc
2014-05-22 22:13:20 +00:00
dec d
jr nz, .calculateHPBarCoordsLoop
2014-05-22 22:13:20 +00:00
jr .doneHealing
.healingItemNoEffect
call ItemUseNoEffect
jp .done
.doneHealing
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Softboiled?
jr nz, .skipRemovingItem ; no item to remove if using Softboiled
2014-05-22 22:13:20 +00:00
push hl
call RemoveUsedItem
pop hl
.skipRemovingItem
ld a, [wcf91]
cp FULL_RESTORE
jr c, .playStatusAilmentCuringSound
cp FULL_HEAL
jr z, .playStatusAilmentCuringSound
ld a, SFX_HEAL_HP
call PlaySoundWaitForCurrent
ldh a, [hFlagsFFF6]
set 0, a
ldh [hFlagsFFF6], a
ld a, $02
ld [wHPBarType], a
predef UpdateHPBar2 ; animate the HP bar lengthening
ldh a, [hFlagsFFF6]
res 0, a
ldh [hFlagsFFF6], a
ld a, REVIVE_MSG
ld [wPartyMenuTypeOrMessageID], a
ld a, [wcf91]
cp REVIVE
jr z, .showHealingItemMessage
cp MAX_REVIVE
jr z, .showHealingItemMessage
ld a, POTION_MSG
ld [wPartyMenuTypeOrMessageID], a
2014-05-22 22:13:20 +00:00
jr .showHealingItemMessage
.playStatusAilmentCuringSound
ld a, SFX_HEAL_AILMENT
2015-02-08 06:18:42 +00:00
call PlaySoundWaitForCurrent
2014-05-22 22:13:20 +00:00
.showHealingItemMessage
xor a
ldh [hAutoBGTransferEnabled], a
2014-05-22 22:13:20 +00:00
call ClearScreen
dec a
ld [wUpdateSpritesEnabled], a
2014-05-22 22:13:20 +00:00
call RedrawPartyMenu ; redraws the party menu and displays the message
ld a, 1
ldh [hAutoBGTransferEnabled], a
ld c, 50
2014-05-22 22:13:20 +00:00
call DelayFrames
2015-02-08 06:18:42 +00:00
call WaitForTextScrollButtonPress
2014-05-22 22:13:20 +00:00
jr .done
.canceledItemUse
xor a
ld [wActionResultOrTookBattleTurn], a ; item use failed
2014-05-22 22:13:20 +00:00
pop af
pop af
.done
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Softboiled?
ret nz ; if so, return
call GBPalWhiteOut
call z, RunDefaultPaletteCommand
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
ret nz
2015-02-08 06:18:42 +00:00
jp ReloadMapData
2014-05-22 22:13:20 +00:00
.useVitamin
push hl
ld a, [hl]
ld [wd0b5], a
ld [wd11e], a
ld bc, wPartyMon1Level - wPartyMon1
add hl, bc ; hl now points to level
ld a, [hl] ; a = level
ld [wCurEnemyLVL], a ; store level
2014-05-22 22:13:20 +00:00
call GetMonHeader
push de
ld a, d
ld hl, wPartyMonNicks
2014-05-22 22:13:20 +00:00
call GetPartyMonName
pop de
pop hl
ld a, [wcf91]
cp RARE_CANDY
jp z, .useRareCandy
2014-05-22 22:13:20 +00:00
push hl
sub HP_UP
2014-05-22 22:13:20 +00:00
add a
ld bc, wPartyMon1HPExp - wPartyMon1
add hl, bc
2014-05-22 22:13:20 +00:00
add l
ld l, a
jr nc, .noCarry2
2014-05-22 22:13:20 +00:00
inc h
.noCarry2
ld a, 10
ld b, a
ld a, [hl] ; a = MSB of stat experience of the appropriate stat
cp 100 ; is there already at least 25600 (256 * 100) stat experience?
jr nc, .vitaminNoEffect ; if so, vitamins can't add any more
2014-05-22 22:13:20 +00:00
add b ; add 2560 (256 * 10) stat experience
jr nc, .noCarry3 ; a carry should be impossible here, so this will always jump
ld a, 255
2014-05-22 22:13:20 +00:00
.noCarry3
ld [hl], a
2014-05-22 22:13:20 +00:00
pop hl
call .recalculateStats
ld hl, VitaminText
ld a, [wcf91]
sub HP_UP - 1
ld c, a
2014-05-22 22:13:20 +00:00
.statNameLoop ; loop to get the address of the name of the stat the vitamin increases
dec c
jr z, .gotStatName
2014-05-22 22:13:20 +00:00
.statNameInnerLoop
ld a, [hli]
ld b, a
ld a, $50
2014-05-22 22:13:20 +00:00
cp b
jr nz, .statNameInnerLoop
2014-05-22 22:13:20 +00:00
jr .statNameLoop
.gotStatName
ld de, wcf4b
ld bc, 10
call CopyData ; copy the stat's name to wcf4b
ld a, SFX_HEAL_AILMENT
call PlaySound
ld hl, VitaminStatRoseText
2014-05-22 22:13:20 +00:00
call PrintText
jp RemoveUsedItem
.vitaminNoEffect
pop hl
ld hl, VitaminNoEffectText
2014-05-22 22:13:20 +00:00
call PrintText
jp GBPalWhiteOut
.recalculateStats
ld bc, wPartyMon1Stats - wPartyMon1
add hl, bc
ld d, h
ld e, l ; de now points to stats
ld bc, (wPartyMon1Exp + 2) - wPartyMon1Stats
add hl, bc ; hl now points to LSB of experience
ld b, 1
2014-05-22 22:13:20 +00:00
jp CalcStats ; recalculate stats
.useRareCandy
push hl
ld bc, wPartyMon1Level - wPartyMon1
add hl, bc ; hl now points to level
ld a, [hl] ; a = level
cp MAX_LEVEL
jr z, .vitaminNoEffect ; can't raise level above 100
2014-05-22 22:13:20 +00:00
inc a
ld [hl], a ; store incremented level
ld [wCurEnemyLVL], a
2014-05-22 22:13:20 +00:00
push hl
push de
ld d, a
callab CalcExperience ; calculate experience for next level and store it at hExperience
2014-05-22 22:13:20 +00:00
pop de
pop hl
ld bc, wPartyMon1Exp - wPartyMon1Level
add hl, bc ; hl now points to MSB of experience
2014-05-22 22:13:20 +00:00
; update experience to minimum for new level
ldh a, [hExperience]
ld [hli], a
ldh a, [hExperience + 1]
ld [hli], a
ldh a, [hExperience + 2]
ld [hl], a
2014-05-22 22:13:20 +00:00
pop hl
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
push de
push hl
ld bc, wPartyMon1MaxHP - wPartyMon1
add hl, bc ; hl now points to MSB of max HP
ld a, [hli]
ld b, a
ld c, [hl]
2014-05-22 22:13:20 +00:00
pop hl
push bc
push hl
call .recalculateStats
pop hl
ld bc, (wPartyMon1MaxHP + 1) - wPartyMon1
add hl, bc ; hl now points to LSB of max HP
2014-05-22 22:13:20 +00:00
pop bc
ld a, [hld]
2014-05-22 22:13:20 +00:00
sub c
ld c, a
ld a, [hl]
2014-05-22 22:13:20 +00:00
sbc b
ld b, a ; bc = the amount of max HP gained from leveling up
2014-05-22 22:13:20 +00:00
; add the amount gained to the current HP
ld de, (wPartyMon1HP + 1) - wPartyMon1MaxHP
add hl, de ; hl now points to LSB of current HP
ld a, [hl]
2014-05-22 22:13:20 +00:00
add c
ld [hld], a
ld a, [hl]
2014-05-22 22:13:20 +00:00
adc b
ld [hl], a
ld a, RARE_CANDY_MSG
ld [wPartyMenuTypeOrMessageID], a
2014-05-22 22:13:20 +00:00
call RedrawPartyMenu
pop de
ld a, d
ld [wWhichPokemon], a
ld a, e
ld [wd11e], a
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2014-05-22 22:13:20 +00:00
call LoadMonData
ld d, $01
2014-05-22 22:13:20 +00:00
callab PrintStatsBox ; display new stats text box
call WaitForTextScrollButtonPress ; wait for button press
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2014-08-09 05:39:13 +00:00
predef LearnMoveFromLevelUp ; learn level up move, if any
2014-05-22 22:13:20 +00:00
xor a
ld [wForceEvolution], a
2014-08-09 05:39:13 +00:00
callab TryEvolvingMon ; evolve pokemon, if appropriate
ld a, $01
ld [wUpdateSpritesEnabled], a
2014-05-22 22:13:20 +00:00
pop af
ld [wcf91], a
2014-05-22 22:13:20 +00:00
pop af
ld [wWhichPokemon], a
2014-05-22 22:13:20 +00:00
jp RemoveUsedItem
2016-06-12 00:24:04 +00:00
VitaminStatRoseText:
text_far _VitaminStatRoseText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
VitaminNoEffectText:
text_far _VitaminNoEffectText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
VitaminText:
2014-05-22 22:13:20 +00:00
db "HEALTH@"
db "ATTACK@"
db "DEFENSE@"
db "SPEED@"
db "SPECIAL@"
2016-06-12 00:24:04 +00:00
ItemUseBait:
ld hl, ThrewBaitText
2014-05-22 22:13:20 +00:00
call PrintText
2018-03-24 18:41:54 +00:00
ld hl, wEnemyMonActualCatchRate ; catch rate
2014-05-22 22:13:20 +00:00
srl [hl] ; halve catch rate
ld a, BAIT_ANIM
ld hl, wSafariBaitFactor ; bait factor
ld de, wSafariEscapeFactor ; escape factor
2014-05-22 22:13:20 +00:00
jr BaitRockCommon
2016-06-12 00:24:04 +00:00
ItemUseRock:
ld hl, ThrewRockText
2014-05-22 22:13:20 +00:00
call PrintText
2018-03-24 18:41:54 +00:00
ld hl, wEnemyMonActualCatchRate ; catch rate
ld a, [hl]
2014-05-22 22:13:20 +00:00
add a ; double catch rate
jr nc, .noCarry
ld a, $ff
2014-05-22 22:13:20 +00:00
.noCarry
ld [hl], a
ld a, ROCK_ANIM
ld hl, wSafariEscapeFactor ; escape factor
ld de, wSafariBaitFactor ; bait factor
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BaitRockCommon:
ld [wAnimationID], a
2014-05-22 22:13:20 +00:00
xor a
ld [wAnimationType], a
ldh [hWhoseTurn], a
ld [de], a ; zero escape factor (for bait), zero bait factor (for rock)
2014-05-22 22:13:20 +00:00
.randomLoop ; loop until a random number less than 5 is generated
call Random
and 7
cp 5
jr nc, .randomLoop
2014-05-22 22:13:20 +00:00
inc a ; increment the random number, giving a range from 1 to 5 inclusive
ld b, a
ld a, [hl]
2014-05-22 22:13:20 +00:00
add b ; increase bait factor (for bait), increase escape factor (for rock)
jr nc, .noCarry
ld a, $ff
2014-05-22 22:13:20 +00:00
.noCarry
ld [hl], a
predef MoveAnimation ; do animation
ld c, 70
2014-05-22 22:13:20 +00:00
jp DelayFrames
2016-06-12 00:24:04 +00:00
ThrewBaitText:
text_far _ThrewBaitText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ThrewRockText:
text_far _ThrewRockText
text_end
2014-05-22 22:13:20 +00:00
; also used for Dig out-of-battle effect
2016-06-12 00:24:04 +00:00
ItemUseEscapeRope:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr nz, .notUsable
ld a, [wCurMap]
cp AGATHAS_ROOM
jr z, .notUsable
ld a, [wCurMapTileset]
ld b, a
ld hl, EscapeRopeTilesets
2014-05-22 22:13:20 +00:00
.loop
ld a, [hli]
cp $ff
jr z, .notUsable
2014-05-22 22:13:20 +00:00
cp b
jr nz, .loop
ld hl, wd732
set 3, [hl]
set 6, [hl]
ld hl, wd72e
res 4, [hl]
2015-07-21 01:32:02 +00:00
ResetEvent EVENT_IN_SAFARI_ZONE
2014-05-22 22:13:20 +00:00
xor a
ld [wNumSafariBalls], a
ld [wSafariZoneGateCurScript], a
2014-05-22 22:13:20 +00:00
inc a
ld [wEscapedFromBattle], a
ld [wActionResultOrTookBattleTurn], a ; item used
ld a, [wPseudoItemID]
2014-05-22 22:13:20 +00:00
and a ; using Dig?
ret nz ; if so, return
call ItemUseReloadOverworldData
ld c, 30
2014-05-22 22:13:20 +00:00
call DelayFrames
jp RemoveUsedItem
.notUsable
jp ItemUseNotTime
2016-06-12 00:24:04 +00:00
EscapeRopeTilesets:
2014-05-22 22:13:20 +00:00
db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
db $ff ; terminator
2016-06-12 00:24:04 +00:00
ItemUseRepel:
ld b, 100
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseRepelCommon:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
ld a, b
ld [wRepelRemainingSteps], a
2014-05-22 22:13:20 +00:00
jp PrintItemUseTextAndRemoveItem
; handles X Accuracy item
2016-06-12 00:24:04 +00:00
ItemUseXAccuracy:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp z, ItemUseNotTime
ld hl, wPlayerBattleStatus2
set USING_X_ACCURACY, [hl] ; X Accuracy bit
2014-05-22 22:13:20 +00:00
jp PrintItemUseTextAndRemoveItem
; This function is bugged and never works. It always jumps to ItemUseNotTime.
; The Card Key is handled in a different way.
2016-06-12 00:24:04 +00:00
ItemUseCardKey:
2014-05-22 22:13:20 +00:00
xor a
ld [wUnusedD71F], a
2014-09-13 07:50:56 +00:00
call GetTileAndCoordsInFrontOfPlayer
ld a, [GetTileAndCoordsInFrontOfPlayer]
cp $18
jr nz, .next0
ld hl, CardKeyTable1
2014-05-22 22:13:20 +00:00
jr .next1
.next0
cp $24
jr nz, .next2
ld hl, CardKeyTable2
2014-05-22 22:13:20 +00:00
jr .next1
.next2
cp $5e
jp nz, ItemUseNotTime
ld hl, CardKeyTable3
2014-05-22 22:13:20 +00:00
.next1
ld a, [wCurMap]
ld b, a
2014-05-22 22:13:20 +00:00
.loop
ld a, [hli]
cp $ff
jp z, ItemUseNotTime
2014-05-22 22:13:20 +00:00
cp b
jr nz, .nextEntry1
ld a, [hli]
2014-05-22 22:13:20 +00:00
cp d
jr nz, .nextEntry2
ld a, [hli]
2014-05-22 22:13:20 +00:00
cp e
jr nz, .nextEntry3
ld a, [hl]
ld [wUnusedD71F], a
2014-05-22 22:13:20 +00:00
jr .done
.nextEntry1
inc hl
.nextEntry2
inc hl
.nextEntry3
inc hl
jr .loop
.done
ld hl, ItemUseText00
2014-05-22 22:13:20 +00:00
call PrintText
ld hl, wd728
set 7, [hl]
2014-05-22 22:13:20 +00:00
ret
; These tables are probably supposed to be door locations in Silph Co.,
; but they are unused.
; The reason there are 3 tables is unknown.
; Format:
; 00: Map ID
; 01: Y
; 02: X
; 03: ID?
2016-06-12 00:24:04 +00:00
CardKeyTable1:
2014-05-22 22:13:20 +00:00
db SILPH_CO_2F,$04,$04,$00
db SILPH_CO_2F,$04,$05,$01
db SILPH_CO_4F,$0C,$04,$02
db SILPH_CO_4F,$0C,$05,$03
db SILPH_CO_7F,$06,$0A,$04
db SILPH_CO_7F,$06,$0B,$05
db SILPH_CO_9F,$04,$12,$06
db SILPH_CO_9F,$04,$13,$07
db SILPH_CO_10F,$08,$0A,$08
db SILPH_CO_10F,$08,$0B,$09
db $ff
2016-06-12 00:24:04 +00:00
CardKeyTable2:
2014-05-22 22:13:20 +00:00
db SILPH_CO_3F,$08,$09,$0A
db SILPH_CO_3F,$09,$09,$0B
db SILPH_CO_5F,$04,$07,$0C
db SILPH_CO_5F,$05,$07,$0D
db SILPH_CO_6F,$0C,$05,$0E
db SILPH_CO_6F,$0D,$05,$0F
db SILPH_CO_8F,$08,$07,$10
db SILPH_CO_8F,$09,$07,$11
db SILPH_CO_9F,$08,$03,$12
db SILPH_CO_9F,$09,$03,$13
db $ff
2016-06-12 00:24:04 +00:00
CardKeyTable3:
2014-05-22 22:13:20 +00:00
db SILPH_CO_11F,$08,$09,$14
db SILPH_CO_11F,$09,$09,$15
db $ff
2016-06-12 00:24:04 +00:00
ItemUsePokedoll:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
dec a
jp nz, ItemUseNotTime
ld a, $01
ld [wEscapedFromBattle], a
2014-05-22 22:13:20 +00:00
jp PrintItemUseTextAndRemoveItem
2016-06-12 00:24:04 +00:00
ItemUseGuardSpec:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp z, ItemUseNotTime
ld hl, wPlayerBattleStatus2
set PROTECTED_BY_MIST, [hl] ; Mist bit
2014-05-22 22:13:20 +00:00
jp PrintItemUseTextAndRemoveItem
2016-06-12 00:24:04 +00:00
ItemUseSuperRepel:
ld b, 200
2014-05-22 22:13:20 +00:00
jp ItemUseRepelCommon
2016-06-12 00:24:04 +00:00
ItemUseMaxRepel:
ld b, 250
2014-05-22 22:13:20 +00:00
jp ItemUseRepelCommon
2016-06-12 00:24:04 +00:00
ItemUseDireHit:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp z, ItemUseNotTime
ld hl, wPlayerBattleStatus2
set GETTING_PUMPED, [hl] ; Focus Energy bit
2014-05-22 22:13:20 +00:00
jp PrintItemUseTextAndRemoveItem
2016-06-12 00:24:04 +00:00
ItemUseXStat:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr nz, .inBattle
2014-05-22 22:13:20 +00:00
call ItemUseNotTime
ld a, 2
ld [wActionResultOrTookBattleTurn], a ; item not used
2014-05-22 22:13:20 +00:00
ret
.inBattle
ld hl, wPlayerMoveNum
ld a, [hli]
2015-08-31 02:38:41 +00:00
push af ; save [wPlayerMoveNum]
ld a, [hl]
2015-08-31 02:38:41 +00:00
push af ; save [wPlayerMoveEffect]
2014-05-22 22:13:20 +00:00
push hl
ld a, [wcf91]
sub X_ATTACK - ATTACK_UP1_EFFECT
ld [hl], a ; store player move effect
2014-05-22 22:13:20 +00:00
call PrintItemUseTextAndRemoveItem
ld a, XSTATITEM_ANIM ; X stat item animation ID
ld [wPlayerMoveNum], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1 ; restore saved screen
call Delay3
xor a
ldh [hWhoseTurn], a ; set turn to player's turn
2014-05-22 22:13:20 +00:00
callba StatModifierUpEffect ; do stat increase move
pop hl
pop af
ld [hld], a ; restore [wPlayerMoveEffect]
2014-05-22 22:13:20 +00:00
pop af
ld [hl], a ; restore [wPlayerMoveNum]
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
ItemUsePokeflute:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr nz, .inBattle
2014-05-22 22:13:20 +00:00
; if not in battle
call ItemUseReloadOverworldData
ld a, [wCurMap]
cp ROUTE_12
jr nz, .notRoute12
2015-07-21 01:32:02 +00:00
CheckEvent EVENT_BEAT_ROUTE12_SNORLAX
jr nz, .noSnorlaxToWakeUp
2014-05-22 22:13:20 +00:00
; if the player hasn't beaten Route 12 Snorlax
ld hl, Route12SnorlaxFluteCoords
2014-05-22 22:13:20 +00:00
call ArePlayerCoordsInArray
jr nc, .noSnorlaxToWakeUp
ld hl, PlayedFluteHadEffectText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-21 01:32:02 +00:00
SetEvent EVENT_FIGHT_ROUTE12_SNORLAX
2014-05-22 22:13:20 +00:00
ret
.notRoute12
cp ROUTE_16
jr nz, .noSnorlaxToWakeUp
2015-07-21 01:32:02 +00:00
CheckEvent EVENT_BEAT_ROUTE16_SNORLAX
jr nz, .noSnorlaxToWakeUp
2014-05-22 22:13:20 +00:00
; if the player hasn't beaten Route 16 Snorlax
ld hl, Route16SnorlaxFluteCoords
2014-05-22 22:13:20 +00:00
call ArePlayerCoordsInArray
jr nc, .noSnorlaxToWakeUp
ld hl, PlayedFluteHadEffectText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-21 01:32:02 +00:00
SetEvent EVENT_FIGHT_ROUTE16_SNORLAX
2014-05-22 22:13:20 +00:00
ret
.noSnorlaxToWakeUp
ld hl, PlayedFluteNoEffectText
2014-05-22 22:13:20 +00:00
jp PrintText
.inBattle
xor a
ld [wWereAnyMonsAsleep], a
ld b, ~SLP & $ff
ld hl, wPartyMon1Status
2014-05-22 22:13:20 +00:00
call WakeUpEntireParty
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
dec a ; is it a trainer battle?
jr z, .skipWakingUpEnemyParty
2014-05-22 22:13:20 +00:00
; if it's a trainer battle
ld hl, wEnemyMon1Status
2014-05-22 22:13:20 +00:00
call WakeUpEntireParty
.skipWakingUpEnemyParty
ld hl, wBattleMonStatus
ld a, [hl]
2014-05-22 22:13:20 +00:00
and b ; remove Sleep status
ld [hl], a
ld hl, wEnemyMonStatus
ld a, [hl]
2014-05-22 22:13:20 +00:00
and b ; remove Sleep status
ld [hl], a
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer2 ; restore saved screen
ld a, [wWereAnyMonsAsleep]
2014-05-22 22:13:20 +00:00
and a ; were any pokemon asleep before playing the flute?
ld hl, PlayedFluteNoEffectText
jp z, PrintText ; if no pokemon were asleep
2014-05-22 22:13:20 +00:00
; if some pokemon were asleep
ld hl, PlayedFluteHadEffectText
2014-05-22 22:13:20 +00:00
call PrintText
ld a, [wLowHealthAlarm]
and $80
jr nz, .skipMusic
2014-05-22 22:13:20 +00:00
call WaitForSoundToFinish ; wait for sound to end
callba Music_PokeFluteInBattle ; play in-battle pokeflute music
.musicWaitLoop ; wait for music to finish playing
ld a, [wChannelSoundIDs + Ch7]
2014-05-22 22:13:20 +00:00
and a ; music off?
jr nz, .musicWaitLoop
2014-05-22 22:13:20 +00:00
.skipMusic
ld hl, FluteWokeUpText
2014-05-22 22:13:20 +00:00
jp PrintText
; wakes up all party pokemon
; INPUT:
; hl must point to status of first pokemon in party (player's or enemy's)
; b must equal ~SLP
2015-07-19 03:49:52 +00:00
; [wWereAnyMonsAsleep] should be initialized to 0
2014-05-22 22:13:20 +00:00
; OUTPUT:
2015-07-19 03:49:52 +00:00
; [wWereAnyMonsAsleep]: set to 1 if any pokemon were asleep
2016-06-12 00:24:04 +00:00
WakeUpEntireParty:
ld de, 44
ld c, 6
2014-05-22 22:13:20 +00:00
.loop
ld a, [hl]
2014-05-22 22:13:20 +00:00
push af
and SLP ; is pokemon asleep?
jr z, .notAsleep
ld a, 1
ld [wWereAnyMonsAsleep], a ; indicate that a pokemon had to be woken up
2014-05-22 22:13:20 +00:00
.notAsleep
pop af
and b ; remove Sleep status
ld [hl], a
add hl, de
2014-05-22 22:13:20 +00:00
dec c
jr nz, .loop
2014-05-22 22:13:20 +00:00
ret
; Format:
; 00: Y
; 01: X
2016-06-12 00:24:04 +00:00
Route12SnorlaxFluteCoords:
2014-05-22 22:13:20 +00:00
db 62,9 ; one space West of Snorlax
db 61,10 ; one space North of Snorlax
db 63,10 ; one space South of Snorlax
db 62,11 ; one space East of Snorlax
db $ff ; terminator
; Format:
; 00: Y
; 01: X
2016-06-12 00:24:04 +00:00
Route16SnorlaxFluteCoords:
2014-05-22 22:13:20 +00:00
db 10,27 ; one space East of Snorlax
db 10,25 ; one space West of Snorlax
db $ff ; terminator
2016-06-12 00:24:04 +00:00
PlayedFluteNoEffectText:
text_far _PlayedFluteNoEffectText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
FluteWokeUpText:
text_far _FluteWokeUpText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PlayedFluteHadEffectText:
text_far _PlayedFluteHadEffectText
text_promptbutton
text_asm
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr nz, .done
2014-05-22 22:13:20 +00:00
; play out-of-battle pokeflute music
ld a, SFX_STOP_ALL_MUSIC
call PlaySound
2017-05-08 07:54:20 +00:00
ld a, SFX_POKEFLUTE
2015-07-22 14:57:31 +00:00
ld c, BANK(SFX_Pokeflute)
call PlayMusic
2014-05-22 22:13:20 +00:00
.musicWaitLoop ; wait for music to finish playing
ld a, [wChannelSoundIDs + Ch3]
cp SFX_POKEFLUTE
jr z, .musicWaitLoop
call PlayDefaultMusic ; start playing normal music again
2014-05-22 22:13:20 +00:00
.done
jp TextScriptEnd ; end text
2016-06-12 00:24:04 +00:00
ItemUseCoinCase:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
ld hl, CoinCaseNumCoinsText
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
CoinCaseNumCoinsText:
text_far _CoinCaseNumCoinsText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseOldRod:
2014-05-22 22:13:20 +00:00
call FishingInit
jp c, ItemUseNotTime
2015-08-05 21:20:29 +00:00
lb bc, 5, MAGIKARP
2014-05-22 22:13:20 +00:00
ld a, $1 ; set bite
jr RodResponse
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseGoodRod:
2014-05-22 22:13:20 +00:00
call FishingInit
jp c, ItemUseNotTime
2014-05-22 22:13:20 +00:00
.RandomLoop
call Random
2014-05-22 22:13:20 +00:00
srl a
jr c, .SetBite
and %11
cp 2
jr nc, .RandomLoop
; choose which monster appears
ld hl, GoodRodMons
add a
ld c, a
ld b, 0
add hl, bc
ld b, [hl]
2014-05-22 22:13:20 +00:00
inc hl
ld c, [hl]
2014-05-22 22:13:20 +00:00
and a
.SetBite
ld a, 0
2014-05-22 22:13:20 +00:00
rla
xor 1
jr RodResponse
INCLUDE "data/wild/good_rod.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseSuperRod:
2014-05-22 22:13:20 +00:00
call FishingInit
jp c, ItemUseNotTime
call ReadSuperRodData
2014-05-22 22:13:20 +00:00
ld a, e
2016-06-12 00:24:04 +00:00
RodResponse:
ld [wRodResponse], a
2014-05-22 22:13:20 +00:00
dec a ; is there a bite?
jr nz, .next
; if yes, store level and species data
ld a, 1
2015-08-31 02:38:41 +00:00
ld [wMoveMissed], a
2014-05-22 22:13:20 +00:00
ld a, b ; level
2015-08-31 02:38:41 +00:00
ld [wCurEnemyLVL], a
2014-05-22 22:13:20 +00:00
ld a, c ; species
2015-08-31 02:38:41 +00:00
ld [wCurOpponent], a
2014-05-22 22:13:20 +00:00
.next
2014-09-13 07:50:56 +00:00
ld hl, wWalkBikeSurfState
2014-05-22 22:13:20 +00:00
ld a, [hl] ; store the value in a
push af
push hl
ld [hl], 0
callba FishingAnim
2014-05-22 22:13:20 +00:00
pop hl
pop af
ld [hl], a
ret
; checks if fishing is possible and if so, runs initialization code common to all rods
; unsets carry if fishing is possible, sets carry if not
2016-06-12 00:24:04 +00:00
FishingInit:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jr z, .notInBattle
2014-05-22 22:13:20 +00:00
scf ; can't fish during battle
ret
.notInBattle
call IsNextTileShoreOrWater
ret c
ld a, [wWalkBikeSurfState]
cp 2 ; Surfing?
jr z, .surfing
2014-05-22 22:13:20 +00:00
call ItemUseReloadOverworldData
ld hl, ItemUseText00
2014-05-22 22:13:20 +00:00
call PrintText
ld a, SFX_HEAL_AILMENT
call PlaySound
ld c, 80
2014-05-22 22:13:20 +00:00
call DelayFrames
and a
ret
.surfing
scf ; can't fish when surfing
ret
2016-06-12 00:24:04 +00:00
ItemUseOaksParcel:
2014-05-22 22:13:20 +00:00
jp ItemUseNotYoursToUse
2016-06-12 00:24:04 +00:00
ItemUseItemfinder:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
2014-05-22 22:13:20 +00:00
call ItemUseReloadOverworldData
callba HiddenItemNear ; check for hidden items
ld hl, ItemfinderFoundNothingText
jr nc, .printText ; if no hidden items
ld c, 4
2014-05-22 22:13:20 +00:00
.loop
ld a, SFX_HEALING_MACHINE
call PlaySoundWaitForCurrent
ld a, SFX_PURCHASE
call PlaySoundWaitForCurrent
2014-05-22 22:13:20 +00:00
dec c
jr nz, .loop
ld hl, ItemfinderFoundItemText
2014-05-22 22:13:20 +00:00
.printText
jp PrintText
2016-06-12 00:24:04 +00:00
ItemfinderFoundItemText:
text_far _ItemfinderFoundItemText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemfinderFoundNothingText:
text_far _ItemfinderFoundNothingText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUsePPUp:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUsePPRestore:
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
ld [wPPRestoreItem], a
2014-05-22 22:13:20 +00:00
.chooseMon
xor a
ld [wUpdateSpritesEnabled], a
ld a, USE_ITEM_PARTY_MENU
ld [wPartyMenuTypeOrMessageID], a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
jr nc, .chooseMove
2014-05-22 22:13:20 +00:00
jp .itemNotUsed
.chooseMove
ld a, [wPPRestoreItem]
cp ELIXER
jp nc, .useElixir ; if Elixir or Max Elixir
ld a, $02
ld [wMoveMenuType], a
ld hl, RaisePPWhichTechniqueText
ld a, [wPPRestoreItem]
cp ETHER ; is it a PP Up?
jr c, .printWhichTechniqueMessage ; if so, print the raise PP message
ld hl, RestorePPWhichTechniqueText ; otherwise, print the restore PP message
2014-05-22 22:13:20 +00:00
.printWhichTechniqueMessage
call PrintText
xor a
ld [wPlayerMoveListIndex], a
2014-05-22 22:13:20 +00:00
callab MoveSelectionMenu ; move selection menu
ld a, 0
ld [wPlayerMoveListIndex], a
jr nz, .chooseMon
ld hl, wPartyMon1Moves
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call GetSelectedMoveOffset
push hl
ld a, [hl]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B ; copy name to wcf4b
2014-05-22 22:13:20 +00:00
pop hl
ld a, [wPPRestoreItem]
cp ETHER
jr nc, .useEther ; if Ether or Max Ether
2014-05-22 22:13:20 +00:00
.usePPUp
ld bc, wPartyMon1PP - wPartyMon1Moves
add hl, bc
ld a, [hl] ; move PP
cp 3 << 6 ; have 3 PP Ups already been used?
jr c, .PPNotMaxedOut
ld hl, PPMaxedOutText
2014-05-22 22:13:20 +00:00
call PrintText
jr .chooseMove
.PPNotMaxedOut
ld a, [hl]
add 1 << 6 ; increase PP Up count by 1
ld [hl], a
ld a, 1 ; 1 PP Up used
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call RestoreBonusPP ; add the bonus PP to current PP
ld hl, PPIncreasedText
2014-05-22 22:13:20 +00:00
call PrintText
.done
pop af
ld [wWhichPokemon], a
2014-05-22 22:13:20 +00:00
call GBPalWhiteOut
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
jp RemoveUsedItem
.afterRestoringPP ; after using a (Max) Ether/Elixir
ld a, [wWhichPokemon]
ld b, a
ld a, [wPlayerMonNumber]
2014-05-22 22:13:20 +00:00
cp b ; is the pokemon whose PP was restored active in battle?
jr nz, .skipUpdatingInBattleData
ld hl, wPartyMon1PP
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call AddNTimes
ld de, wBattleMonPP
ld bc, 4
2014-05-22 22:13:20 +00:00
call CopyData ; copy party data to in-battle data
.skipUpdatingInBattleData
ld a, SFX_HEAL_AILMENT
2014-05-22 22:13:20 +00:00
call PlaySound
ld hl, PPRestoredText
2014-05-22 22:13:20 +00:00
call PrintText
jr .done
.useEther
call .restorePP
jr nz, .afterRestoringPP
2014-05-22 22:13:20 +00:00
jp .noEffect
; unsets zero flag if PP was restored, sets zero flag if not
; however, this is bugged for Max Ethers and Max Elixirs (see below)
.restorePP
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2014-05-22 22:13:20 +00:00
call GetMaxPP
ld hl, wPartyMon1Moves
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call GetSelectedMoveOffset
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon1PP - wPartyMon1Moves
add hl, bc ; hl now points to move's PP
ld a, [wMaxPP]
ld b, a
ld a, [wPPRestoreItem]
cp MAX_ETHER
jr z, .fullyRestorePP
ld a, [hl] ; move PP
and %00111111 ; lower 6 bit bits store current PP
2014-05-22 22:13:20 +00:00
cp b ; does current PP equal max PP?
ret z ; if so, return
add 10 ; increase current PP by 10
2014-05-22 22:13:20 +00:00
; b holds the max PP amount and b will hold the new PP amount.
; So, if the new amount meets or exceeds the max amount,
; cap the amount to the max amount by leaving b unchanged.
; Otherwise, store the new amount in b.
cp b ; does the new amount meet or exceed the maximum?
jr nc, .storeNewAmount
ld b, a
2014-05-22 22:13:20 +00:00
.storeNewAmount
ld a, [hl] ; move PP
and %11000000 ; PP Up counter bits
2014-05-22 22:13:20 +00:00
add b
ld [hl], a
2014-05-22 22:13:20 +00:00
ret
.fullyRestorePP
ld a, [hl] ; move PP
2014-05-22 22:13:20 +00:00
; Note that this code has a bug. It doesn't mask out the upper two bits, which
; are used to count how many PP Ups have been used on the move. So, Max Ethers
; and Max Elixirs will not be detected as having no effect on a move with full
; PP if the move has had any PP Ups used on it.
cp b ; does current PP equal max PP?
ret z
jr .storeNewAmount
.useElixir
; decrement the item ID so that ELIXER becomes ETHER and MAX_ELIXER becomes MAX_ETHER
ld hl, wPPRestoreItem
2014-05-22 22:13:20 +00:00
dec [hl]
dec [hl]
xor a
ld hl, wCurrentMenuItem
ld [hli], a
ld [hl], a ; zero the counter for number of moves that had their PP restored
ld b, 4
2014-05-22 22:13:20 +00:00
; loop through each move and restore PP
.elixirLoop
push bc
ld hl, wPartyMon1Moves
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon2 - wPartyMon1
2014-05-22 22:13:20 +00:00
call GetSelectedMoveOffset
ld a, [hl]
2014-05-22 22:13:20 +00:00
and a ; does the current slot have a move?
jr z, .nextMove
2014-05-22 22:13:20 +00:00
call .restorePP
jr z, .nextMove
2014-05-22 22:13:20 +00:00
; if some PP was restored
ld hl, wTileBehindCursor ; counter for number of moves that had their PP restored
2014-05-22 22:13:20 +00:00
inc [hl]
.nextMove
ld hl, wCurrentMenuItem
2014-05-22 22:13:20 +00:00
inc [hl]
pop bc
dec b
jr nz, .elixirLoop
ld a, [wTileBehindCursor]
2014-05-22 22:13:20 +00:00
and a ; did any moves have their PP restored?
jp nz, .afterRestoringPP
2014-05-22 22:13:20 +00:00
.noEffect
call ItemUseNoEffect
.itemNotUsed
call GBPalWhiteOut
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
pop af
xor a
ld [wActionResultOrTookBattleTurn], a ; item use failed
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
RaisePPWhichTechniqueText:
text_far _RaisePPWhichTechniqueText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
RestorePPWhichTechniqueText:
text_far _RestorePPWhichTechniqueText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PPMaxedOutText:
text_far _PPMaxedOutText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PPIncreasedText:
text_far _PPIncreasedText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PPRestoredText:
text_far _PPRestoredText
text_end
2014-05-22 22:13:20 +00:00
; for items that can't be used from the Item menu
2016-06-12 00:24:04 +00:00
UnusableItem:
2014-05-22 22:13:20 +00:00
jp ItemUseNotTime
2016-06-12 00:24:04 +00:00
ItemUseTMHM:
ld a, [wIsInBattle]
2014-05-22 22:13:20 +00:00
and a
jp nz, ItemUseNotTime
ld a, [wcf91]
2020-07-06 02:52:27 +00:00
sub TM01 ; underflows below 0 for HM items (before TM items)
2014-05-22 22:13:20 +00:00
push af
jr nc, .skipAdding
2020-07-06 02:52:27 +00:00
add NUM_TMS + NUM_HMS ; adjust HM IDs to come after TM IDs
2014-05-22 22:13:20 +00:00
.skipAdding
inc a
ld [wd11e], a
predef TMToMove ; get move ID from TM/HM ID
ld a, [wd11e]
ld [wMoveNum], a
2014-05-22 22:13:20 +00:00
call GetMoveName
call CopyStringToCF4B ; copy name to wcf4b
2014-05-22 22:13:20 +00:00
pop af
ld hl, BootedUpTMText
jr nc, .printBootedUpMachineText
ld hl, BootedUpHMText
2014-05-22 22:13:20 +00:00
.printBootedUpMachineText
call PrintText
ld hl, TeachMachineMoveText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-18 20:52:03 +00:00
coord hl, 14, 7
2015-08-05 21:20:29 +00:00
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID ; yes/no menu
ld a, [wCurrentMenuItem]
2014-05-22 22:13:20 +00:00
and a
jr z, .useMachine
ld a, 2
ld [wActionResultOrTookBattleTurn], a ; item not used
2014-05-22 22:13:20 +00:00
ret
.useMachine
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
push af
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
push af
.chooseMon
ld hl, wcf4b
ld de, wTempMoveNameBuffer
ld bc, 14
2015-08-14 07:36:06 +00:00
call CopyData ; save the move name because DisplayPartyMenu will overwrite it
ld a, $ff
ld [wUpdateSpritesEnabled], a
ld a, TMHM_PARTY_MENU
ld [wPartyMenuTypeOrMessageID], a
2014-05-22 22:13:20 +00:00
call DisplayPartyMenu
push af
ld hl, wTempMoveNameBuffer
ld de, wcf4b
ld bc, 14
2014-05-22 22:13:20 +00:00
call CopyData
pop af
jr nc, .checkIfAbleToLearnMove
2014-05-22 22:13:20 +00:00
; if the player canceled teaching the move
pop af
pop af
call GBPalWhiteOutWithDelay3
2014-05-23 22:34:35 +00:00
call ClearSprites
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
jp LoadScreenTilesFromBuffer1 ; restore saved screen
.checkIfAbleToLearnMove
predef CanLearnTM ; check if the pokemon can learn the move
2014-05-22 22:13:20 +00:00
push bc
ld a, [wWhichPokemon]
ld hl, wPartyMonNicks
2014-05-22 22:13:20 +00:00
call GetPartyMonName
pop bc
ld a, c
2014-05-22 22:13:20 +00:00
and a ; can the pokemon learn the move?
jr nz, .checkIfAlreadyLearnedMove
2014-05-22 22:13:20 +00:00
; if the pokemon can't learn the move
ld a, SFX_DENIED
call PlaySoundWaitForCurrent
ld hl, MonCannotLearnMachineMoveText
2014-05-22 22:13:20 +00:00
call PrintText
jr .chooseMon
.checkIfAlreadyLearnedMove
callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
jr c, .chooseMon
predef LearnMove ; teach move
2014-05-22 22:13:20 +00:00
pop af
ld [wcf91], a
2014-05-22 22:13:20 +00:00
pop af
ld [wWhichPokemon], a
ld a, b
2014-05-22 22:13:20 +00:00
and a
ret z
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
call IsItemHM
ret c
jp RemoveUsedItem
2016-06-12 00:24:04 +00:00
BootedUpTMText:
text_far _BootedUpTMText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BootedUpHMText:
text_far _BootedUpHMText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
TeachMachineMoveText:
text_far _TeachMachineMoveText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
MonCannotLearnMachineMoveText:
text_far _MonCannotLearnMachineMoveText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
PrintItemUseTextAndRemoveItem:
ld hl, ItemUseText00
2014-05-22 22:13:20 +00:00
call PrintText
ld a, SFX_HEAL_AILMENT
call PlaySound
2014-05-22 22:13:20 +00:00
call WaitForTextScrollButtonPress ; wait for button press
2016-06-12 00:24:04 +00:00
RemoveUsedItem:
ld hl, wNumBagItems
ld a, 1 ; one item
ld [wItemQuantity], a
2014-05-22 22:13:20 +00:00
jp RemoveItemFromInventory
2016-06-12 00:24:04 +00:00
ItemUseNoEffect:
ld hl, ItemUseNoEffectText
2014-05-22 22:13:20 +00:00
jr ItemUseFailed
2016-06-12 00:24:04 +00:00
ItemUseNotTime:
ld hl, ItemUseNotTimeText
2014-05-22 22:13:20 +00:00
jr ItemUseFailed
2016-06-12 00:24:04 +00:00
ItemUseNotYoursToUse:
ld hl, ItemUseNotYoursToUseText
2014-05-22 22:13:20 +00:00
jr ItemUseFailed
2016-06-12 00:24:04 +00:00
ThrowBallAtTrainerMon:
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-22 22:13:20 +00:00
call LoadScreenTilesFromBuffer1 ; restore saved screen
call Delay3
ld a, TOSS_ANIM
ld [wAnimationID], a
predef MoveAnimation ; do animation
ld hl, ThrowBallAtTrainerMonText1
2014-05-22 22:13:20 +00:00
call PrintText
ld hl, ThrowBallAtTrainerMonText2
2014-05-22 22:13:20 +00:00
call PrintText
jr RemoveUsedItem
2016-06-12 00:24:04 +00:00
NoCyclingAllowedHere:
ld hl, NoCyclingAllowedHereText
2014-05-22 22:13:20 +00:00
jr ItemUseFailed
2016-06-12 00:24:04 +00:00
BoxFullCannotThrowBall:
ld hl, BoxFullCannotThrowBallText
2014-05-22 22:13:20 +00:00
jr ItemUseFailed
2016-06-12 00:24:04 +00:00
SurfingAttemptFailed:
ld hl, NoSurfingHereText
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseFailed:
2014-05-22 22:13:20 +00:00
xor a
ld [wActionResultOrTookBattleTurn], a ; item use failed
2014-05-22 22:13:20 +00:00
jp PrintText
2016-06-12 00:24:04 +00:00
ItemUseNotTimeText:
text_far _ItemUseNotTimeText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseNotYoursToUseText:
text_far _ItemUseNotYoursToUseText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseNoEffectText:
text_far _ItemUseNoEffectText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ThrowBallAtTrainerMonText1:
text_far _ThrowBallAtTrainerMonText1
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ThrowBallAtTrainerMonText2:
text_far _ThrowBallAtTrainerMonText2
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
NoCyclingAllowedHereText:
text_far _NoCyclingAllowedHereText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
NoSurfingHereText:
text_far _NoSurfingHereText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
BoxFullCannotThrowBallText:
text_far _BoxFullCannotThrowBallText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ItemUseText00:
text_far _ItemUseText001
text_low
text_far _ItemUseText002
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
GotOnBicycleText:
text_far _GotOnBicycleText1
text_low
text_far _GotOnBicycleText2
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
GotOffBicycleText:
text_far _GotOffBicycleText1
text_low
text_far _GotOffBicycleText2
text_end
2014-05-22 22:13:20 +00:00
; restores bonus PP (from PP Ups) when healing at a pokemon center
; also, when a PP Up is used, it increases the current PP by one PP Up bonus
; INPUT:
; [wWhichPokemon] = index of pokemon in party
; [wCurrentMenuItem] = index of move (when using a PP Up)
2016-06-12 00:24:04 +00:00
RestoreBonusPP:
ld hl, wPartyMon1Moves
2015-08-07 12:20:37 +00:00
ld bc, wPartyMon2 - wPartyMon1
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
call AddNTimes
push hl
ld de, wNormalMaxPPList - 1
2015-07-15 06:16:06 +00:00
predef LoadMovePPs ; loads the normal max PP of each of the pokemon's moves to wNormalMaxPPList
2014-05-22 22:13:20 +00:00
pop hl
2015-08-07 12:20:37 +00:00
ld c, wPartyMon1PP - wPartyMon1Moves
ld b, 0
add hl, bc ; hl now points to move 1 PP
ld de, wNormalMaxPPList
ld b, 0 ; initialize move counter to zero
2014-05-22 22:13:20 +00:00
; loop through the pokemon's moves
.loop
inc b
ld a, b
cp 5 ; reached the end of the pokemon's moves?
2014-05-22 22:13:20 +00:00
ret z ; if so, return
ld a, [wUsingPPUp]
2014-05-22 22:13:20 +00:00
dec a ; using a PP Up?
jr nz, .skipMenuItemIDCheck
2014-05-22 22:13:20 +00:00
; if using a PP Up, check if this is the move it's being used on
ld a, [wCurrentMenuItem]
2014-05-22 22:13:20 +00:00
inc a
cp b
jr nz, .nextMove
2014-05-22 22:13:20 +00:00
.skipMenuItemIDCheck
ld a, [hl]
and %11000000 ; have any PP Ups been used?
call nz, AddBonusPP ; if so, add bonus PP
2014-05-22 22:13:20 +00:00
.nextMove
inc hl
inc de
jr .loop
; adds bonus PP from PP Ups to current PP
; 1/5 of normal max PP (capped at 7) is added for each PP Up
; INPUT:
; [de] = normal max PP
; [hl] = move PP
2016-06-12 00:24:04 +00:00
AddBonusPP:
2014-05-22 22:13:20 +00:00
push bc
ld a, [de] ; normal max PP of move
ldh [hDividend + 3], a
2014-05-22 22:13:20 +00:00
xor a
ldh [hDividend], a
ldh [hDividend + 1], a
ldh [hDividend + 2], a
ld a, 5
ldh [hDivisor], a
ld b, 4
2014-05-22 22:13:20 +00:00
call Divide
ld a, [hl] ; move PP
ld b, a
2014-05-22 22:13:20 +00:00
swap a
and %00001111
2014-05-22 22:13:20 +00:00
srl a
srl a
ld c, a ; c = number of PP Ups used
2014-05-22 22:13:20 +00:00
.loop
ldh a, [hQuotient + 3]
cp 8 ; is the amount greater than or equal to 8?
jr c, .addAmount
ld a, 7 ; cap the amount at 7
2014-05-22 22:13:20 +00:00
.addAmount
add b
ld b, a
ld a, [wUsingPPUp]
2015-08-07 12:20:37 +00:00
dec a ; is the player using a PP Up right now?
jr z, .done ; if so, only add the bonus once
2014-05-22 22:13:20 +00:00
dec c
jr nz, .loop
2014-05-22 22:13:20 +00:00
.done
ld [hl], b
2014-05-22 22:13:20 +00:00
pop bc
ret
; gets max PP of a pokemon's move (including PP from PP Ups)
; INPUT:
; [wWhichPokemon] = index of pokemon within party/box
2015-07-16 03:04:58 +00:00
; [wMonDataLocation] = pokemon source
2014-05-22 22:13:20 +00:00
; 00: player's party
; 01: enemy's party
; 02: current box
; 03: daycare
; 04: player's in-battle pokemon
; [wCurrentMenuItem] = move index
; OUTPUT:
2015-08-07 12:20:37 +00:00
; [wMaxPP] = max PP
2016-06-12 00:24:04 +00:00
GetMaxPP:
ld a, [wMonDataLocation]
2014-05-22 22:13:20 +00:00
and a
ld hl, wPartyMon1Moves
ld bc, wPartyMon2 - wPartyMon1
jr z, .sourceWithMultipleMon
ld hl, wEnemyMon1Moves
2014-05-22 22:13:20 +00:00
dec a
jr z, .sourceWithMultipleMon
ld hl, wBoxMon1Moves
ld bc, wBoxMon2 - wBoxMon1
2014-05-22 22:13:20 +00:00
dec a
jr z, .sourceWithMultipleMon
ld hl, wDayCareMonMoves
2014-05-22 22:13:20 +00:00
dec a
jr z, .sourceWithOneMon
ld hl, wBattleMonMoves ; player's in-battle pokemon
2014-05-22 22:13:20 +00:00
.sourceWithOneMon
call GetSelectedMoveOffset2
jr .next
.sourceWithMultipleMon
call GetSelectedMoveOffset
.next
ld a, [hl]
2014-05-22 22:13:20 +00:00
dec a
push hl
ld hl, Moves
ld bc, MoveEnd - Moves
2014-05-22 22:13:20 +00:00
call AddNTimes
ld de, wcd6d
ld a, BANK(Moves)
2014-05-22 22:13:20 +00:00
call FarCopyData
ld de, wcd6d + 5 ; PP is byte 5 of move data
ld a, [de]
ld b, a ; b = normal max PP
2014-05-22 22:13:20 +00:00
pop hl
push bc
ld bc, wPartyMon1PP - wPartyMon1Moves ; PP offset if not player's in-battle pokemon data
ld a, [wMonDataLocation]
cp 4 ; player's in-battle pokemon?
jr nz, .addPPOffset
ld bc, wBattleMonPP - wBattleMonMoves ; PP offset if player's in-battle pokemon data
2014-05-22 22:13:20 +00:00
.addPPOffset
add hl, bc
ld a, [hl] ; a = current PP
and %11000000 ; get PP Up count
2014-05-22 22:13:20 +00:00
pop bc
or b ; place normal max PP in 6 lower bits of a
ld h, d
ld l, e
inc hl ; hl = wcd73
ld [hl], a
2015-08-07 12:20:37 +00:00
xor a ; add the bonus for the existing PP Up count
ld [wUsingPPUp], a
2014-05-22 22:13:20 +00:00
call AddBonusPP ; add bonus PP from PP Ups
ld a, [hl]
and %00111111 ; mask out the PP Up count
ld [wMaxPP], a ; store max PP
2014-05-22 22:13:20 +00:00
ret
2016-06-12 00:24:04 +00:00
GetSelectedMoveOffset:
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
call AddNTimes
2016-06-12 00:24:04 +00:00
GetSelectedMoveOffset2:
ld a, [wCurrentMenuItem]
ld c, a
ld b, 0
add hl, bc
2014-05-22 22:13:20 +00:00
ret
; confirms the item toss and then tosses the item
; INPUT:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [wcf91] = item ID
2014-05-22 22:13:20 +00:00
; [wWhichPokemon] = index of item within inventory
2015-07-13 06:00:48 +00:00
; [wItemQuantity] = quantity to toss
2014-05-22 22:13:20 +00:00
; OUTPUT:
; clears carry flag if the item is tossed, sets carry flag if not
TossItem_::
2014-05-22 22:13:20 +00:00
push hl
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
call IsItemHM
pop hl
jr c, .tooImportantToToss
2014-05-22 22:13:20 +00:00
push hl
call IsKeyItem_
ld a, [wIsKeyItem]
2014-05-22 22:13:20 +00:00
pop hl
and a
jr nz, .tooImportantToToss
2014-05-22 22:13:20 +00:00
push hl
ld a, [wcf91]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetItemName
call CopyStringToCF4B ; copy name to wcf4b
ld hl, IsItOKToTossItemText
2014-05-22 22:13:20 +00:00
call PrintText
2015-07-18 20:52:03 +00:00
coord hl, 14, 7
2015-08-05 21:20:29 +00:00
lb bc, 8, 15
ld a, TWO_OPTION_MENU
ld [wTextBoxID], a
2014-05-22 22:13:20 +00:00
call DisplayTextBoxID ; yes/no menu
ld a, [wMenuExitMethod]
cp CHOSE_SECOND_ITEM
2014-05-22 22:13:20 +00:00
pop hl
scf
2015-07-13 06:00:48 +00:00
ret z ; return if the player chose No
2014-05-22 22:13:20 +00:00
; if the player chose Yes
push hl
ld a, [wWhichPokemon]
2014-05-22 22:13:20 +00:00
call RemoveItemFromInventory
ld a, [wcf91]
ld [wd11e], a
2014-05-22 22:13:20 +00:00
call GetItemName
call CopyStringToCF4B ; copy name to wcf4b
ld hl, ThrewAwayItemText
2014-05-22 22:13:20 +00:00
call PrintText
pop hl
and a
ret
.tooImportantToToss
push hl
ld hl, TooImportantToTossText
2014-05-22 22:13:20 +00:00
call PrintText
pop hl
scf
ret
2016-06-12 00:24:04 +00:00
ThrewAwayItemText:
text_far _ThrewAwayItemText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
IsItOKToTossItemText:
text_far _IsItOKToTossItemText
text_end
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
TooImportantToTossText:
text_far _TooImportantToTossText
text_end
2014-05-22 22:13:20 +00:00
; checks if an item is a key item
; INPUT:
; [wcf91] = item ID
2014-05-22 22:13:20 +00:00
; OUTPUT:
2015-07-13 06:00:48 +00:00
; [wIsKeyItem] = result
2014-05-22 22:13:20 +00:00
; 00: item is not key item
; 01: item is key item
IsKeyItem_::
ld a, $01
ld [wIsKeyItem], a
ld a, [wcf91]
2020-07-06 02:52:27 +00:00
cp HM01 ; is the item an HM or TM?
jr nc, .checkIfItemIsHM
2014-05-22 22:13:20 +00:00
; if the item is not an HM or TM
push af
ld hl, KeyItemBitfield
ld de, wBuffer
ld bc, 15 ; only 11 bytes are actually used
2014-05-22 22:13:20 +00:00
call CopyData
pop af
dec a
ld c, a
ld hl, wBuffer
ld b, FLAG_TEST
2015-07-20 03:45:34 +00:00
predef FlagActionPredef
ld a, c
2014-05-22 22:13:20 +00:00
and a
ret nz
.checkIfItemIsHM
ld a, [wcf91]
2014-05-22 22:13:20 +00:00
call IsItemHM
ret c
xor a
ld [wIsKeyItem], a
2014-05-22 22:13:20 +00:00
ret
INCLUDE "data/items/key_items.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
SendNewMonToBox:
2015-08-31 02:38:41 +00:00
ld de, wNumInBox
2014-05-22 22:13:20 +00:00
ld a, [de]
inc a
ld [de], a
ld a, [wcf91]
ld [wd0b5], a
2014-05-22 22:13:20 +00:00
ld c, a
.asm_e7b1
inc de
ld a, [de]
ld b, a
ld a, c
ld c, b
ld [de], a
cp $ff
jr nz, .asm_e7b1
call GetMonHeader
ld hl, wBoxMonOT
ld bc, NAME_LENGTH
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
jr z, .asm_e7ee
dec a
call AddNTimes
push hl
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
add hl, bc
ld d, h
ld e, l
pop hl
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
ld b, a
.asm_e7db
push bc
push hl
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
pop hl
ld d, h
ld e, l
ld bc, -NAME_LENGTH
2014-05-22 22:13:20 +00:00
add hl, bc
pop bc
dec b
jr nz, .asm_e7db
.asm_e7ee
ld hl, wPlayerName
ld de, wBoxMonOT
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
jr z, .asm_e82a
ld hl, wBoxMonNicks
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
dec a
call AddNTimes
push hl
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
add hl, bc
ld d, h
ld e, l
pop hl
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
ld b, a
.asm_e817
push bc
push hl
ld bc, NAME_LENGTH
2014-05-22 22:13:20 +00:00
call CopyData
pop hl
ld d, h
ld e, l
ld bc, -NAME_LENGTH
2014-05-22 22:13:20 +00:00
add hl, bc
pop bc
dec b
jr nz, .asm_e817
.asm_e82a
ld hl, wBoxMonNicks
ld a, NAME_MON_SCREEN
ld [wNamingScreenType], a
predef AskName
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
jr z, .asm_e867
ld hl, wBoxMons
ld bc, wBoxMon2 - wBoxMon1
2014-05-22 22:13:20 +00:00
dec a
call AddNTimes
push hl
ld bc, wBoxMon2 - wBoxMon1
2014-05-22 22:13:20 +00:00
add hl, bc
ld d, h
ld e, l
pop hl
2015-08-31 02:38:41 +00:00
ld a, [wNumInBox]
2014-05-22 22:13:20 +00:00
dec a
ld b, a
.asm_e854
push bc
push hl
ld bc, wBoxMon2 - wBoxMon1
2014-05-22 22:13:20 +00:00
call CopyData
pop hl
ld d, h
ld e, l
ld bc, wBoxMon1 - wBoxMon2
2014-05-22 22:13:20 +00:00
add hl, bc
pop bc
dec b
jr nz, .asm_e854
.asm_e867
ld a, [wEnemyMonLevel]
ld [wEnemyMonBoxLevel], a
ld hl, wEnemyMon
ld de, wBoxMon1
ld bc, wEnemyMonDVs - wEnemyMon
2014-05-22 22:13:20 +00:00
call CopyData
ld hl, wPlayerID
2014-05-22 22:13:20 +00:00
ld a, [hli]
ld [de], a
inc de
ld a, [hl]
ld [de], a
inc de
push de
2015-08-31 02:38:41 +00:00
ld a, [wCurEnemyLVL]
2014-05-22 22:13:20 +00:00
ld d, a
callab CalcExperience
pop de
ldh a, [hExperience]
2014-05-22 22:13:20 +00:00
ld [de], a
inc de
ldh a, [hExperience + 1]
2014-05-22 22:13:20 +00:00
ld [de], a
inc de
ldh a, [hExperience + 2]
2014-05-22 22:13:20 +00:00
ld [de], a
inc de
xor a
ld b, NUM_STATS * 2
2014-05-22 22:13:20 +00:00
.asm_e89f
ld [de], a
inc de
dec b
jr nz, .asm_e89f
ld hl, wEnemyMonDVs
2014-05-22 22:13:20 +00:00
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
ld hl, wEnemyMonPP
ld b, NUM_MOVES
2014-05-22 22:13:20 +00:00
.asm_e8b1
ld a, [hli]
inc de
ld [de], a
dec b
jr nz, .asm_e8b1
ret
; checks if the tile in front of the player is a shore or water tile
; used for surfing and fishing
; unsets carry if it is, sets carry if not
2016-06-12 00:24:04 +00:00
IsNextTileShoreOrWater:
2015-08-31 02:38:41 +00:00
ld a, [wCurMapTileset]
2014-05-22 22:13:20 +00:00
ld hl, WaterTilesets
ld de, 1
2014-05-22 22:13:20 +00:00
call IsInArray
jr nc, .notShoreOrWater
2015-08-31 02:38:41 +00:00
ld a, [wCurMapTileset]
2014-05-22 22:13:20 +00:00
cp SHIP_PORT ; Vermilion Dock tileset
2014-09-13 07:50:56 +00:00
ld a, [wTileInFrontOfPlayer] ; tile in front of player
2014-05-22 22:13:20 +00:00
jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
cp $48 ; eastern shore tile in Safari Zone
jr z, .shoreOrWater
cp $32 ; usual eastern shore tile
jr z, .shoreOrWater
.skipShoreTiles
cp $14 ; water tile
jr z, .shoreOrWater
.notShoreOrWater
scf
ret
.shoreOrWater
and a
ret
INCLUDE "data/tilesets/water_tilesets.asm"
2014-05-22 22:13:20 +00:00
2016-06-12 00:24:04 +00:00
ReadSuperRodData:
2014-05-22 22:13:20 +00:00
; return e = 2 if no fish on this map
; return e = 1 if a bite, bc = level,species
; return e = 0 if no bite
2015-08-31 02:38:41 +00:00
ld a, [wCurMap]
2014-05-22 22:13:20 +00:00
ld de, 3 ; each fishing group is three bytes wide
ld hl, SuperRodData
call IsInArray
jr c, .ReadFishingGroup
ld e, $2 ; $2 if no fishing groups found
ret
.ReadFishingGroup
2014-05-22 22:13:20 +00:00
; hl points to the fishing group entry in the index
inc hl ; skip map id
; read fishing group address
ld a, [hli]
ld h, [hl]
ld l, a
ld b, [hl] ; how many mons in group
inc hl ; point to data
ld e, $0 ; no bite yet
.RandomLoop
call Random
2014-05-22 22:13:20 +00:00
srl a
ret c ; 50% chance of no battle
and %11 ; 2-bit random number
cp b
jr nc, .RandomLoop ; if a is greater than the number of mons, regenerate
; get the mon
add a
ld c, a
ld b, $0
add hl, bc
ld b, [hl] ; level
inc hl
ld c, [hl] ; species
ld e, $1 ; $1 if there's a bite
ret
INCLUDE "data/wild/super_rod.asm"
2014-05-22 22:13:20 +00:00
; reloads map view and processes sprite data
; for items that cause the overworld to be displayed
2016-06-12 00:24:04 +00:00
ItemUseReloadOverworldData:
2014-05-22 22:13:20 +00:00
call LoadCurrentMapView
jp UpdateSprites
2015-02-08 06:18:42 +00:00
; creates a list at wBuffer of maps where the mon in [wd11e] can be found.
; this is used by the pokedex to display locations the mon can be found on the map.
2016-06-12 00:24:04 +00:00
FindWildLocationsOfMon:
2015-02-08 06:18:42 +00:00
ld hl, WildDataPointers
ld de, wBuffer
2014-05-22 22:13:20 +00:00
ld c, $0
2015-02-08 06:18:42 +00:00
.loop
2014-05-22 22:13:20 +00:00
inc hl
ld a, [hld]
inc a
2015-02-08 06:18:42 +00:00
jr z, .done
2014-05-22 22:13:20 +00:00
push hl
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [hli]
and a
2015-02-08 06:18:42 +00:00
call nz, CheckMapForMon ; land
2014-05-22 22:13:20 +00:00
ld a, [hli]
and a
2015-02-08 06:18:42 +00:00
call nz, CheckMapForMon ; water
2014-05-22 22:13:20 +00:00
pop hl
inc hl
inc hl
inc c
2015-02-08 06:18:42 +00:00
jr .loop
.done
ld a, $ff ; list terminator
2014-05-22 22:13:20 +00:00
ld [de], a
ret
2016-06-12 00:24:04 +00:00
CheckMapForMon:
2014-05-22 22:13:20 +00:00
inc hl
ld b, $a
2015-02-08 06:18:42 +00:00
.loop
ld a, [wd11e]
2014-05-22 22:13:20 +00:00
cp [hl]
2015-02-08 06:18:42 +00:00
jr nz, .nextEntry
2014-05-22 22:13:20 +00:00
ld a, c
ld [de], a
inc de
2015-02-08 06:18:42 +00:00
.nextEntry
2014-05-22 22:13:20 +00:00
inc hl
inc hl
dec b
2015-02-08 06:18:42 +00:00
jr nz, .loop
2014-05-22 22:13:20 +00:00
dec hl
ret