summaryrefslogtreecommitdiff
path: root/engine/items/item_effects.asm
diff options
context:
space:
mode:
Diffstat (limited to 'engine/items/item_effects.asm')
-rw-r--r--engine/items/item_effects.asm2958
1 files changed, 2958 insertions, 0 deletions
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
new file mode 100644
index 000000000..1439b2c6d
--- /dev/null
+++ b/engine/items/item_effects.asm
@@ -0,0 +1,2958 @@
+_DoItemEffect::
+ ld a, [wCurItem]
+ ld [wd265], a
+ call GetItemName
+ call CopyName1
+ ld a, 1
+ ld [wItemEffectSucceeded], a
+ ld a, [wCurItem]
+ dec a
+ ld hl, ItemEffects
+ rst JumpTable
+ ret
+
+ItemEffects:
+; entries correspond to item ids
+ dw PokeBallEffect ; MASTER_BALL
+ dw PokeBallEffect ; ULTRA_BALL
+ dw NoEffect ; BRIGHTPOWDER
+ dw PokeBallEffect ; GREAT_BALL
+ dw PokeBallEffect ; POKE_BALL
+ dw TownMapEffect ; TOWN_MAP
+ dw BicycleEffect ; BICYCLE
+ dw EvoStoneEffect ; MOON_STONE
+ dw StatusHealingEffect ; ANTIDOTE
+ dw StatusHealingEffect ; BURN_HEAL
+ dw StatusHealingEffect ; ICE_HEAL
+ dw StatusHealingEffect ; AWAKENING
+ dw StatusHealingEffect ; PARLYZ_HEAL
+ dw FullRestoreEffect ; FULL_RESTORE
+ dw RestoreHPEffect ; MAX_POTION
+ dw RestoreHPEffect ; HYPER_POTION
+ dw RestoreHPEffect ; SUPER_POTION
+ dw RestoreHPEffect ; POTION
+ dw EscapeRopeEffect ; ESCAPE_ROPE
+ dw RepelEffect ; REPEL
+ dw RestorePPEffect ; MAX_ELIXER
+ dw EvoStoneEffect ; FIRE_STONE
+ dw EvoStoneEffect ; THUNDERSTONE
+ dw EvoStoneEffect ; WATER_STONE
+ dw NoEffect ; ITEM_19
+ dw VitaminEffect ; HP_UP
+ dw VitaminEffect ; PROTEIN
+ dw VitaminEffect ; IRON
+ dw VitaminEffect ; CARBOS
+ dw NoEffect ; LUCKY_PUNCH
+ dw VitaminEffect ; CALCIUM
+ dw RareCandyEffect ; RARE_CANDY
+ dw XAccuracyEffect ; X_ACCURACY
+ dw EvoStoneEffect ; LEAF_STONE
+ dw NoEffect ; METAL_POWDER
+ dw NoEffect ; NUGGET
+ dw PokeDollEffect ; POKE_DOLL
+ dw StatusHealingEffect ; FULL_HEAL
+ dw ReviveEffect ; REVIVE
+ dw ReviveEffect ; MAX_REVIVE
+ dw GuardSpecEffect ; GUARD_SPEC
+ dw SuperRepelEffect ; SUPER_REPEL
+ dw MaxRepelEffect ; MAX_REPEL
+ dw DireHitEffect ; DIRE_HIT
+ dw NoEffect ; ITEM_2D
+ dw RestoreHPEffect ; FRESH_WATER
+ dw RestoreHPEffect ; SODA_POP
+ dw RestoreHPEffect ; LEMONADE
+ dw XItemEffect ; X_ATTACK
+ dw NoEffect ; ITEM_32
+ dw XItemEffect ; X_DEFEND
+ dw XItemEffect ; X_SPEED
+ dw XItemEffect ; X_SPECIAL
+ dw CoinCaseEffect ; COIN_CASE
+ dw ItemfinderEffect ; ITEMFINDER
+ dw PokeFluteEffect ; POKE_FLUTE
+ dw NoEffect ; EXP_SHARE
+ dw OldRodEffect ; OLD_ROD
+ dw GoodRodEffect ; GOOD_ROD
+ dw NoEffect ; SILVER_LEAF
+ dw SuperRodEffect ; SUPER_ROD
+ dw RestorePPEffect ; PP_UP
+ dw RestorePPEffect ; ETHER
+ dw RestorePPEffect ; MAX_ETHER
+ dw RestorePPEffect ; ELIXER
+ dw NoEffect ; RED_SCALE
+ dw NoEffect ; SECRETPOTION
+ dw NoEffect ; S_S_TICKET
+ dw NoEffect ; MYSTERY_EGG
+ dw NoEffect ; CLEAR_BELL
+ dw NoEffect ; SILVER_WING
+ dw RestoreHPEffect ; MOOMOO_MILK
+ dw NoEffect ; QUICK_CLAW
+ dw StatusHealingEffect ; PSNCUREBERRY
+ dw NoEffect ; GOLD_LEAF
+ dw NoEffect ; SOFT_SAND
+ dw NoEffect ; SHARP_BEAK
+ dw StatusHealingEffect ; PRZCUREBERRY
+ dw StatusHealingEffect ; BURNT_BERRY
+ dw StatusHealingEffect ; ICE_BERRY
+ dw NoEffect ; POISON_BARB
+ dw NoEffect ; KINGS_ROCK
+ dw BitterBerryEffect ; BITTER_BERRY
+ dw StatusHealingEffect ; MINT_BERRY
+ dw NoEffect ; RED_APRICORN
+ dw NoEffect ; TINYMUSHROOM
+ dw NoEffect ; BIG_MUSHROOM
+ dw NoEffect ; SILVERPOWDER
+ dw NoEffect ; BLU_APRICORN
+ dw NoEffect ; ITEM_5A
+ dw NoEffect ; AMULET_COIN
+ dw NoEffect ; YLW_APRICORN
+ dw NoEffect ; GRN_APRICORN
+ dw NoEffect ; CLEANSE_TAG
+ dw NoEffect ; MYSTIC_WATER
+ dw NoEffect ; TWISTEDSPOON
+ dw NoEffect ; WHT_APRICORN
+ dw NoEffect ; BLACKBELT
+ dw NoEffect ; BLK_APRICORN
+ dw NoEffect ; ITEM_64
+ dw NoEffect ; PNK_APRICORN
+ dw NoEffect ; BLACKGLASSES
+ dw NoEffect ; SLOWPOKETAIL
+ dw NoEffect ; PINK_BOW
+ dw NoEffect ; STICK
+ dw NoEffect ; SMOKE_BALL
+ dw NoEffect ; NEVERMELTICE
+ dw NoEffect ; MAGNET
+ dw StatusHealingEffect ; MIRACLEBERRY
+ dw NoEffect ; PEARL
+ dw NoEffect ; BIG_PEARL
+ dw NoEffect ; EVERSTONE
+ dw NoEffect ; SPELL_TAG
+ dw RestoreHPEffect ; RAGECANDYBAR
+ dw NoEffect ; GS_BALL
+ dw BlueCardEffect ; BLUE_CARD
+ dw NoEffect ; MIRACLE_SEED
+ dw NoEffect ; THICK_CLUB
+ dw NoEffect ; FOCUS_BAND
+ dw NoEffect ; ITEM_78
+ dw EnergypowderEffect ; ENERGYPOWDER
+ dw EnergyRootEffect ; ENERGY_ROOT
+ dw HealPowderEffect ; HEAL_POWDER
+ dw RevivalHerbEffect ; REVIVAL_HERB
+ dw NoEffect ; HARD_STONE
+ dw NoEffect ; LUCKY_EGG
+ dw CardKeyEffect ; CARD_KEY
+ dw NoEffect ; MACHINE_PART
+ dw NoEffect ; EGG_TICKET
+ dw NoEffect ; LOST_ITEM
+ dw NoEffect ; STARDUST
+ dw NoEffect ; STAR_PIECE
+ dw BasementKeyEffect ; BASEMENT_KEY
+ dw NoEffect ; PASS
+ dw NoEffect ; ITEM_87
+ dw NoEffect ; ITEM_88
+ dw NoEffect ; ITEM_89
+ dw NoEffect ; CHARCOAL
+ dw RestoreHPEffect ; BERRY_JUICE
+ dw NoEffect ; SCOPE_LENS
+ dw NoEffect ; ITEM_8D
+ dw NoEffect ; ITEM_8E
+ dw NoEffect ; METAL_COAT
+ dw NoEffect ; DRAGON_FANG
+ dw NoEffect ; ITEM_91
+ dw NoEffect ; LEFTOVERS
+ dw NoEffect ; ITEM_93
+ dw NoEffect ; ITEM_94
+ dw NoEffect ; ITEM_95
+ dw RestorePPEffect ; MYSTERYBERRY
+ dw NoEffect ; DRAGON_SCALE
+ dw NoEffect ; BERSERK_GENE
+ dw NoEffect ; ITEM_99
+ dw NoEffect ; ITEM_9A
+ dw NoEffect ; ITEM_9B
+ dw SacredAshEffect ; SACRED_ASH
+ dw PokeBallEffect ; HEAVY_BALL
+ dw NoEffect ; FLOWER_MAIL
+ dw PokeBallEffect ; LEVEL_BALL
+ dw PokeBallEffect ; LURE_BALL
+ dw PokeBallEffect ; FAST_BALL
+ dw NoEffect ; ITEM_A2
+ dw NoEffect ; LIGHT_BALL
+ dw PokeBallEffect ; FRIEND_BALL
+ dw PokeBallEffect ; MOON_BALL
+ dw PokeBallEffect ; LOVE_BALL
+ dw NormalBoxEffect ; NORMAL_BOX
+ dw GorgeousBoxEffect ; GORGEOUS_BOX
+ dw EvoStoneEffect ; SUN_STONE
+ dw NoEffect ; POLKADOT_BOW
+ dw NoEffect ; ITEM_AB
+ dw NoEffect ; UP_GRADE
+ dw RestoreHPEffect ; BERRY
+ dw RestoreHPEffect ; GOLD_BERRY
+ dw SquirtbottleEffect ; SQUIRTBOTTLE
+ dw NoEffect ; ITEM_B0
+ dw PokeBallEffect ; PARK_BALL
+ dw NoEffect ; RAINBOW_WING
+ dw NoEffect ; ITEM_B3
+
+PokeBallEffect:
+ ld a, [wBattleMode]
+ dec a
+ jp nz, UseBallInTrainerBattle
+
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH
+ jr nz, .room_in_party
+
+ ld a, BANK(sBoxCount)
+ call GetSRAMBank
+ ld a, [sBoxCount]
+ cp MONS_PER_BOX
+ call CloseSRAM
+ jp z, Ball_BoxIsFullMessage
+
+.room_in_party
+ xor a
+ ld [wWildMon], a
+ ld a, [wCurItem]
+ cp PARK_BALL
+ call nz, ReturnToBattle_UseBall
+
+ ld hl, wOptions
+ res NO_TEXT_SCROLL, [hl]
+ ld hl, UsedItemText
+ call PrintText
+
+ ld a, [wEnemyMonCatchRate]
+ ld b, a
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jp z, .catch_without_fail
+ ld a, [wCurItem]
+ cp MASTER_BALL
+ jp z, .catch_without_fail
+ ld a, [wCurItem]
+ ld c, a
+ ld hl, BallMultiplierFunctionTable
+
+.get_multiplier_loop
+ ld a, [hli]
+ cp $ff
+ jr z, .skip_or_return_from_ball_fn
+ cp c
+ jr z, .call_ball_function
+ inc hl
+ inc hl
+ jr .get_multiplier_loop
+
+.call_ball_function
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .skip_or_return_from_ball_fn
+ push de
+ jp hl
+
+.skip_or_return_from_ball_fn
+ ld a, [wCurItem]
+ cp LEVEL_BALL
+ ld a, b
+ jp z, .skip_hp_calc
+
+ ld a, b
+ ld [hMultiplicand + 2], a
+
+ ld hl, wEnemyMonHP
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ sla c
+ rl b
+
+ ld h, d
+ ld l, e
+ add hl, de
+ add hl, de
+ ld d, h
+ ld e, l
+ ld a, d
+ and a
+ jr z, .okay_1
+
+ srl d
+ rr e
+ srl d
+ rr e
+ srl b
+ rr c
+ srl b
+ rr c
+
+ ld a, c
+ and a
+ jr nz, .okay_1
+ ld c, $1
+.okay_1
+ ld b, e
+
+ push bc
+ ld a, b
+ sub c
+ ld [hMultiplier], a
+ xor a
+ ld [hDividend + 0], a
+ ld [hMultiplicand + 0], a
+ ld [hMultiplicand + 1], a
+ call Multiply
+ pop bc
+
+ ld a, b
+ ld [hDivisor], a
+ ld b, $4
+ call Divide
+
+ ld a, [hQuotient + 2]
+ and a
+ jr nz, .statuscheck
+ ld a, 1
+.statuscheck
+; This routine is buggy. It was intended that SLP and FRZ provide a higher
+; catch rate than BRN/PSN/PAR, which in turn provide a higher catch rate than
+; no status effect at all. But instead, it makes BRN/PSN/PAR provide no
+; benefit.
+; Uncomment the line below to fix this.
+ ld b, a
+ ld a, [wEnemyMonStatus]
+ and 1 << FRZ | SLP
+ ld c, 10
+ jr nz, .addstatus
+ ; ld a, [wEnemyMonStatus]
+ and a
+ ld c, 5
+ jr nz, .addstatus
+ ld c, 0
+.addstatus
+ ld a, b
+ add c
+ jr nc, .max_1
+ ld a, $ff
+.max_1
+
+ ; BUG: farcall overwrites a, and GetItemHeldEffect takes b anyway.
+ ; This is probably the reason the HELD_CATCH_CHANCE effect is never used.
+ ; Uncomment the line below to fix.
+ ld d, a
+ push de
+ ld a, [wBattleMonItem]
+ ; ld b, a
+ farcall GetItemHeldEffect
+ ld a, b
+ cp HELD_CATCH_CHANCE
+ pop de
+ ld a, d
+ jr nz, .max_2
+ add c
+ jr nc, .max_2
+ ld a, $ff
+.max_2
+
+.skip_hp_calc
+ ld b, a
+ ld [wBuffer1], a
+ call Random
+
+ cp b
+ ld a, 0
+ jr z, .catch_without_fail
+ jr nc, .fail_to_catch
+
+.catch_without_fail
+ ld a, [wEnemyMonSpecies]
+
+.fail_to_catch
+ ld [wWildMon], a
+ ld c, 20
+ call DelayFrames
+
+ ld a, [wCurItem]
+ cp POKE_BALL + 1 ; Assumes Master/Ultra/Great come before
+ jr c, .not_kurt_ball
+ ld a, POKE_BALL
+.not_kurt_ball
+ ld [wBattleAnimParam], a
+
+ ld de, ANIM_THROW_POKE_BALL
+ ld a, e
+ ld [wFXAnimID], a
+ ld a, d
+ ld [wFXAnimID + 1], a
+ xor a
+ ld [hBattleTurn], a
+ ld [wBuffer2], a
+ ld [wNumHits], a
+ predef PlayBattleAnim
+
+ ld a, [wWildMon]
+ and a
+ jr nz, .caught
+ ld a, [wBuffer2]
+ cp $1
+ ld hl, Text_NoShake
+ jp z, .shake_and_break_free
+ cp $2
+ ld hl, Text_OneShake
+ jp z, .shake_and_break_free
+ cp $3
+ ld hl, Text_TwoShakes
+ jp z, .shake_and_break_free
+ cp $4
+ ld hl, Text_ThreeShakes
+ jp z, .shake_and_break_free
+.caught
+
+ ld hl, wEnemyMonStatus
+ ld a, [hli]
+ push af
+ inc hl
+ ld a, [hli]
+ push af
+ ld a, [hl]
+ push af
+ push hl
+ ld hl, wEnemyMonItem
+ ld a, [hl]
+ push af
+ push hl
+ ld hl, wEnemySubStatus5
+ ld a, [hl]
+ push af
+ set SUBSTATUS_TRANSFORMED, [hl]
+
+; This code is buggy. Any wild Pokémon that has Transformed will be
+; caught as a Ditto, even if it was something else like Mew.
+; To fix, do not set [wTempEnemyMonSpecies] to DITTO.
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .ditto
+ jr .not_ditto
+
+.ditto
+ ld a, DITTO
+ ld [wTempEnemyMonSpecies], a
+ jr .load_data
+
+.not_ditto
+ set SUBSTATUS_TRANSFORMED, [hl]
+ ld hl, wEnemyBackupDVs
+ ld a, [wEnemyMonDVs]
+ ld [hli], a
+ ld a, [wEnemyMonDVs + 1]
+ ld [hl], a
+
+.load_data
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurPartySpecies], a
+ ld a, [wEnemyMonLevel]
+ ld [wCurPartyLevel], a
+ farcall LoadEnemyMon
+
+ pop af
+ ld [wEnemySubStatus5], a
+
+ pop hl
+ pop af
+ ld [hl], a
+ pop hl
+ pop af
+ ld [hld], a
+ pop af
+ ld [hld], a
+ dec hl
+ pop af
+ ld [hl], a
+
+ ld hl, wEnemySubStatus5
+ bit SUBSTATUS_TRANSFORMED, [hl]
+ jr nz, .Transformed
+ ld hl, wWildMonMoves
+ ld de, wEnemyMonMoves
+ ld bc, NUM_MOVES
+ call CopyBytes
+
+ ld hl, wWildMonPP
+ ld de, wEnemyMonPP
+ ld bc, NUM_MOVES
+ call CopyBytes
+
+.Transformed:
+ ld a, [wEnemyMonSpecies]
+ ld [wWildMon], a
+ ld [wCurPartySpecies], a
+ ld [wd265], a
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jp z, .FinishTutorial
+
+ farcall StubbedTrainerRankings_WildMonsCaught
+
+ ld hl, Text_GotchaMonWasCaught
+ call PrintText
+
+ call ClearSprites
+
+ ld a, [wd265]
+ dec a
+ call CheckCaughtMon
+
+ ld a, c
+ push af
+ ld a, [wd265]
+ dec a
+ call SetSeenAndCaughtMon
+ pop af
+ and a
+ jr nz, .skip_pokedex
+
+ call CheckReceivedDex
+ jr z, .skip_pokedex
+
+ ld hl, Text_AddedToPokedex
+ call PrintText
+
+ call ClearSprites
+
+ ld a, [wEnemyMonSpecies]
+ ld [wd265], a
+ predef NewPokedexEntry
+
+.skip_pokedex
+ ld a, [wBattleType]
+ cp BATTLETYPE_CONTEST
+ jp z, .catch_bug_contest_mon
+ cp BATTLETYPE_CELEBI
+ jr nz, .not_celebi
+ ld hl, wBattleResult
+ set BATTLERESULT_CAUGHT_CELEBI, [hl]
+.not_celebi
+
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH
+ jr z, .SendToPC
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ call ClearSprites
+
+ predef TryAddMonToParty
+
+ farcall SetCaughtData
+
+ ld a, [wCurItem]
+ cp FRIEND_BALL
+ jr nz, .SkipPartyMonFriendBall
+
+ ld a, [wPartyCount]
+ dec a
+ ld hl, wPartyMon1Happiness
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+
+ ld a, FRIEND_BALL_HAPPINESS
+ ld [hl], a
+
+.SkipPartyMonFriendBall:
+ ld hl, Text_AskNicknameNewlyCaughtMon
+ call PrintText
+
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+
+ call YesNoBox
+ jp c, .return_from_capture
+
+ ld a, [wPartyCount]
+ dec a
+ ld [wCurPartyMon], a
+ ld hl, wPartyMonNicknames
+ ld bc, MON_NAME_LENGTH
+ call AddNTimes
+
+ ld d, h
+ ld e, l
+ push de
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld b, 0
+ farcall NamingScreen
+
+ call RotateThreePalettesRight
+
+ call LoadStandardFont
+
+ pop hl
+ ld de, wStringBuffer1
+ call InitName
+
+ jp .return_from_capture
+
+.SendToPC:
+ call ClearSprites
+
+ predef SendMonIntoBox
+
+ farcall SetBoxMonCaughtData
+
+ ld a, BANK(sBoxCount)
+ call GetSRAMBank
+
+ ld a, [sBoxCount]
+ cp MONS_PER_BOX
+ jr nz, .BoxNotFullYet
+ ld hl, wBattleResult
+ set BATTLERESULT_BOX_FULL, [hl]
+.BoxNotFullYet:
+ ld a, [wCurItem]
+ cp FRIEND_BALL
+ jr nz, .SkipBoxMonFriendBall
+ ; The captured mon is now first in the box
+ ld a, FRIEND_BALL_HAPPINESS
+ ld [sBoxMon1Happiness], a
+.SkipBoxMonFriendBall:
+ call CloseSRAM
+
+ ld hl, Text_AskNicknameNewlyCaughtMon
+ call PrintText
+
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+
+ call YesNoBox
+ jr c, .SkipBoxMonNickname
+
+ xor a
+ ld [wCurPartyMon], a
+ ld a, BOXMON
+ ld [wMonType], a
+ ld de, wMonOrItemNameBuffer
+ ld b, $0
+ farcall NamingScreen
+
+ ld a, BANK(sBoxMonNicknames)
+ call GetSRAMBank
+
+ ld hl, wMonOrItemNameBuffer
+ ld de, sBoxMonNicknames
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+ ld hl, sBoxMonNicknames
+ ld de, wStringBuffer1
+ call InitName
+
+ call CloseSRAM
+
+.SkipBoxMonNickname:
+ ld a, BANK(sBoxMonNicknames)
+ call GetSRAMBank
+
+ ld hl, sBoxMonNicknames
+ ld de, wMonOrItemNameBuffer
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+ call CloseSRAM
+
+ ld hl, Text_SentToBillsPC
+ call PrintText
+
+ call RotateThreePalettesRight
+ call LoadStandardFont
+ jr .return_from_capture
+
+.catch_bug_contest_mon
+ farcall BugContest_SetCaughtContestMon
+ jr .return_from_capture
+
+.FinishTutorial:
+ ld hl, Text_GotchaMonWasCaught
+
+.shake_and_break_free
+ call PrintText
+ call ClearSprites
+
+.return_from_capture
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ ret z
+ cp BATTLETYPE_DEBUG
+ ret z
+ cp BATTLETYPE_CONTEST
+ jr z, .used_park_ball
+
+ ld a, [wWildMon]
+ and a
+ jr z, .toss
+
+ call ClearBGPalettes
+ call ClearTileMap
+
+.toss
+ ld hl, wNumItems
+ inc a
+ ld [wItemQuantityChangeBuffer], a
+ jp TossItem
+
+.used_park_ball
+ ld hl, wParkBallsRemaining
+ dec [hl]
+ ret
+
+BallMultiplierFunctionTable:
+; table of routines that increase or decrease the catch rate based on
+; which ball is used in a certain situation.
+ dbw ULTRA_BALL, UltraBallMultiplier
+ dbw GREAT_BALL, GreatBallMultiplier
+ dbw SAFARI_BALL, SafariBallMultiplier ; Safari Ball, leftover from RBY
+ dbw HEAVY_BALL, HeavyBallMultiplier
+ dbw LEVEL_BALL, LevelBallMultiplier
+ dbw LURE_BALL, LureBallMultiplier
+ dbw FAST_BALL, FastBallMultiplier
+ dbw MOON_BALL, MoonBallMultiplier
+ dbw LOVE_BALL, LoveBallMultiplier
+ dbw PARK_BALL, ParkBallMultiplier
+ db -1 ; end
+
+UltraBallMultiplier:
+; multiply catch rate by 2
+ sla b
+ ret nc
+ ld b, $ff
+ ret
+
+SafariBallMultiplier:
+GreatBallMultiplier:
+ParkBallMultiplier:
+; multiply catch rate by 1.5
+ ld a, b
+ srl a
+ add b
+ ld b, a
+ ret nc
+ ld b, $ff
+ ret
+
+GetPokedexEntryBank:
+ push hl
+ push de
+ ld a, [wEnemyMonSpecies]
+ rlca
+ rlca
+ maskbits NUM_DEX_ENTRY_BANKS
+ ld hl, .PokedexEntryBanks
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hl]
+ pop de
+ pop hl
+ ret
+
+.PokedexEntryBanks:
+ db BANK("Pokedex Entries 001-064")
+ db BANK("Pokedex Entries 065-128")
+ db BANK("Pokedex Entries 129-192")
+ db BANK("Pokedex Entries 193-251")
+
+HeavyBallMultiplier:
+; subtract 20 from catch rate if weight < 102.4 kg
+; else add 0 to catch rate if weight < 204.8 kg
+; else add 20 to catch rate if weight < 307.2 kg
+; else add 30 to catch rate if weight < 409.6 kg
+; else add 40 to catch rate (never happens)
+ ld a, [wEnemyMonSpecies]
+ ld hl, PokedexDataPointerTable
+ dec a
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, BANK(PokedexDataPointerTable)
+ call GetFarHalfword
+
+.SkipText:
+ call GetPokedexEntryBank
+ call GetFarByte
+ inc hl
+ cp "@"
+ jr nz, .SkipText
+
+ call GetPokedexEntryBank
+ push bc
+ inc hl
+ inc hl
+ call GetFarHalfword
+
+ srl h
+ rr l
+ ld b, h
+ ld c, l
+
+rept 4
+ srl b
+ rr c
+endr
+ call .subbc
+
+ srl b
+ rr c
+ call .subbc
+
+ ld a, h
+ pop bc
+ jr .compare
+
+.subbc
+ ; subtract bc from hl
+ push bc
+ ld a, b
+ cpl
+ ld b, a
+ ld a, c
+ cpl
+ ld c, a
+ inc bc
+ add hl, bc
+ pop bc
+ ret
+
+.compare
+ ld c, a
+ cp HIGH(1024) ; 102.4 kg
+ jr c, .lightmon
+
+ ld hl, .WeightsTable
+.lookup
+ ld a, c
+ cp [hl]
+ jr c, .heavymon
+ inc hl
+ inc hl
+ jr .lookup
+
+.heavymon
+ inc hl
+ ld a, b
+ add [hl]
+ ld b, a
+ ret nc
+ ld b, $ff
+ ret
+
+.lightmon
+ ld a, b
+ sub 20
+ ld b, a
+ ret nc
+ ld b, $1
+ ret
+
+.WeightsTable:
+; weight factor, boost
+ db HIGH(2048), 0
+ db HIGH(3072), 20
+ db HIGH(4096), 30
+ db HIGH(65280), 40
+
+LureBallMultiplier:
+; multiply catch rate by 3 if this is a fishing rod battle
+ ld a, [wBattleType]
+ cp BATTLETYPE_FISH
+ ret nz
+
+ ld a, b
+ add a
+ jr c, .max
+
+ add b
+ jr nc, .done
+.max
+ ld a, $ff
+.done
+ ld b, a
+ ret
+
+MoonBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 4 if mon evolves with moon stone
+; Reality: no boost
+ push bc
+ ld a, [wTempEnemyMonSpecies]
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, EvosAttacksPointers
+ add hl, bc
+ add hl, bc
+ ld a, BANK(EvosAttacksPointers)
+ call GetFarHalfword
+ pop bc
+
+ push bc
+ ld a, BANK("Evolutions and Attacks")
+ call GetFarByte
+ cp EVOLVE_ITEM
+ pop bc
+ ret nz
+
+ inc hl
+ inc hl
+ inc hl
+
+; Moon Stone's constant from Pokémon Red is used.
+; No Pokémon evolve with Burn Heal,
+; so Moon Balls always have a catch rate of 1×.
+ push bc
+ ld a, BANK("Evolutions and Attacks")
+ call GetFarByte
+ cp MOON_STONE_RED ; BURN_HEAL
+ pop bc
+ ret nz
+
+ sla b
+ jr c, .max
+ sla b
+ jr nc, .done
+.max
+ ld b, $ff
+.done
+ ret
+
+LoveBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 8 if mons are of same species, different sex
+; Reality: multiply catch rate by 8 if mons are of same species, same sex
+
+ ; does species match?
+ ld a, [wTempEnemyMonSpecies]
+ ld c, a
+ ld a, [wTempBattleMonSpecies]
+ cp c
+ ret nz
+
+ ; check player mon species
+ push bc
+ ld a, [wTempBattleMonSpecies]
+ ld [wCurPartySpecies], a
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ farcall GetGender
+ jr c, .done1 ; no effect on genderless
+
+ ld d, 0 ; male
+ jr nz, .playermale
+ inc d ; female
+.playermale
+
+ ; check wild mon species
+ push de
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurPartySpecies], a
+ ld a, WILDMON
+ ld [wMonType], a
+ farcall GetGender
+ jr c, .done2 ; no effect on genderless
+
+ ld d, 0 ; male
+ jr nz, .wildmale
+ inc d ; female
+.wildmale
+
+ ld a, d
+ pop de
+ cp d
+ pop bc
+ ret nz ; for the intended effect, this should be "ret z"
+
+ sla b
+ jr c, .max
+ sla b
+ jr c, .max
+ sla b
+ ret nc
+.max
+ ld b, $ff
+ ret
+
+.done2
+ pop de
+
+.done1
+ pop bc
+ ret
+
+FastBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 4 if enemy mon is in one of the three
+; FleeMons tables.
+; Reality: multiply catch rate by 4 if enemy mon is one of the first three in
+; the first FleeMons table.
+ ld a, [wTempEnemyMonSpecies]
+ ld c, a
+ ld hl, FleeMons
+ ld d, 3
+
+.loop
+ ld a, BANK(FleeMons)
+ call GetFarByte
+
+ inc hl
+ cp -1
+ jr z, .next
+ cp c
+ jr nz, .next ; for the intended effect, this should be "jr nz, .loop"
+ sla b
+ jr c, .max
+
+ sla b
+ ret nc
+
+.max
+ ld b, $ff
+ ret
+
+.next
+ dec d
+ jr nz, .loop
+ ret
+
+LevelBallMultiplier:
+; multiply catch rate by 8 if player mon level / 4 > enemy mon level
+; multiply catch rate by 4 if player mon level / 2 > enemy mon level
+; multiply catch rate by 2 if player mon level > enemy mon level
+ ld a, [wBattleMonLevel]
+ ld c, a
+ ld a, [wEnemyMonLevel]
+ cp c
+ ret nc ; if player is lower level, we're done here
+ sla b
+ jr c, .max
+
+ srl c
+ cp c
+ ret nc ; if player/2 is lower level, we're done here
+ sla b
+ jr c, .max
+
+ srl c
+ cp c
+ ret nc ; if player/4 is lower level, we're done here
+ sla b
+ ret nc
+
+.max
+ ld b, $ff
+ ret
+
+; These two texts were carried over from gen 1.
+; They are not used in gen 2, and are dummied out.
+
+Text_RBY_CatchMarowak:
+ ; It dodged the thrown BALL! This #MON can't be caught!
+ text_jump UnknownText_0x1c5a5a
+ db "@"
+
+Text_RBY_NoShake:
+ ; You missed the #MON!
+ text_jump UnknownText_0x1c5a90
+ db "@"
+
+Text_NoShake:
+ ; Oh no! The #MON broke free!
+ text_jump UnknownText_0x1c5aa6
+ db "@"
+
+Text_OneShake:
+ ; Aww! It appeared to be caught!
+ text_jump UnknownText_0x1c5ac3
+ db "@"
+
+Text_TwoShakes:
+ ; Aargh! Almost had it!
+ text_jump UnknownText_0x1c5ae3
+ db "@"
+
+Text_ThreeShakes:
+ ; Shoot! It was so close too!
+ text_jump UnknownText_0x1c5afa
+ db "@"
+
+Text_GotchaMonWasCaught:
+ ; Gotcha! @ was caught!@ @
+ text_jump UnknownText_0x1c5b17
+ start_asm
+ call WaitSFX
+ push bc
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ld de, MUSIC_CAPTURE
+ call PlayMusic
+ pop bc
+ ld hl, TextJump_Waitbutton
+ ret
+
+TextJump_Waitbutton:
+ ; @
+ text_jump Text_Waitbutton_2
+ db "@"
+
+Text_SentToBillsPC:
+ ; was sent to BILL's PC.
+ text_jump UnknownText_0x1c5b38
+ db "@"
+
+Text_AddedToPokedex:
+ ; 's data was newly added to the #DEX.@ @
+ text_jump UnknownText_0x1c5b53
+ db "@"
+
+Text_AskNicknameNewlyCaughtMon:
+ ; Give a nickname to @ ?
+ text_jump UnknownText_0x1c5b7f
+ db "@"
+
+ReturnToBattle_UseBall:
+ farcall _ReturnToBattle_UseBall
+ ret
+
+TownMapEffect:
+ farcall PokegearMap
+ ret
+
+BicycleEffect:
+ farcall BikeFunction
+ ret
+
+EvoStoneEffect:
+ ld b, PARTYMENUACTION_EVO_STONE
+ call UseItem_SelectMon
+
+ jp c, .DecidedNotToUse
+
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+
+ ld a, [hl]
+ cp EVERSTONE
+ jr z, .NoEffect
+
+ ld a, $1
+ ld [wForceEvolution], a
+ farcall EvolvePokemon
+
+ ld a, [wMonTriedToEvolve]
+ and a
+ jr z, .NoEffect
+
+ jp UseDisposableItem
+
+.NoEffect:
+ call WontHaveAnyEffectMessage
+
+.DecidedNotToUse:
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+
+VitaminEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, RareCandy_StatBooster_ExitMenu
+
+ call RareCandy_StatBooster_GetParameters
+
+ call GetStatExpRelativePointer
+
+ ld a, MON_STAT_EXP
+ call GetPartyParamLocation
+
+ add hl, bc
+ ld a, [hl]
+ cp 100
+ jr nc, NoEffectMessage
+
+ add 10
+ ld [hl], a
+ call UpdateStatsAfterItem
+
+ call GetStatExpRelativePointer
+
+ ld hl, StatStrings
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wStringBuffer2
+ ld bc, ITEM_NAME_LENGTH
+ call CopyBytes
+
+ call Play_SFX_FULL_HEAL
+
+ ld hl, Text_StatRose
+ call PrintText
+
+ ld c, HAPPINESS_USEDITEM
+ farcall ChangeHappiness
+
+ jp UseDisposableItem
+
+NoEffectMessage:
+ ld hl, WontHaveAnyEffectText
+ call PrintText
+ jp ClearPalettes
+
+UpdateStatsAfterItem:
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+ ld a, MON_STAT_EXP - 1
+ call GetPartyParamLocation
+ ld b, TRUE
+ predef_jump CalcMonStats
+
+RareCandy_StatBooster_ExitMenu:
+ xor a
+ ld [wItemEffectSucceeded], a
+ jp ClearPalettes
+
+Text_StatRose:
+ ; 's @ rose.
+ text_jump UnknownText_0x1c5b9a
+ db "@"
+
+StatStrings:
+ dw .health
+ dw .attack
+ dw .defense
+ dw .speed
+ dw .special
+
+.health db "HEALTH@"
+.attack db "ATTACK@"
+.defense db "DEFENSE@"
+.speed db "SPEED@"
+.special db "SPECIAL@"
+
+GetStatExpRelativePointer:
+ ld a, [wCurItem]
+ ld hl, Table_eeeb
+.next
+ cp [hl]
+ inc hl
+ jr z, .got_it
+ inc hl
+ jr .next
+
+.got_it
+ ld a, [hl]
+ ld c, a
+ ld b, 0
+ ret
+
+Table_eeeb:
+ db HP_UP, MON_HP_EXP - MON_STAT_EXP
+ db PROTEIN, MON_ATK_EXP - MON_STAT_EXP
+ db IRON, MON_DEF_EXP - MON_STAT_EXP
+ db CARBOS, MON_SPD_EXP - MON_STAT_EXP
+ db CALCIUM, MON_SPC_EXP - MON_STAT_EXP
+
+RareCandy_StatBooster_GetParameters:
+ ld a, [wCurPartySpecies]
+ ld [wCurSpecies], a
+ ld [wd265], a
+ ld a, MON_LEVEL
+ call GetPartyParamLocation
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ call GetBaseData
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMonNicknames
+ call GetNick
+ ret
+
+RareCandyEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, RareCandy_StatBooster_ExitMenu
+
+ call RareCandy_StatBooster_GetParameters
+
+ ld a, MON_LEVEL
+ call GetPartyParamLocation
+
+ ld a, [hl]
+ cp MAX_LEVEL
+ jp nc, NoEffectMessage
+
+ inc a
+ ld [hl], a
+ ld [wCurPartyLevel], a
+ push de
+ ld d, a
+ farcall CalcExpAtLevel
+
+ pop de
+ ld a, MON_EXP
+ call GetPartyParamLocation
+
+ ld a, [hMultiplicand]
+ ld [hli], a
+ ld a, [hMultiplicand + 1]
+ ld [hli], a
+ ld a, [hMultiplicand + 2]
+ ld [hl], a
+
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ call UpdateStatsAfterItem
+
+ ld a, MON_MAXHP + 1
+ call GetPartyParamLocation
+
+ pop bc
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a
+ dec hl
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ farcall LevelUpHappinessMod
+
+ ld a, PARTYMENUTEXT_LEVEL_UP
+ call ItemActionText
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+
+ hlcoord 9, 0
+ ld b, 10
+ ld c, 9
+ call TextBox
+
+ hlcoord 11, 1
+ ld bc, 4
+ predef PrintTempMonStats
+
+ call WaitPressAorB_BlinkCursor
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ predef LearnLevelMoves
+
+ xor a
+ ld [wForceEvolution], a
+ farcall EvolvePokemon
+
+ jp UseDisposableItem
+
+HealPowderEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, StatusHealer_ExitMenu
+
+ call UseStatusHealer
+
+ cp $0
+ jr nz, .asm_efc9
+ ld c, HAPPINESS_BITTERPOWDER
+ farcall ChangeHappiness
+
+ call LooksBitterMessage
+
+ ld a, $0
+
+.asm_efc9
+ jp StatusHealer_Jumptable
+
+StatusHealingEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+FullyHealStatus:
+ call UseStatusHealer
+ jp StatusHealer_Jumptable
+
+UseStatusHealer:
+ call IsMonFainted
+ ld a, $1
+ ret z
+ call GetItemHealingAction
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ ld a, [hl]
+ and c
+ jr nz, .good
+ call IsItemUsedOnConfusedMon
+ ld a, $1
+ ret nc
+ ld b, PARTYMENUTEXT_HEAL_CONFUSION
+.good
+ xor a
+ ld [hl], a
+ ld a, b
+ ld [wPartyMenuActionText], a
+ call HealStatus
+ call Play_SFX_FULL_HEAL
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, $0
+ ret
+
+IsItemUsedOnConfusedMon:
+ call IsItemUsedOnBattleMon
+ jr nc, .nope
+ ld a, [wPlayerSubStatus3]
+ bit SUBSTATUS_CONFUSED, a
+ jr z, .nope
+ ld a, c
+ cp $ff
+ jr nz, .nope
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+BattlemonRestoreHealth:
+ call IsItemUsedOnBattleMon
+ ret nc
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBattleMonHP], a
+ ld a, [hld]
+ ld [wBattleMonHP + 1], a
+ ret
+
+HealStatus:
+ call IsItemUsedOnBattleMon
+ ret nc
+ xor a
+ ld [wBattleMonStatus], a
+ ld hl, wPlayerSubStatus5
+ res SUBSTATUS_TOXIC, [hl]
+ ld hl, wPlayerSubStatus1
+ res SUBSTATUS_NIGHTMARE, [hl]
+ call GetItemHealingAction
+ ld a, c
+ cp %11111111
+ jr nz, .not_full_heal
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_CONFUSED, [hl]
+.not_full_heal
+ push bc
+ farcall CalcPlayerStats
+ pop bc
+ ret
+
+GetItemHealingAction:
+ push hl
+ ld a, [wCurItem]
+ ld hl, StatusHealingActions
+ ld bc, 3
+.next
+ cp [hl]
+ jr z, .found_it
+ add hl, bc
+ jr .next
+
+.found_it
+ inc hl
+ ld b, [hl]
+ inc hl
+ ld a, [hl]
+ ld c, a
+ cp %11111111
+ pop hl
+ ret
+
+INCLUDE "data/items/heal_status.asm"
+
+StatusHealer_Jumptable:
+ ld hl, .dw
+ rst JumpTable
+ ret
+
+.dw
+ dw StatusHealer_ClearPalettes
+ dw StatusHealer_NoEffect
+ dw StatusHealer_ExitMenu
+
+RevivalHerbEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call RevivePokemon
+ cp 0
+ jr nz, .asm_f0c5
+
+ ld c, HAPPINESS_REVIVALHERB
+ farcall ChangeHappiness
+ call LooksBitterMessage
+ ld a, 0
+
+.asm_f0c5
+ jp StatusHealer_Jumptable
+
+ReviveEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call RevivePokemon
+ jp StatusHealer_Jumptable
+
+RevivePokemon:
+ call IsMonFainted
+ ld a, 1
+ ret nz
+ ld a, [wBattleMode]
+ and a
+ jr z, .skip_to_revive
+
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld d, 0
+ ld hl, wBattleParticipantsIncludingFainted
+ ld b, CHECK_FLAG
+ predef SmallFarFlagAction
+ ld a, c
+ and a
+ jr z, .skip_to_revive
+
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld hl, wBattleParticipantsNotFainted
+ ld b, SET_FLAG
+ predef SmallFarFlagAction
+
+.skip_to_revive
+ xor a
+ ld [wLowHealthAlarm], a
+ ld a, [wCurItem]
+ cp REVIVE
+ jr z, .revive_half_hp
+
+ call ReviveFullHP
+ jr .finish_revive
+
+.revive_half_hp
+ call ReviveHalfHP
+
+.finish_revive
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_REVIVE
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+
+FullRestoreEffect:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call IsMonFainted
+ jp z, StatusHealer_NoEffect
+
+ call IsMonAtFullHealth
+ jr c, .NotAtFullHealth
+
+ jp FullyHealStatus
+
+.NotAtFullHealth:
+ call .FullRestore
+ jp StatusHealer_Jumptable
+
+.FullRestore:
+ xor a
+ ld [wLowHealthAlarm], a
+ call ReviveFullHP
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ xor a
+ ld [hli], a
+ ld [hl], a
+ call HealStatus
+ call BattlemonRestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+
+BitterBerryEffect:
+ ld hl, wPlayerSubStatus3
+ bit SUBSTATUS_CONFUSED, [hl]
+ ld a, 1
+ jr z, .done
+
+ res SUBSTATUS_CONFUSED, [hl]
+ xor a
+ ld [hBattleTurn], a
+ call UseItemText
+
+ ld hl, ConfusedNoMoreText
+ call StdBattleTextBox
+
+ ld a, 0
+
+.done
+ jp StatusHealer_Jumptable
+
+RestoreHPEffect:
+ call ItemRestoreHP
+ jp StatusHealer_Jumptable
+
+EnergypowderEffect:
+ ld c, HAPPINESS_BITTERPOWDER
+ jr EnergypowderEnergyRootCommon
+
+EnergyRootEffect:
+ ld c, HAPPINESS_ENERGYROOT
+
+EnergypowderEnergyRootCommon:
+ push bc
+ call ItemRestoreHP
+ pop bc
+ cp 0
+ jr nz, .skip_happiness
+
+ farcall ChangeHappiness
+ call LooksBitterMessage
+ ld a, 0
+
+.skip_happiness
+ jp StatusHealer_Jumptable
+
+ItemRestoreHP:
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ ld a, 2
+ ret c
+
+ call IsMonFainted
+ ld a, 1
+ ret z
+
+ call IsMonAtFullHealth
+ ld a, 1
+ ret nc
+
+ xor a
+ ld [wLowHealthAlarm], a
+ call GetHealingItemAmount
+ call RestoreHealth
+ call BattlemonRestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+
+HealHP_SFX_GFX:
+ push de
+ ld de, SFX_POTION
+ call WaitPlaySFX
+ pop de
+ ld a, [wCurPartyMon]
+ hlcoord 11, 0
+ ld bc, SCREEN_WIDTH * 2
+ call AddNTimes
+ ld a, $2
+ ld [wWhichHPBar], a
+ predef_jump AnimateHPBar
+
+UseItem_SelectMon:
+ call .SelectMon
+ ret c
+
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr nz, .not_egg
+
+ call CantUseOnEggMessage
+ scf
+ ret
+
+.not_egg
+ and a
+ ret
+
+.SelectMon:
+ ld a, b
+ ld [wPartyMenuActionText], a
+ push hl
+ push de
+ push bc
+ call ClearBGPalettes
+ call ChooseMonToUseItemOn
+ pop bc
+ pop de
+ pop hl
+ ret
+
+ChooseMonToUseItemOn:
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ ret
+
+ItemActionText:
+ ld [wPartyMenuActionText], a
+ ld a, [wCurPartySpecies]
+ push af
+ ld a, [wCurPartyMon]
+ push af
+ push hl
+ push de
+ push bc
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuActionText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ pop bc
+ pop de
+ pop hl
+ pop af
+ ld [wCurPartyMon], a
+ pop af
+ ld [wCurPartySpecies], a
+ ret
+
+ItemActionTextWaitButton:
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 0, 0
+ ld bc, wTileMapEnd - wTileMap
+ ld a, " "
+ call ByteFill
+ ld a, [wPartyMenuActionText]
+ call ItemActionText
+ ld a, $1
+ ld [hBGMapMode], a
+ ld c, 50
+ call DelayFrames
+ jp WaitPressAorB_BlinkCursor
+
+StatusHealer_NoEffect:
+ call WontHaveAnyEffectMessage
+ jr StatusHealer_ClearPalettes
+
+StatusHealer_ExitMenu:
+ xor a
+ ld [wItemEffectSucceeded], a
+StatusHealer_ClearPalettes:
+ call ClearPalettes
+ ret
+
+IsItemUsedOnBattleMon:
+ ld a, [wBattleMode]
+ and a
+ ret z
+ ld a, [wCurPartyMon]
+ push hl
+ ld hl, wCurBattleMon
+ cp [hl]
+ pop hl
+ jr nz, .nope
+ scf
+ ret
+
+.nope
+ xor a
+ ret
+
+ReviveHalfHP:
+ call LoadHPFromBuffer1
+ srl d
+ rr e
+ jr ContinueRevive
+
+ReviveFullHP:
+ call LoadHPFromBuffer1
+ContinueRevive:
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ jp LoadCurHPIntoBuffer5
+
+RestoreHealth:
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hl], a
+ jr c, .full_hp
+ call LoadCurHPIntoBuffer5
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+ ld a, MON_MAXHP + 1
+ call GetPartyParamLocation
+ ld a, [de]
+ sub [hl]
+ dec de
+ dec hl
+ ld a, [de]
+ sbc [hl]
+ jr c, .finish
+.full_hp
+ call ReviveFullHP
+.finish
+ ret
+
+RemoveHP:
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld a, [hl]
+ sub e
+ ld [hld], a
+ ld a, [hl]
+ sbc d
+ ld [hl], a
+ jr nc, .okay
+ xor a
+ ld [hld], a
+ ld [hl], a
+.okay
+ call LoadCurHPIntoBuffer5
+ ret
+
+IsMonFainted:
+ push de
+ call LoadMaxHPToBuffer1
+ call LoadCurHPToBuffer3
+ call LoadHPFromBuffer3
+ ld a, d
+ or e
+ pop de
+ ret
+
+IsMonAtFullHealth:
+ call LoadHPFromBuffer3
+ ld h, d
+ ld l, e
+ call LoadHPFromBuffer1
+ ld a, l
+ sub e
+ ld a, h
+ sbc d
+ ret
+
+LoadCurHPIntoBuffer5:
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer6], a
+ ld a, [hl]
+ ld [wBuffer5], a
+ ret
+
+LoadHPIntoBuffer5:
+ ld a, d
+ ld [wBuffer6], a
+ ld a, e
+ ld [wBuffer5], a
+ ret
+
+LoadHPFromBuffer5:
+ ld a, [wBuffer6]
+ ld d, a
+ ld a, [wBuffer5]
+ ld e, a
+ ret
+
+LoadCurHPToBuffer3:
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer4], a
+ ld a, [hl]
+ ld [wBuffer3], a
+ ret
+
+LoadHPFromBuffer3:
+ ld a, [wBuffer4]
+ ld d, a
+ ld a, [wBuffer3]
+ ld e, a
+ ret
+
+LoadMaxHPToBuffer1:
+ push hl
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld a, [hl]
+ ld [wBuffer1], a
+ pop hl
+ ret
+
+LoadHPFromBuffer1:
+ ld a, [wBuffer2]
+ ld d, a
+ ld a, [wBuffer1]
+ ld e, a
+ ret
+
+GetOneFifthMaxHP:
+ push bc
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [hDividend + 0], a
+ ld a, [hl]
+ ld [hDividend + 1], a
+ ld a, 5
+ ld [hDivisor], a
+ ld b, 2
+ call Divide
+ ld a, [hQuotient + 1]
+ ld d, a
+ ld a, [hQuotient + 2]
+ ld e, a
+ pop bc
+ ret
+
+GetHealingItemAmount:
+ push hl
+ ld a, [wCurItem]
+ ld hl, HealingHPAmounts
+ ld d, a
+.next
+ ld a, [hli]
+ cp -1
+ jr z, .NotFound
+ cp d
+ jr z, .done
+ inc hl
+ inc hl
+ jr .next
+
+.NotFound:
+ scf
+.done
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ ret
+
+INCLUDE "data/items/heal_hp.asm"
+
+Softboiled_MilkDrinkFunction:
+; Softboiled/Milk Drink in the field
+ ld a, [wPartyMenuCursor]
+ dec a
+ ld b, a
+ call .SelectMilkDrinkRecipient ; select pokemon
+ jr c, .skip
+ ld a, b
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ call GetOneFifthMaxHP
+ call RemoveHP
+ push bc
+ call HealHP_SFX_GFX
+ pop bc
+ call GetOneFifthMaxHP
+ ld a, c
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ call RestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ call ItemActionText
+ call JoyWaitAorB
+.skip
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+ ret
+
+.SelectMilkDrinkRecipient:
+.loop
+ push bc
+ ld a, PARTYMENUACTION_HEALING_ITEM
+ ld [wPartyMenuActionText], a
+ call ChooseMonToUseItemOn
+ pop bc
+ jr c, .set_carry
+ ld a, [wPartyMenuCursor]
+ dec a
+ ld c, a
+ ld a, b
+ cp c
+ jr z, .cant_use ; chose the same mon as user
+ ld a, c
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ jr z, .cant_use
+ call IsMonAtFullHealth
+ jr nc, .cant_use
+ xor a
+ ret
+
+.set_carry
+ scf
+ ret
+
+.cant_use
+ push bc
+ ld hl, .Text_CantBeUsed
+ call MenuTextBoxBackup
+ pop bc
+ jr .loop
+
+.Text_CantBeUsed:
+ ; That can't be used on this #MON.
+ text_jump UnknownText_0x1c5bac
+ db "@"
+
+EscapeRopeEffect:
+ xor a
+ ld [wItemEffectSucceeded], a
+ farcall EscapeRopeFunction
+
+ ld a, [wItemEffectSucceeded]
+ cp 1
+ call z, UseDisposableItem
+ ret
+
+SuperRepelEffect:
+ ld b, 200
+ jr UseRepel
+
+MaxRepelEffect:
+ ld b, 250
+ jr UseRepel
+
+RepelEffect:
+ ld b, 100
+
+UseRepel:
+ ld a, [wRepelEffect]
+ and a
+ ld hl, TextJump_RepelUsedEarlierIsStillInEffect
+ jp nz, PrintText
+
+ ld a, b
+ ld [wRepelEffect], a
+ jp UseItemText
+
+TextJump_RepelUsedEarlierIsStillInEffect:
+ ; The REPEL used earlier is still in effect.
+ text_jump Text_RepelUsedEarlierIsStillInEffect
+ db "@"
+
+XAccuracyEffect:
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_X_ACCURACY, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_X_ACCURACY, [hl]
+ jp UseItemText
+
+PokeDollEffect:
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .asm_f4a6
+ inc a
+ ld [wForcedSwitch], a
+ ld a, [wBattleResult]
+ and BATTLERESULT_BITMASK
+ or DRAW
+ ld [wBattleResult], a
+ jp UseItemText
+
+.asm_f4a6
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+
+GuardSpecEffect:
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_MIST, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_MIST, [hl]
+ jp UseItemText
+
+DireHitEffect:
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_FOCUS_ENERGY, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_FOCUS_ENERGY, [hl]
+ jp UseItemText
+
+XItemEffect:
+ call UseItemText
+
+ ld a, [wCurItem]
+ ld hl, XItemStats
+
+.loop
+ cp [hl]
+ jr z, .got_it
+ inc hl
+ inc hl
+ jr .loop
+
+.got_it
+ inc hl
+ ld b, [hl]
+ xor a
+ ld [hBattleTurn], a
+ ld [wAttackMissed], a
+ ld [wEffectFailed], a
+ farcall CheckIfStatCanBeRaised
+ call WaitSFX
+
+ farcall BattleCommand_StatUpMessage
+ farcall BattleCommand_StatUpFailText
+
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ ld c, HAPPINESS_USEDXITEM
+ farcall ChangeHappiness
+ ret
+
+INCLUDE "data/items/x_stats.asm"
+
+PokeFluteEffect:
+ ld a, [wBattleMode]
+ and a
+ jr nz, .dummy
+.dummy
+
+ xor a
+ ld [wd002], a
+
+ ld b, $ff ^ SLP
+
+ ld hl, wPartyMon1Status
+ call .CureSleep
+
+ ld a, [wBattleMode]
+ cp WILD_BATTLE
+ jr z, .skip_otrainer
+ ld hl, wOTPartyMon1Status
+ call .CureSleep
+.skip_otrainer
+
+ ld hl, wBattleMonStatus
+ ld a, [hl]
+ and b
+ ld [hl], a
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and b
+ ld [hl], a
+
+ ld a, [wd002]
+ and a
+ ld hl, .CatchyTune
+ jp z, PrintText
+ ld hl, .PlayedTheFlute
+ call PrintText
+
+ ld a, [wLowHealthAlarm]
+ and 1 << DANGER_ON_F
+ jr nz, .dummy2
+.dummy2
+ ld hl, .AllSleepingMonWokeUp
+ jp PrintText
+
+.CureSleep:
+ ld de, PARTYMON_STRUCT_LENGTH
+ ld c, PARTY_LENGTH
+
+.loop
+ ld a, [hl]
+ push af
+ and SLP
+ jr z, .not_asleep
+ ld a, 1
+ ld [wd002], a
+.not_asleep
+ pop af
+ and b
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+.CatchyTune:
+ ; Played the # FLUTE. Now, that's a catchy tune!
+ text_jump UnknownText_0x1c5bf9
+ db "@"
+
+.AllSleepingMonWokeUp:
+ ; All sleeping #MON woke up.
+ text_jump UnknownText_0x1c5c28
+ db "@"
+
+.PlayedTheFlute:
+ ; played the # FLUTE.@ @
+ text_jump UnknownText_0x1c5c44
+ start_asm
+ ld a, [wBattleMode]
+ and a
+ jr nz, .battle
+
+ push de
+ ld de, SFX_POKEFLUTE
+ call WaitPlaySFX
+ call WaitSFX
+ pop de
+
+.battle
+ jp PokeFluteTerminatorCharacter
+
+BlueCardEffect:
+ ld hl, .bluecardtext
+ jp MenuTextBoxWaitButton
+
+.bluecardtext
+ text_jump UnknownText_0x1c5c5e
+ db "@"
+
+CoinCaseEffect:
+ ld hl, .coincasetext
+ jp MenuTextBoxWaitButton
+
+.coincasetext
+ text_jump UnknownText_0x1c5c7b
+ db "@"
+
+OldRodEffect:
+ ld e, $0
+ jr UseRod
+
+GoodRodEffect:
+ ld e, $1
+ jr UseRod
+
+SuperRodEffect:
+ ld e, $2
+ jr UseRod
+
+UseRod:
+ farcall FishFunction
+ ret
+
+ItemfinderEffect:
+ farcall ItemFinder
+ ret
+
+RestorePPEffect:
+ ld a, [wCurItem]
+ ld [wd002], a
+
+.loop
+ ; Party Screen opens to choose on which mon to use the Item
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, PPRestoreItem_Cancel
+
+.loop2
+ ld a, [wd002]
+ cp MAX_ELIXER
+ jp z, Elixer_RestorePPofAllMoves
+ cp ELIXER
+ jp z, Elixer_RestorePPofAllMoves
+
+ ld hl, TextJump_RaiseThePPOfWhichMove
+ ld a, [wd002]
+ cp PP_UP
+ jr z, .ppup
+ ld hl, TextJump_RestoreThePPOfWhichMove
+
+.ppup
+ call PrintText
+
+ ld a, [wCurMoveNum]
+ push af
+ xor a
+ ld [wCurMoveNum], a
+ ld a, $2
+ ld [wMoveSelectionMenuType], a
+ farcall MoveSelectionScreen
+ pop bc
+
+ ld a, b
+ ld [wCurMoveNum], a
+ jr nz, .loop
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+
+ push hl
+ ld a, [hl]
+ ld [wd265], a
+ call GetMoveName
+ call CopyName1
+ pop hl
+
+ ld a, [wd002]
+ cp PP_UP
+ jp nz, Not_PP_Up
+
+ ld a, [hl]
+ cp SKETCH
+ jr z, .CantUsePPUpOnSketch
+
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld a, [hl]
+ cp PP_UP_MASK
+ jr c, .do_ppup
+
+.CantUsePPUpOnSketch:
+.pp_is_maxed_out
+ ld hl, TextJump_PPIsMaxedOut
+ call PrintText
+ jr .loop2
+
+.do_ppup
+ ld a, [hl]
+ add PP_UP_ONE
+ ld [hl], a
+ ld a, $1
+ ld [wd265], a
+ call ApplyPPUp
+ call Play_SFX_FULL_HEAL
+
+ ld hl, TextJump_PPsIncreased
+ call PrintText
+
+FinishPPRestore:
+ call ClearPalettes
+ jp UseDisposableItem
+
+BattleRestorePP:
+ ld a, [wBattleMode]
+ and a
+ jr z, .not_in_battle
+ ld a, [wCurPartyMon]
+ ld b, a
+ ld a, [wCurBattleMon]
+ cp b
+ jr nz, .not_in_battle
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .not_in_battle
+ call .UpdateBattleMonPP
+
+.not_in_battle
+ call Play_SFX_FULL_HEAL
+ ld hl, UnknownText_0xf739
+ call PrintText
+ jr FinishPPRestore
+
+.UpdateBattleMonPP:
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld de, wBattleMonMoves
+ ld b, NUM_MOVES
+.loop
+ ld a, [de]
+ and a
+ jr z, .done
+ cp [hl]
+ jr nz, .next
+ push hl
+ push de
+ push bc
+rept NUM_MOVES + 2 ; wBattleMonPP - wBattleMonMoves
+ inc de
+endr
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld a, [hl]
+ ld [de], a
+ pop bc
+ pop de
+ pop hl
+
+.next
+ inc hl
+ inc de
+ dec b
+ jr nz, .loop
+
+.done
+ ret
+
+Not_PP_Up:
+ call RestorePP
+ jr nz, BattleRestorePP
+ jp PPRestoreItem_NoEffect
+
+Elixer_RestorePPofAllMoves:
+ xor a
+ ld hl, wMenuCursorY
+ ld [hli], a
+ ld [hl], a
+ ld b, NUM_MOVES
+.moveLoop
+ push bc
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+ ld a, [hl]
+ and a
+ jr z, .next
+
+ call RestorePP
+ jr z, .next
+ ld hl, wMenuCursorX
+ inc [hl]
+
+.next
+ ld hl, wMenuCursorY
+ inc [hl]
+ pop bc
+ dec b
+ jr nz, .moveLoop
+ ld a, [wMenuCursorX]
+ and a
+ jp nz, BattleRestorePP
+
+PPRestoreItem_NoEffect:
+ call WontHaveAnyEffectMessage
+
+PPRestoreItem_Cancel:
+ call ClearPalettes
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+
+RestorePP:
+ xor a ; PARTYMON
+ ld [wMonType], a
+ call GetMaxPPOfMove
+ ld hl, wPartyMon1PP
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+ ld a, [wd265]
+ ld b, a
+ ld a, [hl]
+ and PP_MASK
+ cp b
+ jr nc, .dont_restore
+
+ ld a, [wd002]
+ cp MAX_ELIXER
+ jr z, .restore_all
+ cp MAX_ETHER
+ jr z, .restore_all
+
+ ld c, 5
+ cp MYSTERYBERRY
+ jr z, .restore_some
+
+ ld c, 10
+
+.restore_some
+ ld a, [hl]
+ and PP_MASK
+ add c
+ cp b
+ jr nc, .restore_all
+ ld b, a
+
+.restore_all
+ ld a, [hl]
+ and PP_UP_MASK
+ or b
+ ld [hl], a
+ ret
+
+.dont_restore
+ xor a
+ ret
+
+TextJump_RaiseThePPOfWhichMove:
+ ; Raise the PP of which move?
+ text_jump Text_RaiseThePPOfWhichMove
+ db "@"
+
+TextJump_RestoreThePPOfWhichMove:
+ ; Restore the PP of which move?
+ text_jump Text_RestoreThePPOfWhichMove
+ db "@"
+
+TextJump_PPIsMaxedOut:
+ ; 's PP is maxed out.
+ text_jump Text_PPIsMaxedOut
+ db "@"
+
+TextJump_PPsIncreased:
+ ; 's PP increased.
+ text_jump Text_PPsIncreased
+ db "@"
+
+UnknownText_0xf739:
+ ; PP was restored.
+ text_jump UnknownText_0x1c5cf1
+ db "@"
+
+SquirtbottleEffect:
+ farcall _Squirtbottle
+ ret
+
+CardKeyEffect:
+ farcall _CardKey
+ ret
+
+BasementKeyEffect:
+ farcall _BasementKey
+ ret
+
+SacredAshEffect:
+ farcall _SacredAsh
+ ld a, [wItemEffectSucceeded]
+ cp $1
+ ret nz
+ call UseDisposableItem
+ ret
+
+NormalBoxEffect:
+ ld c, DECOFLAG_SILVER_TROPHY_DOLL
+ jr OpenBox
+
+GorgeousBoxEffect:
+ ld c, DECOFLAG_GOLD_TROPHY_DOLL
+OpenBox:
+ farcall SetSpecificDecorationFlag
+
+ ld hl, .text
+ call PrintText
+
+ jp UseDisposableItem
+
+.text
+ ; There was a trophy inside!
+ text_jump UnknownText_0x1c5d03
+ db "@"
+
+NoEffect:
+ jp IsntTheTimeMessage
+
+Play_SFX_FULL_HEAL:
+ push de
+ ld de, SFX_FULL_HEAL
+ call WaitPlaySFX
+ pop de
+ ret
+
+UseItemText:
+ ld hl, UsedItemText
+ call PrintText
+ call Play_SFX_FULL_HEAL
+ call WaitPressAorB_BlinkCursor
+UseDisposableItem:
+ ld hl, wNumItems
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+ jp TossItem
+
+UseBallInTrainerBattle:
+ call ReturnToBattle_UseBall
+ ld de, ANIM_THROW_POKE_BALL
+ ld a, e
+ ld [wFXAnimID], a
+ ld a, d
+ ld [wFXAnimID + 1], a
+ xor a
+ ld [wBattleAnimParam], a
+ ld [hBattleTurn], a
+ ld [wNumHits], a
+ predef PlayBattleAnim
+ ld hl, BlockedTheBallText
+ call PrintText
+ ld hl, DontBeAThiefText
+ call PrintText
+ jr UseDisposableItem
+
+WontHaveAnyEffect_NotUsedMessage:
+ ld hl, WontHaveAnyEffectText
+ call PrintText
+
+ ; Item wasn't used.
+ ld a, $2
+ ld [wItemEffectSucceeded], a
+ ret
+
+LooksBitterMessage:
+ ld hl, LooksBitterText
+ jp PrintText
+
+Ball_BoxIsFullMessage:
+ ld hl, Ball_BoxIsFullText
+ call PrintText
+
+ ; Item wasn't used.
+ ld a, $2
+ ld [wItemEffectSucceeded], a
+ ret
+
+CantUseOnEggMessage:
+ ld hl, CantUseOnEggText
+ jr CantUseItemMessage
+
+IsntTheTimeMessage:
+ ld hl, IsntTheTimeText
+ jr CantUseItemMessage
+
+WontHaveAnyEffectMessage:
+ ld hl, WontHaveAnyEffectText
+ jr CantUseItemMessage
+
+BelongsToSomeoneElseMessage:
+ ld hl, BelongsToSomeoneElseText
+ jr CantUseItemMessage
+
+CyclingIsntAllowedMessage:
+ ld hl, CyclingIsntAllowedText
+ jr CantUseItemMessage
+
+CantGetOnYourBikeMessage:
+ ld hl, CantGetOnYourBikeText
+
+CantUseItemMessage:
+; Item couldn't be used.
+ xor a
+ ld [wItemEffectSucceeded], a
+ jp PrintText
+
+LooksBitterText:
+ ; It looks bitter…
+ text_jump UnknownText_0x1c5d3e
+ db "@"
+
+CantUseOnEggText:
+ ; That can't be used on an EGG.
+ text_jump UnknownText_0x1c5d50
+ db "@"
+
+IsntTheTimeText:
+ ; OAK: ! This isn't the time to use that!
+ text_jump UnknownText_0x1c5d6e
+ db "@"
+
+BelongsToSomeoneElseText:
+ ; That belongs to someone else!
+ text_jump UnknownText_0x1c5d97
+ db "@"
+
+WontHaveAnyEffectText:
+ ; It won't have any effect.
+ text_jump UnknownText_0x1c5db6
+ db "@"
+
+BlockedTheBallText:
+ ; The trainer blocked the BALL!
+ text_jump UnknownText_0x1c5dd0
+ db "@"
+
+DontBeAThiefText:
+ ; Don't be a thief!
+ text_jump UnknownText_0x1c5def
+ db "@"
+
+CyclingIsntAllowedText:
+ ; Cycling isn't allowed here.
+ text_jump UnknownText_0x1c5e01
+ db "@"
+
+CantGetOnYourBikeText:
+ ; Can't get on your @ now.
+ text_jump UnknownText_0x1c5e1d
+ db "@"
+
+Ball_BoxIsFullText:
+ ; The #MON BOX is full. That can't be used now.
+ text_jump UnknownText_0x1c5e3a
+ db "@"
+
+UsedItemText:
+ ; used the@ .
+ text_jump UnknownText_0x1c5e68
+ db "@"
+
+GotOnTheItemText:
+ ; got on the@ .
+ text_jump UnknownText_0x1c5e7b
+ db "@"
+
+GotOffTheItemText:
+ ; got off@ the @ .
+ text_jump UnknownText_0x1c5e90
+ db "@"
+
+ApplyPPUp:
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+ push hl
+ ld de, wBuffer1
+ predef FillPP
+ pop hl
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld de, wBuffer1
+ ld b, 0
+.loop
+ inc b
+ ld a, b
+ cp NUM_MOVES + 1
+ ret z
+ ld a, [wd265]
+ dec a
+ jr nz, .use
+ ld a, [wMenuCursorY]
+ inc a
+ cp b
+ jr nz, .skip
+
+.use
+ ld a, [hl]
+ and PP_UP_MASK
+ ld a, [de] ; wasted cycle
+ call nz, ComputeMaxPP
+
+.skip
+ inc hl
+ inc de
+ jr .loop
+
+ComputeMaxPP:
+ push bc
+ ; Divide the base PP by 5.
+ ld a, [de]
+ ld [hDividend + 3], a
+ xor a
+ ld [hDividend], a
+ ld [hDividend + 1], a
+ ld [hDividend + 2], a
+ ld a, 5
+ ld [hDivisor], a
+ ld b, 4
+ call Divide
+ ; Get the number of PP, which are bits 6 and 7 of the PP value stored in RAM.
+ ld a, [hl]
+ ld b, a
+ swap a
+ and $f
+ srl a
+ srl a
+ ld c, a
+ ; If this value is 0, we are done
+ and a
+ jr z, .NoPPUp
+
+.loop
+ ; Normally, a move with 40 PP would have 64 PP with three PP Ups.
+ ; Since this would overflow into bit 6, we prevent that from happening
+ ; by decreasing the extra amount of PP each PP Up provides, resulting
+ ; in a maximum of 61.
+ ld a, [hQuotient + 2]
+ cp $8
+ jr c, .okay
+ ld a, $7
+
+.okay
+ add b
+ ld b, a
+ ld a, [wd265]
+ dec a
+ jr z, .NoPPUp
+ dec c
+ jr nz, .loop
+
+.NoPPUp:
+ ld [hl], b
+ pop bc
+ ret
+
+RestoreAllPP:
+ ld a, MON_PP
+ call GetPartyParamLocation
+ push hl
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+ pop de
+ xor a ; PARTYMON
+ ld [wMenuCursorY], a
+ ld [wMonType], a
+ ld c, NUM_MOVES
+.loop
+ ld a, [hli]
+ and a
+ ret z
+ push hl
+ push de
+ push bc
+ call GetMaxPPOfMove
+ pop bc
+ pop de
+ ld a, [de]
+ and PP_UP_MASK
+ ld b, a
+ ld a, [wd265]
+ add b
+ ld [de], a
+ inc de
+ ld hl, wMenuCursorY
+ inc [hl]
+ pop hl
+ dec c
+ jr nz, .loop
+ ret
+
+GetMaxPPOfMove:
+ ld a, [wStringBuffer1 + 0]
+ push af
+ ld a, [wStringBuffer1 + 1]
+ push af
+
+ ld a, [wMonType]
+ and a
+
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ jr z, .got_partymon ; PARTYMON
+
+ ld hl, wOTPartyMon1Moves
+ dec a
+ jr z, .got_partymon ; OTPARTYMON
+
+ ld hl, wTempMonMoves
+ dec a
+ jr z, .got_nonpartymon ; BOXMON
+
+ ld hl, wTempMonMoves ; Wasted cycles
+ dec a
+ jr z, .got_nonpartymon ; TEMPMON
+
+ ld hl, wBattleMonMoves ; WILDMON
+
+.got_nonpartymon ; BOXMON, TEMPMON, WILDMON
+ call GetMthMoveOfCurrentMon
+ jr .gotdatmove
+
+.got_partymon ; PARTYMON, OTPARTYMON
+ call GetMthMoveOfNthPartymon
+
+.gotdatmove
+ ld a, [hl]
+ dec a
+
+ push hl
+ ld hl, Moves + MOVE_PP
+ ld bc, MOVE_LENGTH
+ call AddNTimes
+ ld a, BANK(Moves)
+ call GetFarByte
+ ld b, a
+ ld de, wStringBuffer1
+ ld [de], a
+ pop hl
+
+ push bc
+ ld bc, MON_PP - MON_MOVES
+ ld a, [wMonType]
+ cp WILDMON
+ jr nz, .notwild
+ ld bc, wEnemyMonPP - wEnemyMonMoves
+.notwild
+ add hl, bc
+ ld a, [hl]
+ and PP_UP_MASK
+ pop bc
+
+ or b
+ ld hl, wStringBuffer1 + 1
+ ld [hl], a
+ xor a
+ ld [wd265], a
+ ld a, b ; this gets lost anyway
+ call ComputeMaxPP
+ ld a, [hl]
+ and PP_MASK
+ ld [wd265], a
+
+ pop af
+ ld [wStringBuffer1 + 1], a
+ pop af
+ ld [wStringBuffer1 + 0], a
+ ret
+
+GetMthMoveOfNthPartymon:
+ ld a, [wCurPartyMon]
+ call AddNTimes
+
+GetMthMoveOfCurrentMon:
+ ld a, [wMenuCursorY]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ret